static ALvoid EchoProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MAXCHANNELS]) { ALechoState *state = (ALechoState*)effect; const ALuint mask = state->BufferLength-1; const ALuint tap1 = state->Tap[0].delay; const ALuint tap2 = state->Tap[1].delay; ALuint offset = state->Offset; ALfloat samp[2], smp; ALuint i; for(i = 0;i < SamplesToDo;i++,offset++) { // Sample first tap smp = state->SampleBuffer[(offset-tap1) & mask]; samp[0] = smp * state->GainL; samp[1] = smp * state->GainR; // Sample second tap. Reverse LR panning smp = state->SampleBuffer[(offset-tap2) & mask]; samp[0] += smp * state->GainR; samp[1] += smp * state->GainL; // Apply damping and feedback gain to the second tap, and mix in the // new sample smp = lpFilter2P(&state->iirFilter, 0, smp+SamplesIn[i]); state->SampleBuffer[offset&mask] = smp * state->FeedGain; SamplesOut[i][FRONT_LEFT] += state->Gain[FRONT_LEFT] * samp[0]; SamplesOut[i][FRONT_RIGHT] += state->Gain[FRONT_RIGHT] * samp[1]; SamplesOut[i][SIDE_LEFT] += state->Gain[SIDE_LEFT] * samp[0]; SamplesOut[i][SIDE_RIGHT] += state->Gain[SIDE_RIGHT] * samp[1]; SamplesOut[i][BACK_LEFT] += state->Gain[BACK_LEFT] * samp[0]; SamplesOut[i][BACK_RIGHT] += state->Gain[BACK_RIGHT] * samp[1]; } state->Offset = offset; }
static ALvoid EchoProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MAXCHANNELS]) { ALechoState *state = (ALechoState*)effect; const ALuint mask = state->BufferLength-1; const ALuint tap1 = state->Tap[0].delay; const ALuint tap2 = state->Tap[1].delay; ALuint offset = state->Offset; ALfloat smp; ALuint i, k; for(i = 0;i < SamplesToDo;i++,offset++) { /* First tap */ smp = state->SampleBuffer[(offset-tap1) & mask]; for(k = 0;k < MAXCHANNELS;k++) SamplesOut[i][k] += smp * state->Gain[0][k]; /* Second tap */ smp = state->SampleBuffer[(offset-tap2) & mask]; for(k = 0;k < MAXCHANNELS;k++) SamplesOut[i][k] += smp * state->Gain[1][k]; // Apply damping and feedback gain to the second tap, and mix in the // new sample smp = lpFilter2P(&state->iirFilter, 0, smp+SamplesIn[i]); state->SampleBuffer[offset&mask] = smp * state->FeedGain; } state->Offset = offset; }
// Perform the non-EAX reverb pass on a given input sample, resulting in // four-channel output. static __inline ALvoid VerbPass(ALverbState *State, ALfloat in, ALfloat *early, ALfloat *late) { ALfloat feed, taps[4]; // Low-pass filter the incoming sample. in = lpFilter2P(&State->LpFilter, 0, in); // Feed the initial delay line. DelayLineIn(&State->Delay, State->Offset, in); // Calculate the early reflection from the first delay tap. in = DelayLineOut(&State->Delay, State->Offset - State->DelayTap[0]); EarlyReflection(State, in, early); // Feed the decorrelator from the energy-attenuated output of the second // delay tap. in = DelayLineOut(&State->Delay, State->Offset - State->DelayTap[1]); feed = in * State->Late.DensityGain; DelayLineIn(&State->Decorrelator, State->Offset, feed); // Calculate the late reverb from the decorrelator taps. taps[0] = feed; taps[1] = DelayLineOut(&State->Decorrelator, State->Offset - State->DecoTap[0]); taps[2] = DelayLineOut(&State->Decorrelator, State->Offset - State->DecoTap[1]); taps[3] = DelayLineOut(&State->Decorrelator, State->Offset - State->DecoTap[2]); LateReverb(State, taps, late); // Step all delays forward one sample. State->Offset++; }
static ALvoid EchoProcess(ALeffectState *effect, const ALeffectslot *Slot, ALuint SamplesToDo, const ALfp *SamplesIn, ALfp (*SamplesOut)[MAXCHANNELS]) { ALechoState *state = (ALechoState*)effect; const ALuint mask = state->BufferLength-1; const ALuint tap1 = state->Tap[0].delay; const ALuint tap2 = state->Tap[1].delay; ALuint offset = state->Offset; const ALfp gain = Slot->Gain; ALfp samp[2], smp; ALuint i; for(i = 0; i < SamplesToDo; i++,offset++) { // Sample first tap smp = state->SampleBuffer[(offset-tap1) & mask]; samp[0] = ALfpMult(smp, state->GainL); samp[1] = ALfpMult(smp, state->GainR); // Sample second tap. Reverse LR panning smp = state->SampleBuffer[(offset-tap2) & mask]; samp[0] += ALfpMult(smp, state->GainR); samp[1] += ALfpMult(smp, state->GainL); // Apply damping and feedback gain to the second tap, and mix in the // new sample smp = lpFilter2P(&state->iirFilter, 0, (smp+SamplesIn[i])); state->SampleBuffer[offset&mask] = ALfpMult(smp, state->FeedGain); // Apply slot gain samp[0] = ALfpMult(samp[0], gain); samp[1] = ALfpMult(samp[1], gain); SamplesOut[i][FRONT_LEFT] += ALfpMult(state->Gain[FRONT_LEFT], samp[0]); SamplesOut[i][FRONT_RIGHT] += ALfpMult(state->Gain[FRONT_RIGHT], samp[1]); #ifdef APPORTABLE_OPTIMIZED_OUT SamplesOut[i][SIDE_LEFT] += ALfpMult(state->Gain[SIDE_LEFT], samp[0]); SamplesOut[i][SIDE_RIGHT] += ALfpMult(state->Gain[SIDE_RIGHT], samp[1]); SamplesOut[i][BACK_LEFT] += ALfpMult(state->Gain[BACK_LEFT], samp[0]); SamplesOut[i][BACK_RIGHT] += ALfpMult(state->Gain[BACK_RIGHT], samp[1]); #endif } state->Offset = offset; }
static void VerbPass(IDirectSoundBufferImpl* dsb, float in, float* out) { float feed, late[4], taps[4]; /* Low-pass filter the incoming sample. */ in = lpFilter2P(&dsb->eax.LpFilter, 0, in); /* Feed the initial delay line. */ DelayLineIn(&dsb->eax.Delay, dsb->eax.Offset, in); /* Calculate the early reflection from the first delay tap. */ in = DelayLineOut(&dsb->eax.Delay, dsb->eax.Offset - dsb->eax.DelayTap[0]); EarlyReflection(dsb, in, out); /* Feed the decorrelator from the energy-attenuated output of the second * delay tap. */ in = DelayLineOut(&dsb->eax.Delay, dsb->eax.Offset - dsb->eax.DelayTap[1]); feed = in * dsb->eax.Late.DensityGain; DelayLineIn(&dsb->eax.Decorrelator, dsb->eax.Offset, feed); /* Calculate the late reverb from the decorrelator taps. */ taps[0] = feed; taps[1] = DelayLineOut(&dsb->eax.Decorrelator, dsb->eax.Offset - dsb->eax.DecoTap[0]); taps[2] = DelayLineOut(&dsb->eax.Decorrelator, dsb->eax.Offset - dsb->eax.DecoTap[1]); taps[3] = DelayLineOut(&dsb->eax.Decorrelator, dsb->eax.Offset - dsb->eax.DecoTap[2]); LateReverb(dsb, taps, late); /* Mix early reflections and late reverb. */ out[0] += late[0]; out[1] += late[1]; out[2] += late[2]; out[3] += late[3]; /* Step all delays forward one sample. */ dsb->eax.Offset++; }