Mobile Development 12 min read

Investigation and Fix of Audio Playback Stutter on iOS 14.5 Using Audio Queue and AVPlayer

The article details a systematic investigation of intermittent audio playback stutter on iOS 14.5, tracing the issue from AVPlayer playback through Audio Queue recording, analyzing AudioStreamBasicDescription parameters and buffer size inconsistencies, and presenting a code‑level fix that aligns buffer sizes before invoking AudioConverterFillComplexBuffer.

Liulishuo Tech Team
Liulishuo Tech Team
Liulishuo Tech Team
Investigation and Fix of Audio Playback Stutter on iOS 14.5 Using Audio Queue and AVPlayer

When iOS 14.5 was released, users reported that audio recorded during a quiz would play back with intermittent stutter, making continuous playback impossible. A cross‑system matrix showed the problem only when both recording and playback occurred on iOS 14.5, while iOS 14.0 behaved normally.

Initial debugging focused on the playback side, where the app uses the simple call AVPlayer(url: audioUrl).play() . Because the playback code contains no custom logic, the suspicion shifted to the recording pipeline.

The recording implementation relies on Audio Queue Services to capture audio in real time and stream the encoded Opus data via WebSocket. Audio Queues are software objects that manage a series of buffers; each buffer is filled from the input device (microphone) and later processed by a callback.

Key functions used in the business code include AudioQueueNewInput , AudioQueueStart , AudioQueueStop , AudioQueueAllocateBuffer , and AudioQueueEnqueueBuffer . The callback signature is:

AudioQueueInputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer, const AudioTimeStamp *inStartTime, UInt32 inNumberPacketDescriptions, const AudioStreamPacketDescription *inPacketDescs);

During the investigation the team examined the AudioStreamBasicDescription structure. The original parameters set mBitsPerChannel = 0 and left mReserved non‑zero, which violates Apple’s specifications for lossless formats. Adjusting the description to a proper PCM layout (e.g., 44.1 kHz, 16‑bit, interleaved) resolved the issue for MP3 but not for ALAC.

Further testing revealed that on iOS 14.5 the size of each audio queue buffer varies, whereas on iOS 14.0 it remains constant. The encoder requires a minimum buffer size of 8192 bytes (ALAC 4096 × 2 frames per packet). The solution was to align the accumulated source buffer to this threshold before calling AudioConverterFillComplexBuffer .

/// Adapt iOS 14.5 bug – only process when bufferSize ≥ 8192
func handleRawLPCMAudioBufferData(buffer: UnsafeMutableRawPointer, bufferSize: UInt32, packetCount: UInt32) throws -> ConverterOutputData {
    var error = noErr
    memcpy(settings.sourceBuffer.advanced(by: Int(settings.sourceBufferSize)), buffer, Int(bufferSize))
    settings.sourceBufferSize += bufferSize
    if settings.sourceBufferSize < KALACMaxBuffSize {
        throw getError(code: 2, description: "Buffer Too Small \(settings.sourceBufferSize)")
    }
    // ... processing logic ...
    memcpy(settings.sourceBuffer, settings.sourceBuffer.advanced(by: Int(KALACMaxBuffSize)), Int(settings.sourceBufferSize - KALACMaxBuffSize))
    settings.sourceBufferSize -= KALACMaxBuffSize
    return output
}

In addition, the AudioConverterComplexInputDataProc callback was simplified by removing unnecessary modifications to the mbuffers pointer, further stabilizing the conversion pipeline.

After these changes the recorded files play back smoothly on iOS 14.5, confirming that the root cause was buffer‑size misalignment during ALAC encoding. The investigation deepened the team’s understanding of PCM capture, Audio Queue mechanics, and format‑specific encoder requirements on iOS.

iOSMobileDevelopmentAudioEncodingAudioQueueAVPlayerBugFix
Liulishuo Tech Team
Written by

Liulishuo Tech Team

Help everyone become a global citizen!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.