1 /* Calf DSP plugin pack
2 * Distortion related 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
23 #include <calf/giface.h>
24 #include <calf/modules_dist.h>
27 using namespace calf_plugins
;
29 #define SET_IF_CONNECTED(name) if (params[AM::param_##name] != NULL) *params[AM::param_##name] = name;
31 /**********************************************************************
32 * SATURATOR by Markus Schmidt
33 **********************************************************************/
35 saturator_audio_module::saturator_audio_module()
42 lp_post_freq_old
= -1;
43 hp_post_freq_old
= -1;
49 void saturator_audio_module::activate()
56 void saturator_audio_module::deactivate()
61 void saturator_audio_module::params_changed()
63 // set the params of all filters
64 if(*params
[param_lp_pre_freq
] != lp_pre_freq_old
) {
65 lp
[0][0].set_lp_rbj(*params
[param_lp_pre_freq
], 0.707, (float)srate
);
66 if(in_count
> 1 && out_count
> 1)
67 lp
[1][0].copy_coeffs(lp
[0][0]);
68 lp
[0][1].copy_coeffs(lp
[0][0]);
69 if(in_count
> 1 && out_count
> 1)
70 lp
[1][1].copy_coeffs(lp
[0][0]);
71 lp_pre_freq_old
= *params
[param_lp_pre_freq
];
73 if(*params
[param_hp_pre_freq
] != hp_pre_freq_old
) {
74 hp
[0][0].set_hp_rbj(*params
[param_hp_pre_freq
], 0.707, (float)srate
);
75 if(in_count
> 1 && out_count
> 1)
76 hp
[1][0].copy_coeffs(hp
[0][0]);
77 hp
[0][1].copy_coeffs(hp
[0][0]);
78 if(in_count
> 1 && out_count
> 1)
79 hp
[1][1].copy_coeffs(hp
[0][0]);
80 hp_pre_freq_old
= *params
[param_hp_pre_freq
];
82 if(*params
[param_lp_post_freq
] != lp_post_freq_old
) {
83 lp
[0][2].set_lp_rbj(*params
[param_lp_post_freq
], 0.707, (float)srate
);
84 if(in_count
> 1 && out_count
> 1)
85 lp
[1][2].copy_coeffs(lp
[0][2]);
86 lp
[0][3].copy_coeffs(lp
[0][2]);
87 if(in_count
> 1 && out_count
> 1)
88 lp
[1][3].copy_coeffs(lp
[0][2]);
89 lp_post_freq_old
= *params
[param_lp_post_freq
];
91 if(*params
[param_hp_post_freq
] != hp_post_freq_old
) {
92 hp
[0][2].set_hp_rbj(*params
[param_hp_post_freq
], 0.707, (float)srate
);
93 if(in_count
> 1 && out_count
> 1)
94 hp
[1][2].copy_coeffs(hp
[0][2]);
95 hp
[0][3].copy_coeffs(hp
[0][2]);
96 if(in_count
> 1 && out_count
> 1)
97 hp
[1][3].copy_coeffs(hp
[0][2]);
98 hp_post_freq_old
= *params
[param_hp_post_freq
];
100 if(*params
[param_p_freq
] != p_freq_old
or *params
[param_p_level
] != p_level_old
or *params
[param_p_q
] != p_q_old
) {
101 p
[0].set_peakeq_rbj((float)*params
[param_p_freq
], (float)*params
[param_p_q
], (float)*params
[param_p_level
], (float)srate
);
102 if(in_count
> 1 && out_count
> 1)
103 p
[1].copy_coeffs(p
[0]);
104 p_freq_old
= *params
[param_p_freq
];
105 p_level_old
= *params
[param_p_level
];
106 p_q_old
= *params
[param_p_q
];
109 dist
[0].set_params(*params
[param_blend
], *params
[param_drive
]);
110 if(in_count
> 1 && out_count
> 1)
111 dist
[1].set_params(*params
[param_blend
], *params
[param_drive
]);
114 void saturator_audio_module::set_sample_rate(uint32_t sr
)
117 dist
[0].set_sample_rate(sr
);
118 if(in_count
> 1 && out_count
> 1)
119 dist
[1].set_sample_rate(sr
);
120 int meter
[] = {param_meter_in
, param_meter_out
, param_meter_drive
};
121 int clip
[] = {param_clip_in
, param_clip_out
, -1};
122 meters
.init(params
, meter
, clip
, 3, srate
);
125 uint32_t saturator_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
127 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
128 numsamples
+= offset
;
130 // everything bypassed
131 while(offset
< numsamples
) {
132 if(in_count
> 1 && out_count
> 1) {
133 outs
[0][offset
] = ins
[0][offset
];
134 outs
[1][offset
] = ins
[1][offset
];
135 } else if(in_count
> 1) {
136 outs
[0][offset
] = (ins
[0][offset
] + ins
[1][offset
]) / 2;
137 } else if(out_count
> 1) {
138 outs
[0][offset
] = ins
[0][offset
];
139 outs
[1][offset
] = ins
[0][offset
];
141 outs
[0][offset
] = ins
[0][offset
];
143 float values
[] = {0, 0, 0};
144 meters
.process(values
);
148 uint32_t orig_offset
= offset
;
150 while(offset
< numsamples
) {
151 // cycle through samples
152 float out
[2], in
[2] = {0.f
, 0.f
};
154 float maxDrive
= 0.f
;
155 if(in_count
> 1 && out_count
> 1) {
156 // stereo in/stereo out
157 // handle full stereo
158 in
[0] = ins
[0][offset
];
159 in
[1] = ins
[1][offset
];
162 // in and/or out mono
164 in
[0] = ins
[0][offset
];
170 proc
[0] = in
[0] * *params
[param_level_in
];
171 proc
[1] = in
[1] * *params
[param_level_in
];
173 float onedivlevelin
= 1.0 / *params
[param_level_in
];
175 for (int i
= 0; i
< c
; ++i
) {
176 // all pre filters in chain
177 proc
[i
] = lp
[i
][1].process(lp
[i
][0].process(proc
[i
]));
178 proc
[i
] = hp
[i
][1].process(hp
[i
][0].process(proc
[i
]));
181 proc
[i
] = dist
[i
].process(proc
[i
]);
184 proc
[i
] = p
[i
].process(proc
[i
]);
186 // all post filters in chain
187 proc
[i
] = lp
[i
][2].process(lp
[i
][3].process(proc
[i
]));
188 proc
[i
] = hp
[i
][2].process(hp
[i
][3].process(proc
[i
]));
191 proc
[i
] *= onedivlevelin
;
193 if (*params
[param_level_in
] > 1)
194 proc
[i
] *= 1 + (*params
[param_level_in
] - 1) / 32;
197 maxDrive
= dist
[0].get_distortion_level() * *params
[param_blend
];
199 if(in_count
> 1 && out_count
> 1) {
200 maxDrive
= dist
[1].get_distortion_level() * *params
[param_blend
];
202 out
[0] = ((proc
[0] * *params
[param_mix
]) + in
[0] * (1 - *params
[param_mix
])) * *params
[param_level_out
];
203 outs
[0][offset
] = out
[0];
204 out
[1] = ((proc
[1] * *params
[param_mix
]) + in
[1] * (1 - *params
[param_mix
])) * *params
[param_level_out
];
205 outs
[1][offset
] = out
[1];
206 } else if(out_count
> 1) {
207 // mono -> pseudo stereo
208 out
[0] = ((proc
[0] * *params
[param_mix
]) + in
[0] * (1 - *params
[param_mix
])) * *params
[param_level_out
];
209 outs
[0][offset
] = out
[0];
211 outs
[1][offset
] = out
[1];
215 out
[0] = ((proc
[0] * *params
[param_mix
]) + in
[0] * (1 - *params
[param_mix
])) * *params
[param_level_out
];
216 outs
[0][offset
] = out
[0];
218 float values
[] = {(in
[0] + in
[1]) / 2, (out
[0] + out
[1]) / 2, maxDrive
/ 20};
219 meters
.process(values
);
223 } // cycle trough samples
244 bypass
.crossfade(ins
, outs
, 2, orig_offset
, numsamples
);
246 meters
.fall(numsamples
);
250 /**********************************************************************
251 * EXCITER by Markus Schmidt
252 **********************************************************************/
254 exciter_audio_module::exciter_audio_module()
258 ceil_active_old
= false;
264 void exciter_audio_module::activate()
271 void exciter_audio_module::deactivate()
276 void exciter_audio_module::params_changed()
278 // set the params of all filters
279 if(*params
[param_freq
] != freq_old
) {
280 hp
[0][0].set_hp_rbj(*params
[param_freq
], 0.707, (float)srate
);
281 hp
[0][1].copy_coeffs(hp
[0][0]);
282 hp
[0][2].copy_coeffs(hp
[0][0]);
283 hp
[0][3].copy_coeffs(hp
[0][0]);
284 if(in_count
> 1 && out_count
> 1) {
285 hp
[1][0].copy_coeffs(hp
[0][0]);
286 hp
[1][1].copy_coeffs(hp
[0][0]);
287 hp
[1][2].copy_coeffs(hp
[0][0]);
288 hp
[1][3].copy_coeffs(hp
[0][0]);
290 freq_old
= *params
[param_freq
];
292 // set the params of all filters
293 if(*params
[param_ceil
] != ceil_old
or *params
[param_ceil_active
] != ceil_active_old
) {
294 lp
[0][0].set_lp_rbj(*params
[param_ceil
], 0.707, (float)srate
);
295 lp
[0][1].copy_coeffs(lp
[0][0]);
296 lp
[1][0].copy_coeffs(lp
[0][0]);
297 lp
[1][1].copy_coeffs(lp
[0][0]);
298 ceil_old
= *params
[param_ceil
];
299 ceil_active_old
= *params
[param_ceil_active
];
302 dist
[0].set_params(*params
[param_blend
], *params
[param_drive
]);
303 if(in_count
> 1 && out_count
> 1)
304 dist
[1].set_params(*params
[param_blend
], *params
[param_drive
]);
307 void exciter_audio_module::set_sample_rate(uint32_t sr
)
310 dist
[0].set_sample_rate(sr
);
311 if(in_count
> 1 && out_count
> 1)
312 dist
[1].set_sample_rate(sr
);
313 int meter
[] = {param_meter_in
, param_meter_out
, param_meter_drive
};
314 int clip
[] = {param_clip_in
, param_clip_out
, -1};
315 meters
.init(params
, meter
, clip
, 3, srate
);
318 uint32_t exciter_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
320 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
321 numsamples
+= offset
;
323 // everything bypassed
324 while(offset
< numsamples
) {
325 if(in_count
> 1 && out_count
> 1) {
326 outs
[0][offset
] = ins
[0][offset
];
327 outs
[1][offset
] = ins
[1][offset
];
328 } else if(in_count
> 1) {
329 outs
[0][offset
] = (ins
[0][offset
] + ins
[1][offset
]) / 2;
330 } else if(out_count
> 1) {
331 outs
[0][offset
] = ins
[0][offset
];
332 outs
[1][offset
] = ins
[0][offset
];
334 outs
[0][offset
] = ins
[0][offset
];
336 float values
[] = {0, 0, 0, 0, 0};
337 meters
.process(values
);
343 uint32_t orig_offset
= offset
;
346 float in2out
= *params
[param_listen
] > 0.f
? 0.f
: 1.f
;
349 while(offset
< numsamples
) {
350 // cycle through samples
351 float out
[2], in
[2] = {0.f
, 0.f
};
352 float maxDrive
= 0.f
;
355 if(in_count
> 1 && out_count
> 1) {
356 // stereo in/stereo out
357 // handle full stereo
358 in
[0] = ins
[0][offset
];
359 in
[0] *= *params
[param_level_in
];
360 in
[1] = ins
[1][offset
];
361 in
[1] *= *params
[param_level_in
];
364 // in and/or out mono
366 in
[0] = ins
[0][offset
];
367 in
[0] *= *params
[param_level_in
];
376 for (int i
= 0; i
< c
; ++i
) {
377 // all pre filters in chain
378 proc
[i
] = hp
[i
][1].process(hp
[i
][0].process(proc
[i
]));
381 proc
[i
] = dist
[i
].process(proc
[i
]);
383 // all post filters in chain
384 proc
[i
] = hp
[i
][2].process(hp
[i
][3].process(proc
[i
]));
386 if(*params
[param_ceil_active
] > 0.5f
) {
387 // all H/P post filters in chain
388 proc
[i
] = lp
[i
][0].process(lp
[i
][1].process(proc
[i
]));
392 maxDrive
= dist
[0].get_distortion_level() * *params
[param_amount
];
394 if(in_count
> 1 && out_count
> 1) {
395 maxDrive
= std::max(maxDrive
, dist
[1].get_distortion_level() * *params
[param_amount
]);
397 out
[0] = (proc
[0] * *params
[param_amount
] + in2out
* in
[0]) * *params
[param_level_out
];
398 out
[1] = (proc
[1] * *params
[param_amount
] + in2out
* in
[1]) * *params
[param_level_out
];
399 outs
[0][offset
] = out
[0];
400 outs
[1][offset
] = out
[1];
401 } else if(out_count
> 1) {
402 // mono -> pseudo stereo
403 out
[1] = out
[0] = (proc
[0] * *params
[param_amount
] + in2out
* in
[0]) * *params
[param_level_out
];
404 outs
[0][offset
] = out
[0];
405 outs
[1][offset
] = out
[1];
409 out
[0] = (proc
[0] * *params
[param_amount
] + in2out
* in
[0]) * *params
[param_level_out
];
410 outs
[0][offset
] = out
[0];
412 float values
[] = {(in
[0] + in
[1]) / 2, (out
[0] + out
[1]) / 2, maxDrive
};
413 meters
.process(values
);
416 } // cycle trough samples
417 bypass
.crossfade(ins
, outs
, 2, orig_offset
, numsamples
);
433 meters
.fall(numsamples
);
437 /**********************************************************************
438 * BASS ENHANCER by Markus Schmidt
439 **********************************************************************/
441 bassenhancer_audio_module::bassenhancer_audio_module()
445 floor_active_old
= false;
451 void bassenhancer_audio_module::activate()
457 void bassenhancer_audio_module::deactivate()
462 void bassenhancer_audio_module::params_changed()
464 // set the params of all filters
465 if(*params
[param_freq
] != freq_old
) {
466 lp
[0][0].set_lp_rbj(*params
[param_freq
], 0.707, (float)srate
);
467 lp
[0][1].copy_coeffs(lp
[0][0]);
468 lp
[0][2].copy_coeffs(lp
[0][0]);
469 lp
[0][3].copy_coeffs(lp
[0][0]);
470 if(in_count
> 1 && out_count
> 1) {
471 lp
[1][0].copy_coeffs(lp
[0][0]);
472 lp
[1][1].copy_coeffs(lp
[0][0]);
473 lp
[1][2].copy_coeffs(lp
[0][0]);
474 lp
[1][3].copy_coeffs(lp
[0][0]);
476 freq_old
= *params
[param_freq
];
478 // set the params of all filters
479 if(*params
[param_floor
] != floor_old
or *params
[param_floor_active
] != floor_active_old
) {
480 hp
[0][0].set_hp_rbj(*params
[param_floor
], 0.707, (float)srate
);
481 hp
[0][1].copy_coeffs(hp
[0][0]);
482 hp
[1][0].copy_coeffs(hp
[0][0]);
483 hp
[1][1].copy_coeffs(hp
[0][0]);
484 floor_old
= *params
[param_floor
];
485 floor_active_old
= *params
[param_floor_active
];
488 dist
[0].set_params(*params
[param_blend
], *params
[param_drive
]);
489 if(in_count
> 1 && out_count
> 1)
490 dist
[1].set_params(*params
[param_blend
], *params
[param_drive
]);
493 void bassenhancer_audio_module::set_sample_rate(uint32_t sr
)
496 dist
[0].set_sample_rate(sr
);
497 if(in_count
> 1 && out_count
> 1)
498 dist
[1].set_sample_rate(sr
);
499 int meter
[] = {param_meter_in
, param_meter_out
, param_meter_drive
};
500 int clip
[] = {param_clip_in
, param_clip_out
, -1};
501 meters
.init(params
, meter
, clip
, 3, srate
);
504 uint32_t bassenhancer_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
506 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
507 numsamples
+= offset
;
509 // everything bypassed
510 while(offset
< numsamples
) {
511 if(in_count
> 1 && out_count
> 1) {
512 outs
[0][offset
] = ins
[0][offset
];
513 outs
[1][offset
] = ins
[1][offset
];
514 } else if(in_count
> 1) {
515 outs
[0][offset
] = (ins
[0][offset
] + ins
[1][offset
]) / 2;
516 } else if(out_count
> 1) {
517 outs
[0][offset
] = ins
[0][offset
];
518 outs
[1][offset
] = ins
[0][offset
];
520 outs
[0][offset
] = ins
[0][offset
];
522 float values
[] = {0, 0, 0};
523 meters
.process(values
);
528 uint32_t orig_offset
= offset
;
529 while(offset
< numsamples
) {
530 // cycle through samples
531 float out
[2], in
[2] = {0.f
, 0.f
};
532 float maxDrive
= 0.f
;
535 if(in_count
> 1 && out_count
> 1) {
536 // stereo in/stereo out
537 // handle full stereo
538 in
[0] = ins
[0][offset
];
539 in
[0] *= *params
[param_level_in
];
540 in
[1] = ins
[1][offset
];
541 in
[1] *= *params
[param_level_in
];
544 // in and/or out mono
546 in
[0] = ins
[0][offset
];
547 in
[0] *= *params
[param_level_in
];
556 for (int i
= 0; i
< c
; ++i
) {
557 // all pre filters in chain
558 proc
[i
] = lp
[i
][1].process(lp
[i
][0].process(proc
[i
]));
561 proc
[i
] = dist
[i
].process(proc
[i
]);
563 // all post filters in chain
564 proc
[i
] = lp
[i
][2].process(lp
[i
][3].process(proc
[i
]));
566 if(*params
[param_floor_active
] > 0.5f
) {
567 // all H/P post filters in chain
568 proc
[i
] = hp
[i
][0].process(hp
[i
][1].process(proc
[i
]));
573 if(in_count
> 1 && out_count
> 1) {
575 if(*params
[param_listen
] > 0.f
)
576 out
[0] = proc
[0] * *params
[param_amount
] * *params
[param_level_out
];
578 out
[0] = (proc
[0] * *params
[param_amount
] + in
[0]) * *params
[param_level_out
];
579 outs
[0][offset
] = out
[0];
580 if(*params
[param_listen
] > 0.f
)
581 out
[1] = proc
[1] * *params
[param_amount
] * *params
[param_level_out
];
583 out
[1] = (proc
[1] * *params
[param_amount
] + in
[1]) * *params
[param_level_out
];
584 outs
[1][offset
] = out
[1];
585 maxDrive
= std::max(dist
[0].get_distortion_level() * *params
[param_amount
],
586 dist
[1].get_distortion_level() * *params
[param_amount
]);
587 } else if(out_count
> 1) {
588 // mono -> pseudo stereo
589 if(*params
[param_listen
] > 0.f
)
590 out
[0] = proc
[0] * *params
[param_amount
] * *params
[param_level_out
];
592 out
[0] = (proc
[0] * *params
[param_amount
] + in
[0]) * *params
[param_level_out
];
593 outs
[0][offset
] = out
[0];
595 outs
[1][offset
] = out
[1];
596 maxDrive
= dist
[0].get_distortion_level() * *params
[param_amount
];
600 if(*params
[param_listen
] > 0.f
)
601 out
[0] = proc
[0] * *params
[param_amount
] * *params
[param_level_out
];
603 out
[0] = (proc
[0] * *params
[param_amount
] + in
[0]) * *params
[param_level_out
];
604 outs
[0][offset
] = out
[0];
605 maxDrive
= dist
[0].get_distortion_level() * *params
[param_amount
];
608 float values
[] = {(in
[0] + in
[1]) / 2, (out
[0] + out
[1]) / 2, maxDrive
};
609 meters
.process(values
);
612 } // cycle trough samples
613 bypass
.crossfade(ins
, outs
, 2, orig_offset
, numsamples
);
628 meters
.fall(numsamples
);
632 /**********************************************************************
633 * TAPESIMULATOR by Markus Schmidt
634 **********************************************************************/
636 tapesimulator_audio_module::tapesimulator_audio_module() {
649 transients
.set_channels(channels
);
652 void tapesimulator_audio_module::activate() {
656 void tapesimulator_audio_module::deactivate() {
660 void tapesimulator_audio_module::params_changed() {
661 if(*params
[param_lp
] != lp_old
or *params
[param_mechanical
] != mech_old
) {
662 lp
[0][0].set_lp_rbj(*params
[param_lp
], 0.707, (float)srate
);
663 lp
[0][1].copy_coeffs(lp
[0][0]);
664 lp
[1][0].copy_coeffs(lp
[0][0]);
665 lp
[1][1].copy_coeffs(lp
[0][0]);
666 lp_old
= *params
[param_lp
];
667 mech_old
= *params
[param_mechanical
] > 0.5;
669 transients
.set_params(50.f
/ (*params
[param_speed
] + 1),
670 -0.05f
/ (*params
[param_speed
] + 1),
676 lfo1
.set_params((*params
[param_speed
] + 1) / 2, 0, 0.f
, srate
, 1.f
);
677 lfo2
.set_params((*params
[param_speed
] + 1) / 9.38, 0, 0.f
, srate
, 1.f
);
680 uint32_t tapesimulator_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
) {
681 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
682 uint32_t orig_offset
= offset
;
683 for(uint32_t i
= offset
; i
< offset
+ numsamples
; i
++) {
686 float Lin
= ins
[0][i
];
687 float Rin
= ins
[1][i
];
689 outs
[0][i
] = ins
[0][i
];
690 outs
[1][i
] = ins
[1][i
];
691 float values
[] = {0, 0, 0, 0};
692 meters
.process(values
);
697 if(*params
[param_magnetical
] > 0.5f
) {
698 float values
[] = {L
, R
};
699 transients
.process(values
);
705 if (*params
[param_noise
]) {
706 float Lnoise
= rand() % 2 - 1;
707 float Rnoise
= rand() % 2 - 1;
708 Lnoise
= noisefilters
[0][2].process(noisefilters
[0][1].process(noisefilters
[0][0].process(Lnoise
)));
709 Rnoise
= noisefilters
[1][2].process(noisefilters
[1][1].process(noisefilters
[1][0].process(Rnoise
)));
710 L
+= Lnoise
* *params
[param_noise
] / 12.f
;
711 R
+= Rnoise
* *params
[param_noise
] / 12.f
;
714 // lfo filters / phasing
715 if (*params
[param_mechanical
]) {
717 float freqL1
= *params
[param_lp
] * (1 - ((lfo1
.get_value() + 1) * 0.3 * *params
[param_mechanical
]));
718 float freqL2
= *params
[param_lp
] * (1 - ((lfo2
.get_value() + 1) * 0.2 * *params
[param_mechanical
]));
720 float freqR1
= *params
[param_lp
] * (1 - ((lfo1
.get_value() * -1 + 1) * 0.3 * *params
[param_mechanical
]));
721 float freqR2
= *params
[param_lp
] * (1 - ((lfo2
.get_value() * -1 + 1) * 0.2 * *params
[param_mechanical
]));
723 lp
[0][0].set_lp_rbj(freqL1
, 0.707, (float)srate
);
724 lp
[0][1].set_lp_rbj(freqL2
, 0.707, (float)srate
);
726 lp
[1][0].set_lp_rbj(freqR1
, 0.707, (float)srate
);
727 lp
[1][1].set_lp_rbj(freqR2
, 0.707, (float)srate
);
730 float _phase
= lfo1
.get_value() * *params
[param_mechanical
] * -36;
732 float _phase_cos_coef
= cos(_phase
/ 180 * M_PI
);
733 float _phase_sin_coef
= sin(_phase
/ 180 * M_PI
);
735 float _l
= L
* _phase_cos_coef
- R
* _phase_sin_coef
;
736 float _r
= L
* _phase_sin_coef
+ R
* _phase_cos_coef
;
742 L
*= *params
[param_level_in
];
743 R
*= *params
[param_level_in
];
748 // save for drawing input/output curve
755 if (*params
[param_post
] < 0.5) {
756 L
= lp
[0][1].process(lp
[0][0].process(L
));
757 R
= lp
[1][1].process(lp
[1][0].process(R
));
761 if (L
) L
= L
/ fabs(L
) * (1 - exp((-1) * 3 * fabs(L
)));
762 if (R
) R
= R
/ fabs(R
) * (1 - exp((-1) * 3 * fabs(R
)));
764 if (Lo
) Lo
= Lo
/ fabs(Lo
) * (1 - exp((-1) * 3 * fabs(Lo
)));
765 if (Ro
) Ro
= Ro
/ fabs(Ro
) * (1 - exp((-1) * 3 * fabs(Ro
)));
768 if (*params
[param_post
] >= 0.5) {
769 L
= lp
[0][1].process(lp
[0][0].process(L
));
770 R
= lp
[1][1].process(lp
[1][0].process(R
));
774 L
= L
* *params
[param_mix
] + Lin
* (*params
[param_mix
] * -1 + 1);
775 R
= R
* *params
[param_mix
] + Rin
* (*params
[param_mix
] * -1 + 1);
778 L
*= *params
[param_level_out
];
779 R
*= *params
[param_level_out
];
791 // LFO's should go on
796 rms
= std::max((double)rms
, (fabs(Lo
) + fabs(Ro
)) / 2);
797 input
= std::max((double)input
, (fabs(Lc
) + fabs(Rc
)) / 2);
799 float values
[] = {inL
, inR
, outs
[0][i
], outs
[1][i
]};
800 meters
.process(values
);
804 bypass
.crossfade(ins
, outs
, 2, orig_offset
, numsamples
);
805 meters
.fall(numsamples
);
809 void tapesimulator_audio_module::set_sample_rate(uint32_t sr
)
812 int meter
[] = {param_meter_inL
, param_meter_inR
, param_meter_outL
, param_meter_outR
};
813 int clip
[] = {param_clip_inL
, param_clip_inR
, param_clip_outL
, param_clip_outR
};
814 meters
.init(params
, meter
, clip
, 4, srate
);
815 transients
.set_sample_rate(srate
);
816 noisefilters
[0][0].set_hp_rbj(120.f
, 0.707, (float)srate
);
817 noisefilters
[1][0].copy_coeffs(noisefilters
[0][0]);
818 noisefilters
[0][1].set_lp_rbj(5500.f
, 0.707, (float)srate
);
819 noisefilters
[1][1].copy_coeffs(noisefilters
[0][1]);
820 noisefilters
[0][2].set_highshelf_rbj(1000.f
, 0.707, 0.5, (float)srate
);
821 noisefilters
[1][2].copy_coeffs(noisefilters
[0][2]);
824 bool tapesimulator_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
828 if(index
== param_lp
and phase
) {
829 set_channel_color(context
, subindex
);
830 return ::get_graph(*this, subindex
, data
, points
);
831 } else if (index
== param_level_in
and !phase
) {
833 context
->set_source_rgba(0.15, 0.2, 0.0, 0.3);
834 context
->set_line_width(1);
836 for (int i
= 0; i
< points
; i
++) {
838 float input
= dB_grid_inv(-1.0 + (float)i
* 2.0 / ((float)points
- 1.f
));
839 data
[i
] = dB_grid(input
);
841 float output
= 1 - exp(-3 * (pow(2, -10 + 14 * (float)i
/ (float) points
)));
842 data
[i
] = dB_grid(output
* *params
[param_level_out
]);
849 float tapesimulator_audio_module::freq_gain(int index
, double freq
) const
851 return lp
[index
][0].freq_gain(freq
, srate
) * lp
[index
][1].freq_gain(freq
, srate
);
854 bool tapesimulator_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
858 if (index
== param_level_in
) {
860 vertical
= (subindex
& 1) != 0;
861 bool result
= get_freq_gridline(subindex
>> 1, pos
, tmp
, legend
, context
, false);
862 if (result
&& vertical
) {
863 if ((subindex
& 4) && !legend
.empty()) {
867 size_t pos
= legend
.find(" dB");
868 if (pos
!= std::string::npos
)
871 pos
= 0.5 + 0.5 * pos
;
874 } else if (index
== param_lp
) {
875 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
);
879 bool tapesimulator_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
881 if (index
== param_level_in
and !subindex
and phase
) {
882 x
= log(input
) / log(2) / 14.f
+ 5.f
/ 7.f
;
890 bool tapesimulator_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
893 // always draw grid on cache if surfaces are new on both widgets
895 layers
|= LG_CACHE_GRID
;
896 // compression: dot in realtime, graphs as cache on new surfaces
897 if (index
== param_level_in
and !generation
)
898 layers
|= LG_CACHE_GRAPH
;
899 if (index
== param_level_in
)
900 layers
|= LG_REALTIME_DOT
;
901 // frequency: both graphs in realtime
902 if (index
== param_lp
)
903 layers
|= LG_REALTIME_GRAPH
;
910 /**********************************************************************
911 * CRUSHER by Markus Schmidt and Christian Holschuh
912 **********************************************************************/
915 crusher_audio_module::crusher_audio_module()
920 void crusher_audio_module::activate()
924 void crusher_audio_module::deactivate()
929 void crusher_audio_module::params_changed()
931 bitreduction
.set_params(*params
[param_bits
],
932 *params
[param_morph
],
933 *params
[param_bypass
] > 0.5,
937 samplereduction
[0].set_params(*params
[param_samples
]);
938 samplereduction
[1].set_params(*params
[param_samples
]);
939 lfo
.set_params(*params
[param_lforate
], 0, 0.f
, srate
, 0.5f
);
941 float rad
= *params
[param_lforange
] / 2.f
;
942 smin
= std::max(*params
[param_samples
] - rad
, 1.f
);
943 float sun
= *params
[param_samples
] - rad
- smin
;
944 float smax
= std::min(*params
[param_samples
] + rad
, 250.f
);
945 float sov
= *params
[param_samples
] + rad
- smax
;
951 void crusher_audio_module::set_sample_rate(uint32_t sr
)
954 int meter
[] = {param_meter_inL
, param_meter_inR
, param_meter_outL
, param_meter_outR
};
955 int clip
[] = {param_clip_inL
, param_clip_inR
, param_clip_outL
, param_clip_outR
};
956 meters
.init(params
, meter
, clip
, 4, srate
);
957 bitreduction
.set_sample_rate(srate
);
960 uint32_t crusher_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
962 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
963 numsamples
+= offset
;
965 // everything bypassed
966 while(offset
< numsamples
) {
967 outs
[0][offset
] = ins
[0][offset
];
968 outs
[1][offset
] = ins
[1][offset
];
969 float values
[] = {0, 0, 0, 0};
970 meters
.process(values
);
975 uint32_t orig_offset
= offset
;
976 while(offset
< numsamples
) {
977 // cycle through samples
978 if (*params
[param_lfo
] > 0.5) {
979 samplereduction
[0].set_params(smin
+ sdiff
* (lfo
.get_value() + 0.5));
980 samplereduction
[1].set_params(smin
+ sdiff
* (lfo
.get_value() + 0.5));
982 outs
[0][offset
] = samplereduction
[0].process(ins
[0][offset
] * *params
[param_level_in
]);
983 outs
[1][offset
] = samplereduction
[1].process(ins
[1][offset
] * *params
[param_level_in
]);
984 outs
[0][offset
] = outs
[0][offset
] * *params
[param_morph
] + ins
[0][offset
] * (*params
[param_morph
] * -1 + 1) * *params
[param_level_in
];
985 outs
[1][offset
] = outs
[1][offset
] * *params
[param_morph
] + ins
[1][offset
] * (*params
[param_morph
] * -1 + 1) * *params
[param_level_in
];
986 outs
[0][offset
] = bitreduction
.process(outs
[0][offset
]) * *params
[param_level_out
];
987 outs
[1][offset
] = bitreduction
.process(outs
[1][offset
]) * *params
[param_level_out
];
988 float values
[] = {ins
[0][offset
], ins
[1][offset
], outs
[0][offset
], outs
[1][offset
]};
989 meters
.process(values
);
992 if (*params
[param_lforate
])
994 } // cycle trough samples
995 bypass
.crossfade(ins
, outs
, 2, orig_offset
, numsamples
);
997 meters
.fall(numsamples
);
1000 bool crusher_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
1002 return bitreduction
.get_graph(subindex
, phase
, data
, points
, context
, mode
);
1004 bool crusher_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
1006 return bitreduction
.get_layers(index
, generation
, layers
);
1008 bool crusher_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
1010 return bitreduction
.get_gridline(subindex
, phase
, pos
, vertical
, legend
, context
);