Search code examples
iosavaudiosessionaudioqueue

AudioQueue recording at 8 KHz, not calling Callback every 20 ms


iOS 10+ iPhone: 5s & 6 Xcode: 9+

I'm recording audio using aLaw codec at 8 KHz samplerate with sample size 8 bits. I create an AudioQueue like this:

// create the queue
XThrowIfError(AudioQueueNewInput(
                                 &mRecordFormat,
                                 MyInputBufferHandler,
                                 this /* userData */,
                                 NULL /* run loop */,
                                 kCFRunLoopCommonModes /* run loop mode */,
                                 0 /* flags */,
                                 &mQueue), "AudioQueueNewInput failed");

MyInputBufferHandler is the callback that is called every time a buffer (160 bytes every 20 ms) is filled. So I expect the callback is called every 20 ms. But when testing it, every 128 ms , MyInputBufferHandler callback is called 6 times in a burst. While I expect callback to be called every 20 ms. My recording configuration is:

mRecordFormat.mSampleRate = 8000.0; // 8 KHz
mRecordFormat.mChannelsPerFrame = 1;
mRecordFormat.mBytesPerFrame = 1;
mRecordFormat.mBitsPerChannel = 8;
mRecordFormat.mBytesPerPacket = 1;
mRecordFormat.mFramesPerPacket = 1;

Can someone please help me out? Why is MyInputBufferHandler called every 128 ms instead of 20 ms? Samplerate of 8 KHz with a buffer of 160 bytes of recording, means every 20 ms calling MyInputBufferHandler and not every 128 ms!


Solution

  • It seems that AudioQueue is on top of AudioUnit and somehow can't control the internal buffer size no matter what buffer size you set on AudioQueue level. So by default, the internal buffer is at minimum set to 1024 bytes. So if you want a callback after 160 bytes of recording data, it won't.

    So for those who run into the same problem, you need to use AudioUnit.

    Links of a similar situation: https://stackoverflow.com/a/4597409/1012775 https://stackoverflow.com/a/6687050/1012775