I am trying to use AVAudioEngine for listening to mic samples and playing them simultaneously via external speakers or headphones (assuming they are attached to iOS device). I tried the following using AVAudioPlayerNode and it works, but there is too much delay in the audio playback. Is there a way to hear sound realtime without delay?
var engine: AVAudioEngine!
var playerNode: AVAudioPlayerNode!
var mixer: AVAudioMixerNode!
var audioEngineRunning = false
public func setupAudioEngine() {
self.engine = AVAudioEngine()
let input = engine.inputNode
let format = input.inputFormat(forBus: 0)
playerNode = AVAudioPlayerNode()
engine.attach(playerNode)
self.mixer = engine.mainMixerNode
engine.connect(self.playerNode, to: self.mixer, format: playerNode.outputFormat(forBus: 0))
engine.inputNode.installTap(onBus: 0, bufferSize: 4096, format: format, block: { buffer, time in
self.playerNode.scheduleBuffer(buffer, completionHandler: nil)
})
do {
engine.prepare()
try self.engine.start()
audioEngineRunning = true
self.playerNode.play()
}
catch {
print("error couldn't start engine")
audioEngineRunning = false
}
}
You could try connecting the input node straight into the main mixer or output node so that your input signal passes through the physical output.
If you need, you could, as well, split the signal using connection points. Assuming you've got some effect nodes connected to main mixer's 0 and 1 bus, you could connect input to bus 2 of main mixer and bus 0 on effect nodes. (This is just an example and you could choose your own busses).
In my case there is a slight, millisecond delay that my ear notices but not too dealbreaker. There might be some other stuff that would reduce delay. Maybe we could provide smaller buffering value somewhere but I'm still new with AVFoundation and investigating some stuff.
UPDATE: I've just noticed you're using buffering size of
4096
which is too high for live performance btw. That's one of the reasons of the delay.