我正在寻求创建一个应用程序,该应用程序从麦克风获取输入,对输入音频载体执行处理,并立即通过输出回放.我希望最终对此执行语音处理,因此我需要一个低延迟解决方案.然而,我当前的解决方案大约每100 ms回调一次,这对于我的用例来说太慢了.我希望每8 ms访问缓冲区进行回放.
我目前的解决方案是:
var audioEngine: AVAudioEngine
var inputNode: AVAudioInputNode
var playerNode: AVAudioPlayerNode
var bufferDuration: AVAudioFrameCount
init() {
audioEngine = AVAudioEngine()
inputNode = audioEngine.inputNode
playerNode = AVAudioPlayerNode()
bufferDuration = 960// AVAudioFrameCount(352)
}
func startStreaming() -> Void {
// Configure the session
do {
let audioSession = AVAudioSession.sharedInstance()
try audioSession.setCategory(.playAndRecord, mode: .voiceChat, options: [.defaultToSpeaker])
try audioSession.setPreferredSampleRate(96000)
try audioSession.setPreferredIOBufferDuration(0.008)
try audioSession.setActive(true)
try audioSession.overrideOutputAudioPort(.speaker)
} catch {
print("Audio Session error: \(error)")
}
let fmt = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: AVAudioSession.sharedInstance().sampleRate, channels: 2, interleaved: false)
// Set the playerNode to immediately queue/play the recorded buffer
inputNode.installTap(onBus: 0, bufferSize: bufferDuration, format: fmt) { (buffer: AVAudioPCMBuffer, when: AVAudioTime) in
// Schedule the buffer for playback
playerNode.scheduleBuffer(buffer, at: nil, options: [], completionHandler: nil)
}
// Start the engine
do {
audioEngine.attach(playerNode)
audioEngine.connect(playerNode, to: audioEngine.outputNode, format: fmt/*inputNode.inputFormat(forBus: 0)*/)
try audioEngine.start()
playerNode.play()
} catch {
print("Audio Engine start error: \(error)")
}
我try 过设置buffer. frameSize等选项,但似乎没有什么改变回调的频率.我不清楚这个问题是否在于框架不允许这么小的缓冲区,或者我是否错过了解决方案.该网站上的其他已解决的解决方案提供了不需要低缓冲区大小的理由,但我确实需要一个非常快的解决方案.如果AVFEaudio无法实现这一点,AudioKit.io和Core Audio C API中是否有潜在的解决方案?