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()
41 lp_post_freq_old
= -1;
42 hp_post_freq_old
= -1;
48 void saturator_audio_module::activate()
54 void saturator_audio_module::deactivate()
59 void saturator_audio_module::params_changed()
61 // set the params of all filters
62 if(*params
[param_lp_pre_freq
] != lp_pre_freq_old
) {
63 lp
[0][0].set_lp_rbj(*params
[param_lp_pre_freq
], 0.707, (float)srate
);
64 if(in_count
> 1 && out_count
> 1)
65 lp
[1][0].copy_coeffs(lp
[0][0]);
66 lp
[0][1].copy_coeffs(lp
[0][0]);
67 if(in_count
> 1 && out_count
> 1)
68 lp
[1][1].copy_coeffs(lp
[0][0]);
69 lp_pre_freq_old
= *params
[param_lp_pre_freq
];
71 if(*params
[param_hp_pre_freq
] != hp_pre_freq_old
) {
72 hp
[0][0].set_hp_rbj(*params
[param_hp_pre_freq
], 0.707, (float)srate
);
73 if(in_count
> 1 && out_count
> 1)
74 hp
[1][0].copy_coeffs(hp
[0][0]);
75 hp
[0][1].copy_coeffs(hp
[0][0]);
76 if(in_count
> 1 && out_count
> 1)
77 hp
[1][1].copy_coeffs(hp
[0][0]);
78 hp_pre_freq_old
= *params
[param_hp_pre_freq
];
80 if(*params
[param_lp_post_freq
] != lp_post_freq_old
) {
81 lp
[0][2].set_lp_rbj(*params
[param_lp_post_freq
], 0.707, (float)srate
);
82 if(in_count
> 1 && out_count
> 1)
83 lp
[1][2].copy_coeffs(lp
[0][2]);
84 lp
[0][3].copy_coeffs(lp
[0][2]);
85 if(in_count
> 1 && out_count
> 1)
86 lp
[1][3].copy_coeffs(lp
[0][2]);
87 lp_post_freq_old
= *params
[param_lp_post_freq
];
89 if(*params
[param_hp_post_freq
] != hp_post_freq_old
) {
90 hp
[0][2].set_hp_rbj(*params
[param_hp_post_freq
], 0.707, (float)srate
);
91 if(in_count
> 1 && out_count
> 1)
92 hp
[1][2].copy_coeffs(hp
[0][2]);
93 hp
[0][3].copy_coeffs(hp
[0][2]);
94 if(in_count
> 1 && out_count
> 1)
95 hp
[1][3].copy_coeffs(hp
[0][2]);
96 hp_post_freq_old
= *params
[param_hp_post_freq
];
98 if(*params
[param_p_freq
] != p_freq_old
or *params
[param_p_level
] != p_level_old
or *params
[param_p_q
] != p_q_old
) {
99 p
[0].set_peakeq_rbj((float)*params
[param_p_freq
], (float)*params
[param_p_q
], (float)*params
[param_p_level
], (float)srate
);
100 if(in_count
> 1 && out_count
> 1)
101 p
[1].copy_coeffs(p
[0]);
102 p_freq_old
= *params
[param_p_freq
];
103 p_level_old
= *params
[param_p_level
];
104 p_q_old
= *params
[param_p_q
];
107 dist
[0].set_params(*params
[param_blend
], *params
[param_drive
]);
108 if(in_count
> 1 && out_count
> 1)
109 dist
[1].set_params(*params
[param_blend
], *params
[param_drive
]);
112 void saturator_audio_module::set_sample_rate(uint32_t sr
)
115 dist
[0].set_sample_rate(sr
);
116 if(in_count
> 1 && out_count
> 1)
117 dist
[1].set_sample_rate(sr
);
118 int meter
[] = {param_meter_inL
, param_meter_inR
, param_meter_outL
, param_meter_outR
};
119 int clip
[] = {param_clip_inL
, param_clip_inR
, param_clip_outL
, param_clip_outR
};
120 meters
.init(params
, meter
, clip
, 4, srate
);
123 uint32_t saturator_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
125 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
126 numsamples
+= offset
;
128 // everything bypassed
129 while(offset
< numsamples
) {
130 if(in_count
> 1 && out_count
> 1) {
131 outs
[0][offset
] = ins
[0][offset
];
132 outs
[1][offset
] = ins
[1][offset
];
133 } else if(in_count
> 1) {
134 outs
[0][offset
] = (ins
[0][offset
] + ins
[1][offset
]) / 2;
135 } else if(out_count
> 1) {
136 outs
[0][offset
] = ins
[0][offset
];
137 outs
[1][offset
] = ins
[0][offset
];
139 outs
[0][offset
] = ins
[0][offset
];
141 float values
[] = {0, 0, 0, 0};
142 meters
.process(values
);
146 uint32_t orig_numsamples
= numsamples
-offset
;
147 uint32_t orig_offset
= offset
;
149 while(offset
< numsamples
) {
150 // cycle through samples
151 float out
[2], in
[2] = {0.f
, 0.f
};
153 if(in_count
> 1 && out_count
> 1) {
154 // stereo in/stereo out
155 // handle full stereo
156 in
[0] = ins
[0][offset
];
157 in
[1] = ins
[1][offset
];
160 // in and/or out mono
162 in
[0] = ins
[0][offset
];
168 proc
[0] = in
[0] * *params
[param_level_in
];
169 proc
[1] = in
[1] * *params
[param_level_in
];
171 float onedivlevelin
= 1.0 / *params
[param_level_in
];
173 for (int i
= 0; i
< c
; ++i
) {
174 // all pre filters in chain
175 proc
[i
] = lp
[i
][1].process(lp
[i
][0].process(proc
[i
]));
176 proc
[i
] = hp
[i
][1].process(hp
[i
][0].process(proc
[i
]));
179 proc
[i
] = dist
[i
].process(proc
[i
]);
182 proc
[i
] = p
[i
].process(proc
[i
]);
184 // all post filters in chain
185 proc
[i
] = lp
[i
][2].process(lp
[i
][3].process(proc
[i
]));
186 proc
[i
] = hp
[i
][2].process(hp
[i
][3].process(proc
[i
]));
189 proc
[i
] *= onedivlevelin
;
191 if (*params
[param_level_in
] > 1)
192 proc
[i
] *= 1 + (*params
[param_level_in
] - 1) / 32;
195 if(in_count
> 1 && out_count
> 1) {
197 out
[0] = ((proc
[0] * *params
[param_mix
]) + in
[0] * (1 - *params
[param_mix
])) * *params
[param_level_out
];
198 outs
[0][offset
] = out
[0];
199 out
[1] = ((proc
[1] * *params
[param_mix
]) + in
[1] * (1 - *params
[param_mix
])) * *params
[param_level_out
];
200 outs
[1][offset
] = out
[1];
201 } else if(out_count
> 1) {
202 // mono -> pseudo stereo
203 out
[0] = ((proc
[0] * *params
[param_mix
]) + in
[0] * (1 - *params
[param_mix
])) * *params
[param_level_out
];
204 outs
[0][offset
] = out
[0];
206 outs
[1][offset
] = out
[1];
210 out
[0] = ((proc
[0] * *params
[param_mix
]) + in
[0] * (1 - *params
[param_mix
])) * *params
[param_level_out
];
211 outs
[0][offset
] = out
[0];
213 float values
[] = {in
[0], in
[1], out
[0], out
[1]};
214 meters
.process(values
);
218 } // cycle trough samples
239 bypass
.crossfade(ins
, outs
, 2, orig_offset
, orig_numsamples
);
241 meters
.fall(numsamples
);
245 /**********************************************************************
246 * EXCITER by Markus Schmidt
247 **********************************************************************/
249 exciter_audio_module::exciter_audio_module()
253 ceil_active_old
= false;
259 void exciter_audio_module::activate()
266 void exciter_audio_module::deactivate()
271 void exciter_audio_module::params_changed()
273 // set the params of all filters
274 if(*params
[param_freq
] != freq_old
) {
275 hp
[0][0].set_hp_rbj(*params
[param_freq
], 0.707, (float)srate
);
276 hp
[0][1].copy_coeffs(hp
[0][0]);
277 hp
[0][2].copy_coeffs(hp
[0][0]);
278 hp
[0][3].copy_coeffs(hp
[0][0]);
279 if(in_count
> 1 && out_count
> 1) {
280 hp
[1][0].copy_coeffs(hp
[0][0]);
281 hp
[1][1].copy_coeffs(hp
[0][0]);
282 hp
[1][2].copy_coeffs(hp
[0][0]);
283 hp
[1][3].copy_coeffs(hp
[0][0]);
285 freq_old
= *params
[param_freq
];
287 // set the params of all filters
288 if(*params
[param_ceil
] != ceil_old
or *params
[param_ceil_active
] != ceil_active_old
) {
289 lp
[0][0].set_lp_rbj(*params
[param_ceil
], 0.707, (float)srate
);
290 lp
[0][1].copy_coeffs(lp
[0][0]);
291 lp
[1][0].copy_coeffs(lp
[0][0]);
292 lp
[1][1].copy_coeffs(lp
[0][0]);
293 ceil_old
= *params
[param_ceil
];
294 ceil_active_old
= *params
[param_ceil_active
];
297 dist
[0].set_params(*params
[param_blend
], *params
[param_drive
]);
298 if(in_count
> 1 && out_count
> 1)
299 dist
[1].set_params(*params
[param_blend
], *params
[param_drive
]);
302 void exciter_audio_module::set_sample_rate(uint32_t sr
)
305 dist
[0].set_sample_rate(sr
);
306 if(in_count
> 1 && out_count
> 1)
307 dist
[1].set_sample_rate(sr
);
308 int meter
[] = {param_meter_in
, param_meter_out
, param_meter_drive
};
309 int clip
[] = {param_clip_in
, param_clip_out
, -1};
310 meters
.init(params
, meter
, clip
, 3, srate
);
313 uint32_t exciter_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
315 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
316 numsamples
+= offset
;
318 // everything bypassed
319 while(offset
< numsamples
) {
320 if(in_count
> 1 && out_count
> 1) {
321 outs
[0][offset
] = ins
[0][offset
];
322 outs
[1][offset
] = ins
[1][offset
];
323 } else if(in_count
> 1) {
324 outs
[0][offset
] = (ins
[0][offset
] + ins
[1][offset
]) / 2;
325 } else if(out_count
> 1) {
326 outs
[0][offset
] = ins
[0][offset
];
327 outs
[1][offset
] = ins
[0][offset
];
329 outs
[0][offset
] = ins
[0][offset
];
331 float values
[] = {0, 0, 0, 0, 0};
332 meters
.process(values
);
338 uint32_t orig_numsamples
= numsamples
-offset
;
339 uint32_t orig_offset
= offset
;
342 float in2out
= *params
[param_listen
] > 0.f
? 0.f
: 1.f
;
345 while(offset
< numsamples
) {
346 // cycle through samples
347 float out
[2], in
[2] = {0.f
, 0.f
};
348 float maxDrive
= 0.f
;
351 if(in_count
> 1 && out_count
> 1) {
352 // stereo in/stereo out
353 // handle full stereo
354 in
[0] = ins
[0][offset
];
355 in
[0] *= *params
[param_level_in
];
356 in
[1] = ins
[1][offset
];
357 in
[1] *= *params
[param_level_in
];
360 // in and/or out mono
362 in
[0] = ins
[0][offset
];
363 in
[0] *= *params
[param_level_in
];
372 for (int i
= 0; i
< c
; ++i
) {
373 // all pre filters in chain
374 proc
[i
] = hp
[i
][1].process(hp
[i
][0].process(proc
[i
]));
377 proc
[i
] = dist
[i
].process(proc
[i
]);
379 // all post filters in chain
380 proc
[i
] = hp
[i
][2].process(hp
[i
][3].process(proc
[i
]));
382 if(*params
[param_ceil_active
] > 0.5f
) {
383 // all H/P post filters in chain
384 proc
[i
] = lp
[i
][0].process(lp
[i
][1].process(proc
[i
]));
388 maxDrive
= dist
[0].get_distortion_level() * *params
[param_amount
];
390 if(in_count
> 1 && out_count
> 1) {
391 maxDrive
= std::max(maxDrive
, dist
[1].get_distortion_level() * *params
[param_amount
]);
393 out
[0] = (proc
[0] * *params
[param_amount
] + in2out
* in
[0]) * *params
[param_level_out
];
394 out
[1] = (proc
[1] * *params
[param_amount
] + in2out
* in
[1]) * *params
[param_level_out
];
395 outs
[0][offset
] = out
[0];
396 outs
[1][offset
] = out
[1];
397 } else if(out_count
> 1) {
398 // mono -> pseudo stereo
399 out
[1] = out
[0] = (proc
[0] * *params
[param_amount
] + in2out
* in
[0]) * *params
[param_level_out
];
400 outs
[0][offset
] = out
[0];
401 outs
[1][offset
] = out
[1];
405 out
[0] = (proc
[0] * *params
[param_amount
] + in2out
* in
[0]) * *params
[param_level_out
];
406 outs
[0][offset
] = out
[0];
408 float values
[] = {(in
[0] + in
[1]) / 2, (out
[0] + out
[1]) / 2, maxDrive
};
409 meters
.process(values
);
412 } // cycle trough samples
413 bypass
.crossfade(ins
, outs
, 2, orig_offset
, orig_numsamples
);
429 meters
.fall(numsamples
);
433 /**********************************************************************
434 * BASS ENHANCER by Markus Schmidt
435 **********************************************************************/
437 bassenhancer_audio_module::bassenhancer_audio_module()
441 floor_active_old
= false;
447 void bassenhancer_audio_module::activate()
453 void bassenhancer_audio_module::deactivate()
458 void bassenhancer_audio_module::params_changed()
460 // set the params of all filters
461 if(*params
[param_freq
] != freq_old
) {
462 lp
[0][0].set_lp_rbj(*params
[param_freq
], 0.707, (float)srate
);
463 lp
[0][1].copy_coeffs(lp
[0][0]);
464 lp
[0][2].copy_coeffs(lp
[0][0]);
465 lp
[0][3].copy_coeffs(lp
[0][0]);
466 if(in_count
> 1 && out_count
> 1) {
467 lp
[1][0].copy_coeffs(lp
[0][0]);
468 lp
[1][1].copy_coeffs(lp
[0][0]);
469 lp
[1][2].copy_coeffs(lp
[0][0]);
470 lp
[1][3].copy_coeffs(lp
[0][0]);
472 freq_old
= *params
[param_freq
];
474 // set the params of all filters
475 if(*params
[param_floor
] != floor_old
or *params
[param_floor_active
] != floor_active_old
) {
476 hp
[0][0].set_hp_rbj(*params
[param_floor
], 0.707, (float)srate
);
477 hp
[0][1].copy_coeffs(hp
[0][0]);
478 hp
[1][0].copy_coeffs(hp
[0][0]);
479 hp
[1][1].copy_coeffs(hp
[0][0]);
480 floor_old
= *params
[param_floor
];
481 floor_active_old
= *params
[param_floor_active
];
484 dist
[0].set_params(*params
[param_blend
], *params
[param_drive
]);
485 if(in_count
> 1 && out_count
> 1)
486 dist
[1].set_params(*params
[param_blend
], *params
[param_drive
]);
489 void bassenhancer_audio_module::set_sample_rate(uint32_t sr
)
492 dist
[0].set_sample_rate(sr
);
493 if(in_count
> 1 && out_count
> 1)
494 dist
[1].set_sample_rate(sr
);
495 int meter
[] = {param_meter_in
, param_meter_out
, param_meter_drive
};
496 int clip
[] = {param_clip_in
, param_clip_out
, -1};
497 meters
.init(params
, meter
, clip
, 3, srate
);
500 uint32_t bassenhancer_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 numsamples
+= offset
;
505 // everything bypassed
506 while(offset
< numsamples
) {
507 if(in_count
> 1 && out_count
> 1) {
508 outs
[0][offset
] = ins
[0][offset
];
509 outs
[1][offset
] = ins
[1][offset
];
510 } else if(in_count
> 1) {
511 outs
[0][offset
] = (ins
[0][offset
] + ins
[1][offset
]) / 2;
512 } else if(out_count
> 1) {
513 outs
[0][offset
] = ins
[0][offset
];
514 outs
[1][offset
] = ins
[0][offset
];
516 outs
[0][offset
] = ins
[0][offset
];
518 float values
[] = {0, 0, 0};
519 meters
.process(values
);
524 uint32_t orig_numsamples
= numsamples
-offset
;
525 uint32_t orig_offset
= offset
;
526 while(offset
< numsamples
) {
527 // cycle through samples
528 float out
[2], in
[2] = {0.f
, 0.f
};
529 float maxDrive
= 0.f
;
532 if(in_count
> 1 && out_count
> 1) {
533 // stereo in/stereo out
534 // handle full stereo
535 in
[0] = ins
[0][offset
];
536 in
[0] *= *params
[param_level_in
];
537 in
[1] = ins
[1][offset
];
538 in
[1] *= *params
[param_level_in
];
541 // in and/or out mono
543 in
[0] = ins
[0][offset
];
544 in
[0] *= *params
[param_level_in
];
553 for (int i
= 0; i
< c
; ++i
) {
554 // all pre filters in chain
555 proc
[i
] = lp
[i
][1].process(lp
[i
][0].process(proc
[i
]));
558 proc
[i
] = dist
[i
].process(proc
[i
]);
560 // all post filters in chain
561 proc
[i
] = lp
[i
][2].process(lp
[i
][3].process(proc
[i
]));
563 if(*params
[param_floor_active
] > 0.5f
) {
564 // all H/P post filters in chain
565 proc
[i
] = hp
[i
][0].process(hp
[i
][1].process(proc
[i
]));
570 if(in_count
> 1 && out_count
> 1) {
572 if(*params
[param_listen
] > 0.f
)
573 out
[0] = proc
[0] * *params
[param_amount
] * *params
[param_level_out
];
575 out
[0] = (proc
[0] * *params
[param_amount
] + in
[0]) * *params
[param_level_out
];
576 outs
[0][offset
] = out
[0];
577 if(*params
[param_listen
] > 0.f
)
578 out
[1] = proc
[1] * *params
[param_amount
] * *params
[param_level_out
];
580 out
[1] = (proc
[1] * *params
[param_amount
] + in
[1]) * *params
[param_level_out
];
581 outs
[1][offset
] = out
[1];
582 maxDrive
= std::max(dist
[0].get_distortion_level() * *params
[param_amount
],
583 dist
[1].get_distortion_level() * *params
[param_amount
]);
584 } else if(out_count
> 1) {
585 // mono -> pseudo stereo
586 if(*params
[param_listen
] > 0.f
)
587 out
[0] = proc
[0] * *params
[param_amount
] * *params
[param_level_out
];
589 out
[0] = (proc
[0] * *params
[param_amount
] + in
[0]) * *params
[param_level_out
];
590 outs
[0][offset
] = out
[0];
592 outs
[1][offset
] = out
[1];
593 maxDrive
= dist
[0].get_distortion_level() * *params
[param_amount
];
597 if(*params
[param_listen
] > 0.f
)
598 out
[0] = proc
[0] * *params
[param_amount
] * *params
[param_level_out
];
600 out
[0] = (proc
[0] * *params
[param_amount
] + in
[0]) * *params
[param_level_out
];
601 outs
[0][offset
] = out
[0];
602 maxDrive
= dist
[0].get_distortion_level() * *params
[param_amount
];
605 float values
[] = {(in
[0] + in
[1]) / 2, (out
[0] + out
[1]) / 2, maxDrive
};
606 meters
.process(values
);
609 } // cycle trough samples
610 bypass
.crossfade(ins
, outs
, 2, orig_offset
, orig_numsamples
);
625 meters
.fall(numsamples
);
629 /**********************************************************************
630 * TAPESIMULATOR by Markus Schmidt
631 **********************************************************************/
633 tapesimulator_audio_module::tapesimulator_audio_module() {
647 transients
.set_channels(channels
);
650 void tapesimulator_audio_module::activate() {
654 void tapesimulator_audio_module::deactivate() {
658 void tapesimulator_audio_module::params_changed() {
659 if(*params
[param_lp
] != lp_old
or *params
[param_mechanical
] != mech_old
) {
660 lp
[0][0].set_lp_rbj(*params
[param_lp
], 0.707, (float)srate
);
661 lp
[0][1].copy_coeffs(lp
[0][0]);
662 lp
[1][0].copy_coeffs(lp
[0][0]);
663 lp
[1][1].copy_coeffs(lp
[0][0]);
664 lp_old
= *params
[param_lp
];
665 mech_old
= *params
[param_mechanical
] > 0.5;
667 transients
.set_params(50.f
/ (*params
[param_speed
] + 1),
668 -0.05f
/ (*params
[param_speed
] + 1),
673 lfo1
.set_params((*params
[param_speed
] + 1) / 2, 0, 0.f
, srate
, 1.f
);
674 lfo2
.set_params((*params
[param_speed
] + 1) / 9.38, 0, 0.f
, srate
, 1.f
);
675 if (*params
[param_level_out
] != output_old
) {
676 output_old
= *params
[param_level_out
];
677 redraw_output
= true;
681 uint32_t tapesimulator_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
) {
682 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
683 uint32_t orig_offset
= offset
;
684 for(uint32_t i
= offset
; i
< offset
+ numsamples
; i
++) {
687 float Lin
= ins
[0][i
];
688 float Rin
= ins
[1][i
];
690 outs
[0][i
] = ins
[0][i
];
691 outs
[1][i
] = ins
[1][i
];
692 float values
[] = {0, 0, 0, 0};
693 meters
.process(values
);
698 if(*params
[param_magnetical
] > 0.5f
) {
699 float values
[] = {L
, R
};
700 transients
.process(values
, (L
+ R
) / 2.f
);
706 if (*params
[param_noise
]) {
707 float Lnoise
= rand() % 2 - 1;
708 float Rnoise
= rand() % 2 - 1;
709 Lnoise
= noisefilters
[0][2].process(noisefilters
[0][1].process(noisefilters
[0][0].process(Lnoise
)));
710 Rnoise
= noisefilters
[1][2].process(noisefilters
[1][1].process(noisefilters
[1][0].process(Rnoise
)));
711 L
+= Lnoise
* *params
[param_noise
] / 12.f
;
712 R
+= Rnoise
* *params
[param_noise
] / 12.f
;
715 // lfo filters / phasing
716 if (*params
[param_mechanical
]) {
718 float freqL1
= *params
[param_lp
] * (1 - ((lfo1
.get_value() + 1) * 0.3 * *params
[param_mechanical
]));
719 float freqL2
= *params
[param_lp
] * (1 - ((lfo2
.get_value() + 1) * 0.2 * *params
[param_mechanical
]));
721 float freqR1
= *params
[param_lp
] * (1 - ((lfo1
.get_value() * -1 + 1) * 0.3 * *params
[param_mechanical
]));
722 float freqR2
= *params
[param_lp
] * (1 - ((lfo2
.get_value() * -1 + 1) * 0.2 * *params
[param_mechanical
]));
724 lp
[0][0].set_lp_rbj(freqL1
, 0.707, (float)srate
);
725 lp
[0][1].set_lp_rbj(freqL2
, 0.707, (float)srate
);
727 lp
[1][0].set_lp_rbj(freqR1
, 0.707, (float)srate
);
728 lp
[1][1].set_lp_rbj(freqR2
, 0.707, (float)srate
);
731 float _phase
= lfo1
.get_value() * *params
[param_mechanical
] * -36;
733 float _phase_cos_coef
= cos(_phase
/ 180 * M_PI
);
734 float _phase_sin_coef
= sin(_phase
/ 180 * M_PI
);
736 float _l
= L
* _phase_cos_coef
- R
* _phase_sin_coef
;
737 float _r
= L
* _phase_sin_coef
+ R
* _phase_cos_coef
;
743 L
*= *params
[param_level_in
];
744 R
*= *params
[param_level_in
];
749 // save for drawing input/output curve
756 if (*params
[param_post
] < 0.5) {
757 L
= lp
[0][1].process(lp
[0][0].process(L
));
758 R
= lp
[1][1].process(lp
[1][0].process(R
));
762 if (L
) L
= L
/ fabs(L
) * (1 - exp((-1) * 3 * fabs(L
)));
763 if (R
) R
= R
/ fabs(R
) * (1 - exp((-1) * 3 * fabs(R
)));
765 if (Lo
) Lo
= Lo
/ fabs(Lo
) * (1 - exp((-1) * 3 * fabs(Lo
)));
766 if (Ro
) Ro
= Ro
/ fabs(Ro
) * (1 - exp((-1) * 3 * fabs(Ro
)));
769 if (*params
[param_post
] >= 0.5) {
770 L
= lp
[0][1].process(lp
[0][0].process(L
));
771 R
= lp
[1][1].process(lp
[1][0].process(R
));
775 L
= L
* *params
[param_mix
] + Lin
* (*params
[param_mix
] * -1 + 1);
776 R
= R
* *params
[param_mix
] + Rin
* (*params
[param_mix
] * -1 + 1);
779 L
*= *params
[param_level_out
];
780 R
*= *params
[param_level_out
];
792 // LFO's should go on
797 rms
= std::max((double)rms
, (fabs(Lo
) + fabs(Ro
)) / 2);
798 input
= std::max((double)input
, (fabs(Lc
) + fabs(Rc
)) / 2);
800 float values
[] = {inL
, inR
, outs
[0][i
], outs
[1][i
]};
801 meters
.process(values
);
805 bypass
.crossfade(ins
, outs
, 2, orig_offset
, numsamples
);
806 meters
.fall(numsamples
);
810 void tapesimulator_audio_module::set_sample_rate(uint32_t sr
)
813 int meter
[] = {param_meter_inL
, param_meter_inR
, param_meter_outL
, param_meter_outR
};
814 int clip
[] = {param_clip_inL
, param_clip_inR
, param_clip_outL
, param_clip_outR
};
815 meters
.init(params
, meter
, clip
, 4, srate
);
816 transients
.set_sample_rate(srate
);
817 noisefilters
[0][0].set_hp_rbj(120.f
, 0.707, (float)srate
);
818 noisefilters
[1][0].copy_coeffs(noisefilters
[0][0]);
819 noisefilters
[0][1].set_lp_rbj(5500.f
, 0.707, (float)srate
);
820 noisefilters
[1][1].copy_coeffs(noisefilters
[0][1]);
821 noisefilters
[0][2].set_highshelf_rbj(1000.f
, 0.707, 0.5, (float)srate
);
822 noisefilters
[1][2].copy_coeffs(noisefilters
[0][2]);
825 bool tapesimulator_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
829 if(index
== param_lp
and phase
) {
830 set_channel_color(context
, subindex
);
831 return ::get_graph(*this, subindex
, data
, points
);
832 } else if (index
== param_level_in
and !phase
) {
834 context
->set_source_rgba(0.15, 0.2, 0.0, 0.3);
835 context
->set_line_width(1);
837 for (int i
= 0; i
< points
; i
++) {
839 float input
= dB_grid_inv(-1.0 + (float)i
* 2.0 / ((float)points
- 1.f
));
840 data
[i
] = dB_grid(input
);
842 float output
= 1 - exp(-3 * (pow(2, -10 + 14 * (float)i
/ (float) points
)));
843 data
[i
] = dB_grid(output
* *params
[param_level_out
]);
850 float tapesimulator_audio_module::freq_gain(int index
, double freq
) const
852 return lp
[index
][0].freq_gain(freq
, srate
) * lp
[index
][1].freq_gain(freq
, srate
);
855 bool tapesimulator_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
859 if (index
== param_level_in
) {
861 vertical
= (subindex
& 1) != 0;
862 bool result
= get_freq_gridline(subindex
>> 1, pos
, tmp
, legend
, context
, false);
863 if (result
&& vertical
) {
864 if ((subindex
& 4) && !legend
.empty()) {
868 size_t pos
= legend
.find(" dB");
869 if (pos
!= std::string::npos
)
872 pos
= 0.5 + 0.5 * pos
;
875 } else if (index
== param_lp
) {
876 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
);
880 bool tapesimulator_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
882 if (index
== param_level_in
and !subindex
and phase
) {
883 x
= log(input
) / log(2) / 14.f
+ 5.f
/ 7.f
;
884 y
= dB_grid(rms
* *params
[param_level_out
]);
891 bool tapesimulator_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
894 // always draw grid on cache if surfaces are new on both widgets
896 layers
|= LG_CACHE_GRID
;
897 // compression: dot in realtime, graphs as cache on new surfaces
898 if (index
== param_level_in
and (!generation
or redraw_output
)) {
899 layers
|= LG_CACHE_GRAPH
;
900 redraw_output
= false;
902 if (index
== param_level_in
)
903 layers
|= LG_REALTIME_DOT
;
904 // frequency: both graphs in realtime
905 if (index
== param_lp
)
906 layers
|= LG_REALTIME_GRAPH
;
913 /**********************************************************************
914 * CRUSHER by Markus Schmidt and Christian Holschuh
915 **********************************************************************/
918 crusher_audio_module::crusher_audio_module()
923 void crusher_audio_module::activate()
927 void crusher_audio_module::deactivate()
932 void crusher_audio_module::params_changed()
934 bitreduction
.set_params(*params
[param_bits
],
935 *params
[param_morph
],
936 *params
[param_bypass
] > 0.5,
940 samplereduction
[0].set_params(*params
[param_samples
]);
941 samplereduction
[1].set_params(*params
[param_samples
]);
942 lfo
.set_params(*params
[param_lforate
], 0, 0.f
, srate
, 0.5f
);
944 float rad
= *params
[param_lforange
] / 2.f
;
945 smin
= std::max(*params
[param_samples
] - rad
, 1.f
);
946 float sun
= *params
[param_samples
] - rad
- smin
;
947 float smax
= std::min(*params
[param_samples
] + rad
, 250.f
);
948 float sov
= *params
[param_samples
] + rad
- smax
;
954 void crusher_audio_module::set_sample_rate(uint32_t sr
)
957 int meter
[] = {param_meter_inL
, param_meter_inR
, param_meter_outL
, param_meter_outR
};
958 int clip
[] = {param_clip_inL
, param_clip_inR
, param_clip_outL
, param_clip_outR
};
959 meters
.init(params
, meter
, clip
, 4, srate
);
960 bitreduction
.set_sample_rate(srate
);
963 uint32_t crusher_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
965 bool bypassed
= bypass
.update(*params
[param_bypass
] > 0.5f
, numsamples
);
966 numsamples
+= offset
;
968 // everything bypassed
969 while(offset
< numsamples
) {
970 outs
[0][offset
] = ins
[0][offset
];
971 outs
[1][offset
] = ins
[1][offset
];
972 float values
[] = {0, 0, 0, 0};
973 meters
.process(values
);
978 uint32_t orig_numsamples
= numsamples
-offset
;
979 uint32_t orig_offset
= offset
;
980 while(offset
< numsamples
) {
981 // cycle through samples
982 if (*params
[param_lfo
] > 0.5) {
983 samplereduction
[0].set_params(smin
+ sdiff
* (lfo
.get_value() + 0.5));
984 samplereduction
[1].set_params(smin
+ sdiff
* (lfo
.get_value() + 0.5));
986 outs
[0][offset
] = samplereduction
[0].process(ins
[0][offset
] * *params
[param_level_in
]);
987 outs
[1][offset
] = samplereduction
[1].process(ins
[1][offset
] * *params
[param_level_in
]);
988 outs
[0][offset
] = outs
[0][offset
] * *params
[param_morph
] + ins
[0][offset
] * (*params
[param_morph
] * -1 + 1) * *params
[param_level_in
];
989 outs
[1][offset
] = outs
[1][offset
] * *params
[param_morph
] + ins
[1][offset
] * (*params
[param_morph
] * -1 + 1) * *params
[param_level_in
];
990 outs
[0][offset
] = bitreduction
.process(outs
[0][offset
]) * *params
[param_level_out
];
991 outs
[1][offset
] = bitreduction
.process(outs
[1][offset
]) * *params
[param_level_out
];
992 float values
[] = {ins
[0][offset
], ins
[1][offset
], outs
[0][offset
], outs
[1][offset
]};
993 meters
.process(values
);
996 if (*params
[param_lforate
])
998 } // cycle trough samples
999 bypass
.crossfade(ins
, outs
, 2, orig_offset
, orig_numsamples
);
1001 meters
.fall(numsamples
);
1002 return outputs_mask
;
1004 bool crusher_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
1006 return bitreduction
.get_graph(subindex
, phase
, data
, points
, context
, mode
);
1008 bool crusher_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
1010 return bitreduction
.get_layers(index
, generation
, layers
);
1012 bool crusher_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
1014 return bitreduction
.get_gridline(subindex
, phase
, pos
, vertical
, legend
, context
);