From 9f7ba181207f6b3e1db98d9c3cef7dbb92cd48b9 Mon Sep 17 00:00:00 2001 From: HughhhhCoder Date: Wed, 2 Sep 2026 11:07:24 +0800 Subject: [PATCH] fix(voice): decode PCM16 output as little-endian --- src/agents/voice/result.py | 4 +++- tests/voice/test_pipeline.py | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/agents/voice/result.py b/src/agents/voice/result.py index a01f7d762c..d5d0ecccb8 100644 --- a/src/agents/voice/result.py +++ b/src/agents/voice/result.py @@ -104,7 +104,9 @@ def _transform_audio_buffer( # np.int16 needs 2-byte alignment; pad odd-length chunks safely. combined_buffer += b"\x00" - np_array = np.frombuffer(combined_buffer, dtype=np.int16) + # TTS providers return PCM16 bytes in little-endian order. Decode that wire format + # explicitly, then normalize the result to the native int16 dtype returned to callers. + np_array = np.frombuffer(combined_buffer, dtype=" None: assert transformed.tolist() == [1] +def test_streamed_audio_result_decodes_pcm16_as_little_endian(monkeypatch) -> None: + result = StreamedAudioResult( + ZeroPcmTTSModel(), + TTSModelSettings(dtype=np.int16), + VoicePipelineConfig(), + ) + native_frombuffer = np.frombuffer + + def simulate_big_endian_host(buffer, *, dtype): + if dtype is np.int16: + dtype = np.dtype(">i2") + return native_frombuffer(buffer, dtype=dtype) + + monkeypatch.setattr(np, "frombuffer", simulate_big_endian_host) + + transformed = result._transform_audio_buffer([b"\x01\x02\x03\x04"], np.int16) + + assert transformed.dtype == np.int16 + assert transformed.tolist() == [0x0201, 0x0403] + + @pytest.mark.asyncio async def test_streamed_audio_result_raises_falsy_task_exception() -> None: class FalsyError(RuntimeError):