1 /* Calf DSP plugin pack
2 * Assorted plugins
3 *
4 * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen
5 *
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.
10 *
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.
15 *
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
20 */
21 #include <limits.h>
22 #include <memory.h>
23 #include <calf/giface.h>
24 #include <calf/modules.h>
25 #include <calf/modules_dev.h>
26
27 using namespace dsp;
28 using namespace calf_plugins;
29
30 #define SET_IF_CONNECTED(name) if (params[AM::param_##name] != NULL) *params[AM::param_##name] = name;
31
32 ///////////////////////////////////////////////////////////////////////////////////////////////
33
activate()34 void reverb_audio_module::activate()
35 {
36 reverb.reset();
37 }
38
deactivate()39 void reverb_audio_module::deactivate()
40 {
41 }
42
set_sample_rate(uint32_t sr)43 void reverb_audio_module::set_sample_rate(uint32_t sr)
44 {
45 srate = sr;
46 reverb.setup(sr);
47 amount.set_sample_rate(sr);
48 }
49
params_changed()50 void reverb_audio_module::params_changed()
51 {
52 reverb.set_type_and_diffusion(fastf2i_drm(*params[par_roomsize]), *params[par_diffusion]);
53 reverb.set_time(*params[par_decay]);
54 reverb.set_cutoff(*params[par_hfdamp]);
55 amount.set_inertia(*params[par_amount]);
56 dryamount.set_inertia(*params[par_dry]);
57 left_lo.set_lp(dsp::clip(*params[par_treblecut], 20.f, (float)(srate * 0.49f)), srate);
58 left_hi.set_hp(dsp::clip(*params[par_basscut], 20.f, (float)(srate * 0.49f)), srate);
59 right_lo.copy_coeffs(left_lo);
60 right_hi.copy_coeffs(left_hi);
61 predelay_amt = (int) (srate * (*params[par_predelay]) * (1.0f / 1000.0f) + 1);
62 }
63
process(uint32_t offset,uint32_t numsamples,uint32_t inputs_mask,uint32_t outputs_mask)64 uint32_t reverb_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
65 {
66 numsamples += offset;
67 clip -= std::min(clip, numsamples);
68 for (uint32_t i = offset; i < numsamples; i++) {
69 float dry = dryamount.get();
70 float wet = amount.get();
71 stereo_sample<float> s(ins[0][i], ins[1][i]);
72 stereo_sample<float> s2 = pre_delay.process(s, predelay_amt);
73
74 float rl = s2.left, rr = s2.right;
75 rl = left_lo.process(left_hi.process(rl));
76 rr = right_lo.process(right_hi.process(rr));
77 reverb.process(rl, rr);
78 outs[0][i] = dry*s.left + wet*rl;
79 outs[1][i] = dry*s.right + wet*rr;
80 meter_wet = std::max(fabs(wet*rl), fabs(wet*rr));
81 meter_out = std::max(fabs(outs[0][i]), fabs(outs[1][i]));
82 if(outs[0][i] > 1.f or outs[1][i] > 1.f) {
83 clip = srate >> 3;
84 }
85 }
86 reverb.extra_sanitize();
87 left_lo.sanitize();
88 left_hi.sanitize();
89 right_lo.sanitize();
90 right_hi.sanitize();
91 if(params[par_meter_wet] != NULL) {
92 *params[par_meter_wet] = meter_wet;
93 }
94 if(params[par_meter_out] != NULL) {
95 *params[par_meter_out] = meter_out;
96 }
97 if(params[par_clip] != NULL) {
98 *params[par_clip] = clip;
99 }
100 return outputs_mask;
101 }
102
103 ///////////////////////////////////////////////////////////////////////////////////////////////
104
vintage_delay_audio_module()105 vintage_delay_audio_module::vintage_delay_audio_module()
106 {
107 old_medium = -1;
108 for (int i = 0; i < MAX_DELAY; i++) {
109 buffers[0][i] = 0.f;
110 buffers[1][i] = 0.f;
111 }
112 }
113
params_changed()114 void vintage_delay_audio_module::params_changed()
115 {
116 float unit = 60.0 * srate / (*params[par_bpm] * *params[par_divide]);
117 deltime_l = dsp::fastf2i_drm(unit * *params[par_time_l]);
118 deltime_r = dsp::fastf2i_drm(unit * *params[par_time_r]);
119 int deltime_fb = deltime_l + deltime_r;
120 float fb = *params[par_feedback];
121 dry.set_inertia(*params[par_dryamount]);
122 mixmode = dsp::fastf2i_drm(*params[par_mixmode]);
123 medium = dsp::fastf2i_drm(*params[par_medium]);
124 switch(mixmode)
125 {
126 case MIXMODE_STEREO:
127 fb_left.set_inertia(fb);
128 fb_right.set_inertia(pow(fb, *params[par_time_r] / *params[par_time_l]));
129 amt_left.set_inertia(*params[par_amount]);
130 amt_right.set_inertia(*params[par_amount]);
131 break;
132 case MIXMODE_PINGPONG:
133 fb_left.set_inertia(fb);
134 fb_right.set_inertia(fb);
135 amt_left.set_inertia(*params[par_amount]);
136 amt_right.set_inertia(*params[par_amount]);
137 break;
138 case MIXMODE_LR:
139 fb_left.set_inertia(fb);
140 fb_right.set_inertia(fb);
141 amt_left.set_inertia(*params[par_amount]); // L is straight 'amount'
142 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
143 // deltime_l <<< deltime_r -> pow() = fb -> full delay line worth of dampening
144 // deltime_l >>> deltime_r -> pow() = 1 -> no dampening
145 break;
146 case MIXMODE_RL:
147 fb_left.set_inertia(fb);
148 fb_right.set_inertia(fb);
149 amt_left.set_inertia(*params[par_amount] * pow(fb, 1.0 * deltime_l / deltime_fb));
150 amt_right.set_inertia(*params[par_amount]);
151 break;
152 }
153 chmix.set_inertia((1 - *params[par_width]) * 0.5);
154 if (medium != old_medium)
155 calc_filters();
156 }
157
activate()158 void vintage_delay_audio_module::activate()
159 {
160 bufptr = 0;
161 age = 0;
162 }
163
deactivate()164 void vintage_delay_audio_module::deactivate()
165 {
166 }
167
set_sample_rate(uint32_t sr)168 void vintage_delay_audio_module::set_sample_rate(uint32_t sr)
169 {
170 srate = sr;
171 old_medium = -1;
172 amt_left.set_sample_rate(sr); amt_right.set_sample_rate(sr);
173 fb_left.set_sample_rate(sr); fb_right.set_sample_rate(sr);
174 }
175
calc_filters()176 void vintage_delay_audio_module::calc_filters()
177 {
178 // parameters are heavily influenced by gordonjcp and his tape delay unit
179 // although, don't blame him if it sounds bad - I've messed with them too :)
180 biquad_left[0].set_lp_rbj(6000, 0.707, srate);
181 biquad_left[1].set_bp_rbj(4500, 0.250, srate);
182 biquad_right[0].copy_coeffs(biquad_left[0]);
183 biquad_right[1].copy_coeffs(biquad_left[1]);
184 }
185
186 /// Single delay line with feedback at the same tap
delayline_impl(int age,int deltime,float dry_value,const float & delayed_value,float & out,float & del,gain_smoothing & amt,gain_smoothing & fb)187 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)
188 {
189 // if the buffer hasn't been cleared yet (after activation), pretend we've read zeros
190 if (age <= deltime) {
191 out = 0;
192 del = dry_value;
193 amt.step();
194 fb.step();
195 }
196 else
197 {
198 float delayed = delayed_value; // avoid dereferencing the pointer in 'then' branch of the if()
199 dsp::sanitize(delayed);
200 out = delayed * amt.get();
201 del = dry_value + delayed * fb.get();
202 }
203 }
204
205 /// Single delay line with tap output
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)206 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)
207 {
208 if (age <= deltime) {
209 out = 0;
210 del = dry_value;
211 amt.step();
212 fb.step();
213 }
214 else
215 {
216 out = delayed_value * amt.get();
217 del = dry_value + delayed_value_for_fb * fb.get();
218 dsp::sanitize(out);
219 dsp::sanitize(del);
220 }
221 }
222
delay_mix(float dry_left,float dry_right,float & out_left,float & out_right,float dry,float chmix)223 static inline void delay_mix(float dry_left, float dry_right, float &out_left, float &out_right, float dry, float chmix)
224 {
225 float tmp_left = lerp(out_left, out_right, chmix);
226 float tmp_right = lerp(out_right, out_left, chmix);
227 out_left = dry_left * dry + tmp_left;
228 out_right = dry_right * dry + tmp_right;
229 }
230
process(uint32_t offset,uint32_t numsamples,uint32_t inputs_mask,uint32_t outputs_mask)231 uint32_t vintage_delay_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
232 {
233 uint32_t ostate = 3; // XXXKF optimize!
234 uint32_t end = offset + numsamples;
235 int orig_bufptr = bufptr;
236 float out_left, out_right, del_left, del_right;
237
238 switch(mixmode)
239 {
240 case MIXMODE_STEREO:
241 case MIXMODE_PINGPONG:
242 {
243 int v = mixmode == MIXMODE_PINGPONG ? 1 : 0;
244 for(uint32_t i = offset; i < end; i++)
245 {
246 delayline_impl(age, deltime_l, ins[0][i], buffers[v][(bufptr - deltime_l) & ADDR_MASK], out_left, del_left, amt_left, fb_left);
247 delayline_impl(age, deltime_r, ins[1][i], buffers[1 - v][(bufptr - deltime_r) & ADDR_MASK], out_right, del_right, amt_right, fb_right);
248 delay_mix(ins[0][i], ins[1][i], out_left, out_right, dry.get(), chmix.get());
249
250 age++;
251 outs[0][i] = out_left; outs[1][i] = out_right; buffers[0][bufptr] = del_left; buffers[1][bufptr] = del_right;
252 bufptr = (bufptr + 1) & (MAX_DELAY - 1);
253 }
254 }
255 break;
256
257 case MIXMODE_LR:
258 case MIXMODE_RL:
259 {
260 int v = mixmode == MIXMODE_RL ? 1 : 0;
261 int deltime_fb = deltime_l + deltime_r;
262 int deltime_l_corr = mixmode == MIXMODE_RL ? deltime_fb : deltime_l;
263 int deltime_r_corr = mixmode == MIXMODE_LR ? deltime_fb : deltime_r;
264
265 for(uint32_t i = offset; i < end; i++)
266 {
267 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);
268 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);
269 delay_mix(ins[0][i], ins[1][i], out_left, out_right, dry.get(), chmix.get());
270
271 age++;
272 outs[0][i] = out_left; outs[1][i] = out_right; buffers[0][bufptr] = del_left; buffers[1][bufptr] = del_right;
273 bufptr = (bufptr + 1) & (MAX_DELAY - 1);
274 }
275 }
276 }
277 if (age >= MAX_DELAY)
278 age = MAX_DELAY;
279 if (medium > 0) {
280 bufptr = orig_bufptr;
281 if (medium == 2)
282 {
283 for(uint32_t i = offset; i < end; i++)
284 {
285 buffers[0][bufptr] = biquad_left[0].process_lp(biquad_left[1].process(buffers[0][bufptr]));
286 buffers[1][bufptr] = biquad_right[0].process_lp(biquad_right[1].process(buffers[1][bufptr]));
287 bufptr = (bufptr + 1) & (MAX_DELAY - 1);
288 }
289 biquad_left[0].sanitize();biquad_right[0].sanitize();
290 } else {
291 for(uint32_t i = offset; i < end; i++)
292 {
293 buffers[0][bufptr] = biquad_left[1].process(buffers[0][bufptr]);
294 buffers[1][bufptr] = biquad_right[1].process(buffers[1][bufptr]);
295 bufptr = (bufptr + 1) & (MAX_DELAY - 1);
296 }
297 }
298 biquad_left[1].sanitize();biquad_right[1].sanitize();
299
300 }
301 return ostate;
302 }
303
304 ///////////////////////////////////////////////////////////////////////////////////////////////
305
get_graph(int index,int subindex,float * data,int points,cairo_iface * context) const306 bool filter_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const
307 {
308 if (!is_active)
309 return false;
310 if (index == par_cutoff && !subindex) {
311 context->set_line_width(1.5);
312 return ::get_graph(*this, subindex, data, points);
313 }
314 return false;
315 }
316
get_changed_offsets(int index,int generation,int & subindex_graph,int & subindex_dot,int & subindex_gridline) const317 int filter_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) const
318 {
319 if (fabs(inertia_cutoff.get_last() - old_cutoff) + 100 * fabs(inertia_resonance.get_last() - old_resonance) + fabs(*params[par_mode] - old_mode) > 0.1f)
320 {
321 old_cutoff = inertia_cutoff.get_last();
322 old_resonance = inertia_resonance.get_last();
323 old_mode = *params[par_mode];
324 last_generation++;
325 subindex_graph = 0;
326 subindex_dot = INT_MAX;
327 subindex_gridline = INT_MAX;
328 }
329 else {
330 subindex_graph = 0;
331 subindex_dot = subindex_gridline = generation ? INT_MAX : 0;
332 }
333 if (generation == last_calculated_generation)
334 subindex_graph = INT_MAX;
335 return last_generation;
336 }
337
338
339 ///////////////////////////////////////////////////////////////////////////////////////////////
340
filterclavier_audio_module()341 filterclavier_audio_module::filterclavier_audio_module()
342 : filter_module_with_inertia<biquad_filter_module, filterclavier_metadata>(ins, outs, params)
343 , min_gain(1.0)
344 , max_gain(32.0)
345 , last_note(-1)
346 , last_velocity(-1)
347 {
348 }
349
params_changed()350 void filterclavier_audio_module::params_changed()
351 {
352 inertia_filter_module::inertia_cutoff.set_inertia(
353 note_to_hz(last_note + *params[par_transpose], *params[par_detune]));
354
355 float min_resonance = param_props[par_max_resonance].min;
356 inertia_filter_module::inertia_resonance.set_inertia(
357 (float(last_velocity) / 127.0)
358 // 0.001: see below
359 * (*params[par_max_resonance] - min_resonance + 0.001)
360 + min_resonance);
361
362 adjust_gain_according_to_filter_mode(last_velocity);
363
364 inertia_filter_module::calculate_filter();
365 }
366
activate()367 void filterclavier_audio_module::activate()
368 {
369 inertia_filter_module::activate();
370 }
371
set_sample_rate(uint32_t sr)372 void filterclavier_audio_module::set_sample_rate(uint32_t sr)
373 {
374 inertia_filter_module::set_sample_rate(sr);
375 }
376
deactivate()377 void filterclavier_audio_module::deactivate()
378 {
379 inertia_filter_module::deactivate();
380 }
381
382
note_on(int channel,int note,int vel)383 void filterclavier_audio_module::note_on(int channel, int note, int vel)
384 {
385 last_note = note;
386 last_velocity = vel;
387 inertia_filter_module::inertia_cutoff.set_inertia(
388 note_to_hz(note + *params[par_transpose], *params[par_detune]));
389
390 float min_resonance = param_props[par_max_resonance].min;
391 inertia_filter_module::inertia_resonance.set_inertia(
392 (float(vel) / 127.0)
393 // 0.001: if the difference is equal to zero (which happens
394 // when the max_resonance knom is at minimum position
395 // then the filter gain doesnt seem to snap to zero on most note offs
396 * (*params[par_max_resonance] - min_resonance + 0.001)
397 + min_resonance);
398
399 adjust_gain_according_to_filter_mode(vel);
400
401 inertia_filter_module::calculate_filter();
402 }
403
note_off(int channel,int note,int vel)404 void filterclavier_audio_module::note_off(int channel, int note, int vel)
405 {
406 if (note == last_note) {
407 inertia_filter_module::inertia_resonance.set_inertia(param_props[par_max_resonance].min);
408 inertia_filter_module::inertia_gain.set_inertia(min_gain);
409 inertia_filter_module::calculate_filter();
410 last_velocity = 0;
411 }
412 }
413
adjust_gain_according_to_filter_mode(int velocity)414 void filterclavier_audio_module::adjust_gain_according_to_filter_mode(int velocity)
415 {
416 int mode = dsp::fastf2i_drm(*params[par_mode]);
417
418 // for bandpasses: boost gain for velocities > 0
419 if ( (mode_6db_bp <= mode) && (mode <= mode_18db_bp) ) {
420 // gain for velocity 0: 1.0
421 // gain for velocity 127: 32.0
422 float mode_max_gain = max_gain;
423 // max_gain is right for mode_6db_bp
424 if (mode == mode_12db_bp)
425 mode_max_gain /= 6.0;
426 if (mode == mode_18db_bp)
427 mode_max_gain /= 10.5;
428
429 inertia_filter_module::inertia_gain.set_now(
430 (float(velocity) / 127.0) * (mode_max_gain - min_gain) + min_gain);
431 } else {
432 inertia_filter_module::inertia_gain.set_now(min_gain);
433 }
434 }
435
get_graph(int index,int subindex,float * data,int points,cairo_iface * context) const436 bool filterclavier_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) const
437 {
438 if (!is_active || index != par_mode) {
439 return false;
440 }
441 if (!subindex) {
442 context->set_line_width(1.5);
443 return ::get_graph(*this, subindex, data, points);
444 }
445 return false;
446 }
447
448
449 ///////////////////////////////////////////////////////////////////////////////////////////////
450
stereo_audio_module()451 stereo_audio_module::stereo_audio_module() {
452 active = false;
453 clip_inL = 0.f;
454 clip_inR = 0.f;
455 clip_outL = 0.f;
456 clip_outR = 0.f;
457 meter_inL = 0.f;
458 meter_inR = 0.f;
459 meter_outL = 0.f;
460 meter_outR = 0.f;
461 }
462
~stereo_audio_module()463 stereo_audio_module::~stereo_audio_module()
464 {
465 if( buffer != NULL )
466 {
467 free(buffer);
468 }
469 }
470
activate()471 void stereo_audio_module::activate() {
472 active = true;
473 }
474
deactivate()475 void stereo_audio_module::deactivate() {
476 active = false;
477 }
478
params_changed()479 void stereo_audio_module::params_changed() {
480 float slev = 2 * *params[param_slev]; // stereo level ( -2 -> 2 )
481 float sbal = 1 + *params[param_sbal]; // stereo balance ( 0 -> 2 )
482 float mlev = 2 * *params[param_mlev]; // mono level ( -2 -> 2 )
483 float mpan = 1 + *params[param_mpan]; // mono pan ( 0 -> 2 )
484
485 switch((int)*params[param_mode])
486 {
487 case 0:
488 default:
489 //LR->LR
490 LL = (mlev * (2.f - mpan) + slev * (2.f - sbal));
491 LR = (mlev * mpan - slev * sbal);
492 RL = (mlev * (2.f - mpan) - slev * (2.f - sbal));
493 RR = (mlev * mpan + slev * sbal);
494 break;
495 case 1:
496 //LR->MS
497 LL = (2.f - mpan) * (2.f - sbal);
498 LR = mpan * (2.f - sbal) * -1;
499 RL = (2.f - mpan) * sbal;
500 RR = mpan * sbal;
501 break;
502 case 2:
503 //MS->LR
504 LL = mlev * (2.f - sbal);
505 LR = mlev * mpan;
506 RL = slev * (2.f - sbal);
507 RR = slev * sbal * -1;
508 break;
509 case 3:
510 case 4:
511 case 5:
512 case 6:
513 //LR->LL
514 LL = 0.f;
515 LR = 0.f;
516 RL = 0.f;
517 RR = 0.f;
518 break;
519 }
520 }
521
process(uint32_t offset,uint32_t numsamples,uint32_t inputs_mask,uint32_t outputs_mask)522 uint32_t stereo_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
523 for(uint32_t i = offset; i < offset + numsamples; i++) {
524 if(*params[param_bypass] > 0.5) {
525 outs[0][i] = ins[0][i];
526 outs[1][i] = ins[1][i];
527 clip_inL = 0.f;
528 clip_inR = 0.f;
529 clip_outL = 0.f;
530 clip_outR = 0.f;
531 meter_inL = 0.f;
532 meter_inR = 0.f;
533 meter_outL = 0.f;
534 meter_outR = 0.f;
535 } else {
536 // let meters fall a bit
537 clip_inL -= std::min(clip_inL, numsamples);
538 clip_inR -= std::min(clip_inR, numsamples);
539 clip_outL -= std::min(clip_outL, numsamples);
540 clip_outR -= std::min(clip_outR, numsamples);
541 meter_inL = 0.f;
542 meter_inR = 0.f;
543 meter_outL = 0.f;
544 meter_outR = 0.f;
545
546 float L = ins[0][i];
547 float R = ins[1][i];
548
549 // levels in
550 L *= *params[param_level_in];
551 R *= *params[param_level_in];
552
553 // balance in
554 L *= (1.f - std::max(0.f, *params[param_balance_in]));
555 R *= (1.f + std::min(0.f, *params[param_balance_in]));
556
557 // copy / flip / mono ...
558 switch((int)*params[param_mode])
559 {
560 case 0:
561 default:
562 // LR > LR
563 break;
564 case 1:
565 // LR > MS
566 break;
567 case 2:
568 // MS > LR
569 break;
570 case 3:
571 // LR > LL
572 R = L;
573 break;
574 case 4:
575 // LR > RR
576 L = R;
577 break;
578 case 5:
579 // LR > L+R
580 L = (L + R) / 2;
581 R = L;
582 break;
583 case 6:
584 // LR > RL
585 float tmp = L;
586 L = R;
587 R = tmp;
588 break;
589 }
590
591 // softclip
592 if(*params[param_softclip]) {
593 int ph;
594 ph = L / fabs(L);
595 L = L > 0.63 ? ph * (0.63 + 0.36 * (1 - pow(MATH_E, (1.f / 3) * (0.63 + L * ph)))) : L;
596 ph = R / fabs(R);
597 R = R > 0.63 ? ph * (0.63 + 0.36 * (1 - pow(MATH_E, (1.f / 3) * (0.63 + R * ph)))) : R;
598 }
599
600 // GUI stuff
601 if(L > meter_inL) meter_inL = L;
602 if(R > meter_inR) meter_inR = R;
603 if(L > 1.f) clip_inL = srate >> 3;
604 if(R > 1.f) clip_inR = srate >> 3;
605
606 // mute
607 L *= (1 - floor(*params[param_mute_l] + 0.5));
608 R *= (1 - floor(*params[param_mute_r] + 0.5));
609
610 // phase
611 L *= (2 * (1 - floor(*params[param_phase_l] + 0.5))) - 1;
612 R *= (2 * (1 - floor(*params[param_phase_r] + 0.5))) - 1;
613
614 // LR/MS
615 L += LL*L + RL*R;
616 R += RR*R + LR*L;
617
618 // widener
619 L += *params[param_widener] * R * -1;
620 R += *params[param_widener] * L * -1;
621
622 // delay
623 buffer[pos] = L;
624 buffer[pos + 1] = R;
625
626 int nbuf = srate * (fabs(*params[param_delay]) / 1000.f);
627 nbuf -= nbuf % 2;
628 if(*params[param_delay] > 0.f) {
629 R = buffer[(pos - (int)nbuf + 1 + buffer_size) % buffer_size];
630 } else if (*params[param_delay] < 0.f) {
631 L = buffer[(pos - (int)nbuf + buffer_size) % buffer_size];
632 }
633
634 pos = (pos + 2) % buffer_size;
635
636 // balance out
637 L *= (1.f - std::max(0.f, *params[param_balance_out]));
638 R *= (1.f + std::min(0.f, *params[param_balance_out]));
639
640 // level
641 L *= *params[param_level_out];
642 R *= *params[param_level_out];
643
644 //output
645 outs[0][i] = L;
646 outs[1][i] = R;
647
648 // clip LED's
649 if(L > 1.f) clip_outL = srate >> 3;
650 if(R > 1.f) clip_outR = srate >> 3;
651 if(L > meter_outL) meter_outL = L;
652 if(R > meter_outR) meter_outR = R;
653
654 // phase meter
655 if(fabs(L) > 0.001 and fabs(R) > 0.001) {
656 meter_phase = fabs(fabs(L+R) > 0.000000001 ? sin(fabs((L-R)/(L+R))) : 0.f);
657 } else {
658 meter_phase = 0.f;
659 }
660 }
661 }
662 // draw meters
663 SET_IF_CONNECTED(clip_inL);
664 SET_IF_CONNECTED(clip_inR);
665 SET_IF_CONNECTED(clip_outL);
666 SET_IF_CONNECTED(clip_outR);
667 SET_IF_CONNECTED(meter_inL);
668 SET_IF_CONNECTED(meter_inR);
669 SET_IF_CONNECTED(meter_outL);
670 SET_IF_CONNECTED(meter_outR);
671 SET_IF_CONNECTED(meter_phase);
672 return outputs_mask;
673 }
674
set_sample_rate(uint32_t sr)675 void stereo_audio_module::set_sample_rate(uint32_t sr)
676 {
677 srate = sr;
678 // rebuild buffer
679 buffer_size = (int)(srate * 0.05 * 2.f); // buffer size attack rate multiplied by 2 channels
680 buffer = (float*) calloc(buffer_size, sizeof(float));
681 memset(buffer, 0, buffer_size * sizeof(float)); // reset buffer to zero
682 pos = 0;
683 }
684
685 ///////////////////////////////////////////////////////////////////////////////////////////////
686
mono_audio_module()687 mono_audio_module::mono_audio_module() {
688 active = false;
689 clip_in = 0.f;
690 clip_outL = 0.f;
691 clip_outR = 0.f;
692 meter_in = 0.f;
693 meter_outL = 0.f;
694 meter_outR = 0.f;
695 }
696
~mono_audio_module()697 mono_audio_module::~mono_audio_module()
698 {
699 if( buffer != NULL )
700 {
701 free(buffer);
702 }
703 }
704
activate()705 void mono_audio_module::activate() {
706 active = true;
707 }
708
deactivate()709 void mono_audio_module::deactivate() {
710 active = false;
711 }
712
params_changed()713 void mono_audio_module::params_changed() {
714
715 }
716
process(uint32_t offset,uint32_t numsamples,uint32_t inputs_mask,uint32_t outputs_mask)717 uint32_t mono_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
718 for(uint32_t i = offset; i < offset + numsamples; i++) {
719 if(*params[param_bypass] > 0.5) {
720 outs[0][i] = ins[0][i];
721 outs[1][i] = ins[0][i];
722 clip_in = 0.f;
723 clip_outL = 0.f;
724 clip_outR = 0.f;
725 meter_in = 0.f;
726 meter_outL = 0.f;
727 meter_outR = 0.f;
728 } else {
729 // let meters fall a bit
730 clip_in -= std::min(clip_in, numsamples);
731 clip_outL -= std::min(clip_outL, numsamples);
732 clip_outR -= std::min(clip_outR, numsamples);
733 meter_in = 0.f;
734 meter_outL = 0.f;
735 meter_outR = 0.f;
736
737 float L = ins[0][i];
738
739 // levels in
740 L *= *params[param_level_in];
741
742 // softclip
743 if(*params[param_softclip]) {
744 int ph = L / fabs(L);
745 L = L > 0.63 ? ph * (0.63 + 0.36 * (1 - pow(MATH_E, (1.f / 3) * (0.63 + L * ph)))) : L;
746 }
747
748 // GUI stuff
749 if(L > meter_in) meter_in = L;
750 if(L > 1.f) clip_in = srate >> 3;
751
752 float R = L;
753
754 // mute
755 L *= (1 - floor(*params[param_mute_l] + 0.5));
756 R *= (1 - floor(*params[param_mute_r] + 0.5));
757
758 // phase
759 L *= (2 * (1 - floor(*params[param_phase_l] + 0.5))) - 1;
760 R *= (2 * (1 - floor(*params[param_phase_r] + 0.5))) - 1;
761
762 // delay
763 buffer[pos] = L;
764 buffer[pos + 1] = R;
765
766 int nbuf = srate * (fabs(*params[param_delay]) / 1000.f);
767 nbuf -= nbuf % 2;
768 if(*params[param_delay] > 0.f) {
769 R = buffer[(pos - (int)nbuf + 1 + buffer_size) % buffer_size];
770 } else if (*params[param_delay] < 0.f) {
771 L = buffer[(pos - (int)nbuf + buffer_size) % buffer_size];
772 }
773
774 pos = (pos + 2) % buffer_size;
775
776 // balance out
777 L *= (1.f - std::max(0.f, *params[param_balance_out]));
778 R *= (1.f + std::min(0.f, *params[param_balance_out]));
779
780 // level
781 L *= *params[param_level_out];
782 R *= *params[param_level_out];
783
784 //output
785 outs[0][i] = L;
786 outs[1][i] = R;
787
788 // clip LED's
789 if(L > 1.f) clip_outL = srate >> 3;
790 if(R > 1.f) clip_outR = srate >> 3;
791 if(L > meter_outL) meter_outL = L;
792 if(R > meter_outR) meter_outR = R;
793 }
794 }
795 // draw meters
796 SET_IF_CONNECTED(clip_in);
797 SET_IF_CONNECTED(clip_outL);
798 SET_IF_CONNECTED(clip_outR);
799 SET_IF_CONNECTED(meter_in);
800 SET_IF_CONNECTED(meter_outL);
801 SET_IF_CONNECTED(meter_outR);
802 return outputs_mask;
803 }
804
set_sample_rate(uint32_t sr)805 void mono_audio_module::set_sample_rate(uint32_t sr)
806 {
807 srate = sr;
808 // rebuild buffer
809 buffer_size = (int)srate * 0.05 * 2; // delay buffer size multiplied by 2 channels
810 buffer = (float*) calloc(buffer_size, sizeof(float));
811 memset(buffer, 0, buffer_size * sizeof(float)); // reset buffer to zero
812 pos = 0;
813 }
814