mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-22 00:06:59 +02:00
Add support for panning to sound groups.
This commit is contained in:
@@ -34,15 +34,17 @@ int main(int argc, char** argv)
|
||||
}
|
||||
|
||||
/*ma_data_source_seek_to_pcm_frame(sound.pDataSource, 5000000);*/
|
||||
|
||||
ma_engine_sound_group_set_pan(&engine, NULL, -1);
|
||||
|
||||
/*ma_engine_sound_set_volume(&engine, &sound, 0.25f);*/
|
||||
ma_engine_sound_set_pitch(&engine, &sound, 1.0f);
|
||||
ma_engine_sound_set_pan(&engine, &sound, 0.0f);
|
||||
ma_engine_sound_set_looping(&engine, &sound, MA_TRUE);
|
||||
//ma_engine_sound_seek_to_pcm_frame(&engine, &sound, 6000000);
|
||||
ma_engine_sound_set_start_delay(&engine, &sound, 1110);
|
||||
ma_engine_sound_set_fade_in(&engine, &sound, 2000);
|
||||
ma_engine_sound_set_fade_out(&engine, &sound, 2000);
|
||||
//ma_engine_sound_set_start_delay(&engine, &sound, 1110);
|
||||
//ma_engine_sound_set_fade_in(&engine, &sound, 2000);
|
||||
//ma_engine_sound_set_fade_out(&engine, &sound, 2000);
|
||||
ma_engine_sound_start(&engine, &sound);
|
||||
|
||||
ma_sleep(5000);
|
||||
|
||||
+65
-19
@@ -910,6 +910,7 @@ struct ma_sound_group
|
||||
ma_sound_group* pPrevSibling;
|
||||
ma_sound_group* pNextSibling;
|
||||
ma_sound* pFirstSoundInGroup;
|
||||
ma_engine_effect effect; /* The main effect for panning, etc. This is set on the mixer at initialisation time. */
|
||||
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_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. */
|
||||
@@ -971,11 +972,11 @@ MA_API ma_result ma_engine_sound_start(ma_engine* pEngine, ma_sound* pSound);
|
||||
MA_API ma_result ma_engine_sound_stop(ma_engine* pEngine, ma_sound* pSound);
|
||||
MA_API ma_result ma_engine_sound_set_volume(ma_engine* pEngine, ma_sound* pSound, float volume);
|
||||
MA_API ma_result ma_engine_sound_set_gain_db(ma_engine* pEngine, ma_sound* pSound, float gainDB);
|
||||
MA_API ma_result ma_engine_sound_set_effect(ma_engine* pEngine, ma_sound* pSound, ma_effect* pEffect);
|
||||
MA_API ma_result ma_engine_sound_set_pan(ma_engine* pEngine, ma_sound* pSound, float pan);
|
||||
MA_API ma_result ma_engine_sound_set_pitch(ma_engine* pEngine, ma_sound* pSound, float pitch);
|
||||
MA_API ma_result ma_engine_sound_set_position(ma_engine* pEngine, ma_sound* pSound, ma_vec3 position);
|
||||
MA_API ma_result ma_engine_sound_set_rotation(ma_engine* pEngine, ma_sound* pSound, ma_quat rotation);
|
||||
MA_API ma_result ma_engine_sound_set_effect(ma_engine* pEngine, ma_sound* pSound, ma_effect* pEffect);
|
||||
MA_API ma_result ma_engine_sound_set_looping(ma_engine* pEngine, ma_sound* pSound, ma_bool32 isLooping);
|
||||
MA_API ma_result ma_engine_sound_set_fade_in(ma_engine* pEngine, ma_sound* pSound, ma_uint64 fadeTimeInMilliseconds);
|
||||
MA_API ma_result ma_engine_sound_set_fade_out(ma_engine* pEngine, ma_sound* pSound, ma_uint64 fadeTimeInMilliseconds);
|
||||
@@ -994,6 +995,7 @@ MA_API ma_result ma_engine_sound_group_stop(ma_engine* pEngine, ma_sound_group*
|
||||
MA_API ma_result ma_engine_sound_group_set_volume(ma_engine* pEngine, ma_sound_group* pGroup, float volume);
|
||||
MA_API ma_result ma_engine_sound_group_set_gain_db(ma_engine* pEngine, ma_sound_group* pGroup, float gainDB);
|
||||
MA_API ma_result ma_engine_sound_group_set_effect(ma_engine* pEngine, ma_sound_group* pGroup, ma_effect* pEffect);
|
||||
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_listener_set_position(ma_engine* pEngine, ma_vec3 position);
|
||||
MA_API ma_result ma_engine_listener_set_rotation(ma_engine* pEngine, ma_quat rotation);
|
||||
@@ -4279,13 +4281,27 @@ static void ma_stereo_balance_pcm_frames_f32(float* pFramesOut, const float* pFr
|
||||
|
||||
if (pan > 0) {
|
||||
float factor = 1.0f - pan;
|
||||
for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
|
||||
pFramesOut[iFrame*2 + 0] = pFramesIn[iFrame*2 + 0] * factor;
|
||||
if (pFramesOut == pFramesIn) {
|
||||
for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
|
||||
pFramesOut[iFrame*2 + 0] = pFramesIn[iFrame*2 + 0] * factor;
|
||||
}
|
||||
} else {
|
||||
for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
|
||||
pFramesOut[iFrame*2 + 0] = pFramesIn[iFrame*2 + 0] * factor;
|
||||
pFramesOut[iFrame*2 + 1] = pFramesIn[iFrame*2 + 1];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
float factor = 1.0f + pan;
|
||||
for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
|
||||
pFramesOut[iFrame*2 + 1] = pFramesIn[iFrame*2 + 1] * factor;
|
||||
if (pFramesOut == pFramesIn) {
|
||||
for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
|
||||
pFramesOut[iFrame*2 + 1] = pFramesIn[iFrame*2 + 1] * factor;
|
||||
}
|
||||
} else {
|
||||
for (iFrame = 0; iFrame < frameCount; iFrame += 1) {
|
||||
pFramesOut[iFrame*2 + 0] = pFramesIn[iFrame*2 + 0];
|
||||
pFramesOut[iFrame*2 + 1] = pFramesIn[iFrame*2 + 1] * factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4880,7 +4896,11 @@ static ma_result ma_engine_effect__on_process_pcm_frames__no_pre_effect_no_pitch
|
||||
|
||||
static ma_result ma_engine_effect__on_process_pcm_frames__no_pre_effect(ma_engine_effect* pEngineEffect, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut)
|
||||
{
|
||||
ma_bool32 isPitchingRequired = MA_TRUE;
|
||||
ma_bool32 isPitchingRequired = MA_FALSE;
|
||||
|
||||
if (pEngineEffect->converter.hasResampler && pEngineEffect->pitch != 1) {
|
||||
isPitchingRequired = MA_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
This will be called if either there is no pre-effect or the pre-effect has already been processed. We can safely assume the input and output data in the engine's format so no
|
||||
@@ -5954,6 +5974,17 @@ MA_API ma_result ma_engine_sound_set_gain_db(ma_engine* pEngine, ma_sound* pSoun
|
||||
return ma_engine_sound_set_volume(pEngine, pSound, ma_gain_db_to_factor(gainDB));
|
||||
}
|
||||
|
||||
MA_API ma_result ma_engine_sound_set_effect(ma_engine* pEngine, ma_sound* pSound, ma_effect* pEffect)
|
||||
{
|
||||
if (pEngine == NULL || pSound == NULL) {
|
||||
return MA_INVALID_ARGS;
|
||||
}
|
||||
|
||||
pSound->effect.pPreEffect = pEffect;
|
||||
|
||||
return MA_SUCCESS;
|
||||
}
|
||||
|
||||
MA_API ma_result ma_engine_sound_set_pitch(ma_engine* pEngine, ma_sound* pSound, float pitch)
|
||||
{
|
||||
if (pEngine == NULL || pSound == NULL) {
|
||||
@@ -5992,17 +6023,6 @@ MA_API ma_result ma_engine_sound_set_rotation(ma_engine* pEngine, ma_sound* pSou
|
||||
return ma_spatializer_set_rotation(&pSound->effect.spatializer, rotation);
|
||||
}
|
||||
|
||||
MA_API ma_result ma_engine_sound_set_effect(ma_engine* pEngine, ma_sound* pSound, ma_effect* pEffect)
|
||||
{
|
||||
if (pEngine == NULL || pSound == NULL) {
|
||||
return MA_INVALID_ARGS;
|
||||
}
|
||||
|
||||
pSound->effect.pPreEffect = pEffect;
|
||||
|
||||
return MA_SUCCESS;
|
||||
}
|
||||
|
||||
MA_API ma_result ma_engine_sound_set_looping(ma_engine* pEngine, ma_sound* pSound, ma_bool32 isLooping)
|
||||
{
|
||||
if (pEngine == NULL || pSound == NULL) {
|
||||
@@ -6325,18 +6345,30 @@ MA_API ma_result ma_engine_sound_group_init(ma_engine* pEngine, ma_sound_group*
|
||||
|
||||
/* TODO: Look at the possibility of allowing groups to use a different format to the primary data format. Makes mixing and group management much more complicated. */
|
||||
|
||||
/* For handling panning, etc. we'll need an engine effect. */
|
||||
result = ma_engine_effect_init(pEngine, &pGroup->effect);
|
||||
if (result != MA_SUCCESS) {
|
||||
return result; /* Failed to initialize the engine effect. */
|
||||
}
|
||||
|
||||
/* The sound group needs a mixer. */
|
||||
mixerConfig = ma_mixer_config_init(pEngine->format, pEngine->channels, pEngine->periodSizeInFrames, NULL, &pEngine->allocationCallbacks);
|
||||
result = ma_mixer_init(&mixerConfig, &pGroup->mixer);
|
||||
if (result != MA_SUCCESS) {
|
||||
ma_engine_effect_uninit(pEngine, &pGroup->effect);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* The mixer's effect is always set to the main engine effect. */
|
||||
ma_mixer_set_effect(&pGroup->mixer, &pGroup->effect);
|
||||
|
||||
|
||||
/* Attach the sound group to it's parent if it has one (this will only happen if it's the master group). */
|
||||
if (pParentGroup != NULL) {
|
||||
result = ma_engine_sound_group_attach(pEngine, pGroup, pParentGroup);
|
||||
if (result != MA_SUCCESS) {
|
||||
ma_mixer_uninit(&pGroup->mixer);
|
||||
ma_engine_effect_uninit(pEngine, &pGroup->effect);
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
@@ -6351,6 +6383,7 @@ MA_API ma_result ma_engine_sound_group_init(ma_engine* pEngine, ma_sound_group*
|
||||
if (result != MA_SUCCESS) {
|
||||
ma_engine_sound_group_detach(pEngine, pGroup);
|
||||
ma_mixer_uninit(&pGroup->mixer);
|
||||
ma_engine_effect_uninit(pEngine, &pGroup->effect);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -6395,6 +6428,8 @@ MA_API void ma_engine_sound_group_uninit(ma_engine* pEngine, ma_sound_group* pGr
|
||||
|
||||
ma_mixer_uninit(&pGroup->mixer);
|
||||
ma_mutex_uninit(&pGroup->lock);
|
||||
|
||||
ma_engine_effect_uninit(pEngine, &pGroup->effect);
|
||||
}
|
||||
|
||||
MA_API ma_result ma_engine_sound_group_start(ma_engine* pEngine, ma_sound_group* pGroup)
|
||||
@@ -6462,12 +6497,23 @@ MA_API ma_result ma_engine_sound_group_set_effect(ma_engine* pEngine, ma_sound_g
|
||||
pGroup = &pEngine->masterSoundGroup;
|
||||
}
|
||||
|
||||
/* The effect is set on the mixer. */
|
||||
ma_mixer_set_effect(&pGroup->mixer, pEffect);
|
||||
pGroup->effect.pPreEffect = pEffect;
|
||||
|
||||
return MA_SUCCESS;
|
||||
}
|
||||
|
||||
MA_API ma_result ma_engine_sound_group_set_pan(ma_engine* pEngine, ma_sound_group* pGroup, float pan)
|
||||
{
|
||||
if (pEngine == NULL) {
|
||||
return MA_INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (pGroup == NULL) {
|
||||
pGroup = &pEngine->masterSoundGroup;
|
||||
}
|
||||
|
||||
return ma_panner_set_pan(&pGroup->effect.panner, pan);
|
||||
}
|
||||
|
||||
|
||||
MA_API ma_result ma_engine_listener_set_position(ma_engine* pEngine, ma_vec3 position)
|
||||
|
||||
Reference in New Issue
Block a user