static ALvoid DedicatedUpdate(ALeffectState *effect, ALCcontext *Context, const ALeffectslot *Slot) { ALdedicatedState *state = (ALdedicatedState*)effect; ALCdevice *device = Context->Device; const ALfloat *SpeakerGain; ALfloat Gain; ALint pos; ALsizei s; Gain = Slot->Gain * Slot->effect.Dedicated.Gain; for(s = 0;s < MAXCHANNELS;s++) state->gains[s] = 0.0f; if(Slot->effect.type == AL_EFFECT_DEDICATED_DIALOGUE) { pos = aluCart2LUTpos(1.0f, 0.0f); SpeakerGain = device->PanningLUT[pos]; for(s = 0;s < MAXCHANNELS;s++) state->gains[s] = SpeakerGain[s] * Gain; } else if(Slot->effect.type == AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT) state->gains[LFE] = Gain; }
// Update the early and late 3D panning gains. static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *ReflectionsPan, const ALfloat *LateReverbPan, ALfloat Gain, ALverbState *State) { ALfloat earlyPan[3] = { ReflectionsPan[0], ReflectionsPan[1], ReflectionsPan[2] }; ALfloat latePan[3] = { LateReverbPan[0], LateReverbPan[1], LateReverbPan[2] }; const ALfloat *speakerGain; ALfloat ambientGain; ALfloat dirGain; ALfloat length; ALuint index; ALint pos; Gain *= ReverbBoost; // Attenuate non-directional reverb according to the number of channels ambientGain = aluSqrt(2.0f/Device->NumChan); // Calculate the 3D-panning gains for the early reflections and late // reverb. length = earlyPan[0]*earlyPan[0] + earlyPan[1]*earlyPan[1] + earlyPan[2]*earlyPan[2]; if(length > 1.0f) { length = 1.0f / aluSqrt(length); earlyPan[0] *= length; earlyPan[1] *= length; earlyPan[2] *= length; } length = latePan[0]*latePan[0] + latePan[1]*latePan[1] + latePan[2]*latePan[2]; if(length > 1.0f) { length = 1.0f / aluSqrt(length); latePan[0] *= length; latePan[1] *= length; latePan[2] *= length; } /* This code applies directional reverb just like the mixer applies * directional sources. It diffuses the sound toward all speakers as the * magnitude of the panning vector drops, which is only a rough * approximation of the expansion of sound across the speakers from the * panning direction. */ pos = aluCart2LUTpos(earlyPan[2], earlyPan[0]); speakerGain = Device->PanningLUT[pos]; dirGain = aluSqrt((earlyPan[0] * earlyPan[0]) + (earlyPan[2] * earlyPan[2])); for(index = 0;index < MAXCHANNELS;index++) State->Early.PanGain[index] = 0.0f; for(index = 0;index < Device->NumChan;index++) { enum Channel chan = Device->Speaker2Chan[index]; State->Early.PanGain[chan] = lerp(ambientGain, speakerGain[chan], dirGain) * Gain; } pos = aluCart2LUTpos(latePan[2], latePan[0]); speakerGain = Device->PanningLUT[pos]; dirGain = aluSqrt((latePan[0] * latePan[0]) + (latePan[2] * latePan[2])); for(index = 0;index < MAXCHANNELS;index++) State->Late.PanGain[index] = 0.0f; for(index = 0;index < Device->NumChan;index++) { enum Channel chan = Device->Speaker2Chan[index]; State->Late.PanGain[chan] = lerp(ambientGain, speakerGain[chan], dirGain) * Gain; } }
// Update the early and late 3D panning gains. static ALvoid Update3DPanning( const ALfloat* ReflectionsPan, const ALfloat* LateReverbPan, ALfloat* PanningLUT, ALverbState* State ) { ALfloat length; ALfloat earlyPan[3] = { ReflectionsPan[0], ReflectionsPan[1], ReflectionsPan[2] }; ALfloat latePan[3] = { LateReverbPan[0], LateReverbPan[1], LateReverbPan[2] }; ALint pos; ALfloat* speakerGain, dirGain, ambientGain; ALuint index; // Calculate the 3D-panning gains for the early reflections and late // reverb. length = earlyPan[0] * earlyPan[0] + earlyPan[1] * earlyPan[1] + earlyPan[2] * earlyPan[2]; if ( length > 1.0f ) { length = 1.0f / aluSqrt( length ); earlyPan[0] *= length; earlyPan[1] *= length; earlyPan[2] *= length; } length = latePan[0] * latePan[0] + latePan[1] * latePan[1] + latePan[2] * latePan[2]; if ( length > 1.0f ) { length = 1.0f / aluSqrt( length ); latePan[0] *= length; latePan[1] *= length; latePan[2] *= length; } /* This code applies directional reverb just like the mixer applies * directional sources. It diffuses the sound toward all speakers as the * magnitude of the panning vector drops, which is only a rough * approximation of the expansion of sound across the speakers from the * panning direction. */ pos = aluCart2LUTpos( earlyPan[2], earlyPan[0] ); speakerGain = &PanningLUT[OUTPUTCHANNELS * pos]; dirGain = aluSqrt( ( earlyPan[0] * earlyPan[0] ) + ( earlyPan[2] * earlyPan[2] ) ); ambientGain = ( 1.0 - dirGain ); for ( index = 0; index < OUTPUTCHANNELS; index++ ) { State->Early.PanGain[index] = dirGain * speakerGain[index] + ambientGain; } pos = aluCart2LUTpos( latePan[2], latePan[0] ); speakerGain = &PanningLUT[OUTPUTCHANNELS * pos]; dirGain = aluSqrt( ( latePan[0] * latePan[0] ) + ( latePan[2] * latePan[2] ) ); ambientGain = ( 1.0 - dirGain ); for ( index = 0; index < OUTPUTCHANNELS; index++ ) { State->Late.PanGain[index] = dirGain * speakerGain[index] + ambientGain; } }