Remove ma_audio_queue.

This commit is contained in:
David Reid
2026-01-27 06:17:14 +10:00
parent 2302e58045
commit fcd386dd87
2 changed files with 8 additions and 335 deletions
-324
View File
@@ -6250,60 +6250,6 @@ MA_API ma_result ma_paged_audio_buffer_get_length_in_pcm_frames(ma_paged_audio_b
/*
Audio Queue
===========
The audio queue is a data source that allows you to push data from one thread and then read it from
another. The audio queue can be fixed sized or dynamic. Dynamic is the default. To use a static
queue set the the size to non-0.
With a static queue, if you attempt to push data but there is no room, the entire data will be rejected
and MA_NO_SPACE will be returned. For a dynamic queue it is restricted by memory capacity.
There is no seeking and no notion of a cursor. The length will be how many PCM frames are currently
sitting in the queue.
The total capacity of the queue in PCM frames is restricted to 32-bits.
This is thread safe, but not currently 100% lock-free. This currently uses a dumb spinlock for thread
safety, but there are plans to improve on this later.
*/
typedef struct
{
ma_format format;
ma_uint32 channels;
ma_uint32 sampleRate;
ma_uint32 sizeInFrames; /* When set to 0 (the default), the queue will be dynamically expanding. When set to non-0, the audio queue will be static. */
ma_allocation_callbacks allocationCallbacks;
} ma_audio_queue_config;
MA_API ma_audio_queue_config ma_audio_queue_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, ma_uint32 sizeInFrames);
typedef struct
{
ma_data_source_base ds;
ma_format format;
ma_uint32 channels;
ma_uint32 sampleRate;
ma_bool32 isStatic;
ma_uint32 capacityInFrames;
ma_uint64 cursorWrite;
ma_uint64 cursorRead;
void* pBuffer;
ma_allocation_callbacks allocationCallbacks;
ma_spinlock lock; /* Temporary until we get a good lock-free solution working. */
} ma_audio_queue;
MA_API ma_result ma_audio_queue_init(const ma_audio_queue_config* pConfig, ma_audio_queue* pAudioQueue);
MA_API void ma_audio_queue_uninit(ma_audio_queue* pAudioQueue);
MA_API ma_result ma_audio_queue_push_pcm_frames(ma_audio_queue* pAudioQueue, const void* pFrames, ma_uint64 frameCount);
MA_API ma_result ma_audio_queue_read_pcm_frames(ma_audio_queue* pAudioQueue, void* pFrames, ma_uint64 frameCount, ma_uint64* pFramesRead);
MA_API ma_result ma_audio_queue_get_length_in_pcm_frames(ma_audio_queue* pAudioQueue, ma_uint64* pLength);
/************************************************************************************************************************************************************
Ring Buffer
@@ -65923,276 +65869,6 @@ MA_API ma_result ma_paged_audio_buffer_get_length_in_pcm_frames(ma_paged_audio_b
MA_API ma_audio_queue_config ma_audio_queue_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, ma_uint32 sizeInFrames)
{
ma_audio_queue_config config;
MA_ZERO_OBJECT(&config);
config.format = format;
config.channels = channels;
config.sampleRate = sampleRate;
config.sizeInFrames = sizeInFrames;
return config;
}
static ma_result ma_audio_queue__data_source_on_read(ma_data_source* pDataSource, void* pFrames, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
return ma_audio_queue_read_pcm_frames((ma_audio_queue*)pDataSource, pFrames, frameCount, pFramesRead);
}
static ma_result ma_audio_queue__data_source_on_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap)
{
ma_audio_queue* pAudioQueue = (ma_audio_queue*)pDataSource;
*pFormat = pAudioQueue->format;
*pChannels = pAudioQueue->channels;
*pSampleRate = pAudioQueue->sampleRate;
ma_channel_map_init_standard(ma_standard_channel_map_default, pChannelMap, channelMapCap, pAudioQueue->channels);
return MA_SUCCESS;
}
static ma_result ma_audio_queue__data_source_on_get_length(ma_data_source* pDataSource, ma_uint64* pLength)
{
return ma_audio_queue_get_length_in_pcm_frames((ma_audio_queue*)pDataSource, pLength);
}
static ma_data_source_vtable ma_gDataSourceVTable_AudioQueue =
{
ma_audio_queue__data_source_on_read,
NULL, /* No seeking in audio queues. */
ma_audio_queue__data_source_on_get_data_format,
NULL, /* No notion of a cursor. */
ma_audio_queue__data_source_on_get_length,
NULL, /* onSetLooping */
0
};
MA_API ma_result ma_audio_queue_init(const ma_audio_queue_config* pConfig, ma_audio_queue* pAudioQueue)
{
ma_result result;
ma_data_source_config dataSourceConfig;
if (pAudioQueue == NULL) {
return MA_INVALID_ARGS;
}
MA_ZERO_OBJECT(pAudioQueue);
if (pConfig == NULL) {
return MA_INVALID_ARGS;
}
/* Initialize the data source first. */
dataSourceConfig = ma_data_source_config_init();
dataSourceConfig.pVTable = &ma_gDataSourceVTable_AudioQueue;
result = ma_data_source_init(&dataSourceConfig, &pAudioQueue->ds);
if (result != MA_SUCCESS) {
return result;
}
pAudioQueue->format = pConfig->format;
pAudioQueue->channels = pConfig->channels;
pAudioQueue->sampleRate = pConfig->sampleRate;
pAudioQueue->capacityInFrames = pConfig->sizeInFrames;
ma_allocation_callbacks_init_copy(&pAudioQueue->allocationCallbacks, &pConfig->allocationCallbacks);
if (pAudioQueue->capacityInFrames > 0) {
pAudioQueue->pBuffer = ma_malloc(pAudioQueue->capacityInFrames * ma_get_bytes_per_frame(pAudioQueue->format, pAudioQueue->channels), &pAudioQueue->allocationCallbacks);
if (pAudioQueue->pBuffer == NULL) {
return MA_OUT_OF_MEMORY;
}
pAudioQueue->isStatic = MA_TRUE;
}
return MA_SUCCESS;
}
MA_API void ma_audio_queue_uninit(ma_audio_queue* pAudioQueue)
{
if (pAudioQueue == NULL) {
return;
}
ma_free(pAudioQueue->pBuffer, &pAudioQueue->allocationCallbacks);
ma_data_source_uninit(&pAudioQueue->ds);
}
static void ma_audio_queue_write_pcm_frames_nolock(ma_audio_queue* pAudioQueue, const void* pFrames, ma_uint64 frameCount, ma_uint32 bpf)
{
ma_uint64 framesWritten = 0;
while (framesWritten < frameCount) {
ma_uint64 framesRemaining = (frameCount - framesWritten);
ma_uint64 framesToWriteThisIteration = framesRemaining;
ma_uint64 writeOffset;
writeOffset = pAudioQueue->cursorWrite % pAudioQueue->capacityInFrames;
if (framesToWriteThisIteration + writeOffset > pAudioQueue->capacityInFrames) {
framesToWriteThisIteration = pAudioQueue->capacityInFrames - writeOffset;
}
MA_COPY_MEMORY(ma_offset_ptr(pAudioQueue->pBuffer, writeOffset * bpf), ma_offset_ptr(pFrames, framesWritten * bpf), (size_t)(framesToWriteThisIteration * bpf));
pAudioQueue->cursorWrite += framesToWriteThisIteration;
framesWritten += framesToWriteThisIteration;
}
}
static void ma_audio_queue_read_pcm_frames_nolock(ma_audio_queue* pAudioQueue, void* pFrames, ma_uint64 frameCount, ma_uint32 bpf)
{
ma_uint64 framesRead = 0;
while (framesRead < frameCount) {
ma_uint64 framesRemaining = (frameCount - framesRead);
ma_uint64 framesToReadThisIteration = framesRemaining;
ma_uint64 readOffset;
readOffset = pAudioQueue->cursorRead % pAudioQueue->capacityInFrames;
if (framesToReadThisIteration + readOffset > pAudioQueue->capacityInFrames) {
framesToReadThisIteration = pAudioQueue->capacityInFrames - readOffset;
}
MA_COPY_MEMORY(ma_offset_ptr(pFrames, framesRead * bpf), ma_offset_ptr(pAudioQueue->pBuffer, readOffset * bpf), (size_t)(framesToReadThisIteration * bpf));
pAudioQueue->cursorRead += framesToReadThisIteration;
framesRead += framesToReadThisIteration;
}
}
MA_API ma_result ma_audio_queue_push_pcm_frames(ma_audio_queue* pAudioQueue, const void* pFrames, ma_uint64 frameCount)
{
ma_result result;
ma_uint64 length;
ma_uint32 bpf;
ma_uint32 newCapacity;
void* pNewBuffer = NULL;
void* pOldBuffer = NULL;
if (pAudioQueue == NULL) {
return MA_INVALID_ARGS;
}
if (pFrames == NULL) {
return MA_INVALID_ARGS; /* Push silence instead? */
}
result = ma_audio_queue_get_length_in_pcm_frames(pAudioQueue, &length);
if (result != MA_SUCCESS) {
return result;
}
bpf = ma_get_bytes_per_frame(pAudioQueue->format, pAudioQueue->channels);
if (frameCount > (pAudioQueue->capacityInFrames - length)) {
if (pAudioQueue->isStatic) {
return MA_NO_SPACE;
} else {
newCapacity = pAudioQueue->capacityInFrames * 2;
if (newCapacity < length + frameCount) {
newCapacity = length + frameCount;
}
pNewBuffer = ma_malloc(newCapacity * bpf, &pAudioQueue->allocationCallbacks);
if (pNewBuffer == NULL) {
return MA_OUT_OF_MEMORY;
}
}
}
ma_spinlock_lock(&pAudioQueue->lock);
{
length = pAudioQueue->cursorWrite - pAudioQueue->cursorRead;
/* If we have a new buffer we need to swap out the old one with the new. */
if (pNewBuffer != NULL) {
pOldBuffer = pAudioQueue->pBuffer;
/* Fill the new buffer. */
ma_audio_queue_read_pcm_frames_nolock(pAudioQueue, pNewBuffer, length, bpf);
/* Normalize our cursors. */
pAudioQueue->cursorRead = 0;
pAudioQueue->cursorWrite = length;
/* Swap out the buffer. */
pAudioQueue->pBuffer = pNewBuffer;
pAudioQueue->capacityInFrames = newCapacity;
}
ma_audio_queue_write_pcm_frames_nolock(pAudioQueue, pFrames, frameCount, bpf);
}
ma_spinlock_unlock(&pAudioQueue->lock);
if (pOldBuffer != NULL) {
ma_free(pOldBuffer, &pAudioQueue->allocationCallbacks);
}
return MA_SUCCESS;
}
MA_API ma_result ma_audio_queue_read_pcm_frames(ma_audio_queue* pAudioQueue, void* pFrames, ma_uint64 frameCount, ma_uint64* pFramesRead)
{
ma_result result;
ma_uint64 length;
ma_uint32 bpf;
/* Clamp the frame count to the length. */
result = ma_audio_queue_get_length_in_pcm_frames(pAudioQueue, &length);
if (result != MA_SUCCESS) {
return result;
}
if (frameCount > length) {
frameCount = length;
}
bpf = ma_get_bytes_per_frame(pAudioQueue->format, pAudioQueue->channels);
ma_spinlock_lock(&pAudioQueue->lock);
{
ma_audio_queue_read_pcm_frames_nolock(pAudioQueue, pFrames, frameCount, bpf);
}
ma_spinlock_unlock(&pAudioQueue->lock);
if (pFramesRead != NULL) {
*pFramesRead = frameCount;
}
/* Note that we never returning MA_AT_END for a queue because there isn't really a notion of it. */
return MA_SUCCESS;
}
MA_API ma_result ma_audio_queue_get_length_in_pcm_frames(ma_audio_queue* pAudioQueue, ma_uint64* pLength)
{
if (pLength == NULL) {
return MA_INVALID_ARGS;
}
*pLength = 0;
if (pAudioQueue == NULL) {
return MA_INVALID_ARGS;
}
ma_spinlock_lock(&pAudioQueue->lock);
{
*pLength = (pAudioQueue->cursorWrite - pAudioQueue->cursorRead);
}
ma_spinlock_unlock(&pAudioQueue->lock);
return MA_SUCCESS;
}
/**************************************************************************************************************************************************************
VFS