HEJ.我想在
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,我很感谢所有的注释,评论,解决方案等.
我一直在Objective-C和Swift上试验AVAudioEngine.在我的引擎的Objective-C版本中,所有的音频处理都是纯粹在C(通过缓存通过AVAudioPCMBuffer可用的原始C样本指针,并且仅使用C代码对数据进行操作)完成的.表现令人印象深刻.出于好奇,我把这个引擎移植到了斯威夫特.通过线性播放音频文件或通过FM合成产生音调的任务,性能相当好,但是一旦涉及阵列(例如,使用细粒度合成,音频部分以非线性方式播放和操作) ),有一个显着的性能命中.即使采用最佳优化,cpu使用率也比Objective-C/C++版本高30-40%.我是Swift的新手,所以也许还有其他的优化我很无知,但据我所知,C/C++仍然是实时音频的最佳选择.还看看惊人的音频引擎.我正在考虑这一点,以及直接使用旧的C API.
如果您需要处理现场音频,则AVAudioEngine可能不适合您.看到我对这个问题的回答:I want to call 20 times per second the installTapOnBus:bufferSize:format:block: