audio: Change SDL_AudioStreamCallback

Now it offers the total requested bytes in addition to the amount
immediately needed (and immediately needed might be zero if the stream
already has enough queued to satisfy the request.
main
Ryan C. Gordon 2023-09-13 10:11:23 -04:00
parent 9da34e8fb5
commit 8b26e95f91
No known key found for this signature in database
GPG Key ID: FA148B892AB48044
4 changed files with 21 additions and 14 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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;

View File

@ -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;