// This updates the EAX reverb state.  This is called any time the EAX reverb
// effect is loaded into a slot.
static ALvoid EAXVerbUpdate( ALeffectState* effect, ALCcontext* Context, const ALeffect* Effect )
{
	ALverbState* State = ( ALverbState* )effect;
	ALuint frequency = Context->Device->Frequency;
	ALfloat cw, x, y, hfRatio;

	// Calculate the master low-pass filter (from the master effect HF gain).
	cw = CalcI3DL2HFreq( Effect->Reverb.HFReference, frequency );
	// This is done with 2 chained 1-pole filters, so no need to square g.
	State->LpFilter.coeff = lpCoeffCalc( Effect->Reverb.GainHF, cw );

	// Update the modulator line.
	UpdateModulator( Effect->Reverb.ModulationTime,
	                 Effect->Reverb.ModulationDepth, frequency, State );

	// Update the initial effect delay.
	UpdateDelayLine( Effect->Reverb.ReflectionsDelay,
	                 Effect->Reverb.LateReverbDelay, frequency, State );

	// Update the early lines.
	UpdateEarlyLines( Effect->Reverb.Gain, Effect->Reverb.ReflectionsGain,
	                  Effect->Reverb.LateReverbDelay, State );

	// Update the decorrelator.
	UpdateDecorrelator( Effect->Reverb.Density, frequency, State );

	// Get the mixing matrix coefficients (x and y).
	CalcMatrixCoeffs( Effect->Reverb.Diffusion, &x, &y );
	// Then divide x into y to simplify the matrix calculation.
	State->Late.MixCoeff = y / x;

	// If the HF limit parameter is flagged, calculate an appropriate limit
	// based on the air absorption parameter.
	hfRatio = Effect->Reverb.DecayHFRatio;

	if ( Effect->Reverb.DecayHFLimit && Effect->Reverb.AirAbsorptionGainHF < 1.0f )
		hfRatio = CalcLimitedHfRatio( hfRatio, Effect->Reverb.AirAbsorptionGainHF,
		                              Effect->Reverb.DecayTime );

	// Update the late lines.
	UpdateLateLines( Effect->Reverb.Gain, Effect->Reverb.LateReverbGain,
	                 x, Effect->Reverb.Density, Effect->Reverb.DecayTime,
	                 Effect->Reverb.Diffusion, hfRatio, cw, frequency, State );

	// Update the echo line.
	UpdateEchoLine( Effect->Reverb.Gain, Effect->Reverb.LateReverbGain,
	                Effect->Reverb.EchoTime, Effect->Reverb.DecayTime,
	                Effect->Reverb.Diffusion, Effect->Reverb.EchoDepth,
	                hfRatio, cw, frequency, State );

	// Update early and late 3D panning.
	Update3DPanning( Effect->Reverb.ReflectionsPan, Effect->Reverb.LateReverbPan,
	                 Context->Device->PanningLUT, State );
}
예제 #2
0
// This updates the EAX reverb state.  This is called any time the EAX reverb
// effect is loaded into a slot.
static ALvoid ReverbUpdate(ALeffectState *effect, ALCcontext *Context, const ALeffectslot *Slot)
{
    ALverbState *State = (ALverbState*)effect;
    ALuint frequency = Context->Device->Frequency;
    ALboolean isEAX = AL_FALSE;
    ALfloat cw, x, y, hfRatio;

    if(Slot->effect.type == AL_EFFECT_EAXREVERB && !EmulateEAXReverb)
    {
        State->state.Process = EAXVerbProcess;
        isEAX = AL_TRUE;
    }
    else if(Slot->effect.type == AL_EFFECT_REVERB || EmulateEAXReverb)
    {
        State->state.Process = VerbProcess;
        isEAX = AL_FALSE;
    }

    // Calculate the master low-pass filter (from the master effect HF gain).
    cw = CalcI3DL2HFreq(Slot->effect.Params.Reverb.HFReference, frequency);
    // This is done with 2 chained 1-pole filters, so no need to square g.
    State->LpFilter.coeff = lpCoeffCalc(Slot->effect.Params.Reverb.GainHF, cw);

    if(isEAX)
    {
        // Update the modulator line.
        UpdateModulator(Slot->effect.Params.Reverb.ModulationTime,
                        Slot->effect.Params.Reverb.ModulationDepth,
                        frequency, State);
    }

    // Update the initial effect delay.
    UpdateDelayLine(Slot->effect.Params.Reverb.ReflectionsDelay,
                    Slot->effect.Params.Reverb.LateReverbDelay,
                    frequency, State);

    // Update the early lines.
    UpdateEarlyLines(Slot->effect.Params.Reverb.Gain,
                     Slot->effect.Params.Reverb.ReflectionsGain,
                     Slot->effect.Params.Reverb.LateReverbDelay, State);

    // Update the decorrelator.
    UpdateDecorrelator(Slot->effect.Params.Reverb.Density, frequency, State);

    // Get the mixing matrix coefficients (x and y).
    CalcMatrixCoeffs(Slot->effect.Params.Reverb.Diffusion, &x, &y);
    // Then divide x into y to simplify the matrix calculation.
    State->Late.MixCoeff = y / x;

    // If the HF limit parameter is flagged, calculate an appropriate limit
    // based on the air absorption parameter.
    hfRatio = Slot->effect.Params.Reverb.DecayHFRatio;
    if(Slot->effect.Params.Reverb.DecayHFLimit &&
       Slot->effect.Params.Reverb.AirAbsorptionGainHF < 1.0f)
        hfRatio = CalcLimitedHfRatio(hfRatio,
                                     Slot->effect.Params.Reverb.AirAbsorptionGainHF,
                                     Slot->effect.Params.Reverb.DecayTime);

    // Update the late lines.
    UpdateLateLines(Slot->effect.Params.Reverb.Gain, Slot->effect.Params.Reverb.LateReverbGain,
                    x, Slot->effect.Params.Reverb.Density, Slot->effect.Params.Reverb.DecayTime,
                    Slot->effect.Params.Reverb.Diffusion, hfRatio, cw, frequency, State);

    if(isEAX)
    {
        // Update the echo line.
        UpdateEchoLine(Slot->effect.Params.Reverb.Gain, Slot->effect.Params.Reverb.LateReverbGain,
                       Slot->effect.Params.Reverb.EchoTime, Slot->effect.Params.Reverb.DecayTime,
                       Slot->effect.Params.Reverb.Diffusion, Slot->effect.Params.Reverb.EchoDepth,
                       hfRatio, cw, frequency, State);

        // Update early and late 3D panning.
        Update3DPanning(Context->Device, Slot->effect.Params.Reverb.ReflectionsPan,
                        Slot->effect.Params.Reverb.LateReverbPan, Slot->Gain, State);
    }
    else
    {
        ALCdevice *Device = Context->Device;
        ALfloat gain = Slot->Gain;
        ALuint index;

        /* Update channel gains */
        gain *= aluSqrt(2.0f/Device->NumChan) * ReverbBoost;
        for(index = 0;index < MAXCHANNELS;index++)
             State->Gain[index] = 0.0f;
        for(index = 0;index < Device->NumChan;index++)
        {
            enum Channel chan = Device->Speaker2Chan[index];
            State->Gain[chan] = gain;
        }
    }
}