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
25 #include <calf/giface.h>
26 #include <calf/modules_delay.h>
27 #include <calf/modules_dev.h>
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()
44 void reverb_audio_module::deactivate()
48 void reverb_audio_module::set_sample_rate(uint32_t 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
)
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
) {
94 meters
.fall(numsamples
);
95 reverb
.extra_sanitize();
100 float values
[] = {meter_wet
, meter_out
};
101 meters
.process(values
);
105 /**********************************************************************
106 * VINTAGE DELAY by Krzysztof Foltman
107 **********************************************************************/
109 vintage_delay_audio_module::vintage_delay_audio_module()
112 for (int i
= 0; i
< MAX_DELAY
; i
++) {
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
]);
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
]);
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
]);
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
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
]);
161 chmix
.set_inertia((1 - *params
[par_width
]) * 0.5);
162 if (medium
!= old_medium
)
166 void vintage_delay_audio_module::activate()
172 void vintage_delay_audio_module::deactivate()
176 void vintage_delay_audio_module::set_sample_rate(uint32_t sr
)
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
) {
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
) {
224 out
= delayed_value
* amt
.get();
225 del
= dry_value
+ delayed_value_for_fb
* fb
.get();
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
;
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());
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);
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());
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
)
288 bufptr
= orig_bufptr
;
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();
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();
313 /**********************************************************************
314 * COMPENSATION DELAY LINE by Vladimir Sadovnikov
315 **********************************************************************/
317 comp_delay_audio_module::comp_delay_audio_module()
325 comp_delay_audio_module::~comp_delay_audio_module()
331 void comp_delay_audio_module::params_changed()
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()
348 void comp_delay_audio_module::deactivate()
352 void comp_delay_audio_module::set_sample_rate(uint32_t 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
)
362 float *new_buf
= new float[new_buf_size
];
363 for (size_t i
=0; i
<new_buf_size
; i
++)
366 // Assign new pointer and size
368 buf_size
= new_buf_size
;
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
];
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
;
405 /**********************************************************************
406 * HAAS enhancer by Vladimir Sadovnikov
407 **********************************************************************/
409 haas_enhancer_audio_module::haas_enhancer_audio_module()
425 haas_enhancer_audio_module::~haas_enhancer_audio_module()
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()
454 void haas_enhancer_audio_module::deactivate()
458 void haas_enhancer_audio_module::set_sample_rate(uint32_t 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
)
468 float *new_buf
= new float[new_buf_size
];
469 for (size_t i
=0; i
<new_buf_size
; i
++)
472 // Assign new pointer and size
474 buf_size
= new_buf_size
;
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
;
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};
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;
512 buffer
[w_ptr
] = mid
* *params
[param_level_in
];
515 outs
[0][offset
] = ins
[0][offset
];
516 outs
[1][offset
] = ins
[1][offset
];
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
;
523 mid
= mid
* *params
[param_level_in
];
524 if (*params
[par_m_phase
] > 0.5f
)
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
];
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
;
548 bypass
.crossfade(ins
, outs
, 2, off_
, end
);
550 meters
.fall(numsamples
);