From e3a70e50216850aff2721ce3cc4a3e1c2cee311f Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 12 May 2010 04:56:03 -0700 Subject: [PATCH] Scale output of effects to compensate for device down-mixing --- Alc/alcEcho.c | 9 ++++++++- Alc/alcModulator.c | 12 +++++++++--- Alc/alcReverb.c | 13 +++++++++++-- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/Alc/alcEcho.c b/Alc/alcEcho.c index d9700527..d6f7fbb3 100644 --- a/Alc/alcEcho.c +++ b/Alc/alcEcho.c @@ -49,6 +49,8 @@ typedef struct ALechoState { ALfloat FeedGain; + ALfloat Scale; + FILTER iirFilter; ALfloat history[2]; } ALechoState; @@ -88,6 +90,9 @@ static ALboolean EchoDeviceUpdate(ALeffectState *effect, ALCdevice *Device) for(i = 0;i < state->BufferLength;i++) state->SampleBuffer[i] = 0.0f; + state->Scale = aluSqrt(Device->NumChan / 6.0f); + state->Scale = __min(state->Scale, 1.0f); + return AL_TRUE; } @@ -122,7 +127,7 @@ static ALvoid EchoProcess(ALeffectState *effect, const ALeffectslot *Slot, ALuin const ALuint tap1 = state->Tap[0].delay; const ALuint tap2 = state->Tap[1].delay; ALuint offset = state->Offset; - const ALfloat gain = Slot->Gain; + const ALfloat gain = Slot->Gain * state->Scale; ALfloat samp[2], smp; ALuint i; @@ -178,6 +183,8 @@ ALeffectState *EchoCreate(void) state->GainL = 0.0f; state->GainR = 0.0f; + state->Scale = 1.0f; + state->iirFilter.coeff = 0.0f; state->iirFilter.history[0] = 0.0f; state->iirFilter.history[1] = 0.0f; diff --git a/Alc/alcModulator.c b/Alc/alcModulator.c index cabbaeb6..0578ee1c 100644 --- a/Alc/alcModulator.c +++ b/Alc/alcModulator.c @@ -43,6 +43,8 @@ typedef struct ALmodulatorState { ALuint index; ALuint step; + ALfloat Scale; + FILTER iirFilter; ALfloat history[1]; } ALmodulatorState; @@ -87,9 +89,11 @@ static ALvoid ModulatorDestroy(ALeffectState *effect) static ALboolean ModulatorDeviceUpdate(ALeffectState *effect, ALCdevice *Device) { + ALmodulatorState *state = (ALmodulatorState*)effect; + + state->Scale = aluSqrt(Device->NumChan / 8.0f); + return AL_TRUE; - (void)effect; - (void)Device; } static ALvoid ModulatorUpdate(ALeffectState *effect, ALCcontext *Context, const ALeffect *Effect) @@ -117,7 +121,7 @@ static ALvoid ModulatorUpdate(ALeffectState *effect, ALCcontext *Context, const static ALvoid ModulatorProcess(ALeffectState *effect, const ALeffectslot *Slot, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[OUTPUTCHANNELS]) { ALmodulatorState *state = (ALmodulatorState*)effect; - const ALfloat gain = Slot->Gain; + const ALfloat gain = Slot->Gain * state->Scale; const ALuint step = state->step; ALuint index = state->index; ALfloat samp; @@ -187,6 +191,8 @@ ALeffectState *ModulatorCreate(void) state->index = 0.0f; state->step = 1.0f; + state->Scale = 1.0f; + state->iirFilter.coeff = 0.0f; state->iirFilter.history[0] = 0.0f; diff --git a/Alc/alcReverb.c b/Alc/alcReverb.c index 3529c08d..6ca47d2d 100644 --- a/Alc/alcReverb.c +++ b/Alc/alcReverb.c @@ -129,6 +129,9 @@ typedef struct ALverbState { } Echo; // The current read offset for all delay lines. ALuint Offset; + + // Gain scale to account for device down-mixing + ALfloat Scale; } ALverbState; /* This coefficient is used to define the maximum frequency range controlled @@ -987,6 +990,8 @@ static ALboolean VerbDeviceUpdate(ALeffectState *effect, ALCdevice *Device) if(!AllocLines(AL_FALSE, frequency, State)) return AL_FALSE; + State->Scale = aluSqrt(Device->NumChan / 8.0f); + // The early reflection and late all-pass filter line lengths are static, // so their offsets only need to be calculated once. for(index = 0;index < 4;index++) @@ -1012,6 +1017,8 @@ static ALboolean EAXVerbDeviceUpdate(ALeffectState *effect, ALCdevice *Device) if(!AllocLines(AL_TRUE, frequency, State)) return AL_FALSE; + State->Scale = aluSqrt(Device->NumChan / 8.0f); + // Calculate the modulation filter coefficient. Notice that the exponent // is calculated given the current sample rate. This ensures that the // resulting filter response over time is consistent across all sample @@ -1141,7 +1148,7 @@ static ALvoid VerbProcess(ALeffectState *effect, const ALeffectslot *Slot, ALuin ALverbState *State = (ALverbState*)effect; ALuint index; ALfloat early[4], late[4], out[4]; - ALfloat gain = Slot->Gain; + ALfloat gain = Slot->Gain * State->Scale; for(index = 0;index < SamplesToDo;index++) { @@ -1173,7 +1180,7 @@ static ALvoid EAXVerbProcess(ALeffectState *effect, const ALeffectslot *Slot, AL ALverbState *State = (ALverbState*)effect; ALuint index; ALfloat early[4], late[4]; - ALfloat gain = Slot->Gain; + ALfloat gain = Slot->Gain * State->Scale; for(index = 0;index < SamplesToDo;index++) { @@ -1304,6 +1311,8 @@ ALeffectState *VerbCreate(void) State->Offset = 0; + State->Scale = 1.0f; + return &State->state; } -- 2.11.4.GIT