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
* 2);
358 uint32_t new_buf_size
= 2;
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 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
378 bool stereo
= ins
[1];
379 uint32_t w_ptr
= write_ptr
;
380 uint32_t b_mask
= buf_size
- 2;
381 uint32_t end
= offset
+ numsamples
;
382 uint32_t off
= offset
;
385 while(offset
< end
) {
386 outs
[0][offset
] = ins
[0][offset
];
387 buffer
[w_ptr
] = ins
[0][offset
];
389 outs
[1][offset
] = ins
[1][offset
];
390 buffer
[w_ptr
+ 1] = ins
[1][offset
];
391 w_ptr
= (w_ptr
+ 2) & b_mask
;
395 uint32_t r_ptr
= (write_ptr
+ buf_size
- delay
) & b_mask
; // Unsigned math, that's why we add buf_size
396 float dry
= *params
[par_dry
];
397 float wet
= *params
[par_wet
];
400 for (uint32_t i
=offset
; i
<end
; i
++)
404 outs
[0][i
] = dry
* L
+ wet
* buffer
[r_ptr
];
407 buffer
[w_ptr
+ 1] = R
;
408 outs
[1][i
] = dry
* R
+ wet
* buffer
[r_ptr
+ 1];
410 w_ptr
= (w_ptr
+ 2) & b_mask
;
411 r_ptr
= (r_ptr
+ 2) & b_mask
;
415 bypass
.crossfade(ins
, outs
, stereo
? 2 : 1, off
, numsamples
);
420 /**********************************************************************
421 * HAAS enhancer by Vladimir Sadovnikov
422 **********************************************************************/
424 haas_enhancer_audio_module::haas_enhancer_audio_module()
440 haas_enhancer_audio_module::~haas_enhancer_audio_module()
449 void haas_enhancer_audio_module::params_changed()
451 m_source
= (uint32_t)(*params
[par_m_source
]);
452 s_delay
[0] = (uint32_t)(*params
[par_s_delay0
] * 0.001 * srate
);
453 s_delay
[1] = (uint32_t)(*params
[par_s_delay1
] * 0.001 * srate
);
455 float phase0
= ((*params
[par_s_phase0
]) > 0.5f
) ? 1.0f
: -1.0f
;
456 float phase1
= ((*params
[par_s_phase1
]) > 0.5f
) ? 1.0f
: -1.0f
;
458 s_bal_l
[0] = (*params
[par_s_balance0
] + 1) / 2 * (*params
[par_s_gain0
]) * phase0
;
459 s_bal_r
[0] = (1.0 - (*params
[par_s_balance0
] + 1) / 2) * (*params
[par_s_gain0
]) * phase0
;
460 s_bal_l
[1] = (*params
[par_s_balance1
] + 1) / 2 * (*params
[par_s_gain1
]) * phase1
;
461 s_bal_r
[1] = (1.0 - (*params
[par_s_balance1
] + 1) / 2) * (*params
[par_s_gain1
]) * phase1
;
464 void haas_enhancer_audio_module::activate()
469 void haas_enhancer_audio_module::deactivate()
473 void haas_enhancer_audio_module::set_sample_rate(uint32_t sr
)
476 float *old_buf
= buffer
;
478 uint32_t min_buf_size
= (uint32_t)(srate
* HAAS_ENHANCER_MAX_DELAY
);
479 uint32_t new_buf_size
= 1;
480 while (new_buf_size
< min_buf_size
)
483 float *new_buf
= new float[new_buf_size
];
484 for (size_t i
=0; i
<new_buf_size
; i
++)
487 // Assign new pointer and size
489 buf_size
= new_buf_size
;
495 int meter
[] = {param_meter_inL
, param_meter_inR
, param_meter_outL
, param_meter_outR
, param_meter_sideL
, param_meter_sideR
};
496 int clip
[] = {param_clip_inL
, param_clip_inR
, param_clip_outL
, param_clip_outR
, -1, -1};
497 meters
.init(params
, meter
, clip
, 6, srate
);
500 uint32_t haas_enhancer_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
502 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
503 uint32_t end
= offset
+ numsamples
;
504 uint32_t off_
= offset
;
505 uint32_t w_ptr
= write_ptr
;
508 float mid
, side
[2], side_l
, side_r
;
509 // Boundaries and pointers
510 uint32_t b_mask
= buf_size
-1;
512 while(offset
< end
) {
513 float values
[] = {0, 0, 0, 0, 0, 0};
519 case 0: mid
= ins
[0][offset
]; break;
520 case 1: mid
= ins
[1][offset
]; break;
521 case 2: mid
= (ins
[0][offset
] + ins
[1][offset
]) * 0.5f
; break;
522 case 3: mid
= (ins
[0][offset
] - ins
[1][offset
]) * 0.5f
; break;
527 buffer
[w_ptr
] = mid
* *params
[param_level_in
];
530 outs
[0][offset
] = ins
[0][offset
];
531 outs
[1][offset
] = ins
[1][offset
];
533 // Delays for mid and side. Unsigned math, that's why we add buf_size
534 uint32_t s0_ptr
= (w_ptr
+ buf_size
- s_delay
[0]) & b_mask
;
535 uint32_t s1_ptr
= (w_ptr
+ buf_size
- s_delay
[1]) & b_mask
;
538 mid
= mid
* *params
[param_level_in
];
539 if (*params
[par_m_phase
] > 0.5f
)
541 side
[0] = buffer
[s0_ptr
] * (*params
[par_s_gain
]);
542 side
[1] = buffer
[s1_ptr
] * (*params
[par_s_gain
]);
543 side_l
= side
[0] * s_bal_l
[0] - side
[1] * s_bal_l
[1];
544 side_r
= side
[1] * s_bal_r
[1] - side
[0] * s_bal_r
[0];
546 // Output stereo image
547 outs
[0][offset
] = (mid
+ side_l
) * *params
[param_level_out
];
548 outs
[1][offset
] = (mid
+ side_r
) * *params
[param_level_out
];
551 s0_ptr
= (s0_ptr
+ 1) & b_mask
;
552 s1_ptr
= (s1_ptr
+ 1) & b_mask
;
554 *p
++ = ins
[0][offset
]; *p
++ = ins
[1][offset
];
555 *p
++ = outs
[0][offset
]; *p
++ = outs
[1][offset
];
556 *p
++ = side_l
; *p
++ = side_r
;
558 meters
.process (values
);
559 w_ptr
= (w_ptr
+ 1) & b_mask
;
563 bypass
.crossfade(ins
, outs
, 2, off_
, numsamples
);
565 meters
.fall(numsamples
);
569 /**********************************************************************
571 **********************************************************************/
573 reverse_delay_audio_module::reverse_delay_audio_module()
575 for (int i
= 0; i
< MAX_DELAY
; i
++) {
587 void reverse_delay_audio_module::params_changed()
589 if (*params
[par_sync
] > 0.5f
)
590 *params
[par_bpm
] = *params
[par_bpm_host
];
592 //Max delay line length: (60*192000/30)*16 = 6144000, see buffers declaration
593 float unit
= 60.0 * srate
/ (*params
[par_bpm
] * *params
[par_divide
]);
594 deltime_l
= dsp::fastf2i_drm(unit
* *params
[par_time_l
]);
595 deltime_r
= dsp::fastf2i_drm(unit
* *params
[par_time_r
]);
597 fb_val
.set_inertia(*params
[par_feedback
]);
598 dry
.set_inertia(*params
[par_amount
]);
603 ow
[0].set_coef((*params
[par_window
] + 0.005), deltime_l
/2);
604 ow
[1].set_coef((*params
[par_window
] + 0.005), deltime_r
/2);
606 width
.set_inertia(*params
[par_width
]);
608 //Cleanup delay line buffers if reset
609 if(*params
[par_reset
])
611 for (int i
= 0; i
< MAX_DELAY
; i
++) {
621 void reverse_delay_audio_module::activate()
625 void reverse_delay_audio_module::deactivate()
629 void reverse_delay_audio_module::set_sample_rate(uint32_t sr
)
632 fb_val
.set_sample_rate(sr
);
633 dry
.set_sample_rate(sr
);
634 width
.set_sample_rate(sr
);
637 static float reverse_delay_line_impl(float in
, float* buf
, int* counter
, int length
)
642 if(*counter
< length
- 1)
644 unsigned int read_counter
= length
- 1 - (*counter
);
645 out
= buf
[read_counter
];
649 *(buf
+ (*counter
)) = in
;
651 if ((*counter
) > length
-1)
657 uint32_t reverse_delay_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
660 uint32_t ostate
= 3; // XXXKF optimize!
661 uint32_t end
= offset
+ numsamples
;
664 for(uint32_t i
= offset
; i
< end
; i
++)
667 if(counters
[0] < deltime_l
/4)
668 *params
[par_sync_led_l
] = true;
670 *params
[par_sync_led_l
] = false;
672 if(counters
[1] < deltime_r
/4)
673 *params
[par_sync_led_r
] = true;
675 *params
[par_sync_led_r
] = false;
678 float feedback_val
= fb_val
.get();
679 float st_width_val
= width
.get();
681 float inL
= ins
[0][i
] + st_width_val
*ins
[1][i
];
682 float inR
= ins
[1][i
]*(1 - st_width_val
);
687 inL
= inL
+ feedback_buf
[0]* feedback_val
*(1 - st_width_val
) + feedback_buf
[1]* st_width_val
*feedback_val
;
688 inR
= inR
+ feedback_buf
[1]* feedback_val
*(1 - st_width_val
) + feedback_buf
[0]* st_width_val
*feedback_val
;
690 outL
= reverse_delay_line_impl(inL
, &buffers
[0][0], &counters
[0], deltime_l
);
691 outR
= reverse_delay_line_impl(inR
, &buffers
[1][0], &counters
[1], deltime_r
);
692 feedback_buf
[0] = outL
;
693 feedback_buf
[1] = outR
;
698 outL
= outL
*(1 + dry
.get()) + inL
*(1 - dry
.get());
699 outR
= outR
*(1 + dry
.get()) + inR
*(1 - dry
.get());