mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-23 08:44:04 +02:00
Add support for offsets to the low-level mixing API.
This commit is contained in:
+24
-19
@@ -599,7 +599,7 @@ ma_mixer_mix_pcm_frames()
|
|||||||
ma_mixer_begin()
|
ma_mixer_begin()
|
||||||
ma_mixer_end()
|
ma_mixer_end()
|
||||||
*/
|
*/
|
||||||
MA_API ma_result ma_mixer_mix_pcm_frames(ma_mixer* pMixer, const void* pFramesIn, ma_uint64 frameCountIn, float volume, ma_format formatIn, ma_uint32 channelsIn);
|
MA_API ma_result ma_mixer_mix_pcm_frames(ma_mixer* pMixer, const void* pFramesIn, ma_uint64 offsetInFrames, ma_uint64 frameCountIn, float volume, ma_format formatIn, ma_uint32 channelsIn);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Mixes audio data from a data source
|
Mixes audio data from a data source
|
||||||
@@ -645,9 +645,9 @@ See Also
|
|||||||
ma_mixer_begin()
|
ma_mixer_begin()
|
||||||
ma_mixer_end()
|
ma_mixer_end()
|
||||||
*/
|
*/
|
||||||
MA_API ma_result ma_mixer_mix_data_source(ma_mixer* pMixer, ma_data_source* pDataSource, ma_uint64 frameCountIn, ma_uint64* pFrameCountOut, float volume, ma_effect* pEffect, ma_bool32 loop);
|
MA_API ma_result ma_mixer_mix_data_source(ma_mixer* pMixer, ma_data_source* pDataSource, ma_uint64 offsetInFrames, ma_uint64 frameCountIn, ma_uint64* pFrameCountOut, float volume, ma_effect* pEffect, ma_bool32 loop);
|
||||||
MA_API ma_result ma_mixer_mix_rb(ma_mixer* pMixer, ma_rb* pRB, ma_uint64 frameCountIn, ma_uint64* pFrameCountOut, float volume, ma_effect* pEffect, ma_format formatIn, ma_uint32 channelsIn); /* Caller is the consumer. */
|
MA_API ma_result ma_mixer_mix_rb(ma_mixer* pMixer, ma_rb* pRB, ma_uint64 offsetInFrames, ma_uint64 frameCountIn, ma_uint64* pFrameCountOut, float volume, ma_effect* pEffect, ma_format formatIn, ma_uint32 channelsIn); /* Caller is the consumer. */
|
||||||
MA_API ma_result ma_mixer_mix_pcm_rb(ma_mixer* pMixer, ma_pcm_rb* pRB, ma_uint64 frameCountIn, ma_uint64* pFrameCountOut, float volume, ma_effect* pEffect); /* Caller is the consumer. */
|
MA_API ma_result ma_mixer_mix_pcm_rb(ma_mixer* pMixer, ma_pcm_rb* pRB, ma_uint64 offsetInFrames, ma_uint64 frameCountIn, ma_uint64* pFrameCountOut, float volume, ma_effect* pEffect); /* Caller is the consumer. */
|
||||||
|
|
||||||
MA_API ma_result ma_mixer_set_volume(ma_mixer* pMixer, float volume);
|
MA_API ma_result ma_mixer_set_volume(ma_mixer* pMixer, float volume);
|
||||||
MA_API ma_result ma_mixer_get_volume(ma_mixer* pMixer, float* pVolume);
|
MA_API ma_result ma_mixer_get_volume(ma_mixer* pMixer, float* pVolume);
|
||||||
@@ -2463,7 +2463,7 @@ MA_API ma_result ma_mixer_end(ma_mixer* pMixer, ma_mixer* pParentMixer, void* pF
|
|||||||
return MA_SUCCESS;
|
return MA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
MA_API ma_result ma_mixer_mix_pcm_frames(ma_mixer* pMixer, const void* pFramesIn, ma_uint64 frameCountIn, float volume, ma_format formatIn, ma_uint32 channelsIn)
|
MA_API ma_result ma_mixer_mix_pcm_frames(ma_mixer* pMixer, const void* pFramesIn, ma_uint64 offsetInFrames, ma_uint64 frameCountIn, float volume, ma_format formatIn, ma_uint32 channelsIn)
|
||||||
{
|
{
|
||||||
if (pMixer == NULL || pFramesIn == NULL) {
|
if (pMixer == NULL || pFramesIn == NULL) {
|
||||||
return MA_INVALID_ARGS;
|
return MA_INVALID_ARGS;
|
||||||
@@ -2473,16 +2473,16 @@ MA_API ma_result ma_mixer_mix_pcm_frames(ma_mixer* pMixer, const void* pFramesIn
|
|||||||
return MA_INVALID_ARGS; /* Passing in too many input frames. */
|
return MA_INVALID_ARGS; /* Passing in too many input frames. */
|
||||||
}
|
}
|
||||||
|
|
||||||
ma_mix_pcm_frames(pMixer->pAccumulationBuffer, pFramesIn, frameCountIn, formatIn, channelsIn, volume);
|
ma_mix_pcm_frames(ma_offset_ptr(pMixer->pAccumulationBuffer, offsetInFrames * ma_get_accumulation_bytes_per_frame(pMixer->format, pMixer->channels)), pFramesIn, frameCountIn, formatIn, channelsIn, volume);
|
||||||
|
|
||||||
return MA_SUCCESS;
|
return MA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ma_result ma_mixer_mix_data_source_mmap(ma_mixer* pMixer, ma_data_source* pDataSource, ma_uint64 frameCountIn, ma_uint64* pFrameCountOut, float volume, ma_effect* pEffect, ma_format formatIn, ma_uint32 channelsIn, ma_bool32 loop)
|
static ma_result ma_mixer_mix_data_source_mmap(ma_mixer* pMixer, ma_data_source* pDataSource, ma_uint64 offsetInFrames, ma_uint64 frameCountIn, ma_uint64* pFrameCountOut, float volume, ma_effect* pEffect, ma_format formatIn, ma_uint32 channelsIn, ma_bool32 loop)
|
||||||
{
|
{
|
||||||
ma_result result = MA_SUCCESS;
|
ma_result result = MA_SUCCESS;
|
||||||
ma_uint64 totalFramesProcessed = 0;
|
ma_uint64 totalFramesProcessed = 0;
|
||||||
void* pRunningAccumulationBuffer = pMixer->pAccumulationBuffer;
|
void* pRunningAccumulationBuffer = NULL;
|
||||||
ma_bool32 preEffectConversionRequired = MA_FALSE;
|
ma_bool32 preEffectConversionRequired = MA_FALSE;
|
||||||
ma_format effectFormatIn = ma_format_unknown;
|
ma_format effectFormatIn = ma_format_unknown;
|
||||||
ma_uint32 effectChannelsIn = 0;
|
ma_uint32 effectChannelsIn = 0;
|
||||||
@@ -2496,10 +2496,13 @@ static ma_result ma_mixer_mix_data_source_mmap(ma_mixer* pMixer, ma_data_source*
|
|||||||
*pFrameCountOut = 0;
|
*pFrameCountOut = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frameCountIn > pMixer->mixingState.frameCountIn) {
|
if ((offsetInFrames + frameCountIn) > pMixer->mixingState.frameCountIn) {
|
||||||
return MA_INVALID_ARGS; /* Passing in too many input frames. */
|
return MA_INVALID_ARGS; /* Passing in too many input frames. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initially offset the accumulation buffer by the offset. */
|
||||||
|
pRunningAccumulationBuffer = ma_offset_ptr(pMixer->pAccumulationBuffer, offsetInFrames * ma_get_accumulation_bytes_per_frame(pMixer->format, pMixer->channels));
|
||||||
|
|
||||||
if (pEffect != NULL) {
|
if (pEffect != NULL) {
|
||||||
/* We need to know the effect's input and output data format before we'll be able to apply it properly. */
|
/* We need to know the effect's input and output data format before we'll be able to apply it properly. */
|
||||||
result = ma_effect_get_input_data_format(pEffect, &effectFormatIn, &effectChannelsIn, NULL);
|
result = ma_effect_get_input_data_format(pEffect, &effectFormatIn, &effectChannelsIn, NULL);
|
||||||
@@ -2597,7 +2600,7 @@ static ma_result ma_mixer_mix_data_source_mmap(ma_mixer* pMixer, ma_data_source*
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ma_result ma_mixer_mix_data_source_read(ma_mixer* pMixer, ma_data_source* pDataSource, ma_uint64 frameCountIn, ma_uint64* pFrameCountOut, float volume, ma_effect* pEffect, ma_format formatIn, ma_uint32 channelsIn, ma_bool32 loop)
|
static ma_result ma_mixer_mix_data_source_read(ma_mixer* pMixer, ma_data_source* pDataSource, ma_uint64 offsetInFrames, ma_uint64 frameCountIn, ma_uint64* pFrameCountOut, float volume, ma_effect* pEffect, ma_format formatIn, ma_uint32 channelsIn, ma_bool32 loop)
|
||||||
{
|
{
|
||||||
ma_result result = MA_SUCCESS;
|
ma_result result = MA_SUCCESS;
|
||||||
ma_uint8 preMixBuffer[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
|
ma_uint8 preMixBuffer[MA_DATA_CONVERTER_STACK_BUFFER_SIZE];
|
||||||
@@ -2617,7 +2620,7 @@ static ma_result ma_mixer_mix_data_source_read(ma_mixer* pMixer, ma_data_source*
|
|||||||
*pFrameCountOut = 0;
|
*pFrameCountOut = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frameCountIn > pMixer->mixingState.frameCountIn) {
|
if ((offsetInFrames + frameCountIn) > pMixer->mixingState.frameCountIn) {
|
||||||
return MA_INVALID_ARGS; /* Passing in too many input frames. */
|
return MA_INVALID_ARGS; /* Passing in too many input frames. */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2642,7 +2645,9 @@ static ma_result ma_mixer_mix_data_source_read(ma_mixer* pMixer, ma_data_source*
|
|||||||
preMixBufferCap = sizeof(preMixBuffer) / ma_get_bytes_per_frame(preMixFormat, preMixChannels);
|
preMixBufferCap = sizeof(preMixBuffer) / ma_get_bytes_per_frame(preMixFormat, preMixChannels);
|
||||||
|
|
||||||
totalFramesProcessed = 0;
|
totalFramesProcessed = 0;
|
||||||
pRunningAccumulationBuffer = pMixer->pAccumulationBuffer;
|
|
||||||
|
/* Initially offset the accumulation buffer by the offset. */
|
||||||
|
pRunningAccumulationBuffer = ma_offset_ptr(pMixer->pAccumulationBuffer, offsetInFrames * ma_get_accumulation_bytes_per_frame(pMixer->format, pMixer->channels));
|
||||||
|
|
||||||
while (totalFramesProcessed < frameCountIn) {
|
while (totalFramesProcessed < frameCountIn) {
|
||||||
ma_uint64 framesRead;
|
ma_uint64 framesRead;
|
||||||
@@ -2714,7 +2719,7 @@ static ma_result ma_mixer_mix_data_source_read(ma_mixer* pMixer, ma_data_source*
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
MA_API ma_result ma_mixer_mix_data_source(ma_mixer* pMixer, ma_data_source* pDataSource, ma_uint64 frameCountIn, ma_uint64* pFrameCountOut, float volume, ma_effect* pEffect, ma_bool32 loop)
|
MA_API ma_result ma_mixer_mix_data_source(ma_mixer* pMixer, ma_data_source* pDataSource, ma_uint64 offsetInFrames, ma_uint64 frameCountIn, ma_uint64* pFrameCountOut, float volume, ma_effect* pEffect, ma_bool32 loop)
|
||||||
{
|
{
|
||||||
ma_result result;
|
ma_result result;
|
||||||
ma_format formatIn;
|
ma_format formatIn;
|
||||||
@@ -2738,10 +2743,10 @@ MA_API ma_result ma_mixer_mix_data_source(ma_mixer* pMixer, ma_data_source* pDat
|
|||||||
|
|
||||||
if (supportsMMap) {
|
if (supportsMMap) {
|
||||||
/* Fast path. This is memory mapping mode. */
|
/* Fast path. This is memory mapping mode. */
|
||||||
return ma_mixer_mix_data_source_mmap(pMixer, pDataSourceCallbacks, frameCountIn, pFrameCountOut, volume, pEffect, formatIn, channelsIn, loop);
|
return ma_mixer_mix_data_source_mmap(pMixer, pDataSourceCallbacks, offsetInFrames, frameCountIn, pFrameCountOut, volume, pEffect, formatIn, channelsIn, loop);
|
||||||
} else {
|
} else {
|
||||||
/* Slow path. This is reading mode. */
|
/* Slow path. This is reading mode. */
|
||||||
return ma_mixer_mix_data_source_read(pMixer, pDataSourceCallbacks, frameCountIn, pFrameCountOut, volume, pEffect, formatIn, channelsIn, loop);
|
return ma_mixer_mix_data_source_read(pMixer, pDataSourceCallbacks, offsetInFrames, frameCountIn, pFrameCountOut, volume, pEffect, formatIn, channelsIn, loop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2815,18 +2820,18 @@ static ma_result ma_rb_data_source_init(ma_rb* pRB, ma_format format, ma_uint32
|
|||||||
return MA_SUCCESS;
|
return MA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
MA_API ma_result ma_mixer_mix_rb(ma_mixer* pMixer, ma_rb* pRB, ma_uint64 frameCountIn, ma_uint64* pFrameCountOut, float volume, ma_effect* pEffect, ma_format formatIn, ma_uint32 channelsIn)
|
MA_API ma_result ma_mixer_mix_rb(ma_mixer* pMixer, ma_rb* pRB, ma_uint64 offsetInFrames, ma_uint64 frameCountIn, ma_uint64* pFrameCountOut, float volume, ma_effect* pEffect, ma_format formatIn, ma_uint32 channelsIn)
|
||||||
{
|
{
|
||||||
/* Ring buffer mixing can be implemented in terms of a memory mapped data source. */
|
/* Ring buffer mixing can be implemented in terms of a memory mapped data source. */
|
||||||
ma_rb_data_source ds;
|
ma_rb_data_source ds;
|
||||||
ma_rb_data_source_init(pRB, formatIn, channelsIn, &ds); /* Will never fail and does not require an uninit() implementation. */
|
ma_rb_data_source_init(pRB, formatIn, channelsIn, &ds); /* Will never fail and does not require an uninit() implementation. */
|
||||||
|
|
||||||
return ma_mixer_mix_data_source(pMixer, &ds, frameCountIn, pFrameCountOut, volume, pEffect, MA_TRUE); /* Ring buffers always loop, but the loop parameter will never actually be used because ma_rb_data_source__on_unmap() will never return MA_AT_END. */
|
return ma_mixer_mix_data_source(pMixer, &ds, offsetInFrames, frameCountIn, pFrameCountOut, volume, pEffect, MA_TRUE); /* Ring buffers always loop, but the loop parameter will never actually be used because ma_rb_data_source__on_unmap() will never return MA_AT_END. */
|
||||||
}
|
}
|
||||||
|
|
||||||
MA_API ma_result ma_mixer_mix_pcm_rb(ma_mixer* pMixer, ma_pcm_rb* pRB, ma_uint64 frameCountIn, ma_uint64* pFrameCountOut, float volume, ma_effect* pEffect)
|
MA_API ma_result ma_mixer_mix_pcm_rb(ma_mixer* pMixer, ma_pcm_rb* pRB, ma_uint64 offsetInFrames, ma_uint64 frameCountIn, ma_uint64* pFrameCountOut, float volume, ma_effect* pEffect)
|
||||||
{
|
{
|
||||||
return ma_mixer_mix_rb(pMixer, &pRB->rb, frameCountIn, pFrameCountOut, volume, pEffect, pRB->format, pRB->channels);
|
return ma_mixer_mix_rb(pMixer, &pRB->rb, offsetInFrames, frameCountIn, pFrameCountOut, volume, pEffect, pRB->format, pRB->channels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user