4
declare name "compressor -- compressor/limiter unit";
5
declare author "Albert Graef";
12
// partition the controls into these three groups
13
comp_group(x) = hgroup("1-compression", x);
14
env_group(x) = vgroup("2-envelop", x);
15
gain_group(x) = vgroup("3-gain", x);
17
// compressor controls: ratio, threshold and knee size
18
ratio = comp_group(nentry("ratio", 2, 1, 20, 0.1));
19
threshold = comp_group(nentry("threshold", -20, -96, 10, 0.1));
20
knee = comp_group(nentry("knee", 3, 0, 20, 0.1));
22
// attack and release controls; clamped to a minimum of 1 sample
23
attack = env_group(hslider("attack", 0.002, 0, 1, 0.001)) : max(1/SR);
24
release = env_group(hslider("release", 0.5, 0, 10, 0.01)) : max(1/SR);
26
// gain controls: make-up gain, compression gain meter
27
makeup_gain = gain_group(hslider("makeup gain", 0, -96, 96, 0.1));
28
gain(x) = attach(x, x : gain_group(hbargraph("gain", -96, 0)));
30
/* Envelop detector. This is basically the same as in amp.dsp. */
34
env = abs : *(1-g) : + ~ *(g);
35
rms = sqr : *(1-g) : + ~ *(g) : sqrt;
38
/* Compute the envelop of a stereo signal. Replace env with rms if you want to
39
use the RMS value instead. */
41
env2(x,y) = max(env(x),env(y));
43
/* Compute the compression factor for the current input level. The gain is
44
always 0 dB if we're below the reduced threshold, threshold-knee. Beyond
45
the real threshold value the level is scaled by 1/ratio. Between these two
46
extremes we return a convex combination of those factors. This is also
47
known as "soft-knee" compression: the compression kicks in gradually at
48
threshold-knee and reaches its full value at threshold. For special
49
effects, you can also achieve old-school "hard-knee" compression by setting
50
the knee value to zero. Also note that, before computing the gain, the
51
input level is first smoothed out using a 1 pole IIR to prevent clicks when
52
the input level changes abruptly. The attack and release times of this
53
filter are configured with the corresponding envelop controls of the
56
compress(env) = level*(1-r)/r
58
// the (filtered) input level above the threshold
59
level = env : h ~ _ : linear2db : (_-threshold+knee) : max(0)
61
h(x,y) = f*x+(1-f)*y with { f = (x<y)*ga+(x>=y)*gr; };
62
ga = exp(-1/(SR*attack));
63
gr = exp(-1/(SR*release));
65
// the knee factor, clamped to 0..1; we add a small perturbation in
66
// the denominator to prevent infinities and nan when knee<<1
67
p = level/(knee+eps) : max(0) : min(1) with { eps = 0.001; };
68
// the actual compression ratio
72
process(x,y) = (g*x,g*y)
74
g = env2(x,y) : compress : gain : +(makeup_gain) : db2linear;