1 /* WhySynth DSSI software synthesizer plugin
2 *
3 * Copyright (C) 2005, 2010 Sean Bolton and others.
4 *
5 * Nearly all of the Plate reverb code comes from the Plate2x2
6 * reverb in CAPS 0.2.3, copyright (c) 2002-4 Tim Goetze.
7 * The Dual Delay is original, using Tim's delay and filter
8 * objects.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be
16 * useful, but WITHOUT ANY WARRANTY; without even the implied
17 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
18 * PURPOSE. See the GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public
21 * License along with this program; if not, write to the Free
22 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301 USA.
24 */
25
26 #define _BSD_SOURCE 1
27 #define _SVID_SOURCE 1
28 #define _ISOC99_SOURCE 1
29
30 #include <string.h>
31 #include <math.h>
32
33 #include <ladspa.h>
34
35 #include "whysynth_types.h"
36 #include "dssp_event.h"
37 #include "effects.h"
38 #include "effect_reverb.h"
39
40 /* ==== Plate Reverb ==== */
41
42 static float _Plate_l[] = {
43 0.004771345048889486, 0.0035953092974026408,
44 0.01273478713752898, 0.0093074829474816042,
45 0.022579886428547427, 0.030509727495715868,
46 0.14962534861059779, 0.060481838647894894, 0.12499579987231611,
47 0.14169550754342933, 0.089244313027116023, 0.10628003091293972
48 };
49
50 static float _Plate_t[] = {
51 0.0089378717113000241, 0.099929437854910791, 0.064278754074123853,
52 0.067067638856221232, 0.066866032727394914, 0.006283391015086859,
53 0.01186116057928161, 0.12187090487550822, 0.041262054366452743,
54 0.089815530392123921, 0.070931756325392295, 0.011256342192802662
55 };
56
57 void
effect_reverb_request_buffers(y_synth_t * synth)58 effect_reverb_request_buffers(y_synth_t *synth)
59 {
60 struct Plate *plate = (struct Plate *)effects_request_buffer(synth, sizeof(struct Plate));
61 int i;
62
63 memset(plate, 0, sizeof(struct Plate));
64
65 plate->fs = (double)synth->sample_rate;
66
67 effects_request_silencing_of_subsequent_allocations(synth);
68
69 # define L(i) ((int) (_Plate_l[i] * plate->fs))
70 /* lh */
71 Delay_init(&plate->input.lattice[0], synth, L(0));
72 Delay_init(&plate->input.lattice[1], synth, L(1));
73
74 /* rh */
75 Delay_init(&plate->input.lattice[2], synth, L(2));
76 Delay_init(&plate->input.lattice[3], synth, L(3));
77
78 /* modulated, width about 12 samples @ 44.1 */
79 ModLattice_init(&plate->tank.mlattice[0], synth, L(4), (int) (0.00040322707570310132 * plate->fs));
80 ModLattice_init(&plate->tank.mlattice[1], synth, L(5), (int) (0.00040322707570310132 * plate->fs));
81
82 /* lh */
83 Delay_init(&plate->tank.delay[0], synth, L(6));
84 Delay_init(&plate->tank.lattice[0], synth, L(7));
85 Delay_init(&plate->tank.delay[1], synth, L(8));
86
87 /* rh */
88 Delay_init(&plate->tank.delay[2], synth, L(9));
89 Delay_init(&plate->tank.lattice[1], synth, L(10));
90 Delay_init(&plate->tank.delay[3], synth, L(11));
91 # undef L
92
93 # define T(i) ((int) (_Plate_t[i] * plate->fs))
94
95 for (i = 0; i < 12; ++i)
96 plate->tank.taps[i] = T(i);
97 # undef T
98
99 /* tuned for soft attack, ambience */
100 plate->indiff1 = .742;
101 plate->indiff2 = .712;
102
103 plate->dediff1 = .723;
104 plate->dediff2 = .729;
105 }
106
effect_reverb_setup(y_synth_t * synth)107 void effect_reverb_setup(y_synth_t *synth)
108 {
109 struct Plate *plate = (struct Plate *)synth->effect_buffer;
110 int i;
111
112 OnePoleLP_reset(&plate->input.bandwidth);
113
114 for (i = 0; i < 4; ++i)
115 {
116 Delay_reset(&plate->input.lattice[i]);
117 Delay_reset(&plate->tank.delay[i]);
118 }
119
120 for (i = 0; i < 2; ++i)
121 {
122 ModLattice_reset(&plate->tank.mlattice[i]);
123 Delay_reset(&plate->tank.lattice[i]);
124 OnePoleLP_reset(&plate->tank.damping[i]);
125 }
126
127 Sine_set_f3(&plate->tank.mlattice[0].lfo, 1.2, plate->fs, 0);
128 Sine_set_f3(&plate->tank.mlattice[1].lfo, 1.2, plate->fs, .5 * M_PI);
129 }
130
131 static inline void
Plate_process(struct Plate * plate,float x,float decay,float * _xl,float * _xr)132 Plate_process (struct Plate *plate, float x, float decay, float * _xl, float * _xr)
133 {
134 register float xl, xr;
135
136 x = OnePoleLP_process(&plate->input.bandwidth, x);
137
138 /* lh */
139 x = Lattice_process(&plate->input.lattice[0], x, plate->indiff1);
140 x = Lattice_process(&plate->input.lattice[1], x, plate->indiff1);
141
142 /* rh */
143 x = Lattice_process(&plate->input.lattice[2], x, plate->indiff2);
144 x = Lattice_process(&plate->input.lattice[3], x, plate->indiff2);
145
146 /* summation point */
147 xl = x + decay * Delay_get(&plate->tank.delay[3]);
148 xr = x + decay * Delay_get(&plate->tank.delay[1]);
149
150 /* lh */
151 xl = ModLattice_process(&plate->tank.mlattice[0], xl, plate->dediff1);
152 xl = Delay_putget(&plate->tank.delay[0], xl);
153 xl = OnePoleLP_process(&plate->tank.damping[0], xl);
154 xl *= decay;
155 xl = Lattice_process(&plate->tank.lattice[0], xl, plate->dediff2);
156 Delay_put(&plate->tank.delay[1], xl);
157
158 /* rh */
159 xr = ModLattice_process(&plate->tank.mlattice[1], xr, plate->dediff1);
160 xr = Delay_putget(&plate->tank.delay[2], xr);
161 xr = OnePoleLP_process(&plate->tank.damping[1], xr);
162 xr *= decay;
163 xr = Lattice_process(&plate->tank.lattice[1], xr, plate->dediff2);
164 Delay_put(&plate->tank.delay[3], xr);
165
166 /* gather output */
167 xl = .6 * Delay_peek(&plate->tank.delay[2], plate->tank.taps[0]);
168 xl += .6 * Delay_peek(&plate->tank.delay[2], plate->tank.taps[1]);
169 xl -= .6 * Delay_peek(&plate->tank.lattice[1], plate->tank.taps[2]);
170 xl += .6 * Delay_peek(&plate->tank.delay[3], plate->tank.taps[3]);
171 xl -= .6 * Delay_peek(&plate->tank.delay[0], plate->tank.taps[4]);
172 xl += .6 * Delay_peek(&plate->tank.lattice[0], plate->tank.taps[5]);
173
174 xr = .6 * Delay_peek(&plate->tank.delay[0], plate->tank.taps[6]);
175 xr += .6 * Delay_peek(&plate->tank.delay[0], plate->tank.taps[7]);
176 xr -= .6 * Delay_peek(&plate->tank.lattice[0], plate->tank.taps[8]);
177 xr += .6 * Delay_peek(&plate->tank.delay[1], plate->tank.taps[9]);
178 xr -= .6 * Delay_peek(&plate->tank.delay[2], plate->tank.taps[10]);
179 xr += .6 * Delay_peek(&plate->tank.lattice[1], plate->tank.taps[11]);
180
181 *_xl = xl;
182 *_xr = xr;
183 }
184
185 void
effect_reverb_process(y_synth_t * synth,unsigned long frames,LADSPA_Data * out_left,LADSPA_Data * out_right)186 effect_reverb_process(y_synth_t *synth, unsigned long frames,
187 LADSPA_Data *out_left, LADSPA_Data *out_right)
188 {
189 struct Plate *plate = (struct Plate *)synth->effect_buffer;
190 double d, damp;
191 float decay, blend, dry;
192 int i;
193
194 blend = *(synth->effect_mix);
195 dry = 1.0f - blend;
196
197 /* originally:
198 * d = *(synth->effect_param4) * 0.994f + 0.005f;
199 * OnePoleLP_set(&plate->input.bandwidth, exp(-M_PI * (1. - d)));
200 * a quick approximation of the above: */
201 d = *(synth->effect_param4);
202 d = ((1.26595 * d - 0.614577) * d + 0.305691) * d + 0.0422856;
203 OnePoleLP_set(&plate->input.bandwidth, d); /* "bandwidth" */
204
205 decay = *(synth->effect_param5) * 0.749f; /* "tail" */
206
207 d = *(synth->effect_param6) * 0.9995f + 0.0005f;
208 damp = exp(-M_PI * d); /* "damping" */
209 OnePoleLP_set(&plate->tank.damping[0], damp);
210 OnePoleLP_set(&plate->tank.damping[1], damp);
211
212 for (i = 0; i < frames; ++i)
213 {
214 float sl, sr, x, xl, xr;
215
216 /* DC blocker */
217 sl = synth->voice_bus_l[i] - synth->dc_block_l_xnm1 +
218 synth->dc_block_r * synth->dc_block_l_ynm1;
219 synth->dc_block_l_ynm1 = sl;
220 synth->dc_block_l_xnm1 = synth->voice_bus_l[i];
221 sr = synth->voice_bus_r[i] - synth->dc_block_r_xnm1 +
222 synth->dc_block_r * synth->dc_block_r_ynm1;
223 synth->dc_block_r_ynm1 = sr;
224 synth->dc_block_r_xnm1 = synth->voice_bus_r[i];
225
226 /* Plate2x2 reverb */
227 x = (sl + sr) * 0.5f;
228
229 Plate_process (plate, x, decay, &xl, &xr);
230
231 out_left[i] = blend * xl + dry * sl;
232 out_right[i] = blend * xr + dry * sr;
233 }
234 }
235
236 /* ==== Dual Delay ==== */
237
238 void
effect_delay_request_buffers(y_synth_t * synth)239 effect_delay_request_buffers(y_synth_t *synth)
240 {
241 struct DualDelay *delay = (struct DualDelay *)effects_request_buffer(synth, sizeof(struct DualDelay));
242
243 memset(delay, 0, sizeof(struct DualDelay));
244
245 delay->max_delay = lrintf(2.0f * synth->sample_rate);
246
247 effects_request_silencing_of_subsequent_allocations(synth);
248
249 /* !FIX! buffers actually allocated are next power of two, which wastes a good chunk of memory
250 * (like 334k to 548k; it's okay for the reverb because the buffers are relatively small, but
251 * here they're much larger.) */
252 Delay_init(&delay->delay_l, synth, delay->max_delay);
253 Delay_init(&delay->delay_r, synth, delay->max_delay);
254 }
255
effect_delay_setup(y_synth_t * synth)256 void effect_delay_setup(y_synth_t *synth)
257 {
258 struct DualDelay *delay = (struct DualDelay *)synth->effect_buffer;
259
260 Delay_reset(&delay->delay_l);
261 Delay_reset(&delay->delay_r);
262 OnePoleLP_reset(&delay->damping_l);
263 OnePoleLP_reset(&delay->damping_r);
264 }
265
266 void
effect_delay_process(y_synth_t * synth,unsigned long frames,LADSPA_Data * out_left,LADSPA_Data * out_right)267 effect_delay_process(y_synth_t *synth, unsigned long frames,
268 LADSPA_Data *out_left, LADSPA_Data *out_right)
269 {
270 struct DualDelay *delay = (struct DualDelay *)synth->effect_buffer;
271 float wet, dry, fb, fa, fia, damping;
272 int i, delay_l, delay_r;
273
274 wet = *(synth->effect_mix);
275 dry = 1.0f - wet;
276
277 fb = *(synth->effect_param2);
278 fa = *(synth->effect_param3);
279 fia = 1.0f - fa;
280
281 delay_l = lrintf(*(synth->effect_param4) * 2.0f * synth->sample_rate);
282 if (delay_l < 1) delay_l = 1;
283 else if (delay_l > delay->max_delay) delay_l = delay->max_delay;
284 delay_r = lrintf(*(synth->effect_param5) * 2.0f * synth->sample_rate);
285 if (delay_r < 1) delay_r = 1;
286 else if (delay_r > delay->max_delay) delay_r = delay->max_delay;
287
288 damping = *(synth->effect_param6);
289 if (damping < 1e-3) {
290
291 for (i = 0; i < frames; ++i) {
292 float sl, sr, il, ir, xl, xr;
293
294 /* DC blocker */
295 sl = synth->voice_bus_l[i] - synth->dc_block_l_xnm1 +
296 synth->dc_block_r * synth->dc_block_l_ynm1;
297 synth->dc_block_l_ynm1 = sl;
298 synth->dc_block_l_xnm1 = synth->voice_bus_l[i];
299 sr = synth->voice_bus_r[i] - synth->dc_block_r_xnm1 +
300 synth->dc_block_r * synth->dc_block_r_ynm1;
301 synth->dc_block_r_ynm1 = sr;
302 synth->dc_block_r_xnm1 = synth->voice_bus_r[i];
303
304 /* Dual delay */
305 xl = Delay_peek(&delay->delay_l, delay_l);
306 xr = Delay_peek(&delay->delay_r, delay_r);
307 il = sl + xl * fb;
308 ir = sr + xr * fb;
309 Delay_put(&delay->delay_l, fia * il + fa * ir);
310 Delay_put(&delay->delay_r, fia * ir + fa * il);
311
312 out_left[i] = wet * xl + dry * sl;
313 out_right[i] = wet * xr + dry * sr;
314 }
315 } else {
316
317 damping = exp(-M_PI * (damping * 0.9995f + 0.0005f));
318 OnePoleLP_set(&delay->damping_l, damping);
319 OnePoleLP_set(&delay->damping_r, damping);
320
321 for (i = 0; i < frames; ++i) {
322 float sl, sr, il, ir, xl, xr;
323
324 /* DC blocker */
325 sl = synth->voice_bus_l[i] - synth->dc_block_l_xnm1 +
326 synth->dc_block_r * synth->dc_block_l_ynm1;
327 synth->dc_block_l_ynm1 = sl;
328 synth->dc_block_l_xnm1 = synth->voice_bus_l[i];
329 sr = synth->voice_bus_r[i] - synth->dc_block_r_xnm1 +
330 synth->dc_block_r * synth->dc_block_r_ynm1;
331 synth->dc_block_r_ynm1 = sr;
332 synth->dc_block_r_xnm1 = synth->voice_bus_r[i];
333
334 /* Dual delay */
335 xl = Delay_peek(&delay->delay_l, delay_l);
336 xr = Delay_peek(&delay->delay_r, delay_r);
337 il = sl + xl * fb;
338 ir = sr + xr * fb;
339 il = OnePoleLP_process(&delay->damping_l, il);
340 ir = OnePoleLP_process(&delay->damping_r, ir);
341 Delay_put(&delay->delay_l, fia * il + fa * ir);
342 Delay_put(&delay->delay_r, fia * ir + fa * il);
343
344 out_left[i] = wet * xl + dry * sl;
345 out_right[i] = wet * xr + dry * sr;
346 }
347 }
348 }
349
350