diff --git a/include/SDL3/SDL_audio.h b/include/SDL3/SDL_audio.h index 84894cebae..dcbb71154f 100644 --- a/include/SDL3/SDL_audio.h +++ b/include/SDL3/SDL_audio.h @@ -954,13 +954,22 @@ extern DECLSPEC int SDLCALL SDL_UnlockAudioStream(SDL_AudioStream *stream); * before your callback is called, so your callback does not need to * manage the lock explicitly. * + * Two values are offered here: one is the amount of additional data needed + * to satisfy the immediate request (which might be zero if the stream + * already has enough data queued) and the other is the total amount + * being requested. In a Get call triggering a Put callback, these + * values can be different. In a Put call triggering a Get callback, + * these values are always the same. + * + * Byte counts might be slightly overestimated due to buffering or + * resampling, and may change from call to call. + * * \param stream The SDL audio stream associated with this callback. - * \param approx_amount The _approximate_ amount of data, in bytes, that is requested or available. - * This might be slightly overestimated due to buffering or - * resampling, and may change from call to call. + * \param additional The amount of data, in bytes, that is needed right now + * \param total_amount The total amount of data requested, in bytes, that is requested or available. * \param userdata An opaque pointer provided by the app for their personal use. */ -typedef void (SDLCALL *SDL_AudioStreamCallback)(void *userdata, SDL_AudioStream *stream, int approx_amount); +typedef void (SDLCALL *SDL_AudioStreamCallback)(void *userdata, SDL_AudioStream *stream, int additional_amount, int total_amount); /** * Set a callback that runs when data is requested from an audio stream. diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index 70a405b15d..dc521f1349 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -1342,9 +1342,7 @@ int SDL_PutAudioStreamData(SDL_AudioStream *stream, const void *buf, int len) if ((retval == 0) && stream->put_callback) { const int newavail = SDL_GetAudioStreamAvailable(stream) - prev_available; - if (newavail > 0) { // don't call the callback if we can't actually offer new data (still filling future buffer, only added 1 frame but downsampling needs more to produce new sound, etc). - stream->put_callback(stream->put_callback_userdata, stream, newavail); - } + stream->put_callback(stream->put_callback_userdata, stream, newavail, newavail); } SDL_UnlockMutex(stream->lock); @@ -1647,7 +1645,8 @@ int SDL_GetAudioStreamData(SDL_AudioStream *stream, void *voidbuf, int len) // give the callback a chance to fill in more stream data if it wants. if (stream->get_callback) { - Sint64 approx_request = len / dst_frame_size; // start with sample frames desired + Sint64 total_request = len / dst_frame_size; // start with sample frames desired + Sint64 approx_request = total_request; const Sint64 available_frames = GetAudioStreamAvailableFrames(stream); approx_request -= SDL_min(available_frames, approx_request); @@ -1655,14 +1654,13 @@ int SDL_GetAudioStreamData(SDL_AudioStream *stream, void *voidbuf, int len) const Sint64 resample_rate = GetStreamResampleRate(stream, stream->src_spec.freq); if (resample_rate) { + total_request = GetResamplerNeededInputFrames((int) total_request, resample_rate, 0); approx_request = GetResamplerNeededInputFrames((int) approx_request, resample_rate, 0); } + total_request *= SDL_AUDIO_FRAMESIZE(stream->src_spec); // convert sample frames to bytes. approx_request *= SDL_AUDIO_FRAMESIZE(stream->src_spec); // convert sample frames to bytes. - - if (approx_request > 0) { // don't call the callback if we can satisfy this request with existing data. - stream->get_callback(stream->get_callback_userdata, stream, (int) SDL_min(approx_request, SDL_INT_MAX)); - } + stream->get_callback(stream->get_callback_userdata, stream, (int) SDL_min(approx_request, SDL_INT_MAX), (int) SDL_min(total_request, SDL_INT_MAX)); } const int chunk_size = 4096; diff --git a/test/testaudiostreamdynamicresample.c b/test/testaudiostreamdynamicresample.c index 15d6dec272..7e9e09211b 100644 --- a/test/testaudiostreamdynamicresample.c +++ b/test/testaudiostreamdynamicresample.c @@ -356,7 +356,7 @@ static void loop(void) } } -static void SDLCALL our_get_callback(void *userdata, SDL_AudioStream *strm, int approx_amount) +static void SDLCALL our_get_callback(void *userdata, SDL_AudioStream *strm, int approx_amount, int total_amount) { last_get_callback = SDL_GetTicks(); last_get_amount = approx_amount; diff --git a/test/testsurround.c b/test/testsurround.c index 001952ea1b..551f316b9d 100644 --- a/test/testsurround.c +++ b/test/testsurround.c @@ -96,7 +96,7 @@ static SDL_bool is_lfe_channel(int channel_index, int channel_count) return (channel_count == 3 && channel_index == 2) || (channel_count >= 6 && channel_index == 3); } -static void SDLCALL fill_buffer(void *userdata, SDL_AudioStream *stream, int len) +static void SDLCALL fill_buffer(void *userdata, SDL_AudioStream *stream, int len, int totallen) { const int samples = len / sizeof(Sint16); Sint16 *buffer = NULL;