0
votes

I use AudioUnit to record and play audio with 8 KHz samplerate and 8 bits audio sample. I use the example from the following source: https://github.com/fuxx/MicInput

The playback part is based on a callback pattern. With this method, I don't have control on when to play audio, the Core Audio calls the callback when it needs more audio data to be played.

The thing is, I get audio data from the network and thus can't promise to have the audio data ready for the next callback. Sometimes, the callback misses the audio data from the network and so there's a gap of around 20 ms which sounds like a click.

Is it possible to render audio immediately without waiting for a callback? With AudioQueue it's possible by calling AudioQueueEnqueueBuffer(), I don't know how to that with AudioUnit. I hope you can help me.

1

1 Answers

1
votes

There is no way to play audio "immediately" without waiting for a callback (possibly hidden by the API), even ignoring issues such as hardware DMA interrupt timing, data buffering, and DAC latency.

The DAC (digital-to-analog converter) outputs audio samples at a fixed sample rate. Either you have data ready when audio samples need to be sent through the DAC, or some garbage (clicks, gaps, etc.) gets converted to analog audio.

Audio Units are based on a pull model (likely due to the needs of the underlying hardware DMA system and OS device driver). Audio Queues (and other APIs, such as the AVAudioPlayer) are built on top of Audio Units. So when you enqueue buffer to an Audio Queue, it doesn't really play immediately. Instead, that queue buffer still waits for an Audio Unit callback "under the hood".