소스 검색

audio: fixed flushed stream reporting bytes but not being able to get them.

This would happen when you had ~1 frame of audio left in the stream, and
resampling needs would cause this to not be enough to produce audio.

But since we're already flushed, we can just add silence padding to let the
app extract these last bits.
Ryan C. Gordon 2 년 전
부모
커밋
a93fcf2444
1개의 변경된 파일12개의 추가작업 그리고 3개의 파일을 삭제
  1. 12 3
      src/audio/SDL_audiocvt.c

+ 12 - 3
src/audio/SDL_audiocvt.c

@@ -872,9 +872,18 @@ static int GetAudioStreamDataInternal(SDL_AudioStream *stream, void *buf, int le
     input_frames = len / dst_sample_frame_size;  // total sample frames caller wants
     if (dst_rate != src_rate) {
         // calculate requested sample frames needed before resampling. Use a Uint64 so the multiplication doesn't overflow.
-        input_frames = (int) ((((Uint64) input_frames) * src_rate) / dst_rate);
-        if (input_frames == 0) {
-            return 0;  // if they are upsampling and we end up needing less than a frame of input, we reject it because it would cause artifacts on future reads to eat a full input frame.
+        const int resampled_input_frames = (int) ((((Uint64) input_frames) * src_rate) / dst_rate);
+        if (resampled_input_frames > 0) {
+            input_frames = resampled_input_frames;
+        } else {  // uhoh, not enough input frames!
+            // if they are upsampling and we end up needing less than a frame of input, we reject it because it would cause artifacts on future reads to eat a full input frame.
+            //  however, if the stream is flushed, we would just be padding any remaining input with silence anyhow, so use it up.
+            if (stream->flushed) {
+                SDL_assert(((input_frames * src_sample_frame_size) + future_buffer_filled_frames) <= stream->future_buffer_allocation);
+                // leave input_frames alone; this will just shuffle what's available from the future buffer and pad with silence as appropriate, below.
+            } else {
+                return 0;
+            }
         }
     }