fix(voice): honor sample width in AudioInput.to_base64 - #4364
fix(voice): honor sample width in AudioInput.to_base64#4364abhay-codes07 wants to merge 1 commit into
Conversation
openai#4361 made `to_audio_file` respect `AudioInput.sample_width`, but `to_base64` still hardcoded a PCM16 conversion. The same object with the same declared width therefore produced two different encodings: AudioInput(buffer=..., sample_width=1) to_audio_file() -> 8 bytes (8-bit frames, header says 8-bit) to_base64() -> 16 bytes (16-bit samples) `to_base64` feeds the transcription span input when `trace_include_sensitive_audio_data` is enabled, and that span records `input_format = "pcm"`, so a 1, 3 or 4 byte input was traced as 16-bit PCM and could not be played back correctly from the trace. The width conversion is extracted from `_buffer_to_audio_file` into `_buffer_to_pcm_bytes` and shared, so the two paths cannot drift again. The 16-bit default is byte for byte what it was before, the caller's buffer is still never mutated, and an unsupported dtype or sample width still raises `UserError`, now from the shared encoder rather than a duplicated check.
|
Thanks for the contribution. I traced I am going to close this PR. If there is a reproducible Traces dashboard failure for a supported non-default |
Summary
#4361 made
to_audio_filerespectAudioInput.sample_width, butto_base64on the same class still hardcodes a PCM16 conversion. One object with one declared width now produces two different encodings:sample_widthto_audio_file()framesto_base64()bytes(5-sample buffer.)
Why it matters
to_base64is what feeds the transcription span input whentrace_include_sensitive_audio_datais enabled:That span also records
input_format = "pcm". So for an input declared as 1, 3 or 4 bytes per sample, the traced audio is 16-bit data labelled as the session's PCM format, and cannot be played back correctly from the trace. #4361 validatedsample_widthinto{1, 2, 3, 4}and made those widths a supported, exercised configuration, which is what turns this from a latent inconsistency into a reachable one.Fix
The width conversion is extracted from
_buffer_to_audio_fileinto_buffer_to_pcm_bytesand shared by both paths, so they cannot drift again. No conversion logic changed; it only moved.Preserved exactly:
UserError, now from the shared encoder instead of a duplicated checkTest plan
New
TestAudioInputBase64SampleWidthintests/voice/test_input.py:test_base64_matches_the_wav_frames_for_every_width, parametrized over widths 1-4 and bothint16andfloat32, asserting the base64 bytes are byte-identical to the WAV frames for the same object. 7 of these fail onmain.test_default_width_encoding_is_unchanged, pinning the 16-bit output against the old expression; passes both with and without the change.test_invalid_sample_width_is_rejected, which also fails onmainbecauseto_base64never validated the width at all.make format/make lintmake mypy/make pyrightuv run pytest tests/voice/make testsRun on Windows against a
mainbaseline captured at the same commit. One test differed,tests/test_trace_processor.py::test_backend_span_exporter_deadline_stops_during_5xx_retry_backoff; it is a wall-clock deadline test that passes 4/4 in isolation on this branch and 6/6 on unmodifiedmain, and only fails under-n 6load.Issue number
None. Found while auditing #4361.
Checks
.agents/skills/code-change-verification/scripts/run.sh/reviewbefore submitting this PRThe verification script shells out to
make; I ran the underlying steps individually, with the results above.