mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-22 00:06:59 +02:00
Update the audio ring buffer to use the standard config/init pattern.
This makes it consistent with everything else in the library.
This commit is contained in:
@@ -53,6 +53,7 @@ int main(int argc, char** argv)
|
|||||||
ma_data_source_node_config sourceNodeConfig;
|
ma_data_source_node_config sourceNodeConfig;
|
||||||
ma_data_source_node_config exciteNodeConfig;
|
ma_data_source_node_config exciteNodeConfig;
|
||||||
ma_waveform_config waveformConfig;
|
ma_waveform_config waveformConfig;
|
||||||
|
ma_audio_ring_buffer_config ringBufferConfig;
|
||||||
|
|
||||||
deviceConfig = ma_device_config_init(ma_device_type_duplex);
|
deviceConfig = ma_device_config_init(ma_device_type_duplex);
|
||||||
deviceConfig.capture.pDeviceID = NULL;
|
deviceConfig.capture.pDeviceID = NULL;
|
||||||
@@ -115,7 +116,9 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
|
|
||||||
/* Excite/modulator. Attached to input bus 1 of the vocoder node. */
|
/* Excite/modulator. Attached to input bus 1 of the vocoder node. */
|
||||||
result = ma_audio_ring_buffer_init(device.capture.format, device.capture.channels, device.sampleRate, device.capture.internalPeriodSizeInFrames * 3, NULL, &g_exciteData);
|
ringBufferConfig = ma_audio_ring_buffer_config_init(device.capture.format, device.capture.channels, device.sampleRate, device.capture.internalPeriodSizeInFrames * 3);
|
||||||
|
|
||||||
|
result = ma_audio_ring_buffer_init(&ringBufferConfig, &g_exciteData);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
printf("Failed to initialize audio buffer for source.");
|
printf("Failed to initialize audio buffer for source.");
|
||||||
goto done2;
|
goto done2;
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ int main(int argc, char** argv)
|
|||||||
{
|
{
|
||||||
ma_result result;
|
ma_result result;
|
||||||
ma_device_config deviceConfig;
|
ma_device_config deviceConfig;
|
||||||
|
ma_audio_ring_buffer_config ringBufferConfig;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The first thing we'll do is set up the capture side. There are two parts to this. The first is
|
The first thing we'll do is set up the capture side. There are two parts to this. The first is
|
||||||
@@ -59,7 +60,9 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the ring buffer. Make sure the sample rate is set so the engine can resample it if necessary. */
|
/* Initialize the ring buffer. Make sure the sample rate is set so the engine can resample it if necessary. */
|
||||||
result = ma_audio_ring_buffer_init(device.capture.format, device.capture.channels, device.sampleRate, device.capture.internalPeriodSizeInFrames * 3, NULL, &rb);
|
ringBufferConfig = ma_audio_ring_buffer_config_init(device.capture.format, device.capture.channels, device.sampleRate, device.capture.internalPeriodSizeInFrames * 3);
|
||||||
|
|
||||||
|
result = ma_audio_ring_buffer_init(&ringBufferConfig, &rb);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
printf("Failed to initialize the ring buffer.");
|
printf("Failed to initialize the ring buffer.");
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
+94
-59
@@ -3568,25 +3568,30 @@ you will want to use. To initialize a ring buffer, do something like the followi
|
|||||||
|
|
||||||
```c
|
```c
|
||||||
ma_audio_ring_buffer rb;
|
ma_audio_ring_buffer rb;
|
||||||
ma_result result = ma_audio_ring_buffer_init(FORMAT, CHANNELS, SAMPLE_RATE, BUFFER_SIZE_IN_FRAMES, NULL, &rb);
|
ma_audio_ring_buffer_config rbConfig;
|
||||||
|
|
||||||
|
rbConfig = ma_audio_ring_buffer_config_init(FORMAT, CHANNELS, SAMPLE_RATE, BUFFER_SIZE_IN_FRAMES);
|
||||||
|
|
||||||
|
ma_result result = ma_audio_ring_buffer_init(&rbConfig, &rb);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
// Error
|
// Error
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The `ma_audio_ring_buffer_init()` function takes the sample format, channel count and sample rate
|
The `ma_audio_ring_buffer_init()` follows the same config/init pattern used throughout miniaudio.
|
||||||
as parameters because it's the PCM variant of the ring buffer API. The sample rate is not used by
|
The sample rate is not used by the ring buffer internally and can be set to 0, but it is provided
|
||||||
the ring buffer internally and can be set to 0, but it is provided for the purpose of the data
|
for the purpose of the data source implementation.
|
||||||
source implementation.
|
|
||||||
|
|
||||||
You can allocate your own underlying buffer to act as the backing store in which case you can
|
You can allocate your own underlying buffer to act as the backing store in which case you can
|
||||||
initialize it like this:
|
initialize specify it in the config:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
void* pBuffer = malloc(BUFFER_SIZE_IN_FRAMES * bytesPerFrame * 2); // <-- The 2x is important.
|
void* pBuffer = malloc(BUFFER_SIZE_IN_FRAMES * bytesPerFrame * 2); // <-- The 2x is important.
|
||||||
|
|
||||||
ma_audio_ring_buffer rb;
|
rbConfig = ma_audio_ring_buffer_config_init(FORMAT, CHANNELS, SAMPLE_RATE, BUFFER_SIZE_IN_FRAMES);
|
||||||
ma_audio_ring_Buffer_init_ex(FORMAT, CHANNELS, SAMPLE_RATE, BUFFER_SIZE_IN_FRAMES, 0, pBuffer, &rb);
|
rbConfig.pBuffer = pBuffer;
|
||||||
|
|
||||||
|
ma_audio_ring_Buffer_init(&rbConfig, &rb);
|
||||||
```
|
```
|
||||||
|
|
||||||
The size of the buffer must be 2 times the capacity. It is possible for you to use a mirrored
|
The size of the buffer must be 2 times the capacity. It is possible for you to use a mirrored
|
||||||
@@ -3594,7 +3599,13 @@ buffer where the second half of the buffer maps to the same physical memory as t
|
|||||||
this case you can specify the `MA_RING_BUFFER_FLAG_MIRRORED` flag:
|
this case you can specify the `MA_RING_BUFFER_FLAG_MIRRORED` flag:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
ma_audio_ring_buffer_init_ex(FORMAT, CHANNELS, SAMPLE_RATE, BUFFER_SIZE_IN_FRAMES, MA_RING_BUFFER_FLAG_MIRRORED, pBuffer, &rb);
|
void* pBuffer = ...; // <-- Your own OS-specific allocation routine goes here. It must have 2x the addressable space as the the capacity.
|
||||||
|
|
||||||
|
rbConfig = ma_audio_ring_buffer_config_init(FORMAT, CHANNELS, SAMPLE_RATE, BUFFER_SIZE_IN_FRAMES);
|
||||||
|
rbConfig.flags = MA_RING_BUFFER_FLAG_MIRRORED;
|
||||||
|
rbConfig.pBuffer = pBuffer;
|
||||||
|
|
||||||
|
ma_audio_ring_buffer_init(&rbConfig, &rb);
|
||||||
```
|
```
|
||||||
|
|
||||||
To read and write data you map and unmap a pointer. For writing, you can do something like this:
|
To read and write data you map and unmap a pointer. For writing, you can do something like this:
|
||||||
@@ -6284,6 +6295,20 @@ MA_API ma_uint32 ma_ring_buffer_capacity(const ma_ring_buffer* pRingBuffer);
|
|||||||
/* END ma_ring_buffer.h */
|
/* END ma_ring_buffer.h */
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct ma_audio_ring_buffer_config
|
||||||
|
{
|
||||||
|
ma_format format;
|
||||||
|
ma_uint32 channels;
|
||||||
|
ma_uint32 sampleRate; /* Can be zero. Not used for the actual function of the ring buffer. Stored for the purpose of the data source abstraction. */
|
||||||
|
ma_uint32 sizeInFrames; /* The capacity of the ring buffer in frames. */
|
||||||
|
ma_uint32 flags;
|
||||||
|
void* pBuffer; /* Can be null in which case it'll be allocated internally. */
|
||||||
|
const ma_allocation_callbacks* pAllocationCallbacks;
|
||||||
|
} ma_audio_ring_buffer_config;
|
||||||
|
|
||||||
|
MA_API ma_audio_ring_buffer_config ma_audio_ring_buffer_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, ma_uint32 sizeInFrames);
|
||||||
|
|
||||||
|
|
||||||
typedef struct ma_audio_ring_buffer
|
typedef struct ma_audio_ring_buffer
|
||||||
{
|
{
|
||||||
ma_data_source_base ds;
|
ma_data_source_base ds;
|
||||||
@@ -6296,8 +6321,7 @@ typedef struct ma_audio_ring_buffer
|
|||||||
ma_allocation_callbacks allocationCallbacks;
|
ma_allocation_callbacks allocationCallbacks;
|
||||||
} ma_audio_ring_buffer;
|
} ma_audio_ring_buffer;
|
||||||
|
|
||||||
MA_API ma_result ma_audio_ring_buffer_init_ex(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, ma_uint32 capacityInFrames, ma_uint32 flags, void* pBuffer, ma_audio_ring_buffer* pRingBuffer);
|
MA_API ma_result ma_audio_ring_buffer_init(const ma_audio_ring_buffer_config* pConfig, ma_audio_ring_buffer* pRingBuffer);
|
||||||
MA_API ma_result ma_audio_ring_buffer_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, ma_uint32 capacityInFrames, const ma_allocation_callbacks* pAllocationCallbacks, ma_audio_ring_buffer* pRingBuffer);
|
|
||||||
MA_API void ma_audio_ring_buffer_uninit(ma_audio_ring_buffer* pRingBuffer);
|
MA_API void ma_audio_ring_buffer_uninit(ma_audio_ring_buffer* pRingBuffer);
|
||||||
MA_API ma_uint32 ma_audio_ring_buffer_map_produce(ma_audio_ring_buffer* pRingBuffer, ma_uint32 frameCount, void** ppMappedBuffer); /* Returns the number of frames actually mapped. */
|
MA_API ma_uint32 ma_audio_ring_buffer_map_produce(ma_audio_ring_buffer* pRingBuffer, ma_uint32 frameCount, void** ppMappedBuffer); /* Returns the number of frames actually mapped. */
|
||||||
MA_API void ma_audio_ring_buffer_unmap_produce(ma_audio_ring_buffer* pRingBuffer, ma_uint32 frameCount);
|
MA_API void ma_audio_ring_buffer_unmap_produce(ma_audio_ring_buffer* pRingBuffer, ma_uint32 frameCount);
|
||||||
@@ -32474,7 +32498,10 @@ static void ma_stream_event_process__pipewire(void* pUserData, ma_device_type de
|
|||||||
pStreamState->rbSizeInFrames = (ma_uint32)time.size;
|
pStreamState->rbSizeInFrames = (ma_uint32)time.size;
|
||||||
|
|
||||||
if (ma_device_get_threading_mode(pDeviceStatePipeWire->pDevice) == MA_THREADING_MODE_SINGLE_THREADED) {
|
if (ma_device_get_threading_mode(pDeviceStatePipeWire->pDevice) == MA_THREADING_MODE_SINGLE_THREADED) {
|
||||||
ma_audio_ring_buffer_init(pStreamState->format, pStreamState->channels, pStreamState->sampleRate, pStreamState->rbSizeInFrames, ma_device_get_allocation_callbacks(pDeviceStatePipeWire->pDevice), &pStreamState->rb);
|
ma_audio_ring_buffer_config ringBufferConfig = ma_audio_ring_buffer_config_init(pStreamState->format, pStreamState->channels, pStreamState->sampleRate, pStreamState->rbSizeInFrames);
|
||||||
|
ringBufferConfig.pAllocationCallbacks = ma_device_get_allocation_callbacks(pDeviceStatePipeWire->pDevice);
|
||||||
|
|
||||||
|
ma_audio_ring_buffer_init(&ringBufferConfig, &pStreamState->rb);
|
||||||
}
|
}
|
||||||
|
|
||||||
pStreamState->initStatus |= MA_PIPEWIRE_INIT_STATUS_HAS_LATENCY;
|
pStreamState->initStatus |= MA_PIPEWIRE_INIT_STATUS_HAS_LATENCY;
|
||||||
@@ -63666,11 +63693,28 @@ static ma_data_source_vtable ma_gDataSourceVTable_AudioRingBuffer =
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
MA_API ma_result ma_audio_ring_buffer_init_ex(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, ma_uint32 capacityInFrames, ma_uint32 flags, void* pBuffer, ma_audio_ring_buffer* pRingBuffer)
|
MA_API ma_audio_ring_buffer_config ma_audio_ring_buffer_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, ma_uint32 sizeInFrames)
|
||||||
|
{
|
||||||
|
ma_audio_ring_buffer_config config;
|
||||||
|
|
||||||
|
MA_ZERO_OBJECT(&config);
|
||||||
|
config.format = format;
|
||||||
|
config.channels = channels;
|
||||||
|
config.sampleRate = sampleRate;
|
||||||
|
config.sizeInFrames = sizeInFrames;
|
||||||
|
config.flags = 0;
|
||||||
|
config.pBuffer = NULL;
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
MA_API ma_result ma_audio_ring_buffer_init(const ma_audio_ring_buffer_config* pConfig, ma_audio_ring_buffer* pRingBuffer)
|
||||||
{
|
{
|
||||||
ma_result result;
|
ma_result result;
|
||||||
ma_data_source_config dataSourceConfig;
|
ma_data_source_config dataSourceConfig;
|
||||||
ma_uint32 bpf;
|
ma_uint32 bpf;
|
||||||
|
ma_bool32 isOwnerOfBuffer = MA_FALSE;
|
||||||
|
void* pBuffer;
|
||||||
|
|
||||||
if (pRingBuffer == NULL) {
|
if (pRingBuffer == NULL) {
|
||||||
return MA_INVALID_ARGS;
|
return MA_INVALID_ARGS;
|
||||||
@@ -63678,11 +63722,15 @@ MA_API ma_result ma_audio_ring_buffer_init_ex(ma_format format, ma_uint32 channe
|
|||||||
|
|
||||||
MA_ZERO_OBJECT(pRingBuffer);
|
MA_ZERO_OBJECT(pRingBuffer);
|
||||||
|
|
||||||
if (capacityInFrames == 0) {
|
if (pConfig == NULL) {
|
||||||
return MA_INVALID_ARGS;
|
return MA_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bpf = ma_get_bytes_per_frame(format, channels);
|
if (pConfig->format == ma_format_unknown || pConfig->channels == 0 || pConfig->sizeInFrames == 0) {
|
||||||
|
return MA_INVALID_ARGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bpf = ma_get_bytes_per_frame(pConfig->format, pConfig->channels);
|
||||||
if (bpf == 0) {
|
if (bpf == 0) {
|
||||||
return MA_INVALID_ARGS;
|
return MA_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
@@ -63696,50 +63744,33 @@ MA_API ma_result ma_audio_ring_buffer_init_ex(ma_format format, ma_uint32 channe
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Allocate a buffer if necessary. */
|
||||||
|
if (pConfig->pBuffer == NULL) {
|
||||||
|
size_t bufferSizeInBytes;
|
||||||
|
|
||||||
|
bufferSizeInBytes = pConfig->sizeInFrames * bpf * 2; /* Buffer must 2x the capacity. */
|
||||||
|
MA_ASSERT(bufferSizeInBytes != 0);
|
||||||
|
|
||||||
|
pBuffer = ma_malloc(bufferSizeInBytes, pConfig->pAllocationCallbacks);
|
||||||
|
if (pBuffer == NULL) {
|
||||||
|
ma_data_source_uninit(&pRingBuffer->ds);
|
||||||
|
return MA_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
isOwnerOfBuffer = MA_TRUE;
|
||||||
|
} else {
|
||||||
|
pBuffer = pConfig->pBuffer;
|
||||||
|
isOwnerOfBuffer = MA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Now for the ring buffer. */
|
/* Now for the ring buffer. */
|
||||||
ma_ring_buffer_init(capacityInFrames, bpf, flags, pBuffer, &pRingBuffer->rb);
|
ma_ring_buffer_init(pConfig->sizeInFrames, bpf, pConfig->flags, pBuffer, &pRingBuffer->rb);
|
||||||
pRingBuffer->format = format;
|
pRingBuffer->format = pConfig->format;
|
||||||
pRingBuffer->channels = channels;
|
pRingBuffer->channels = pConfig->channels;
|
||||||
pRingBuffer->sampleRate = sampleRate;
|
pRingBuffer->sampleRate = pConfig->sampleRate;
|
||||||
pRingBuffer->pBuffer = pBuffer;
|
pRingBuffer->isOwnerOfBuffer = isOwnerOfBuffer;
|
||||||
|
pRingBuffer->pBuffer = pBuffer;
|
||||||
return MA_SUCCESS;
|
ma_allocation_callbacks_init_copy(&pRingBuffer->allocationCallbacks, pConfig->pAllocationCallbacks);
|
||||||
}
|
|
||||||
|
|
||||||
MA_API ma_result ma_audio_ring_buffer_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, ma_uint32 capacityInFrames, const ma_allocation_callbacks* pAllocationCallbacks, ma_audio_ring_buffer* pRingBuffer)
|
|
||||||
{
|
|
||||||
ma_result result;
|
|
||||||
ma_uint32 bpf;
|
|
||||||
void* pBuffer;
|
|
||||||
|
|
||||||
if (pRingBuffer == NULL) {
|
|
||||||
return MA_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
MA_ZERO_OBJECT(pRingBuffer);
|
|
||||||
|
|
||||||
if (capacityInFrames == 0) {
|
|
||||||
return MA_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
bpf = ma_get_bytes_per_frame(format, channels);
|
|
||||||
if (bpf == 0) {
|
|
||||||
return MA_INVALID_ARGS;
|
|
||||||
}
|
|
||||||
|
|
||||||
pBuffer = ma_malloc(capacityInFrames * bpf * 2, pAllocationCallbacks);
|
|
||||||
if (pBuffer == NULL) {
|
|
||||||
return MA_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = ma_audio_ring_buffer_init_ex(format, channels, sampleRate, capacityInFrames, 0, pBuffer, pRingBuffer);
|
|
||||||
if (result != MA_SUCCESS) {
|
|
||||||
ma_free(pBuffer, pAllocationCallbacks);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
ma_allocation_callbacks_init_copy(&pRingBuffer->allocationCallbacks, pAllocationCallbacks);
|
|
||||||
pRingBuffer->isOwnerOfBuffer = MA_TRUE;
|
|
||||||
|
|
||||||
return MA_SUCCESS;
|
return MA_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -63907,13 +63938,17 @@ MA_API ma_result ma_duplex_rb_init(ma_format captureFormat, ma_uint32 captureCha
|
|||||||
{
|
{
|
||||||
ma_result result;
|
ma_result result;
|
||||||
ma_uint32 sizeInFrames;
|
ma_uint32 sizeInFrames;
|
||||||
|
ma_audio_ring_buffer_config ringBufferConfig;
|
||||||
|
|
||||||
sizeInFrames = (ma_uint32)ma_calculate_frame_count_after_resampling(sampleRate, captureInternalSampleRate, captureInternalPeriodSizeInFrames * 3);
|
sizeInFrames = (ma_uint32)ma_calculate_frame_count_after_resampling(sampleRate, captureInternalSampleRate, captureInternalPeriodSizeInFrames * 3);
|
||||||
if (sizeInFrames == 0) {
|
if (sizeInFrames == 0) {
|
||||||
return MA_INVALID_ARGS;
|
return MA_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = ma_audio_ring_buffer_init(captureFormat, captureChannels, sampleRate, sizeInFrames, pAllocationCallbacks, &pRB->rb);
|
ringBufferConfig = ma_audio_ring_buffer_config_init(captureFormat, captureChannels, sampleRate, sizeInFrames);
|
||||||
|
ringBufferConfig.pAllocationCallbacks = pAllocationCallbacks;
|
||||||
|
|
||||||
|
result = ma_audio_ring_buffer_init(&ringBufferConfig, &pRB->rb);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user