Implement a new reverb effect
[openal-soft.git] / Alc / alcReverb.c
blobbadbac34dc88370be3c4058475ee4805383a42b9
1 // TODO: Look into the distance attenuation done by the statistical model,
2 // and see if it matches 1 / sqrt (distance) or some variant thereof.
3 // If not, try to map it so it can replace the current dry-path model.
4 // Also see how it responds to the distance model. Then if necessary
5 // update ALu.c to compensate.
6 // TODO: Finalize all updates and add necessary comments. Merge changes
7 // with latest GIT snapshot and test all parameters thoroughly. When
8 // ready produce some .diff files for the changes and include with
9 // alReverb.c for presentation.
11 #include "config.h"
13 #include <math.h>
14 #include <stdlib.h>
16 #include "AL/al.h"
17 #include "AL/alc.h"
18 #include "alMain.h"
19 #include "alAuxEffectSlot.h"
20 #include "alEffect.h"
21 #include "alReverb.h"
23 #ifdef HAVE_SQRTF
24 #define aluSqrt(x) ((ALfloat)sqrtf((float)(x)))
25 #else
26 #define aluSqrt(x) ((ALfloat)sqrt((double)(x)))
27 #endif
29 // fixes for mingw32.
30 #if defined(max) && !defined(__max)
31 #define __max max
32 #endif
33 #if defined(min) && !defined(__min)
34 #define __min min
35 #endif
37 typedef struct DelayLine
39 // The delay lines use lengths that are powers of 2 to allow bitmasking
40 // instead of modulus wrapping.
41 ALuint Mask;
42 ALfloat *Line;
43 } DelayLine;
45 struct ALverbState
47 // All delay lines are allocated as a single buffer to reduce memory
48 // fragmentation and teardown code.
49 ALfloat *SampleBuffer;
50 // Master reverb gain.
51 ALfloat Gain;
52 // Initial reverb delay.
53 DelayLine Delay;
54 // The tap points for the initial delay. First tap goes to early
55 // reflections, the second to late reverb.
56 ALuint Tap[2];
57 struct {
58 // Gain for early reflections.
59 ALfloat Gain;
60 // Early reflections are done with 4 delay lines.
61 ALfloat Coeff[4];
62 DelayLine Delay[4];
63 ALuint Offset[4];
64 } Early;
65 struct {
66 // Gain for late reverb.
67 ALfloat Gain;
68 // Diffusion of late reverb.
69 ALfloat Diffusion;
70 // Late reverb is done with 8 delay lines.
71 ALfloat Coeff[8];
72 DelayLine Delay[8];
73 ALuint Offset[8];
74 // The input and last 4 delay lines are low-pass filtered.
75 ALfloat LpCoeff[5];
76 ALfloat LpSample[5];
77 } Late;
78 ALuint Offset;
81 // All delay line lengths are specified in seconds.
83 // The length of the initial delay line (a sum of the maximum delay before
84 // early reflections and late reverb; 0.3 + 0.1).
85 static const ALfloat MASTER_LINE_LENGTH = 0.4000f;
87 // The lengths of the early delay lines.
88 static const ALfloat EARLY_LINE_LENGTH[4] =
90 0.0015f, 0.0045f, 0.0135f, 0.0405f
93 // The lengths of the late delay lines.
94 static const ALfloat LATE_LINE_LENGTH[8] =
96 0.0015f, 0.0037f, 0.0093f, 0.0234f,
97 0.0100f, 0.0150f, 0.0225f, 0.0337f
100 // The last 4 late delay lines have a variable length dependent on the effect
101 // density parameter and this multiplier.
102 static const ALfloat LATE_LINE_MULTIPLIER = 9.0f;
104 static ALuint NextPowerOf2(ALuint value)
106 ALuint powerOf2 = 1;
108 if(value)
110 value--;
111 while(value)
113 value >>= 1;
114 powerOf2 <<= 1;
117 return powerOf2;
120 // Basic delay line input/output routines.
121 static __inline ALfloat DelayLineOut(DelayLine *Delay, ALuint offset)
123 return Delay->Line[offset&Delay->Mask];
126 static __inline ALvoid DelayLineIn(DelayLine *Delay, ALuint offset, ALfloat in)
128 Delay->Line[offset&Delay->Mask] = in;
131 // Delay line output routine for early reflections.
132 static __inline ALfloat EarlyDelayLineOut(ALverbState *State, ALuint index)
134 return State->Early.Coeff[index] *
135 DelayLineOut(&State->Early.Delay[index],
136 State->Offset - State->Early.Offset[index]);
139 // Given an input sample, this function produces a decorrelated stereo output
140 // for early reflections.
141 static __inline ALvoid EarlyReflection(ALverbState *State, ALfloat in, ALfloat *out)
143 ALfloat d[4], v, f[4];
145 // Obtain the decayed results of each early delay line.
146 d[0] = EarlyDelayLineOut(State, 0);
147 d[1] = EarlyDelayLineOut(State, 1);
148 d[2] = EarlyDelayLineOut(State, 2);
149 d[3] = EarlyDelayLineOut(State, 3);
151 /* The following uses a lossless scattering junction from waveguide
152 * theory. It actually amounts to a householder mixing matrix, which
153 * will produce a maximally diffuse response, and means this can probably
154 * be considered a simple FDN.
156 * ---
158 * v = 2/N / di
159 * ---
160 * i=1
162 v = (d[0] + d[1] + d[2] + d[3]) * 0.5f;
163 // The junction is loaded with the input here.
164 v += in;
166 // Calculate the feed values for the delay lines.
167 f[0] = v - d[0];
168 f[1] = v - d[1];
169 f[2] = v - d[2];
170 f[3] = v - d[3];
172 // To increase reflection complexity (and help reduce coloration) the
173 // delay lines cyclicly refeed themselves (0 -> 1 -> 3 -> 2 -> 0...).
174 DelayLineIn(&State->Early.Delay[0], State->Offset, f[2]);
175 DelayLineIn(&State->Early.Delay[1], State->Offset, f[0]);
176 DelayLineIn(&State->Early.Delay[2], State->Offset, f[3]);
177 DelayLineIn(&State->Early.Delay[3], State->Offset, f[1]);
179 // To decorrelate the output for stereo separation, the cyclical nature
180 // of the feed path is exploited. The two outputs are obtained from the
181 // inner delay lines.
182 // Output is instant by using the inputs to them instead of taking the
183 // result of the two delay lines directly (f[0] and f[3] instead of d[1]
184 // and d[2]).
185 out[0] = State->Early.Gain * f[0];
186 out[1] = State->Early.Gain * f[3];
189 // Delay line output routine for late reverb.
190 static __inline ALfloat LateDelayLineOut(ALverbState *State, ALuint index)
192 return State->Late.Coeff[index] *
193 DelayLineOut(&State->Late.Delay[index],
194 State->Offset - State->Late.Offset[index]);
197 // Low-pass filter input/output routine for late reverb.
198 static __inline ALfloat LateLowPassInOut(ALverbState *State, ALuint index, ALfloat in)
200 State->Late.LpSample[index] = in + ((State->Late.LpSample[index] - in) *
201 State->Late.LpCoeff[index]);
202 return State->Late.LpSample[index];
205 // Given an input sample, this function produces a decorrelated stereo output
206 // for late reverb.
207 static __inline ALvoid LateReverb(ALverbState *State, ALfloat in, ALfloat *out)
209 ALfloat din, d[8], v, dv, f[8];
211 // Since the input will be sent directly to the output as in the early
212 // reflections function, it needs to take into account some immediate
213 // absorption.
214 in = LateLowPassInOut(State, 0, in);
216 // When diffusion is full, no input is directly passed to the variable-
217 // length delay lines (the last 4).
218 din = (1.0f - State->Late.Diffusion) * in;
220 // Obtain the decayed results of the fixed-length delay lines.
221 d[0] = LateDelayLineOut(State, 0);
222 d[1] = LateDelayLineOut(State, 1);
223 d[2] = LateDelayLineOut(State, 2);
224 d[3] = LateDelayLineOut(State, 3);
225 // Obtain the decayed and low-pass filtered results of the variable-
226 // length delay lines.
227 d[4] = LateLowPassInOut(State, 1, LateDelayLineOut(State, 4));
228 d[5] = LateLowPassInOut(State, 2, LateDelayLineOut(State, 5));
229 d[6] = LateLowPassInOut(State, 3, LateDelayLineOut(State, 6));
230 d[7] = LateLowPassInOut(State, 4, LateDelayLineOut(State, 7));
232 // The waveguide formula used in the early reflections function works
233 // great for high diffusion, but it is not obviously paramerized to allow
234 // a variable diffusion. With only limited time and resources, what
235 // follows is the best variation of that formula I could come up with.
236 // First, there are 8 delay lines used. The first 4 are fixed-length and
237 // generate the highest density of the diffuse response. The last 4 are
238 // variable-length, and are used to smooth out the diffuse response. The
239 // density effect parameter alters their length. The inner two delay
240 // lines of each group have their signs reversed (more about this later).
241 v = (d[0] - d[1] - d[2] + d[3] +
242 d[4] - d[5] - d[6] + d[7]) * 0.25f;
243 // Diffusion is applied as a reduction of the junction pressure for all
244 // branches. This presents two problems. When the diffusion factor (0
245 // to 1) reaches 0.5, the average feed value is reduced (the junction
246 // becomes lossy). Thus, at 0.5 the signal decays almost twice as fast
247 // as it should. The second problem is the introduction of some
248 // resonant frequencies (coloration). The reversed signs above are used
249 // to help combat some of the coloration by adding variations along the
250 // feed cycle.
251 v *= State->Late.Diffusion;
252 // Load the junction with the input. To reduce the noticeable echo of
253 // the longer delay lines (the variable-length ones) the input is loaded
254 // with the inverse of the effect diffusion. So at full diffusion, the
255 // input is not applied to the last 4 delay lines. Input signs reversed
256 // to balance the equation.
257 dv = v + din;
258 v += in;
260 // As with the reversed signs above, to balance the equation the signs
261 // need to be reversed here, too.
262 f[0] = d[0] - v;
263 f[1] = d[1] + v;
264 f[2] = d[2] + v;
265 f[3] = d[3] - v;
266 f[4] = d[4] - dv;
267 f[5] = d[5] + dv;
268 f[6] = d[6] + dv;
269 f[7] = d[7] - dv;
271 // Feed the fixed-length delay lines with their own cycle (0 -> 1 -> 3 ->
272 // 2 -> 0...).
273 DelayLineIn(&State->Late.Delay[0], State->Offset, f[2]);
274 DelayLineIn(&State->Late.Delay[1], State->Offset, f[0]);
275 DelayLineIn(&State->Late.Delay[2], State->Offset, f[3]);
276 DelayLineIn(&State->Late.Delay[3], State->Offset, f[1]);
277 // Feed the variable-length delay lines with their cycle (4 -> 6 -> 7 ->
278 // 5 -> 4...).
279 DelayLineIn(&State->Late.Delay[4], State->Offset, f[5]);
280 DelayLineIn(&State->Late.Delay[5], State->Offset, f[7]);
281 DelayLineIn(&State->Late.Delay[6], State->Offset, f[4]);
282 DelayLineIn(&State->Late.Delay[7], State->Offset, f[6]);
284 // Output is derived from the values fed to the inner two variable-length
285 // delay lines (5 and 6).
286 out[0] = State->Late.Gain * f[7];
287 out[1] = State->Late.Gain * f[4];
290 // This creates the reverb state. It should be called only when the reverb
291 // effect is loaded into a slot that doesn't already have a reverb effect.
292 ALverbState *VerbCreate(ALCcontext *Context)
294 ALverbState *State = NULL;
295 ALuint length[13], totalLength, index;
297 State = malloc(sizeof(ALverbState));
298 if(!State)
299 return NULL;
301 // All line lengths are powers of 2, calculated from the line timings and
302 // the addition of an extra sample (for safety).
303 length[0] = NextPowerOf2((ALuint)(MASTER_LINE_LENGTH*Context->Frequency) + 1);
304 totalLength = length[0];
305 for(index = 0;index < 4;index++)
307 length[1+index] = NextPowerOf2((ALuint)(EARLY_LINE_LENGTH[index]*Context->Frequency) + 1);
308 totalLength += length[1+index];
310 for(index = 0;index < 4;index++)
312 length[5+index] = NextPowerOf2((ALuint)(LATE_LINE_LENGTH[index]*Context->Frequency) + 1);
313 totalLength += length[5+index];
315 for(index = 4;index < 8;index++)
317 length[5+index] = NextPowerOf2((ALuint)(LATE_LINE_LENGTH[index]*(1.0f + LATE_LINE_MULTIPLIER)*Context->Frequency) + 1);
318 totalLength += length[5+index];
321 // They all share a single sample buffer.
322 State->SampleBuffer = malloc(totalLength * sizeof(ALfloat));
323 if(!State->SampleBuffer)
325 free(State);
326 return NULL;
328 for(index = 0; index < totalLength;index++)
329 State->SampleBuffer[index] = 0.0f;
331 // Each one has its mask and start address calculated one time.
332 State->Gain = 0.0f;
333 State->Delay.Mask = length[0] - 1;
334 State->Delay.Line = &State->SampleBuffer[0];
335 totalLength = length[0];
337 State->Tap[0] = 0;
338 State->Tap[1] = 0;
340 State->Early.Gain = 0.0f;
341 // All fixed-length delay lines have their read-write offsets calculated
342 // one time.
343 for(index = 0;index < 4;index++)
345 State->Early.Coeff[index] = 0.0f;
346 State->Early.Delay[index].Mask = length[1 + index] - 1;
347 State->Early.Delay[index].Line = &State->SampleBuffer[totalLength];
348 totalLength += length[1 + index];
350 State->Early.Offset[index] = (ALuint)(EARLY_LINE_LENGTH[index] * Context->Frequency);
353 State->Late.Gain = 0.0f;
354 State->Late.Diffusion = 0.0f;
355 for(index = 0;index < 8;index++)
357 State->Late.Coeff[index] = 0.0f;
358 State->Late.Delay[index].Mask = length[5 + index] - 1;
359 State->Late.Delay[index].Line = &State->SampleBuffer[totalLength];
360 totalLength += length[5 + index];
362 State->Late.Offset[index] = 0;
363 if(index < 4)
365 State->Late.Offset[index] = (ALuint)(LATE_LINE_LENGTH[index] * Context->Frequency);
366 State->Late.LpCoeff[index] = 0.0f;
367 State->Late.LpSample[index] = 0.0f;
369 else if(index == 4)
371 State->Late.LpCoeff[index] = 0.0f;
372 State->Late.LpSample[index] = 0.0f;
376 State->Offset = 0;
377 return State;
380 // This destroys the reverb state. It should be called only when the effect
381 // slot has a different (or no) effect loaded over the reverb effect.
382 ALvoid VerbDestroy(ALverbState *State)
384 if(State)
386 free(State->SampleBuffer);
387 State->SampleBuffer = NULL;
388 free(State);
392 // This updates the reverb state. This is called any time the reverb effect
393 // is loaded into a slot.
394 ALvoid VerbUpdate(ALCcontext *Context, ALeffectslot *Slot, ALeffect *Effect)
396 ALverbState *State = Slot->ReverbState;
397 ALuint index, index2;
398 ALfloat length, lpcoeff, cw, g;
399 ALfloat hfRatio = Effect->Reverb.DecayHFRatio;
401 // Calculate the master gain (from the slot and master reverb gain).
402 State->Gain = Slot->Gain * Effect->Reverb.Gain;
404 // Calculate the initial delay taps.
405 length = Effect->Reverb.ReflectionsDelay;
406 State->Tap[0] = (ALuint)(length * Context->Frequency);
407 length += Effect->Reverb.LateReverbDelay;
408 State->Tap[1] = (ALuint)(length * Context->Frequency);
410 // Calculate the early reflections gain. Right now this uses a gain of
411 // 0.75 to compensate for the increase in density. It should probably
412 // use a power (RMS) based measurement from the resulting distribution of
413 // early delay lines.
414 State->Early.Gain = Effect->Reverb.ReflectionsGain * 0.75f;
416 // Calculate the gain (coefficient) for each early delay line.
417 for(index = 0;index < 4;index++)
418 State->Early.Coeff[index] = pow(10.0f, EARLY_LINE_LENGTH[index] /
419 Effect->Reverb.LateReverbDelay *
420 -60.0f / 20.0f);
422 // Calculate the late reverb gain, adjusted by density, diffusion, and
423 // decay time. To be accurate, the adjustments should probably use power
424 // measurements for each contribution, but they are not too bad as they
425 // are.
426 State->Late.Gain = Effect->Reverb.LateReverbGain *
427 (0.45f + (0.55f * Effect->Reverb.Density)) *
428 (1.0f - (0.25f * Effect->Reverb.Diffusion)) *
429 (1.0f - (0.025f * Effect->Reverb.DecayTime));
430 State->Late.Diffusion = Effect->Reverb.Diffusion;
432 // The EFX specification does not make it clear whether the air
433 // absorption parameter should always take effect. Both Generic Software
434 // and Generic Hardware only apply it when HF limit is flagged, so that's
435 // what is done here.
436 // If the HF limit parameter is flagged, calculate an appropriate limit
437 // based on the air absorption parameter.
438 if(Effect->Reverb.DecayHFLimit)
440 ALfloat limitRatio;
442 // The following is my best guess at how to limit the HF ratio by the
443 // air absorption parameter.
444 // For each of the last 4 delays, find the attenuation due to air
445 // absorption in dB (converting delay time to meters using the speed
446 // of sound). Then reversing the decay equation, solve for HF ratio.
447 // The delay length is cancelled out of the equation, so it can be
448 // calculated once for all lines.
449 limitRatio = 1.0f / (log10(Effect->Reverb.AirAbsorptionGainHF) *
450 SPEEDOFSOUNDMETRESPERSEC*Effect->Reverb.DecayTime/
451 -60.0f * 20.0f);
452 // Need to limit the result to a minimum of 0.1, just like the HF
453 // ratio parameter.
454 limitRatio = __max(limitRatio, 0.1f);
456 // Using the limit calculated above, apply the upper bound to the
457 // HF ratio.
458 hfRatio = __min(hfRatio, limitRatio);
461 cw = cos(2.0f*3.141592654f * LOWPASSFREQCUTOFF / Context->Frequency);
463 for(index = 0;index < 8;index++)
465 // Calculate the length (in seconds) of each delay line.
466 length = LATE_LINE_LENGTH[index];
467 if(index >= 4)
469 index2 = index - 3;
471 length *= 1.0f + (Effect->Reverb.Density * LATE_LINE_MULTIPLIER);
473 // Calculate the delay offset for the variable-length delay
474 // lines.
475 State->Late.Offset[index] = (ALuint)(length * Context->Frequency);
477 // Calculate the decay equation for each low-pass filter.
478 g = pow(10.0f, length / (Effect->Reverb.DecayTime * hfRatio) *
479 -60.0f / 20.0f);
480 g = __max(g, 0.1f);
481 g *= g;
482 // Calculate the gain (coefficient) for each low-pass filter.
483 lpcoeff = 0.0f;
484 if(g < 0.9999f) // 1-epsilon
485 lpcoeff = (1 - g*cw - aluSqrt(2*g*(1-cw) - g*g*(1 - cw*cw))) / (1 - g);
487 // Very low decay times will produce minimal output, so apply an
488 // upper bound to the coefficient.
489 State->Late.LpCoeff[index2] = __min(lpcoeff, 0.98f);
492 // Calculate the gain (coefficient) for each line.
493 State->Late.Coeff[index] = pow(10.0f, length / Effect->Reverb.DecayTime *
494 -60.0f / 20.0f);
497 // This just calculates the coefficient for the late reverb input low-
498 // pass filter. It is calculated based the average (hence -30 instead
499 // of -60) length of the inner two variable-length delay lines.
500 length = LATE_LINE_LENGTH[5] * (1.0f + Effect->Reverb.Density * LATE_LINE_MULTIPLIER) +
501 LATE_LINE_LENGTH[6] * (1.0f + Effect->Reverb.Density * LATE_LINE_MULTIPLIER);
503 g = pow(10.0f, length / (Effect->Reverb.DecayTime * hfRatio) * -30.0f / 20.0f);
504 g = __max(g, 0.1f);
505 g *= g;
507 lpcoeff = 0.0f;
508 if(g < 0.9999f) // 1-epsilon
509 lpcoeff = (1 - g*cw - aluSqrt(2*g*(1-cw) - g*g*(1 - cw*cw))) / (1 - g);
511 State->Late.LpCoeff[0] = __min(lpcoeff, 0.98f);
514 // This processes the reverb state, given the input samples and an output
515 // buffer.
516 ALvoid VerbProcess(ALverbState *State, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[OUTPUTCHANNELS])
518 ALuint index;
519 ALfloat in, early[2], late[2], out[2];
521 for(index = 0;index < SamplesToDo;index++)
523 // Feed the initial delay line.
524 DelayLineIn(&State->Delay, State->Offset, SamplesIn[index]);
526 // Calculate the early reflection from the first delay tap.
527 in = DelayLineOut(&State->Delay, State->Offset - State->Tap[0]);
528 EarlyReflection(State, in, early);
530 // Calculate the late reverb from the second delay tap.
531 in = DelayLineOut(&State->Delay, State->Offset - State->Tap[1]);
532 LateReverb(State, in, late);
534 // Mix early reflections and late reverb.
535 out[0] = State->Gain * (early[0] + late[0]);
536 out[1] = State->Gain * (early[1] + late[1]);
538 // Step all delays forward one sample.
539 State->Offset++;
541 // Output the results.
542 SamplesOut[index][FRONT_LEFT] += out[0];
543 SamplesOut[index][FRONT_RIGHT] += out[1];
544 SamplesOut[index][SIDE_LEFT] += out[0];
545 SamplesOut[index][SIDE_RIGHT] += out[1];
546 SamplesOut[index][BACK_LEFT] += out[0];
547 SamplesOut[index][BACK_RIGHT] += out[1];