当前位置: 首页 > 知识库问答 >
问题:

使用AVAudioEngine的实时音频

孙修德
2023-03-14

嘿。我想在Swift中用新的AvaudioEngine实现一个实时音频应用程序。有人对新框架有经验吗?实时应用程序如何工作?

我的第一个想法是将(处理过的)输入数据存储到AvaudioPcmBuffer对象中,然后让它通过AvaudioPlayerNode播放,如您在我的演示类中所见:

import AVFoundation

class AudioIO {
    var audioEngine: AVAudioEngine
    var audioInputNode : AVAudioInputNode
    var audioPlayerNode: AVAudioPlayerNode
    var audioMixerNode: AVAudioMixerNode
    var audioBuffer: AVAudioPCMBuffer

    init(){
        audioEngine = AVAudioEngine()
        audioPlayerNode = AVAudioPlayerNode()
        audioMixerNode = audioEngine.mainMixerNode

        let frameLength = UInt32(256)
        audioBuffer = AVAudioPCMBuffer(PCMFormat: audioPlayerNode.outputFormatForBus(0), frameCapacity: frameLength)
        audioBuffer.frameLength = frameLength

        audioInputNode = audioEngine.inputNode

        audioInputNode.installTapOnBus(0, bufferSize:frameLength, format: audioInputNode.outputFormatForBus(0), block: {(buffer, time) in
            let channels = UnsafeArray(start: buffer.floatChannelData, length: Int(buffer.format.channelCount))
            let floats = UnsafeArray(start: channels[0], length: Int(buffer.frameLength))

            for var i = 0; i < Int(self.audioBuffer.frameLength); i+=Int(self.audioMixerNode.outputFormatForBus(0).channelCount)
            {
                // doing my real time stuff
                self.audioBuffer.floatChannelData.memory[i] = floats[i];
            }
            })

        // setup audio engine
        audioEngine.attachNode(audioPlayerNode)
        audioEngine.connect(audioPlayerNode, to: audioMixerNode, format: audioPlayerNode.outputFormatForBus(0))
        audioEngine.startAndReturnError(nil)

        // play player and buffer
        audioPlayerNode.play()
        audioPlayerNode.scheduleBuffer(audioBuffer, atTime: nil, options: .Loops, completionHandler: nil)
    }
}

但这离实时很远,效率也不是很高。有什么想法或经历吗?如果您更喜欢Objective-C或Swift,我非常感谢所有的注释、评论、意见、解决方案等。

共有1个答案

郑高驰
2023-03-14

我一直在Objective-C和Swift中试验AVAudioEngine。在我的引擎的Objective-C版本中,所有音频处理都完全用C语言完成(通过缓存通过AVAudioPCMBuffer获得的原始C示例指针,并仅用C代码对数据进行操作)。表演令人印象深刻。出于好奇,我把这个引擎移植到了Swift上。对于像线性播放音频文件或通过FM合成生成音调这样的任务,性能相当不错,但一旦涉及到阵列(例如,在粒度合成中,音频部分以非线性方式回放和操作),性能就会受到显著影响。即使进行了最好的优化,CPU使用率也比Objective-C/C版本高出30-40%。我刚接触过Swift,所以可能还有其他一些我不知道的优化,但就我所知,C/C++仍然是实时音频的最佳选择。还要看看惊人的音频引擎。我正在考虑这一点,以及直接使用旧的C API。

如果您需要处理现场音频,那么AVAudioEngine可能不适合您。请参阅我对此问题的回答:我希望每秒调用20次installTaponbus:buffersize:format:block:

 类似资料:
  • 我想创建一个实时正弦发生器使用苹果核心音频框架。我想做低水平,这样我就可以学习和理解基本原理。 通过使用VSYNC,我可以将循环降低到60 fps。时间不是很紧,但相当稳定。我也有一些代码来手动使用马赫计时,这甚至更不精确。为了可读性我把它省略了。不使用VSYNC或使用马赫定时来获得每秒60次迭代也会造成音频故障。 定时日志: 这里重要的是函数。它每秒被调用60次,并传递给它一个包含基本信息的结构

  • 我面临的问题,使用MediaPlayer以及原生Android音频播放器播放音频网址。这是我的网址http://live.politiafm.com:8500/politiafm.mp3 这是我的代码使用本机音频播放器Intent意图=new Intent(android.content.Intent。ACTION_VIEW);intent.setDataAndType(Uri.parse(STR

  • A.我正在努力实现的目标。 允许在网络浏览器内进行实时语音识别的网络应用程序(像这样)。 B.我目前正在考虑使用的技术来实现A。 JavaScript 节点。js WebRTC 微软语音API或Pocketsphinx。js或其他东西(不能使用Web语音API) C.非常基本的工作流程 Web浏览器建立到节点服务器的连接(服务器充当信令服务器,还提供静态文件) D.问题 将节点。js是否适合实现C

  • 问题内容: 我正在另一台PC上实现从MIC到Java服务器的实时流传输。但是我只听到白噪声。 我已经附上了客户端程序和服务器程序 并且服务器端没有问题。它与android客户端AudioRecord完美运行。 问题答案: 因此,我用正弦波(或某种在某种意义上类似正弦波的东西)填充了麦克风,并且您的程序运行正常。 因此,我的具体更改是: 显然,我将其误解为一个512字节长的片段,并破坏了正弦波,但事

  • 问题内容: 我正在 iPhone6 Plus*上进行测试,插入或拔出耳机后会崩溃。 ,,在我的应用程序使用。 * 不带耳机的启动应用程序可以播放iPhone扬声器的声音。 带有耳机的启动应用可以播放耳机的声音。 在以下情况下发生错误。启动不带耳机的应用,并播放扬声器的声音。然后,如果我连接耳机,则耳机没有声音。之后拔下耳机的插头,即使扬声器也没有声音。当我触摸屏幕时,audioApp崩溃。 与使用

  • 问题内容: 我对从麦克风获取的音频进行下采样时遇到问题。我正在使用AVAudioEngine通过以下代码从麦克风中采样: 这段代码在iPhone 5s上非常有效,因为麦克风输入为8000Hz,并且缓冲区中充满了来自麦克风的数据。 问题是我希望能够从iPhone 6s(及更高版本)录制哪个麦克风以16000Hz录制的声音。奇怪的是,如果我将mixernode与引擎mainmixernode连接(使用