Refactored audio conversion to reduce copying

More of the logic has been moved into SDL_AudioQueue,
allowing data to be converted directly from the input buffer.
This commit is contained in:
Brick 2024-04-04 19:22:29 +01:00 committed by Sam Lantinga
parent ae57b0c9d8
commit edaab8ad9f
7 changed files with 478 additions and 409 deletions

View file

@ -25,6 +25,8 @@
// Internal functions used by SDL_AudioStream for queueing audio.
typedef void(SDLCALL *SDL_ReleaseAudioBufferCallback)(void *userdata, const void *buffer, int buflen);
typedef struct SDL_AudioQueue SDL_AudioQueue;
typedef struct SDL_AudioTrack SDL_AudioTrack;
@ -44,16 +46,14 @@ void SDL_FlushAudioQueue(SDL_AudioQueue *queue);
// REQUIRES: The head track must exist, and must have been flushed
void SDL_PopAudioQueueHead(SDL_AudioQueue *queue);
// Get the chunk size, mostly for use with SDL_CreateChunkedAudioTrack
// This can be called from any thread
size_t SDL_GetAudioQueueChunkSize(SDL_AudioQueue *queue);
// Write data to the end of queue
// REQUIRES: If the spec has changed, the last track must have been flushed
int SDL_WriteToAudioQueue(SDL_AudioQueue *queue, const SDL_AudioSpec *spec, const Uint8 *data, size_t len);
// Create a track without needing to hold any locks
SDL_AudioTrack *SDL_CreateChunkedAudioTrack(const SDL_AudioSpec *spec, const Uint8 *data, size_t len, size_t chunk_size);
// Create a track where the input data is owned by the caller
SDL_AudioTrack *SDL_CreateAudioTrack(SDL_AudioQueue *queue,
const SDL_AudioSpec *spec, Uint8 *data, size_t len, size_t capacity,
SDL_ReleaseAudioBufferCallback callback, void *userdata);
// Add a track to the end of the queue
// REQUIRES: `track != NULL`
@ -66,12 +66,14 @@ void *SDL_BeginAudioQueueIter(SDL_AudioQueue *queue);
// REQUIRES: `*inout_iter != NULL` (a valid iterator)
size_t SDL_NextAudioQueueIter(SDL_AudioQueue *queue, void **inout_iter, SDL_AudioSpec *out_spec, SDL_bool *out_flushed);
// Read data from the start of the queue
// REQUIRES: There must be enough data in the queue
int SDL_ReadFromAudioQueue(SDL_AudioQueue *queue, Uint8 *data, size_t len);
const Uint8 *SDL_ReadFromAudioQueue(SDL_AudioQueue *queue,
Uint8 *dst, SDL_AudioFormat dst_format, int dst_channels,
int past_frames, int present_frames, int future_frames,
Uint8 *scratch);
// Peek into the start of the queue
// REQUIRES: There must be enough data in the queue, unless it has been flushed, in which case missing data is filled with silence.
int SDL_PeekIntoAudioQueue(SDL_AudioQueue *queue, Uint8 *data, size_t len);
// Get the total number of bytes currently queued
size_t SDL_GetAudioQueueQueued(SDL_AudioQueue *queue);
int SDL_ResetAudioQueueHistory(SDL_AudioQueue *queue, int num_frames);
#endif // SDL_audioqueue_h_