185
217
// effect's density parameter (inverted for some reason) and this multiplier.
186
218
static const ALfloat LATE_LINE_MULTIPLIER = 4.0f;
221
// Basic delay line input/output routines.
222
static __inline ALfloat DelayLineOut(DelayLine *Delay, ALuint offset)
224
return Delay->Line[offset&Delay->Mask];
227
static __inline ALvoid DelayLineIn(DelayLine *Delay, ALuint offset, ALfloat in)
229
Delay->Line[offset&Delay->Mask] = in;
232
// Attenuated delay line output routine.
233
static __inline ALfloat AttenuatedDelayLineOut(DelayLine *Delay, ALuint offset, ALfloat coeff)
235
return coeff * Delay->Line[offset&Delay->Mask];
238
// Basic attenuated all-pass input/output routine.
239
static __inline ALfloat AllpassInOut(DelayLine *Delay, ALuint outOffset, ALuint inOffset, ALfloat in, ALfloat feedCoeff, ALfloat coeff)
243
out = DelayLineOut(Delay, outOffset);
244
feed = feedCoeff * in;
245
DelayLineIn(Delay, inOffset, (feedCoeff * (out - feed)) + in);
247
// The time-based attenuation is only applied to the delay output to
248
// keep it from affecting the feed-back path (which is already controlled
249
// by the all-pass feed coefficient).
250
return (coeff * out) - feed;
253
// Given an input sample, this function produces modulation for the late
255
static __inline ALfloat EAXModulation(ALverbState *State, ALfloat in)
261
// Calculate the sinus rythm (dependent on modulation time and the
262
// sampling rate). The center of the sinus is moved to reduce the delay
263
// of the effect when the time or depth are low.
264
sinus = 1.0f - aluCos(F_PI*2.0f * State->Mod.Index / State->Mod.Range);
266
// The depth determines the range over which to read the input samples
267
// from, so it must be filtered to reduce the distortion caused by even
268
// small parameter changes.
269
State->Mod.Filter = lerp(State->Mod.Filter, State->Mod.Depth,
272
// Calculate the read offset and fraction between it and the next sample.
273
frac = (1.0f + (State->Mod.Filter * sinus));
274
offset = fastf2u(frac);
277
// Get the two samples crossed by the offset, and feed the delay line
278
// with the next input sample.
279
out0 = DelayLineOut(&State->Mod.Delay, State->Offset - offset);
280
out1 = DelayLineOut(&State->Mod.Delay, State->Offset - offset - 1);
281
DelayLineIn(&State->Mod.Delay, State->Offset, in);
283
// Step the modulation index forward, keeping it bound to its range.
284
State->Mod.Index = (State->Mod.Index + 1) % State->Mod.Range;
286
// The output is obtained by linearly interpolating the two samples that
287
// were acquired above.
288
return lerp(out0, out1, frac);
291
// Delay line output routine for early reflections.
292
static __inline ALfloat EarlyDelayLineOut(ALverbState *State, ALuint index)
294
return AttenuatedDelayLineOut(&State->Early.Delay[index],
295
State->Offset - State->Early.Offset[index],
296
State->Early.Coeff[index]);
299
// Given an input sample, this function produces four-channel output for the
300
// early reflections.
301
static __inline ALvoid EarlyReflection(ALverbState *State, ALfloat in, ALfloat *out)
303
ALfloat d[4], v, f[4];
305
// Obtain the decayed results of each early delay line.
306
d[0] = EarlyDelayLineOut(State, 0);
307
d[1] = EarlyDelayLineOut(State, 1);
308
d[2] = EarlyDelayLineOut(State, 2);
309
d[3] = EarlyDelayLineOut(State, 3);
311
/* The following uses a lossless scattering junction from waveguide
312
* theory. It actually amounts to a householder mixing matrix, which
313
* will produce a maximally diffuse response, and means this can probably
314
* be considered a simple feed-back delay network (FDN).
322
v = (d[0] + d[1] + d[2] + d[3]) * 0.5f;
323
// The junction is loaded with the input here.
326
// Calculate the feed values for the delay lines.
332
// Re-feed the delay lines.
333
DelayLineIn(&State->Early.Delay[0], State->Offset, f[0]);
334
DelayLineIn(&State->Early.Delay[1], State->Offset, f[1]);
335
DelayLineIn(&State->Early.Delay[2], State->Offset, f[2]);
336
DelayLineIn(&State->Early.Delay[3], State->Offset, f[3]);
338
// Output the results of the junction for all four channels.
339
out[0] = State->Early.Gain * f[0];
340
out[1] = State->Early.Gain * f[1];
341
out[2] = State->Early.Gain * f[2];
342
out[3] = State->Early.Gain * f[3];
345
// All-pass input/output routine for late reverb.
346
static __inline ALfloat LateAllPassInOut(ALverbState *State, ALuint index, ALfloat in)
348
return AllpassInOut(&State->Late.ApDelay[index],
349
State->Offset - State->Late.ApOffset[index],
350
State->Offset, in, State->Late.ApFeedCoeff,
351
State->Late.ApCoeff[index]);
354
// Delay line output routine for late reverb.
355
static __inline ALfloat LateDelayLineOut(ALverbState *State, ALuint index)
357
return AttenuatedDelayLineOut(&State->Late.Delay[index],
358
State->Offset - State->Late.Offset[index],
359
State->Late.Coeff[index]);
362
// Low-pass filter input/output routine for late reverb.
363
static __inline ALfloat LateLowPassInOut(ALverbState *State, ALuint index, ALfloat in)
365
in = lerp(in, State->Late.LpSample[index], State->Late.LpCoeff[index]);
366
State->Late.LpSample[index] = in;
370
// Given four decorrelated input samples, this function produces four-channel
371
// output for the late reverb.
372
static __inline ALvoid LateReverb(ALverbState *State, ALfloat *in, ALfloat *out)
376
// Obtain the decayed results of the cyclical delay lines, and add the
377
// corresponding input channels. Then pass the results through the
380
// This is where the feed-back cycles from line 0 to 1 to 3 to 2 and back
382
d[0] = LateLowPassInOut(State, 2, in[2] + LateDelayLineOut(State, 2));
383
d[1] = LateLowPassInOut(State, 0, in[0] + LateDelayLineOut(State, 0));
384
d[2] = LateLowPassInOut(State, 3, in[3] + LateDelayLineOut(State, 3));
385
d[3] = LateLowPassInOut(State, 1, in[1] + LateDelayLineOut(State, 1));
387
// To help increase diffusion, run each line through an all-pass filter.
388
// When there is no diffusion, the shortest all-pass filter will feed the
389
// shortest delay line.
390
d[0] = LateAllPassInOut(State, 0, d[0]);
391
d[1] = LateAllPassInOut(State, 1, d[1]);
392
d[2] = LateAllPassInOut(State, 2, d[2]);
393
d[3] = LateAllPassInOut(State, 3, d[3]);
395
/* Late reverb is done with a modified feed-back delay network (FDN)
396
* topology. Four input lines are each fed through their own all-pass
397
* filter and then into the mixing matrix. The four outputs of the
398
* mixing matrix are then cycled back to the inputs. Each output feeds
399
* a different input to form a circlular feed cycle.
401
* The mixing matrix used is a 4D skew-symmetric rotation matrix derived
402
* using a single unitary rotational parameter:
404
* [ d, a, b, c ] 1 = a^2 + b^2 + c^2 + d^2
409
* The rotation is constructed from the effect's diffusion parameter,
410
* yielding: 1 = x^2 + 3 y^2; where a, b, and c are the coefficient y
411
* with differing signs, and d is the coefficient x. The matrix is thus:
413
* [ x, y, -y, y ] n = sqrt(matrix_order - 1)
414
* [ -y, x, y, y ] t = diffusion_parameter * atan(n)
415
* [ y, -y, x, y ] x = cos(t)
416
* [ -y, -y, -y, x ] y = sin(t) / n
418
* To reduce the number of multiplies, the x coefficient is applied with
419
* the cyclical delay line coefficients. Thus only the y coefficient is
420
* applied when mixing, and is modified to be: y / x.
422
f[0] = d[0] + (State->Late.MixCoeff * ( d[1] + -d[2] + d[3]));
423
f[1] = d[1] + (State->Late.MixCoeff * (-d[0] + d[2] + d[3]));
424
f[2] = d[2] + (State->Late.MixCoeff * ( d[0] + -d[1] + d[3]));
425
f[3] = d[3] + (State->Late.MixCoeff * (-d[0] + -d[1] + -d[2] ));
427
// Output the results of the matrix for all four channels, attenuated by
428
// the late reverb gain (which is attenuated by the 'x' mix coefficient).
429
out[0] = State->Late.Gain * f[0];
430
out[1] = State->Late.Gain * f[1];
431
out[2] = State->Late.Gain * f[2];
432
out[3] = State->Late.Gain * f[3];
434
// Re-feed the cyclical delay lines.
435
DelayLineIn(&State->Late.Delay[0], State->Offset, f[0]);
436
DelayLineIn(&State->Late.Delay[1], State->Offset, f[1]);
437
DelayLineIn(&State->Late.Delay[2], State->Offset, f[2]);
438
DelayLineIn(&State->Late.Delay[3], State->Offset, f[3]);
441
// Given an input sample, this function mixes echo into the four-channel late
443
static __inline ALvoid EAXEcho(ALverbState *State, ALfloat in, ALfloat *late)
447
// Get the latest attenuated echo sample for output.
448
feed = AttenuatedDelayLineOut(&State->Echo.Delay,
449
State->Offset - State->Echo.Offset,
452
// Mix the output into the late reverb channels.
453
out = State->Echo.MixCoeff[0] * feed;
454
late[0] = (State->Echo.MixCoeff[1] * late[0]) + out;
455
late[1] = (State->Echo.MixCoeff[1] * late[1]) + out;
456
late[2] = (State->Echo.MixCoeff[1] * late[2]) + out;
457
late[3] = (State->Echo.MixCoeff[1] * late[3]) + out;
459
// Mix the energy-attenuated input with the output and pass it through
460
// the echo low-pass filter.
461
feed += State->Echo.DensityGain * in;
462
feed = lerp(feed, State->Echo.LpSample, State->Echo.LpCoeff);
463
State->Echo.LpSample = feed;
465
// Then the echo all-pass filter.
466
feed = AllpassInOut(&State->Echo.ApDelay,
467
State->Offset - State->Echo.ApOffset,
468
State->Offset, feed, State->Echo.ApFeedCoeff,
469
State->Echo.ApCoeff);
471
// Feed the delay with the mixed and filtered sample.
472
DelayLineIn(&State->Echo.Delay, State->Offset, feed);
475
// Perform the non-EAX reverb pass on a given input sample, resulting in
476
// four-channel output.
477
static __inline ALvoid VerbPass(ALverbState *State, ALfloat in, ALfloat *early, ALfloat *late)
479
ALfloat feed, taps[4];
481
// Low-pass filter the incoming sample.
482
in = lpFilter2P(&State->LpFilter, 0, in);
484
// Feed the initial delay line.
485
DelayLineIn(&State->Delay, State->Offset, in);
487
// Calculate the early reflection from the first delay tap.
488
in = DelayLineOut(&State->Delay, State->Offset - State->DelayTap[0]);
489
EarlyReflection(State, in, early);
491
// Feed the decorrelator from the energy-attenuated output of the second
493
in = DelayLineOut(&State->Delay, State->Offset - State->DelayTap[1]);
494
feed = in * State->Late.DensityGain;
495
DelayLineIn(&State->Decorrelator, State->Offset, feed);
497
// Calculate the late reverb from the decorrelator taps.
499
taps[1] = DelayLineOut(&State->Decorrelator, State->Offset - State->DecoTap[0]);
500
taps[2] = DelayLineOut(&State->Decorrelator, State->Offset - State->DecoTap[1]);
501
taps[3] = DelayLineOut(&State->Decorrelator, State->Offset - State->DecoTap[2]);
502
LateReverb(State, taps, late);
504
// Step all delays forward one sample.
508
// Perform the EAX reverb pass on a given input sample, resulting in four-
510
static __inline ALvoid EAXVerbPass(ALverbState *State, ALfloat in, ALfloat *early, ALfloat *late)
512
ALfloat feed, taps[4];
514
// Low-pass filter the incoming sample.
515
in = lpFilter2P(&State->LpFilter, 0, in);
517
// Perform any modulation on the input.
518
in = EAXModulation(State, in);
520
// Feed the initial delay line.
521
DelayLineIn(&State->Delay, State->Offset, in);
523
// Calculate the early reflection from the first delay tap.
524
in = DelayLineOut(&State->Delay, State->Offset - State->DelayTap[0]);
525
EarlyReflection(State, in, early);
527
// Feed the decorrelator from the energy-attenuated output of the second
529
in = DelayLineOut(&State->Delay, State->Offset - State->DelayTap[1]);
530
feed = in * State->Late.DensityGain;
531
DelayLineIn(&State->Decorrelator, State->Offset, feed);
533
// Calculate the late reverb from the decorrelator taps.
535
taps[1] = DelayLineOut(&State->Decorrelator, State->Offset - State->DecoTap[0]);
536
taps[2] = DelayLineOut(&State->Decorrelator, State->Offset - State->DecoTap[1]);
537
taps[3] = DelayLineOut(&State->Decorrelator, State->Offset - State->DecoTap[2]);
538
LateReverb(State, taps, late);
540
// Calculate and mix in any echo.
541
EAXEcho(State, in, late);
543
// Step all delays forward one sample.
547
// This processes the reverb state, given the input samples and an output
549
static ALvoid VerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MAXCHANNELS])
551
ALverbState *State = (ALverbState*)effect;
553
ALfloat early[4], late[4], out[4];
554
const ALfloat *panGain = State->Gain;
556
for(index = 0;index < SamplesToDo;index++)
558
// Process reverb for this sample.
559
VerbPass(State, SamplesIn[index], early, late);
561
// Mix early reflections and late reverb.
562
out[0] = (early[0] + late[0]);
563
out[1] = (early[1] + late[1]);
564
out[2] = (early[2] + late[2]);
565
out[3] = (early[3] + late[3]);
567
// Output the results.
568
for(c = 0;c < MAXCHANNELS;c++)
569
SamplesOut[index][c] += panGain[c] * out[c&3];
573
// This processes the EAX reverb state, given the input samples and an output
575
static ALvoid EAXVerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MAXCHANNELS])
577
ALverbState *State = (ALverbState*)effect;
579
ALfloat early[4], late[4];
581
for(index = 0;index < SamplesToDo;index++)
583
// Process reverb for this sample.
584
EAXVerbPass(State, SamplesIn[index], early, late);
586
for(c = 0;c < MAXCHANNELS;c++)
587
SamplesOut[index][c] += State->Early.PanGain[c]*early[c&3] +
588
State->Late.PanGain[c]*late[c&3];
593
// Given the allocated sample buffer, this function updates each delay line
595
static __inline ALvoid RealizeLineOffset(ALfloat * sampleBuffer, DelayLine *Delay)
597
Delay->Line = &sampleBuffer[(ALintptrEXT)Delay->Line];
188
600
// Calculate the length of a delay line and store its mask and offset.
189
601
static ALuint CalcLineLength(ALfloat length, ALintptrEXT offset, ALuint frequency, DelayLine *Delay)
627
1054
* panning direction.
629
1056
pos = aluCart2LUTpos(earlyPan[2], earlyPan[0]);
630
speakerGain = &Device->PanningLUT[MAXCHANNELS * pos];
1057
ChannelGain = Device->PanningLUT[pos];
631
1058
dirGain = aluSqrt((earlyPan[0] * earlyPan[0]) + (earlyPan[2] * earlyPan[2]));
633
1060
for(index = 0;index < MAXCHANNELS;index++)
634
1061
State->Early.PanGain[index] = 0.0f;
635
1062
for(index = 0;index < Device->NumChan;index++)
637
Channel chan = Device->Speaker2Chan[index];
638
State->Early.PanGain[chan] = 1.0 + (speakerGain[chan]-1.0)*dirGain;
1064
enum Channel chan = Device->Speaker2Chan[index];
1065
State->Early.PanGain[chan] = lerp(ambientGain, ChannelGain[chan], dirGain) * Gain;
642
1069
pos = aluCart2LUTpos(latePan[2], latePan[0]);
643
speakerGain = &Device->PanningLUT[MAXCHANNELS * pos];
1070
ChannelGain = Device->PanningLUT[pos];
644
1071
dirGain = aluSqrt((latePan[0] * latePan[0]) + (latePan[2] * latePan[2]));
646
1073
for(index = 0;index < MAXCHANNELS;index++)
647
1074
State->Late.PanGain[index] = 0.0f;
648
1075
for(index = 0;index < Device->NumChan;index++)
650
Channel chan = Device->Speaker2Chan[index];
651
State->Late.PanGain[chan] = 1.0 + (speakerGain[chan]-1.0)*dirGain;
655
// Basic delay line input/output routines.
656
static __inline ALfloat DelayLineOut(DelayLine *Delay, ALuint offset)
658
return Delay->Line[offset&Delay->Mask];
661
static __inline ALvoid DelayLineIn(DelayLine *Delay, ALuint offset, ALfloat in)
663
Delay->Line[offset&Delay->Mask] = in;
666
// Attenuated delay line output routine.
667
static __inline ALfloat AttenuatedDelayLineOut(DelayLine *Delay, ALuint offset, ALfloat coeff)
669
return coeff * Delay->Line[offset&Delay->Mask];
672
// Basic attenuated all-pass input/output routine.
673
static __inline ALfloat AllpassInOut(DelayLine *Delay, ALuint outOffset, ALuint inOffset, ALfloat in, ALfloat feedCoeff, ALfloat coeff)
677
out = DelayLineOut(Delay, outOffset);
678
feed = feedCoeff * in;
679
DelayLineIn(Delay, inOffset, (feedCoeff * (out - feed)) + in);
681
// The time-based attenuation is only applied to the delay output to
682
// keep it from affecting the feed-back path (which is already controlled
683
// by the all-pass feed coefficient).
684
return (coeff * out) - feed;
687
// Given an input sample, this function produces modulation for the late
689
static __inline ALfloat EAXModulation(ALverbState *State, ALfloat in)
695
// Calculate the sinus rythm (dependent on modulation time and the
696
// sampling rate). The center of the sinus is moved to reduce the delay
697
// of the effect when the time or depth are low.
698
sinus = 1.0f - cos(2.0f * M_PI * State->Mod.Index / State->Mod.Range);
700
// The depth determines the range over which to read the input samples
701
// from, so it must be filtered to reduce the distortion caused by even
702
// small parameter changes.
703
State->Mod.Filter = lerp(State->Mod.Filter, State->Mod.Depth,
706
// Calculate the read offset and fraction between it and the next sample.
707
frac = (1.0f + (State->Mod.Filter * sinus));
708
offset = (ALuint)frac;
711
// Get the two samples crossed by the offset, and feed the delay line
712
// with the next input sample.
713
out0 = DelayLineOut(&State->Mod.Delay, State->Offset - offset);
714
out1 = DelayLineOut(&State->Mod.Delay, State->Offset - offset - 1);
715
DelayLineIn(&State->Mod.Delay, State->Offset, in);
717
// Step the modulation index forward, keeping it bound to its range.
718
State->Mod.Index = (State->Mod.Index + 1) % State->Mod.Range;
720
// The output is obtained by linearly interpolating the two samples that
721
// were acquired above.
722
return lerp(out0, out1, frac);
725
// Delay line output routine for early reflections.
726
static __inline ALfloat EarlyDelayLineOut(ALverbState *State, ALuint index)
728
return AttenuatedDelayLineOut(&State->Early.Delay[index],
729
State->Offset - State->Early.Offset[index],
730
State->Early.Coeff[index]);
733
// Given an input sample, this function produces four-channel output for the
734
// early reflections.
735
static __inline ALvoid EarlyReflection(ALverbState *State, ALfloat in, ALfloat *out)
737
ALfloat d[4], v, f[4];
739
// Obtain the decayed results of each early delay line.
740
d[0] = EarlyDelayLineOut(State, 0);
741
d[1] = EarlyDelayLineOut(State, 1);
742
d[2] = EarlyDelayLineOut(State, 2);
743
d[3] = EarlyDelayLineOut(State, 3);
745
/* The following uses a lossless scattering junction from waveguide
746
* theory. It actually amounts to a householder mixing matrix, which
747
* will produce a maximally diffuse response, and means this can probably
748
* be considered a simple feed-back delay network (FDN).
756
v = (d[0] + d[1] + d[2] + d[3]) * 0.5f;
757
// The junction is loaded with the input here.
760
// Calculate the feed values for the delay lines.
766
// Re-feed the delay lines.
767
DelayLineIn(&State->Early.Delay[0], State->Offset, f[0]);
768
DelayLineIn(&State->Early.Delay[1], State->Offset, f[1]);
769
DelayLineIn(&State->Early.Delay[2], State->Offset, f[2]);
770
DelayLineIn(&State->Early.Delay[3], State->Offset, f[3]);
772
// Output the results of the junction for all four channels.
773
out[0] = State->Early.Gain * f[0];
774
out[1] = State->Early.Gain * f[1];
775
out[2] = State->Early.Gain * f[2];
776
out[3] = State->Early.Gain * f[3];
779
// All-pass input/output routine for late reverb.
780
static __inline ALfloat LateAllPassInOut(ALverbState *State, ALuint index, ALfloat in)
782
return AllpassInOut(&State->Late.ApDelay[index],
783
State->Offset - State->Late.ApOffset[index],
784
State->Offset, in, State->Late.ApFeedCoeff,
785
State->Late.ApCoeff[index]);
788
// Delay line output routine for late reverb.
789
static __inline ALfloat LateDelayLineOut(ALverbState *State, ALuint index)
791
return AttenuatedDelayLineOut(&State->Late.Delay[index],
792
State->Offset - State->Late.Offset[index],
793
State->Late.Coeff[index]);
796
// Low-pass filter input/output routine for late reverb.
797
static __inline ALfloat LateLowPassInOut(ALverbState *State, ALuint index, ALfloat in)
799
in = lerp(in, State->Late.LpSample[index], State->Late.LpCoeff[index]);
800
State->Late.LpSample[index] = in;
804
// Given four decorrelated input samples, this function produces four-channel
805
// output for the late reverb.
806
static __inline ALvoid LateReverb(ALverbState *State, ALfloat *in, ALfloat *out)
810
// Obtain the decayed results of the cyclical delay lines, and add the
811
// corresponding input channels. Then pass the results through the
814
// This is where the feed-back cycles from line 0 to 1 to 3 to 2 and back
816
d[0] = LateLowPassInOut(State, 2, in[2] + LateDelayLineOut(State, 2));
817
d[1] = LateLowPassInOut(State, 0, in[0] + LateDelayLineOut(State, 0));
818
d[2] = LateLowPassInOut(State, 3, in[3] + LateDelayLineOut(State, 3));
819
d[3] = LateLowPassInOut(State, 1, in[1] + LateDelayLineOut(State, 1));
821
// To help increase diffusion, run each line through an all-pass filter.
822
// When there is no diffusion, the shortest all-pass filter will feed the
823
// shortest delay line.
824
d[0] = LateAllPassInOut(State, 0, d[0]);
825
d[1] = LateAllPassInOut(State, 1, d[1]);
826
d[2] = LateAllPassInOut(State, 2, d[2]);
827
d[3] = LateAllPassInOut(State, 3, d[3]);
829
/* Late reverb is done with a modified feed-back delay network (FDN)
830
* topology. Four input lines are each fed through their own all-pass
831
* filter and then into the mixing matrix. The four outputs of the
832
* mixing matrix are then cycled back to the inputs. Each output feeds
833
* a different input to form a circlular feed cycle.
835
* The mixing matrix used is a 4D skew-symmetric rotation matrix derived
836
* using a single unitary rotational parameter:
838
* [ d, a, b, c ] 1 = a^2 + b^2 + c^2 + d^2
843
* The rotation is constructed from the effect's diffusion parameter,
844
* yielding: 1 = x^2 + 3 y^2; where a, b, and c are the coefficient y
845
* with differing signs, and d is the coefficient x. The matrix is thus:
847
* [ x, y, -y, y ] n = sqrt(matrix_order - 1)
848
* [ -y, x, y, y ] t = diffusion_parameter * atan(n)
849
* [ y, -y, x, y ] x = cos(t)
850
* [ -y, -y, -y, x ] y = sin(t) / n
852
* To reduce the number of multiplies, the x coefficient is applied with
853
* the cyclical delay line coefficients. Thus only the y coefficient is
854
* applied when mixing, and is modified to be: y / x.
856
f[0] = d[0] + (State->Late.MixCoeff * ( d[1] + -d[2] + d[3]));
857
f[1] = d[1] + (State->Late.MixCoeff * (-d[0] + d[2] + d[3]));
858
f[2] = d[2] + (State->Late.MixCoeff * ( d[0] + -d[1] + d[3]));
859
f[3] = d[3] + (State->Late.MixCoeff * (-d[0] + -d[1] + -d[2] ));
861
// Output the results of the matrix for all four channels, attenuated by
862
// the late reverb gain (which is attenuated by the 'x' mix coefficient).
863
out[0] = State->Late.Gain * f[0];
864
out[1] = State->Late.Gain * f[1];
865
out[2] = State->Late.Gain * f[2];
866
out[3] = State->Late.Gain * f[3];
868
// Re-feed the cyclical delay lines.
869
DelayLineIn(&State->Late.Delay[0], State->Offset, f[0]);
870
DelayLineIn(&State->Late.Delay[1], State->Offset, f[1]);
871
DelayLineIn(&State->Late.Delay[2], State->Offset, f[2]);
872
DelayLineIn(&State->Late.Delay[3], State->Offset, f[3]);
875
// Given an input sample, this function mixes echo into the four-channel late
877
static __inline ALvoid EAXEcho(ALverbState *State, ALfloat in, ALfloat *late)
881
// Get the latest attenuated echo sample for output.
882
feed = AttenuatedDelayLineOut(&State->Echo.Delay,
883
State->Offset - State->Echo.Offset,
886
// Mix the output into the late reverb channels.
887
out = State->Echo.MixCoeff[0] * feed;
888
late[0] = (State->Echo.MixCoeff[1] * late[0]) + out;
889
late[1] = (State->Echo.MixCoeff[1] * late[1]) + out;
890
late[2] = (State->Echo.MixCoeff[1] * late[2]) + out;
891
late[3] = (State->Echo.MixCoeff[1] * late[3]) + out;
893
// Mix the energy-attenuated input with the output and pass it through
894
// the echo low-pass filter.
895
feed += State->Echo.DensityGain * in;
896
feed = lerp(feed, State->Echo.LpSample, State->Echo.LpCoeff);
897
State->Echo.LpSample = feed;
899
// Then the echo all-pass filter.
900
feed = AllpassInOut(&State->Echo.ApDelay,
901
State->Offset - State->Echo.ApOffset,
902
State->Offset, feed, State->Echo.ApFeedCoeff,
903
State->Echo.ApCoeff);
905
// Feed the delay with the mixed and filtered sample.
906
DelayLineIn(&State->Echo.Delay, State->Offset, feed);
909
// Perform the non-EAX reverb pass on a given input sample, resulting in
910
// four-channel output.
911
static __inline ALvoid VerbPass(ALverbState *State, ALfloat in, ALfloat *early, ALfloat *late)
913
ALfloat feed, taps[4];
915
// Low-pass filter the incoming sample.
916
in = lpFilter2P(&State->LpFilter, 0, in);
918
// Feed the initial delay line.
919
DelayLineIn(&State->Delay, State->Offset, in);
921
// Calculate the early reflection from the first delay tap.
922
in = DelayLineOut(&State->Delay, State->Offset - State->DelayTap[0]);
923
EarlyReflection(State, in, early);
925
// Feed the decorrelator from the energy-attenuated output of the second
927
in = DelayLineOut(&State->Delay, State->Offset - State->DelayTap[1]);
928
feed = in * State->Late.DensityGain;
929
DelayLineIn(&State->Decorrelator, State->Offset, feed);
931
// Calculate the late reverb from the decorrelator taps.
933
taps[1] = DelayLineOut(&State->Decorrelator, State->Offset - State->DecoTap[0]);
934
taps[2] = DelayLineOut(&State->Decorrelator, State->Offset - State->DecoTap[1]);
935
taps[3] = DelayLineOut(&State->Decorrelator, State->Offset - State->DecoTap[2]);
936
LateReverb(State, taps, late);
938
// Step all delays forward one sample.
942
// Perform the EAX reverb pass on a given input sample, resulting in four-
944
static __inline ALvoid EAXVerbPass(ALverbState *State, ALfloat in, ALfloat *early, ALfloat *late)
946
ALfloat feed, taps[4];
948
// Low-pass filter the incoming sample.
949
in = lpFilter2P(&State->LpFilter, 0, in);
951
// Perform any modulation on the input.
952
in = EAXModulation(State, in);
954
// Feed the initial delay line.
955
DelayLineIn(&State->Delay, State->Offset, in);
957
// Calculate the early reflection from the first delay tap.
958
in = DelayLineOut(&State->Delay, State->Offset - State->DelayTap[0]);
959
EarlyReflection(State, in, early);
961
// Feed the decorrelator from the energy-attenuated output of the second
963
in = DelayLineOut(&State->Delay, State->Offset - State->DelayTap[1]);
964
feed = in * State->Late.DensityGain;
965
DelayLineIn(&State->Decorrelator, State->Offset, feed);
967
// Calculate the late reverb from the decorrelator taps.
969
taps[1] = DelayLineOut(&State->Decorrelator, State->Offset - State->DecoTap[0]);
970
taps[2] = DelayLineOut(&State->Decorrelator, State->Offset - State->DecoTap[1]);
971
taps[3] = DelayLineOut(&State->Decorrelator, State->Offset - State->DecoTap[2]);
972
LateReverb(State, taps, late);
974
// Calculate and mix in any echo.
975
EAXEcho(State, in, late);
977
// Step all delays forward one sample.
1077
enum Channel chan = Device->Speaker2Chan[index];
1078
State->Late.PanGain[chan] = lerp(ambientGain, ChannelGain[chan], dirGain) * Gain;
1082
// This updates the EAX reverb state. This is called any time the EAX reverb
1083
// effect is loaded into a slot.
1084
static ALvoid ReverbUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot)
1086
ALverbState *State = (ALverbState*)effect;
1087
ALuint frequency = Device->Frequency;
1088
ALboolean isEAX = AL_FALSE;
1089
ALfloat cw, x, y, hfRatio;
1091
if(Slot->effect.type == AL_EFFECT_EAXREVERB && !EmulateEAXReverb)
1093
State->state.Process = EAXVerbProcess;
1096
else if(Slot->effect.type == AL_EFFECT_REVERB || EmulateEAXReverb)
1098
State->state.Process = VerbProcess;
1102
// Calculate the master low-pass filter (from the master effect HF gain).
1103
if(isEAX) cw = CalcI3DL2HFreq(Slot->effect.Reverb.HFReference, frequency);
1104
else cw = CalcI3DL2HFreq(LOWPASSFREQREF, frequency);
1105
// This is done with 2 chained 1-pole filters, so no need to square g.
1106
State->LpFilter.coeff = lpCoeffCalc(Slot->effect.Reverb.GainHF, cw);
1110
// Update the modulator line.
1111
UpdateModulator(Slot->effect.Reverb.ModulationTime,
1112
Slot->effect.Reverb.ModulationDepth,
1116
// Update the initial effect delay.
1117
UpdateDelayLine(Slot->effect.Reverb.ReflectionsDelay,
1118
Slot->effect.Reverb.LateReverbDelay,
1121
// Update the early lines.
1122
UpdateEarlyLines(Slot->effect.Reverb.Gain,
1123
Slot->effect.Reverb.ReflectionsGain,
1124
Slot->effect.Reverb.LateReverbDelay, State);
1126
// Update the decorrelator.
1127
UpdateDecorrelator(Slot->effect.Reverb.Density, frequency, State);
1129
// Get the mixing matrix coefficients (x and y).
1130
CalcMatrixCoeffs(Slot->effect.Reverb.Diffusion, &x, &y);
1131
// Then divide x into y to simplify the matrix calculation.
1132
State->Late.MixCoeff = y / x;
1134
// If the HF limit parameter is flagged, calculate an appropriate limit
1135
// based on the air absorption parameter.
1136
hfRatio = Slot->effect.Reverb.DecayHFRatio;
1137
if(Slot->effect.Reverb.DecayHFLimit &&
1138
Slot->effect.Reverb.AirAbsorptionGainHF < 1.0f)
1139
hfRatio = CalcLimitedHfRatio(hfRatio,
1140
Slot->effect.Reverb.AirAbsorptionGainHF,
1141
Slot->effect.Reverb.DecayTime);
1143
// Update the late lines.
1144
UpdateLateLines(Slot->effect.Reverb.Gain, Slot->effect.Reverb.LateReverbGain,
1145
x, Slot->effect.Reverb.Density, Slot->effect.Reverb.DecayTime,
1146
Slot->effect.Reverb.Diffusion, hfRatio, cw, frequency, State);
1150
// Update the echo line.
1151
UpdateEchoLine(Slot->effect.Reverb.Gain, Slot->effect.Reverb.LateReverbGain,
1152
Slot->effect.Reverb.EchoTime, Slot->effect.Reverb.DecayTime,
1153
Slot->effect.Reverb.Diffusion, Slot->effect.Reverb.EchoDepth,
1154
hfRatio, cw, frequency, State);
1156
// Update early and late 3D panning.
1157
Update3DPanning(Device, Slot->effect.Reverb.ReflectionsPan,
1158
Slot->effect.Reverb.LateReverbPan, Slot->Gain, State);
1162
ALfloat gain = Slot->Gain;
1165
/* Update channel gains */
1166
gain *= aluSqrt(2.0f/Device->NumChan) * ReverbBoost;
1167
for(index = 0;index < MAXCHANNELS;index++)
1168
State->Gain[index] = 0.0f;
1169
for(index = 0;index < Device->NumChan;index++)
1171
enum Channel chan = Device->Speaker2Chan[index];
1172
State->Gain[chan] = gain;
981
1177
// This destroys the reverb state. It should be called only when the effect
982
1178
// slot has a different (or no) effect loaded over the reverb effect.
983
static ALvoid VerbDestroy(ALeffectState *effect)
1179
static ALvoid ReverbDestroy(ALeffectState *effect)
985
1181
ALverbState *State = (ALverbState*)effect;
994
// This updates the device-dependant reverb state. This is called on
995
// initialization and any time the device parameters (eg. playback frequency,
996
// or format) have been changed.
997
static ALboolean VerbDeviceUpdate(ALeffectState *effect, ALCdevice *Device)
999
ALverbState *State = (ALverbState*)effect;
1000
ALuint frequency = Device->Frequency;
1003
// Allocate the delay lines.
1004
if(!AllocLines(AL_FALSE, frequency, State))
1007
// The early reflection and late all-pass filter line lengths are static,
1008
// so their offsets only need to be calculated once.
1009
for(index = 0;index < 4;index++)
1011
State->Early.Offset[index] = (ALuint)(EARLY_LINE_LENGTH[index] *
1013
State->Late.ApOffset[index] = (ALuint)(ALLPASS_LINE_LENGTH[index] *
1017
for(index = 0;index < MAXCHANNELS;index++)
1018
State->Gain[index] = 0.0f;
1019
for(index = 0;index < Device->NumChan;index++)
1021
Channel chan = Device->Speaker2Chan[index];
1022
State->Gain[chan] = 1.0f;
1028
// This updates the device-dependant EAX reverb state. This is called on
1029
// initialization and any time the device parameters (eg. playback frequency,
1030
// format) have been changed.
1031
static ALboolean EAXVerbDeviceUpdate(ALeffectState *effect, ALCdevice *Device)
1033
ALverbState *State = (ALverbState*)effect;
1034
ALuint frequency = Device->Frequency, index;
1036
// Allocate the delay lines.
1037
if(!AllocLines(AL_TRUE, frequency, State))
1040
// Calculate the modulation filter coefficient. Notice that the exponent
1041
// is calculated given the current sample rate. This ensures that the
1042
// resulting filter response over time is consistent across all sample
1044
State->Mod.Coeff = aluPow(MODULATION_FILTER_COEFF,
1045
MODULATION_FILTER_CONST / frequency);
1047
// The early reflection and late all-pass filter line lengths are static,
1048
// so their offsets only need to be calculated once.
1049
for(index = 0;index < 4;index++)
1051
State->Early.Offset[index] = (ALuint)(EARLY_LINE_LENGTH[index] *
1053
State->Late.ApOffset[index] = (ALuint)(ALLPASS_LINE_LENGTH[index] *
1057
// The echo all-pass filter line length is static, so its offset only
1058
// needs to be calculated once.
1059
State->Echo.ApOffset = (ALuint)(ECHO_ALLPASS_LENGTH * frequency);
1064
// This updates the reverb state. This is called any time the reverb effect
1065
// is loaded into a slot.
1066
static ALvoid VerbUpdate(ALeffectState *effect, ALCcontext *Context, const ALeffect *Effect)
1068
ALverbState *State = (ALverbState*)effect;
1069
ALuint frequency = Context->Device->Frequency;
1070
ALfloat cw, x, y, hfRatio;
1072
// Calculate the master low-pass filter (from the master effect HF gain).
1073
cw = CalcI3DL2HFreq(Effect->Reverb.HFReference, frequency);
1074
// This is done with 2 chained 1-pole filters, so no need to square g.
1075
State->LpFilter.coeff = lpCoeffCalc(Effect->Reverb.GainHF, cw);
1077
// Update the initial effect delay.
1078
UpdateDelayLine(Effect->Reverb.ReflectionsDelay,
1079
Effect->Reverb.LateReverbDelay, frequency, State);
1081
// Update the early lines.
1082
UpdateEarlyLines(Effect->Reverb.Gain, Effect->Reverb.ReflectionsGain,
1083
Effect->Reverb.LateReverbDelay, State);
1085
// Update the decorrelator.
1086
UpdateDecorrelator(Effect->Reverb.Density, frequency, State);
1088
// Get the mixing matrix coefficients (x and y).
1089
CalcMatrixCoeffs(Effect->Reverb.Diffusion, &x, &y);
1090
// Then divide x into y to simplify the matrix calculation.
1091
State->Late.MixCoeff = y / x;
1093
// If the HF limit parameter is flagged, calculate an appropriate limit
1094
// based on the air absorption parameter.
1095
hfRatio = Effect->Reverb.DecayHFRatio;
1096
if(Effect->Reverb.DecayHFLimit && Effect->Reverb.AirAbsorptionGainHF < 1.0f)
1097
hfRatio = CalcLimitedHfRatio(hfRatio, Effect->Reverb.AirAbsorptionGainHF,
1098
Effect->Reverb.DecayTime);
1100
// Update the late lines.
1101
UpdateLateLines(Effect->Reverb.Gain, Effect->Reverb.LateReverbGain,
1102
x, Effect->Reverb.Density, Effect->Reverb.DecayTime,
1103
Effect->Reverb.Diffusion, hfRatio, cw, frequency, State);
1106
// This updates the EAX reverb state. This is called any time the EAX reverb
1107
// effect is loaded into a slot.
1108
static ALvoid EAXVerbUpdate(ALeffectState *effect, ALCcontext *Context, const ALeffect *Effect)
1110
ALverbState *State = (ALverbState*)effect;
1111
ALuint frequency = Context->Device->Frequency;
1112
ALfloat cw, x, y, hfRatio;
1114
// Calculate the master low-pass filter (from the master effect HF gain).
1115
cw = CalcI3DL2HFreq(Effect->Reverb.HFReference, frequency);
1116
// This is done with 2 chained 1-pole filters, so no need to square g.
1117
State->LpFilter.coeff = lpCoeffCalc(Effect->Reverb.GainHF, cw);
1119
// Update the modulator line.
1120
UpdateModulator(Effect->Reverb.ModulationTime,
1121
Effect->Reverb.ModulationDepth, frequency, State);
1123
// Update the initial effect delay.
1124
UpdateDelayLine(Effect->Reverb.ReflectionsDelay,
1125
Effect->Reverb.LateReverbDelay, frequency, State);
1127
// Update the early lines.
1128
UpdateEarlyLines(Effect->Reverb.Gain, Effect->Reverb.ReflectionsGain,
1129
Effect->Reverb.LateReverbDelay, State);
1131
// Update the decorrelator.
1132
UpdateDecorrelator(Effect->Reverb.Density, frequency, State);
1134
// Get the mixing matrix coefficients (x and y).
1135
CalcMatrixCoeffs(Effect->Reverb.Diffusion, &x, &y);
1136
// Then divide x into y to simplify the matrix calculation.
1137
State->Late.MixCoeff = y / x;
1139
// If the HF limit parameter is flagged, calculate an appropriate limit
1140
// based on the air absorption parameter.
1141
hfRatio = Effect->Reverb.DecayHFRatio;
1142
if(Effect->Reverb.DecayHFLimit && Effect->Reverb.AirAbsorptionGainHF < 1.0f)
1143
hfRatio = CalcLimitedHfRatio(hfRatio, Effect->Reverb.AirAbsorptionGainHF,
1144
Effect->Reverb.DecayTime);
1146
// Update the late lines.
1147
UpdateLateLines(Effect->Reverb.Gain, Effect->Reverb.LateReverbGain,
1148
x, Effect->Reverb.Density, Effect->Reverb.DecayTime,
1149
Effect->Reverb.Diffusion, hfRatio, cw, frequency, State);
1151
// Update the echo line.
1152
UpdateEchoLine(Effect->Reverb.Gain, Effect->Reverb.LateReverbGain,
1153
Effect->Reverb.EchoTime, Effect->Reverb.DecayTime,
1154
Effect->Reverb.Diffusion, Effect->Reverb.EchoDepth,
1155
hfRatio, cw, frequency, State);
1157
// Update early and late 3D panning.
1158
Update3DPanning(Context->Device, Effect->Reverb.ReflectionsPan,
1159
Effect->Reverb.LateReverbPan, State);
1162
// This processes the reverb state, given the input samples and an output
1164
static ALvoid VerbProcess(ALeffectState *effect, const ALeffectslot *Slot, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MAXCHANNELS])
1166
ALverbState *State = (ALverbState*)effect;
1168
ALfloat early[4], late[4], out[4];
1169
ALfloat gain = Slot->Gain;
1170
const ALfloat *panGain = State->Gain;
1172
for(index = 0;index < SamplesToDo;index++)
1174
// Process reverb for this sample.
1175
VerbPass(State, SamplesIn[index], early, late);
1177
// Mix early reflections and late reverb.
1178
out[0] = (early[0] + late[0]) * gain;
1179
out[1] = (early[1] + late[1]) * gain;
1180
out[2] = (early[2] + late[2]) * gain;
1181
out[3] = (early[3] + late[3]) * gain;
1183
// Output the results.
1184
SamplesOut[index][FRONT_LEFT] += panGain[FRONT_LEFT] * out[0];
1185
SamplesOut[index][FRONT_RIGHT] += panGain[FRONT_RIGHT] * out[1];
1186
SamplesOut[index][FRONT_CENTER] += panGain[FRONT_CENTER] * out[3];
1187
SamplesOut[index][SIDE_LEFT] += panGain[SIDE_LEFT] * out[0];
1188
SamplesOut[index][SIDE_RIGHT] += panGain[SIDE_RIGHT] * out[1];
1189
SamplesOut[index][BACK_LEFT] += panGain[BACK_LEFT] * out[0];
1190
SamplesOut[index][BACK_RIGHT] += panGain[BACK_RIGHT] * out[1];
1191
SamplesOut[index][BACK_CENTER] += panGain[BACK_CENTER] * out[2];
1195
// This processes the EAX reverb state, given the input samples and an output
1197
static ALvoid EAXVerbProcess(ALeffectState *effect, const ALeffectslot *Slot, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MAXCHANNELS])
1199
ALverbState *State = (ALverbState*)effect;
1201
ALfloat early[4], late[4];
1202
ALfloat gain = Slot->Gain;
1204
for(index = 0;index < SamplesToDo;index++)
1206
// Process reverb for this sample.
1207
EAXVerbPass(State, SamplesIn[index], early, late);
1209
// Unfortunately, while the number and configuration of gains for
1210
// panning adjust according to MAXCHANNELS, the output from the
1211
// reverb engine is not so scalable.
1212
SamplesOut[index][FRONT_LEFT] +=
1213
(State->Early.PanGain[FRONT_LEFT]*early[0] +
1214
State->Late.PanGain[FRONT_LEFT]*late[0]) * gain;
1215
SamplesOut[index][FRONT_RIGHT] +=
1216
(State->Early.PanGain[FRONT_RIGHT]*early[1] +
1217
State->Late.PanGain[FRONT_RIGHT]*late[1]) * gain;
1218
SamplesOut[index][FRONT_CENTER] +=
1219
(State->Early.PanGain[FRONT_CENTER]*early[3] +
1220
State->Late.PanGain[FRONT_CENTER]*late[3]) * gain;
1221
SamplesOut[index][SIDE_LEFT] +=
1222
(State->Early.PanGain[SIDE_LEFT]*early[0] +
1223
State->Late.PanGain[SIDE_LEFT]*late[0]) * gain;
1224
SamplesOut[index][SIDE_RIGHT] +=
1225
(State->Early.PanGain[SIDE_RIGHT]*early[1] +
1226
State->Late.PanGain[SIDE_RIGHT]*late[1]) * gain;
1227
SamplesOut[index][BACK_LEFT] +=
1228
(State->Early.PanGain[BACK_LEFT]*early[0] +
1229
State->Late.PanGain[BACK_LEFT]*late[0]) * gain;
1230
SamplesOut[index][BACK_RIGHT] +=
1231
(State->Early.PanGain[BACK_RIGHT]*early[1] +
1232
State->Late.PanGain[BACK_RIGHT]*late[1]) * gain;
1233
SamplesOut[index][BACK_CENTER] +=
1234
(State->Early.PanGain[BACK_CENTER]*early[2] +
1235
State->Late.PanGain[BACK_CENTER]*late[2]) * gain;
1239
1190
// This creates the reverb state. It should be called only when the reverb
1240
1191
// effect is loaded into a slot that doesn't already have a reverb effect.
1241
ALeffectState *VerbCreate(void)
1192
ALeffectState *ReverbCreate(void)
1243
1194
ALverbState *State = NULL;