Search code examples
iosaudioqueue

The sound muted after playing audio with Audio Queue on iOS for a while


I am coding a real time audio playback program on iOS.

It receives audio RTP packages from the peer, and put it into audio queue to play.

When start playing, the sound is OK. But after 1 or 2 minutes, the sound muted, and there is no error reported from AudioQueue API. The callback function continues being called normally, nothing abnormal.

But it just muted.

My callback function:

1: Loop until there is enough data can be copied to audio queue buffer

do 
{
    read_bytes_enabled = g_audio_playback_buf.GetReadByteLen();
    if (read_bytes_enabled >= kAudioQueueBufferLength)
    {
        break;
    }
    usleep(10*1000);
}
while (true);

2: Copy to AudioQueue Buffer, and enqueue it. This callback function keeps running normally and no error.

//copy to audio queue buffer
read_bytes = kAudioQueueBufferLength;

g_audio_playback_buf.Read((unsigned char *)inBuffer->mAudioData, read_bytes);

WriteLog(LOG_PHONE_DEBUG, "AudioQueueBuffer(Play): copy [%d] bytes to AudioQueue buffer! Total len = %d", read_bytes, read_bytes_enabled);

inBuffer->mAudioDataByteSize = read_bytes;

UInt32 nPackets = read_bytes / g_audio_periodsize; // mono

inBuffer->mPacketDescriptionCount = nPackets;

// re-enqueue this buffer
AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL);

Solution

  • The problem has been resolved.

    The key point is, you can not let the audio queue buffer waits, you must keep feeding it, or it might be muted. If you don't have enough data, fill it with blank data.

    so the following code should be changed:

    do 
    {
        read_bytes_enabled = g_audio_playback_buf.GetReadByteLen();
        if (read_bytes_enabled >= kAudioQueueBufferLength)
    {
        break;
    }
        usleep(10*1000);
    }
    while (true);
    

    changed to this:

    read_bytes_enabled = g_audio_playback_buf.GetReadByteLen();
    if (read_bytes_enabled < kAudioQueueBufferLength)
    {
        memset(inBuffer->mAudioData, 0x00, kAudioQueueBufferLength);
    }
    else
    {
        inBuffer->mAudioDataByteSize = kAudioQueueBufferLength;
    }
    ...