@@ -63,6 +63,7 @@ static unsigned CountsPerByte;
6363static AudioConverterRef audio_converter ;
6464static unsigned converter_input_rate ;
6565static int16_t * audio_out_buffer_s16 ;
66+ static bool converter_needs_reset ;
6667
6768/* Context for AudioConverter input callback */
6869typedef struct
@@ -149,6 +150,7 @@ static int create_audio_converter(unsigned input_rate)
149150 sizeof (quality ), & quality );
150151
151152 converter_input_rate = input_rate ;
153+ converter_needs_reset = false;
152154 return 0 ;
153155}
154156
@@ -274,9 +276,6 @@ static void aiLenChanged(void* user_data, const void* buffer, size_t size)
274276 return ;
275277 }
276278
277- /* Reset converter to clear end-of-stream state from previous call */
278- AudioConverterReset (audio_converter );
279-
280279 ctx .data = raw_data ;
281280 ctx .frames_left = frames ;
282281
@@ -297,6 +296,32 @@ static void aiLenChanged(void* user_data, const void* buffer, size_t size)
297296 if (err != noErr && err != 1 )
298297 return ;
299298
299+ /* If converter returned 0 output while we have input, it may be stuck
300+ * in "end of stream" state. Reset and retry once. */
301+ if (output_frames == 0 && ctx .frames_left > 0 && !converter_needs_reset )
302+ {
303+ AudioConverterReset (audio_converter );
304+ converter_needs_reset = true;
305+
306+ /* Retry with fresh context */
307+ ctx .data = raw_data ;
308+ ctx .frames_left = frames ;
309+ output_frames = (UInt32 )((frames * OUTPUT_RATE ) / GameFreq + 1 );
310+ if (output_frames > MAX_AUDIO_FRAMES * 2 )
311+ output_frames = MAX_AUDIO_FRAMES * 2 ;
312+ output_buffer .mBuffers [0 ].mDataByteSize = output_frames * 4 ;
313+
314+ err = AudioConverterFillComplexBuffer (audio_converter ,
315+ converter_input_cb , & ctx ,
316+ & output_frames , & output_buffer , NULL );
317+
318+ if (err != noErr && err != 1 )
319+ return ;
320+ }
321+
322+ if (output_frames > 0 )
323+ converter_needs_reset = false;
324+
300325 out = audio_out_buffer_s16 ;
301326 while (output_frames )
302327 {
0 commit comments