Stdin, stdout and stderr updated, tested.
[Faustine.git] / interpreter / preprocessor / faust-0.9.47mr3 / tools / faust2pd / examples / synth / compressor.dsp
1
2 /* Compressor unit. */
3
4 declare name "compressor -- compressor/limiter unit";
5 declare author "Albert Graef";
6 declare version "1.0";
7
8 import("music.lib");
9
10 /* Controls. */
11
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);
16
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));
21
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);
25
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)));
29
30 /* Envelop detector. This is basically the same as in amp.dsp. */
31
32 t = 0.1;
33 g = exp(-1/(SR*t));
34 env = abs : *(1-g) : + ~ *(g);
35 rms = sqr : *(1-g) : + ~ *(g) : sqrt;
36 sqr(x) = x*x;
37
38 /* Compute the envelop of a stereo signal. Replace env with rms if you want to
39 use the RMS value instead. */
40
41 env2(x,y) = max(env(x),env(y));
42
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
54 compressor. */
55
56 compress(env) = level*(1-r)/r
57 with {
58 // the (filtered) input level above the threshold
59 level = env : h ~ _ : linear2db : (_-threshold+knee) : max(0)
60 with {
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));
64 };
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
69 r = 1-p+p*ratio;
70 };
71
72 process(x,y) = (g*x,g*y)
73 with {
74 g = env2(x,y) : compress : gain : +(makeup_gain) : db2linear;
75 };