mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-23 16:54:03 +02:00
Add support for start delays to sound groups.
This commit is contained in:
@@ -38,6 +38,7 @@ int main(int argc, char** argv)
|
|||||||
//ma_engine_sound_group_set_pan(&engine, NULL, -1);
|
//ma_engine_sound_group_set_pan(&engine, NULL, -1);
|
||||||
ma_engine_sound_group_set_pitch(&engine, NULL, 1.0f);
|
ma_engine_sound_group_set_pitch(&engine, NULL, 1.0f);
|
||||||
ma_engine_sound_group_set_fade_in(&engine, NULL, 4000);
|
ma_engine_sound_group_set_fade_in(&engine, NULL, 4000);
|
||||||
|
ma_engine_sound_group_set_start_delay(&engine, NULL, 2000);
|
||||||
|
|
||||||
/*ma_engine_sound_set_volume(&engine, &sound, 0.25f);*/
|
/*ma_engine_sound_set_volume(&engine, &sound, 0.25f);*/
|
||||||
//ma_engine_sound_set_pitch(&engine, &sound, 2.0f);
|
//ma_engine_sound_set_pitch(&engine, &sound, 2.0f);
|
||||||
|
|||||||
+41
-7
@@ -913,6 +913,8 @@ struct ma_sound_group
|
|||||||
ma_engine_effect effect; /* The main effect for panning, etc. This is set on the mixer at initialisation time. */
|
ma_engine_effect effect; /* The main effect for panning, etc. This is set on the mixer at initialisation time. */
|
||||||
ma_mixer mixer;
|
ma_mixer mixer;
|
||||||
ma_mutex lock; /* Only used by ma_engine_sound_init_*() and ma_engine_sound_uninit(). Not used in the mixing thread. */
|
ma_mutex lock; /* Only used by ma_engine_sound_init_*() and ma_engine_sound_uninit(). Not used in the mixing thread. */
|
||||||
|
ma_uint64 runningTimeInEngineFrames; /* The amount of time the sound has been running in engine frames, including start delays. */
|
||||||
|
ma_uint64 startDelayInEngineFrames;
|
||||||
ma_bool32 isPlaying; /* True by default. Sound groups can be stopped with ma_engine_sound_stop() and resumed with ma_engine_sound_start(). Also affects children. */
|
ma_bool32 isPlaying; /* True by default. Sound groups can be stopped with ma_engine_sound_stop() and resumed with ma_engine_sound_start(). Also affects children. */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -998,6 +1000,7 @@ MA_API ma_result ma_engine_sound_group_set_effect(ma_engine* pEngine, ma_sound_g
|
|||||||
MA_API ma_result ma_engine_sound_group_set_pan(ma_engine* pEngine, ma_sound_group* pGroup, float pan);
|
MA_API ma_result ma_engine_sound_group_set_pan(ma_engine* pEngine, ma_sound_group* pGroup, float pan);
|
||||||
MA_API ma_result ma_engine_sound_group_set_pitch(ma_engine* pEngine, ma_sound_group* pGroup, float pitch);
|
MA_API ma_result ma_engine_sound_group_set_pitch(ma_engine* pEngine, ma_sound_group* pGroup, float pitch);
|
||||||
MA_API ma_result ma_engine_sound_group_set_fade_in(ma_engine* pEngine, ma_sound_group* pGroup, ma_uint64 fadeTimeInMilliseconds);
|
MA_API ma_result ma_engine_sound_group_set_fade_in(ma_engine* pEngine, ma_sound_group* pGroup, ma_uint64 fadeTimeInMilliseconds);
|
||||||
|
MA_API ma_result ma_engine_sound_group_set_start_delay(ma_engine* pEngine, ma_sound_group* pGroup, ma_uint64 delayInMilliseconds);
|
||||||
|
|
||||||
MA_API ma_result ma_engine_listener_set_position(ma_engine* pEngine, ma_vec3 position);
|
MA_API ma_result ma_engine_listener_set_position(ma_engine* pEngine, ma_vec3 position);
|
||||||
MA_API ma_result ma_engine_listener_set_rotation(ma_engine* pEngine, ma_quat rotation);
|
MA_API ma_result ma_engine_listener_set_rotation(ma_engine* pEngine, ma_quat rotation);
|
||||||
@@ -5336,7 +5339,7 @@ static void ma_engine_mix_sound(ma_engine* pEngine, ma_sound_group* pGroup, ma_s
|
|||||||
c89atomic_exchange_32(&pSound->atEnd, MA_TRUE); /* This will be set to false in ma_engine_sound_start(). */
|
c89atomic_exchange_32(&pSound->atEnd, MA_TRUE); /* This will be set to false in ma_engine_sound_start(). */
|
||||||
}
|
}
|
||||||
|
|
||||||
pSound->runningTimeInEngineFrames += framesProcessed;
|
pSound->runningTimeInEngineFrames += offsetInFrames + framesProcessed;
|
||||||
} else {
|
} else {
|
||||||
/* The sound hasn't started yet. Just keep advancing time forward, but leave the data source alone. */
|
/* The sound hasn't started yet. Just keep advancing time forward, but leave the data source alone. */
|
||||||
pSound->runningTimeInEngineFrames += frameCount;
|
pSound->runningTimeInEngineFrames += frameCount;
|
||||||
@@ -5372,16 +5375,26 @@ static void ma_engine_mix_sound_group(ma_engine* pEngine, ma_sound_group* pGroup
|
|||||||
frameCountOut = frameCount;
|
frameCountOut = frameCount;
|
||||||
frameCountIn = frameCount;
|
frameCountIn = frameCount;
|
||||||
|
|
||||||
|
/* If the group is being delayed we don't want to mix anything. */
|
||||||
|
if ((pGroup->runningTimeInEngineFrames + frameCount) > pGroup->startDelayInEngineFrames) {
|
||||||
|
/* We're not delayed so we can mix or seek. In order to get frame-exact playback timing we need to start mixing from an offset. */
|
||||||
|
ma_uint64 offsetInFrames = 0;
|
||||||
|
if (pGroup->startDelayInEngineFrames > pGroup->runningTimeInEngineFrames) {
|
||||||
|
offsetInFrames = pGroup->startDelayInEngineFrames - pGroup->runningTimeInEngineFrames;
|
||||||
|
}
|
||||||
|
|
||||||
|
MA_ASSERT(offsetInFrames < frameCount);
|
||||||
|
|
||||||
/* We need to loop here to ensure we fill every frame. This won't necessarily be able to be done in one iteration due to resampling within the effect. */
|
/* We need to loop here to ensure we fill every frame. This won't necessarily be able to be done in one iteration due to resampling within the effect. */
|
||||||
totalFramesProcessed = 0;
|
totalFramesProcessed = 0;
|
||||||
while (totalFramesProcessed < frameCount) {
|
while (totalFramesProcessed < (frameCount - offsetInFrames)) {
|
||||||
frameCountOut = frameCount - totalFramesProcessed;
|
frameCountOut = frameCount - offsetInFrames - totalFramesProcessed;
|
||||||
frameCountIn = frameCount - totalFramesProcessed;
|
frameCountIn = frameCount - offsetInFrames - totalFramesProcessed;
|
||||||
|
|
||||||
/* Before can mix the group we need to mix it's children. */
|
/* Before can mix the group we need to mix it's children. */
|
||||||
result = ma_mixer_begin(&pGroup->mixer, pParentMixer, &frameCountOut, &frameCountIn);
|
result = ma_mixer_begin(&pGroup->mixer, pParentMixer, &frameCountOut, &frameCountIn);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
MA_ASSERT(frameCountIn < 0xFFFFFFFF);
|
MA_ASSERT(frameCountIn < 0xFFFFFFFF);
|
||||||
@@ -5397,13 +5410,19 @@ static void ma_engine_mix_sound_group(ma_engine* pEngine, ma_sound_group* pGroup
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Now mix into the parent. */
|
/* Now mix into the parent. */
|
||||||
result = ma_mixer_end(&pGroup->mixer, pParentMixer, pFramesOut, totalFramesProcessed);
|
result = ma_mixer_end(&pGroup->mixer, pParentMixer, pFramesOut, offsetInFrames + totalFramesProcessed);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
totalFramesProcessed += frameCountOut;
|
totalFramesProcessed += frameCountOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pGroup->runningTimeInEngineFrames += offsetInFrames + totalFramesProcessed;
|
||||||
|
} else {
|
||||||
|
/* The group hasn't started yet. Just keep advancing time forward, but leave the data source alone. */
|
||||||
|
pGroup->runningTimeInEngineFrames += frameCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ma_engine_listener__data_callback_fixed(ma_engine* pEngine, void* pFramesOut, ma_uint32 frameCount)
|
static void ma_engine_listener__data_callback_fixed(ma_engine* pEngine, void* pFramesOut, ma_uint32 frameCount)
|
||||||
@@ -6568,6 +6587,21 @@ MA_API ma_result ma_engine_sound_group_set_fade_in(ma_engine* pEngine, ma_sound_
|
|||||||
return ma_dual_fader_set_fade(&pGroup->effect.fader, 0, 0, 1, pGroup->effect.fader.timeInFramesCur, pGroup->effect.fader.timeInFramesCur + (fadeTimeInMilliseconds * pGroup->effect.fader.config.sampleRate) / 1000);
|
return ma_dual_fader_set_fade(&pGroup->effect.fader, 0, 0, 1, pGroup->effect.fader.timeInFramesCur, pGroup->effect.fader.timeInFramesCur + (fadeTimeInMilliseconds * pGroup->effect.fader.config.sampleRate) / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MA_API ma_result ma_engine_sound_group_set_start_delay(ma_engine* pEngine, ma_sound_group* pGroup, ma_uint64 delayInMilliseconds)
|
||||||
|
{
|
||||||
|
if (pEngine == NULL) {
|
||||||
|
return MA_INVALID_ARGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pGroup == NULL) {
|
||||||
|
pGroup = &pEngine->masterSoundGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
pGroup->startDelayInEngineFrames = (pEngine->sampleRate * delayInMilliseconds) / 1000;
|
||||||
|
|
||||||
|
return MA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
MA_API ma_result ma_engine_listener_set_position(ma_engine* pEngine, ma_vec3 position)
|
MA_API ma_result ma_engine_listener_set_position(ma_engine* pEngine, ma_vec3 position)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user