Haas Enhancer: mid phase switch
[calf.git] / src / modules_delay.cpp
blob7ca4be1961daf9071b80015d49af385f06f4f305
1 /* Calf DSP plugin pack
2 * Modulation effect plugins
4 * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA
22 #include <limits.h>
23 #include <memory.h>
24 #include <math.h>
25 #include <calf/giface.h>
26 #include <calf/modules_delay.h>
27 #include <calf/modules_dev.h>
28 #include <sys/time.h>
30 using namespace dsp;
31 using namespace calf_plugins;
33 #define SET_IF_CONNECTED(name) if (params[AM::param_##name] != NULL) *params[AM::param_##name] = name;
35 /**********************************************************************
36 * REVERB by Krzysztof Foltman
37 **********************************************************************/
39 void reverb_audio_module::activate()
41 reverb.reset();
44 void reverb_audio_module::deactivate()
48 void reverb_audio_module::set_sample_rate(uint32_t sr)
50 srate = sr;
51 reverb.setup(sr);
52 amount.set_sample_rate(sr);
53 int meter[] = {par_meter_wet, par_meter_out};
54 int clip[] = {-1, par_clip};
55 meters.init(params, meter, clip, 2, srate);
58 void reverb_audio_module::params_changed()
60 reverb.set_type_and_diffusion(fastf2i_drm(*params[par_roomsize]), *params[par_diffusion]);
61 reverb.set_time(*params[par_decay]);
62 reverb.set_cutoff(*params[par_hfdamp]);
63 amount.set_inertia(*params[par_amount]);
64 dryamount.set_inertia(*params[par_dry]);
65 left_lo.set_lp(dsp::clip(*params[par_treblecut], 20.f, (float)(srate * 0.49f)), srate);
66 left_hi.set_hp(dsp::clip(*params[par_basscut], 20.f, (float)(srate * 0.49f)), srate);
67 right_lo.copy_coeffs(left_lo);
68 right_hi.copy_coeffs(left_hi);
69 predelay_amt = (int) (srate * (*params[par_predelay]) * (1.0f / 1000.0f) + 1);
72 uint32_t reverb_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
74 numsamples += offset;
75 clip -= std::min(clip, numsamples);
76 for (uint32_t i = offset; i < numsamples; i++) {
77 float dry = dryamount.get();
78 float wet = amount.get();
79 stereo_sample<float> s(ins[0][i], ins[1][i]);
80 stereo_sample<float> s2 = pre_delay.process(s, predelay_amt);
82 float rl = s2.left, rr = s2.right;
83 rl = left_lo.process(left_hi.process(rl));
84 rr = right_lo.process(right_hi.process(rr));
85 reverb.process(rl, rr);
86 outs[0][i] = dry*s.left + wet*rl;
87 outs[1][i] = dry*s.right + wet*rr;
88 meter_wet = std::max(fabs(wet*rl), fabs(wet*rr));
89 meter_out = std::max(fabs(outs[0][i]), fabs(outs[1][i]));
90 if(outs[0][i] > 1.f or outs[1][i] > 1.f) {
91 clip = srate >> 3;
94 meters.fall(numsamples);
95 reverb.extra_sanitize();
96 left_lo.sanitize();
97 left_hi.sanitize();
98 right_lo.sanitize();
99 right_hi.sanitize();
100 float values[] = {meter_wet, meter_out};
101 meters.process(values);
102 return outputs_mask;
105 /**********************************************************************
106 * VINTAGE DELAY by Krzysztof Foltman
107 **********************************************************************/
109 vintage_delay_audio_module::vintage_delay_audio_module()
111 old_medium = -1;
112 for (int i = 0; i < MAX_DELAY; i++) {
113 buffers[0][i] = 0.f;
114 buffers[1][i] = 0.f;
116 _tap_avg = 0;
117 _tap_last = 0;
120 void vintage_delay_audio_module::params_changed()
122 if (*params[par_sync] > 0.5f)
123 *params[par_bpm] = *params[par_bpm_host];
124 float unit = 60.0 * srate / (*params[par_bpm] * *params[par_divide]);
125 deltime_l = dsp::fastf2i_drm(unit * *params[par_time_l]);
126 deltime_r = dsp::fastf2i_drm(unit * *params[par_time_r]);
127 int deltime_fb = deltime_l + deltime_r;
128 float fb = *params[par_feedback];
129 dry.set_inertia(*params[par_dryamount]);
130 mixmode = dsp::fastf2i_drm(*params[par_mixmode]);
131 medium = dsp::fastf2i_drm(*params[par_medium]);
132 switch(mixmode)
134 case MIXMODE_STEREO:
135 fb_left.set_inertia(fb);
136 fb_right.set_inertia(pow(fb, *params[par_time_r] / *params[par_time_l]));
137 amt_left.set_inertia(*params[par_amount]);
138 amt_right.set_inertia(*params[par_amount]);
139 break;
140 case MIXMODE_PINGPONG:
141 fb_left.set_inertia(fb);
142 fb_right.set_inertia(fb);
143 amt_left.set_inertia(*params[par_amount]);
144 amt_right.set_inertia(*params[par_amount]);
145 break;
146 case MIXMODE_LR:
147 fb_left.set_inertia(fb);
148 fb_right.set_inertia(fb);
149 amt_left.set_inertia(*params[par_amount]); // L is straight 'amount'
150 amt_right.set_inertia(*params[par_amount] * pow(fb, 1.0 * deltime_r / deltime_fb)); // R is amount with feedback based dampening as if it ran through R/FB*100% of delay line's dampening
151 // deltime_l <<< deltime_r -> pow() = fb -> full delay line worth of dampening
152 // deltime_l >>> deltime_r -> pow() = 1 -> no dampening
153 break;
154 case MIXMODE_RL:
155 fb_left.set_inertia(fb);
156 fb_right.set_inertia(fb);
157 amt_left.set_inertia(*params[par_amount] * pow(fb, 1.0 * deltime_l / deltime_fb));
158 amt_right.set_inertia(*params[par_amount]);
159 break;
161 chmix.set_inertia((1 - *params[par_width]) * 0.5);
162 if (medium != old_medium)
163 calc_filters();
166 void vintage_delay_audio_module::activate()
168 bufptr = 0;
169 age = 0;
172 void vintage_delay_audio_module::deactivate()
176 void vintage_delay_audio_module::set_sample_rate(uint32_t sr)
178 srate = sr;
179 old_medium = -1;
180 amt_left.set_sample_rate(sr); amt_right.set_sample_rate(sr);
181 fb_left.set_sample_rate(sr); fb_right.set_sample_rate(sr);
184 void vintage_delay_audio_module::calc_filters()
186 // parameters are heavily influenced by gordonjcp and his tape delay unit
187 // although, don't blame him if it sounds bad - I've messed with them too :)
188 biquad_left[0].set_lp_rbj(6000, 0.707, srate);
189 biquad_left[1].set_bp_rbj(4500, 0.250, srate);
190 biquad_right[0].copy_coeffs(biquad_left[0]);
191 biquad_right[1].copy_coeffs(biquad_left[1]);
194 /// Single delay line with feedback at the same tap
195 static inline void delayline_impl(int age, int deltime, float dry_value, const float &delayed_value, float &out, float &del, gain_smoothing &amt, gain_smoothing &fb)
197 // if the buffer hasn't been cleared yet (after activation), pretend we've read zeros
198 if (age <= deltime) {
199 out = 0;
200 del = dry_value;
201 amt.step();
202 fb.step();
204 else
206 float delayed = delayed_value; // avoid dereferencing the pointer in 'then' branch of the if()
207 dsp::sanitize(delayed);
208 out = delayed * amt.get();
209 del = dry_value + delayed * fb.get();
213 /// Single delay line with tap output
214 static inline void delayline2_impl(int age, int deltime, float dry_value, const float &delayed_value, const float &delayed_value_for_fb, float &out, float &del, gain_smoothing &amt, gain_smoothing &fb)
216 if (age <= deltime) {
217 out = 0;
218 del = dry_value;
219 amt.step();
220 fb.step();
222 else
224 out = delayed_value * amt.get();
225 del = dry_value + delayed_value_for_fb * fb.get();
226 dsp::sanitize(out);
227 dsp::sanitize(del);
231 static inline void delay_mix(float dry_left, float dry_right, float &out_left, float &out_right, float dry, float chmix)
233 float tmp_left = lerp(out_left, out_right, chmix);
234 float tmp_right = lerp(out_right, out_left, chmix);
235 out_left = dry_left * dry + tmp_left;
236 out_right = dry_right * dry + tmp_right;
239 uint32_t vintage_delay_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
241 uint32_t ostate = 3; // XXXKF optimize!
242 uint32_t end = offset + numsamples;
243 int orig_bufptr = bufptr;
244 float out_left, out_right, del_left, del_right;
246 switch(mixmode)
248 case MIXMODE_STEREO:
249 case MIXMODE_PINGPONG:
251 int v = mixmode == MIXMODE_PINGPONG ? 1 : 0;
252 for(uint32_t i = offset; i < end; i++)
254 delayline_impl(age, deltime_l, ins[0][i], buffers[v][(bufptr - deltime_l) & ADDR_MASK], out_left, del_left, amt_left, fb_left);
255 delayline_impl(age, deltime_r, ins[1][i], buffers[1 - v][(bufptr - deltime_r) & ADDR_MASK], out_right, del_right, amt_right, fb_right);
256 delay_mix(ins[0][i], ins[1][i], out_left, out_right, dry.get(), chmix.get());
258 age++;
259 outs[0][i] = out_left; outs[1][i] = out_right; buffers[0][bufptr] = del_left; buffers[1][bufptr] = del_right;
260 bufptr = (bufptr + 1) & (MAX_DELAY - 1);
263 break;
265 case MIXMODE_LR:
266 case MIXMODE_RL:
268 int v = mixmode == MIXMODE_RL ? 1 : 0;
269 int deltime_fb = deltime_l + deltime_r;
270 int deltime_l_corr = mixmode == MIXMODE_RL ? deltime_fb : deltime_l;
271 int deltime_r_corr = mixmode == MIXMODE_LR ? deltime_fb : deltime_r;
273 for(uint32_t i = offset; i < end; i++)
275 delayline2_impl(age, deltime_l, ins[0][i], buffers[v][(bufptr - deltime_l_corr) & ADDR_MASK], buffers[v][(bufptr - deltime_fb) & ADDR_MASK], out_left, del_left, amt_left, fb_left);
276 delayline2_impl(age, deltime_r, ins[1][i], buffers[1 - v][(bufptr - deltime_r_corr) & ADDR_MASK], buffers[1-v][(bufptr - deltime_fb) & ADDR_MASK], out_right, del_right, amt_right, fb_right);
277 delay_mix(ins[0][i], ins[1][i], out_left, out_right, dry.get(), chmix.get());
279 age++;
280 outs[0][i] = out_left; outs[1][i] = out_right; buffers[0][bufptr] = del_left; buffers[1][bufptr] = del_right;
281 bufptr = (bufptr + 1) & (MAX_DELAY - 1);
285 if (age >= MAX_DELAY)
286 age = MAX_DELAY;
287 if (medium > 0) {
288 bufptr = orig_bufptr;
289 if (medium == 2)
291 for(uint32_t i = offset; i < end; i++)
293 buffers[0][bufptr] = biquad_left[0].process_lp(biquad_left[1].process(buffers[0][bufptr]));
294 buffers[1][bufptr] = biquad_right[0].process_lp(biquad_right[1].process(buffers[1][bufptr]));
295 bufptr = (bufptr + 1) & (MAX_DELAY - 1);
297 biquad_left[0].sanitize();biquad_right[0].sanitize();
298 } else {
299 for(uint32_t i = offset; i < end; i++)
301 buffers[0][bufptr] = biquad_left[1].process(buffers[0][bufptr]);
302 buffers[1][bufptr] = biquad_right[1].process(buffers[1][bufptr]);
303 bufptr = (bufptr + 1) & (MAX_DELAY - 1);
306 biquad_left[1].sanitize();biquad_right[1].sanitize();
310 return ostate;
313 /**********************************************************************
314 * COMPENSATION DELAY LINE by Vladimir Sadovnikov
315 **********************************************************************/
317 comp_delay_audio_module::comp_delay_audio_module()
319 buffer = NULL;
320 buf_size = 0;
321 delay = 0;
322 write_ptr = 0;
325 comp_delay_audio_module::~comp_delay_audio_module()
327 if (buffer != NULL)
328 delete [] buffer;
331 void comp_delay_audio_module::params_changed()
333 delay = (uint32_t)
336 (*params[par_distance_m] * 100.0) +
337 (*params[par_distance_cm] * 1.0) +
338 (*params[par_distance_mm] * 0.1)
339 ) * COMP_DELAY_SOUND_FRONT_DELAY(std::max(50, (int) *params[param_temp])) * srate
343 void comp_delay_audio_module::activate()
345 write_ptr = 0;
348 void comp_delay_audio_module::deactivate()
352 void comp_delay_audio_module::set_sample_rate(uint32_t sr)
354 srate = sr;
355 float *old_buf = buffer;
357 uint32_t min_buf_size = (uint32_t)(srate * COMP_DELAY_MAX_DELAY);
358 uint32_t new_buf_size = 1;
359 while (new_buf_size < min_buf_size)
360 new_buf_size <<= 1;
362 float *new_buf = new float[new_buf_size];
363 for (size_t i=0; i<new_buf_size; i++)
364 new_buf[i] = 0.0f;
366 // Assign new pointer and size
367 buffer = new_buf;
368 buf_size = new_buf_size;
370 // Delete old buffer
371 if (old_buf != NULL)
372 delete [] old_buf;
375 uint32_t comp_delay_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
377 if (*params[param_bypass] > 0.5f) {
378 while(offset < numsamples) {
379 outs[0][offset] = ins[0][offset];
380 ++offset;
382 } else {
383 uint32_t b_mask = buf_size-1;
384 uint32_t end = offset + numsamples;
385 uint32_t w_ptr = write_ptr;
386 uint32_t r_ptr = (write_ptr + buf_size - delay) & b_mask; // Unsigned math, that's why we add buf_size
387 float dry = *params[par_dry];
388 float wet = *params[par_wet];
390 for (uint32_t i=offset; i<end; i++)
392 float sample = ins[0][i];
393 buffer[w_ptr] = sample;
395 outs[0][i] = dry * sample + wet * buffer[r_ptr];
397 w_ptr = (w_ptr + 1) & b_mask;
398 r_ptr = (r_ptr + 1) & b_mask;
400 write_ptr = w_ptr;
402 return outputs_mask;
405 /**********************************************************************
406 * HAAS enhancer by Vladimir Sadovnikov
407 **********************************************************************/
409 haas_enhancer_audio_module::haas_enhancer_audio_module()
411 buffer = NULL;
412 srate = 0;
413 buf_size = 0;
414 write_ptr = 0;
416 m_source = 2;
417 s_delay[0] = 0;
418 s_delay[1] = 0;
419 s_bal_l[0] = 0.0f;
420 s_bal_l[1] = 0.0f;
421 s_bal_r[0] = 0.0f;
422 s_bal_r[1] = 0.0f;
425 haas_enhancer_audio_module::~haas_enhancer_audio_module()
427 if (buffer != NULL)
429 delete [] buffer;
430 buffer = NULL;
434 void haas_enhancer_audio_module::params_changed()
436 m_source = (uint32_t)(*params[par_m_source]);
437 s_delay[0] = (uint32_t)(*params[par_s_delay0] * 0.001 * srate);
438 s_delay[1] = (uint32_t)(*params[par_s_delay1] * 0.001 * srate);
440 float phase0 = ((*params[par_s_phase0]) > 0.5f) ? 1.0f : -1.0f;
441 float phase1 = ((*params[par_s_phase1]) > 0.5f) ? 1.0f : -1.0f;
443 s_bal_l[0] = (*params[par_s_balance0] + 1) / 2 * (*params[par_s_gain0]) * phase0;
444 s_bal_r[0] = (1.0 - (*params[par_s_balance0] + 1) / 2) * (*params[par_s_gain0]) * phase0;
445 s_bal_l[1] = (*params[par_s_balance1] + 1) / 2 * (*params[par_s_gain1]) * phase1;
446 s_bal_r[1] = (1.0 - (*params[par_s_balance1] + 1) / 2) * (*params[par_s_gain1]) * phase1;
449 void haas_enhancer_audio_module::activate()
451 write_ptr = 0;
454 void haas_enhancer_audio_module::deactivate()
458 void haas_enhancer_audio_module::set_sample_rate(uint32_t sr)
460 srate = sr;
461 float *old_buf = buffer;
463 uint32_t min_buf_size = (uint32_t)(srate * HAAS_ENHANCER_MAX_DELAY);
464 uint32_t new_buf_size = 1;
465 while (new_buf_size < min_buf_size)
466 new_buf_size <<= 1;
468 float *new_buf = new float[new_buf_size];
469 for (size_t i=0; i<new_buf_size; i++)
470 new_buf[i] = 0.0f;
472 // Assign new pointer and size
473 buffer = new_buf;
474 buf_size = new_buf_size;
476 // Delete old buffer
477 if (old_buf != NULL)
478 delete [] old_buf;
480 int meter[] = {param_meter_inL, param_meter_inR, param_meter_outL, param_meter_outR, param_meter_sideL, param_meter_sideR};
481 int clip[] = {param_clip_inL, param_clip_inR, param_clip_outL, param_clip_outR, -1, -1};
482 meters.init(params, meter, clip, 6, srate);
485 uint32_t haas_enhancer_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
487 bool bypassed = bypass.update(*params[param_bypass] > 0.5f, numsamples);
488 uint32_t end = offset + numsamples;
489 uint32_t off_ = offset;
490 uint32_t w_ptr = write_ptr;
492 // Sample variables
493 float mid, side[2], side_l, side_r;
494 // Boundaries and pointers
495 uint32_t b_mask = buf_size-1;
497 while(offset < end) {
498 float values[] = {0, 0, 0, 0, 0, 0};
499 float *p = values;
501 // Get middle sample
502 switch (m_source)
504 case 0: mid = ins[0][offset]; break;
505 case 1: mid = ins[1][offset]; break;
506 case 2: mid = (ins[0][offset] + ins[1][offset]) * 0.5f; break;
507 case 3: mid = (ins[0][offset] - ins[1][offset]) * 0.5f; break;
508 default: mid = 0.0f;
511 // Store middle
512 buffer[w_ptr] = mid * *params[param_level_in];
514 if (bypassed) {
515 outs[0][offset] = ins[0][offset];
516 outs[1][offset] = ins[1][offset];
517 } else {
518 // Delays for mid and side. Unsigned math, that's why we add buf_size
519 uint32_t s0_ptr = (w_ptr + buf_size - s_delay[0]) & b_mask;
520 uint32_t s1_ptr = (w_ptr + buf_size - s_delay[1]) & b_mask;
522 // Calculate side
523 mid = mid * *params[param_level_in];
524 if (*params[par_m_phase] > 0.5f)
525 mid = -mid;
526 side[0] = buffer[s0_ptr] * (*params[par_s_gain]);
527 side[1] = buffer[s1_ptr] * (*params[par_s_gain]);
528 side_l = side[0] * s_bal_l[0] - side[1] * s_bal_l[1];
529 side_r = side[1] * s_bal_r[1] - side[0] * s_bal_r[0];
531 // Output stereo image
532 outs[0][offset] = (mid + side_l) * *params[param_level_out];
533 outs[1][offset] = (mid + side_r) * *params[param_level_out];
535 // Update pointers
536 s0_ptr = (s0_ptr + 1) & b_mask;
537 s1_ptr = (s1_ptr + 1) & b_mask;
539 *p++ = ins[0][offset]; *p++ = ins[1][offset];
540 *p++ = outs[0][offset]; *p++ = outs[1][offset];
541 *p++ = side_l; *p++ = side_r;
543 meters.process (values);
544 w_ptr = (w_ptr + 1) & b_mask;
545 ++offset;
547 if (!bypassed)
548 bypass.crossfade(ins, outs, 2, off_, end);
549 write_ptr = w_ptr;
550 meters.fall(numsamples);
551 return outputs_mask;