Skip to content

fix(ios): push the frames AVAudioConverter actually produced in the recorder callback#1097

Merged
mdydek merged 2 commits into
software-mansion:mainfrom
yocontra:fix/ios-recorder-converter-frame-count
Jun 11, 2026
Merged

fix(ios): push the frames AVAudioConverter actually produced in the recorder callback#1097
mdydek merged 2 commits into
software-mansion:mainfrom
yocontra:fix/ios-recorder-converter-frame-count

Conversation

@yocontra

Copy link
Copy Markdown
Contributor

Closes #1096

⚠️ Breaking changes ⚠️

None.

Introduced changes

  • IOSRecorderCallback::taskOffloaderFunction now pushes converterOutputBuffer_.frameLength — the frame count AVAudioConverter actually produced — into the circular buffer, instead of a ceil(numFrames * ratio) estimate.
  • Removed the post-conversion converterOutputBuffer_.frameLength = ... assignment that was overwriting the converter's real output count with that estimate.
  • Early-return when the converter produced zero frames.

Why

The SRC's filter phase makes per-call output fluctuate around numFrames * ratio (a 512-frame block at 48 kHz → 16 kHz yields 170 or 171 frames depending on accumulated phase). Whenever the converter produced fewer frames than the ceil() estimate, the extra pushed samples were stale data from a previous render block — a single-sample impulse (audible click) at nearly every block boundary, in every recording where the requested onAudioReady sample rate differs from the hardware input rate. Full analysis with PCM evidence in #1096.

Android is unaffected: AndroidRecorderCallback already uses the produced count reported by ma_data_converter_process_pcm_frames.

Checklist

yocontra and others added 2 commits June 10, 2026 18:20
…ecorder callback

convertToBuffer:error:withInputFromBlock: sets frameLength to the number
of frames it wrote, but the recorder callback overwrote it with a
computed estimate and pushed ceil(numFrames * ratio) frames into the
circular buffer. When the SRC's filter phase produced fewer frames than
the estimate, the extra pushed samples were stale data from a previous
render block - an audible click at nearly every block boundary whenever
the requested callback rate differs from the hardware input rate.

Fixes software-mansion#1096
@mdydek

mdydek commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

thank you for pointing out the issue

@mdydek mdydek merged commit ec47c89 into software-mansion:main Jun 11, 2026
6 checks passed
@yocontra yocontra deleted the fix/ios-recorder-converter-frame-count branch June 12, 2026 04:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

iOS: recorder resampling path pushes estimated frame counts, injecting a stale sample (audible click) at render-block boundaries

2 participants