+ Phaser: add live frequency response graph
[calf.git] / src / calf / modules.h
blobc55d568e02d06687c830a55485420c5d1011adc9
1 /* Calf DSP Library
2 * Example audio modules
4 * Copyright (C) 2001-2007 Krzysztof Foltman
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., 59 Temple Place, Suite 330,
19 * Boston, MA 02111-1307, USA.
21 #ifndef __CALF_MODULES_H
22 #define __CALF_MODULES_H
24 #include <assert.h>
25 #include "biquad.h"
26 #include "inertia.h"
27 #include "audio_fx.h"
28 #include "multichorus.h"
29 #include "giface.h"
30 #include "metadata.h"
31 #include "loudness.h"
32 #include "primitives.h"
34 namespace calf_plugins {
36 using namespace dsp;
38 struct ladspa_plugin_info;
40 #if 0
41 class amp_audio_module: public null_audio_module
43 public:
44 enum { in_count = 2, out_count = 2, param_count = 1, support_midi = false, require_midi = false, rt_capable = true };
45 float *ins[2];
46 float *outs[2];
47 float *params[1];
48 uint32_t srate;
49 static parameter_properties param_props[];
50 uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
51 if (!inputs_mask)
52 return 0;
53 float gain = *params[0];
54 numsamples += offset;
55 for (uint32_t i = offset; i < numsamples; i++) {
56 outs[0][i] = ins[0][i] * gain;
57 outs[1][i] = ins[1][i] * gain;
59 return inputs_mask;
62 #endif
64 class flanger_audio_module: public audio_module<flanger_metadata>, public line_graph_iface
66 public:
67 dsp::simple_flanger<float, 2048> left, right;
68 float *ins[in_count];
69 float *outs[out_count];
70 float *params[param_count];
71 uint32_t srate;
72 bool clear_reset;
73 float last_r_phase;
74 bool is_active;
75 public:
76 flanger_audio_module() {
77 is_active = false;
79 void set_sample_rate(uint32_t sr);
80 void params_changed() {
81 float dry = *params[par_dryamount];
82 float wet = *params[par_amount];
83 float rate = *params[par_rate]; // 0.01*pow(1000.0f,*params[par_rate]);
84 float min_delay = *params[par_delay] / 1000.0;
85 float mod_depth = *params[par_depth] / 1000.0;
86 float fb = *params[par_fb];
87 left.set_dry(dry); right.set_dry(dry);
88 left.set_wet(wet); right.set_wet(wet);
89 left.set_rate(rate); right.set_rate(rate);
90 left.set_min_delay(min_delay); right.set_min_delay(min_delay);
91 left.set_mod_depth(mod_depth); right.set_mod_depth(mod_depth);
92 left.set_fb(fb); right.set_fb(fb);
93 float r_phase = *params[par_stereo] * (1.f / 360.f);
94 clear_reset = false;
95 if (*params[par_reset] >= 0.5) {
96 clear_reset = true;
97 left.reset_phase(0.f);
98 right.reset_phase(r_phase);
99 } else {
100 if (fabs(r_phase - last_r_phase) > 0.0001f) {
101 right.phase = left.phase;
102 right.inc_phase(r_phase);
103 last_r_phase = r_phase;
107 void params_reset()
109 if (clear_reset) {
110 *params[par_reset] = 0.f;
111 clear_reset = false;
114 void activate();
115 void deactivate();
116 uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
117 left.process(outs[0] + offset, ins[0] + offset, nsamples);
118 right.process(outs[1] + offset, ins[1] + offset, nsamples);
119 return outputs_mask; // XXXKF allow some delay after input going blank
121 bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
122 bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
123 float freq_gain(int subindex, float freq, float srate);
126 class phaser_audio_module: public audio_module<phaser_metadata>, public line_graph_iface
128 public:
129 float *ins[in_count];
130 float *outs[out_count];
131 float *params[param_count];
132 uint32_t srate;
133 bool clear_reset;
134 float last_r_phase;
135 dsp::simple_phaser<12> left, right;
136 bool is_active;
137 public:
138 phaser_audio_module() {
139 is_active = false;
141 void params_changed() {
142 float dry = *params[par_dryamount];
143 float wet = *params[par_amount];
144 float rate = *params[par_rate]; // 0.01*pow(1000.0f,*params[par_rate]);
145 float base_frq = *params[par_freq];
146 float mod_depth = *params[par_depth];
147 float fb = *params[par_fb];
148 int stages = (int)*params[par_stages];
149 left.set_dry(dry); right.set_dry(dry);
150 left.set_wet(wet); right.set_wet(wet);
151 left.set_rate(rate); right.set_rate(rate);
152 left.set_base_frq(base_frq); right.set_base_frq(base_frq);
153 left.set_mod_depth(mod_depth); right.set_mod_depth(mod_depth);
154 left.set_fb(fb); right.set_fb(fb);
155 left.set_stages(stages); right.set_stages(stages);
156 float r_phase = *params[par_stereo] * (1.f / 360.f);
157 clear_reset = false;
158 if (*params[par_reset] >= 0.5) {
159 clear_reset = true;
160 left.reset_phase(0.f);
161 right.reset_phase(r_phase);
162 } else {
163 if (fabs(r_phase - last_r_phase) > 0.0001f) {
164 right.phase = left.phase;
165 right.inc_phase(r_phase);
166 last_r_phase = r_phase;
170 void params_reset()
172 if (clear_reset) {
173 *params[par_reset] = 0.f;
174 clear_reset = false;
177 void activate();
178 void set_sample_rate(uint32_t sr);
179 void deactivate();
180 uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
181 left.process(outs[0] + offset, ins[0] + offset, nsamples);
182 right.process(outs[1] + offset, ins[1] + offset, nsamples);
183 return outputs_mask; // XXXKF allow some delay after input going blank
185 bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
186 bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
187 float freq_gain(int subindex, float freq, float srate);
190 class reverb_audio_module: public audio_module<reverb_metadata>
192 public:
193 dsp::reverb<float> reverb;
194 dsp::simple_delay<16384, stereo_sample<float> > pre_delay;
195 dsp::onepole<float> left_lo, right_lo, left_hi, right_hi;
196 uint32_t srate;
197 gain_smoothing amount, dryamount;
198 int predelay_amt;
199 float *ins[in_count];
200 float *outs[out_count];
201 float *params[param_count];
203 void params_changed() {
204 //reverb.set_time(0.5*pow(8.0f, *params[par_decay]));
205 //reverb.set_cutoff(2000*pow(10.0f, *params[par_hfdamp]));
206 reverb.set_type_and_diffusion(fastf2i_drm(*params[par_roomsize]), *params[par_diffusion]);
207 reverb.set_time(*params[par_decay]);
208 reverb.set_cutoff(*params[par_hfdamp]);
209 amount.set_inertia(*params[par_amount]);
210 dryamount.set_inertia(*params[par_dry]);
211 left_lo.set_lp(dsp::clip(*params[par_treblecut], 20.f, (float)(srate * 0.49f)), srate);
212 left_hi.set_hp(dsp::clip(*params[par_basscut], 20.f, (float)(srate * 0.49f)), srate);
213 right_lo.copy_coeffs(left_lo);
214 right_hi.copy_coeffs(left_hi);
215 predelay_amt = srate * (*params[par_predelay]) * (1.0f / 1000.0f) + 1;
217 uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
218 numsamples += offset;
220 for (uint32_t i = offset; i < numsamples; i++) {
221 float dry = dryamount.get();
222 float wet = amount.get();
223 stereo_sample<float> s(ins[0][i], ins[1][i]);
224 stereo_sample<float> s2 = pre_delay.process(s, predelay_amt);
226 float rl = s2.left, rr = s2.right;
227 rl = left_lo.process(left_hi.process(rl));
228 rr = right_lo.process(right_hi.process(rr));
229 reverb.process(rl, rr);
230 outs[0][i] = dry*s.left + wet*rl;
231 outs[1][i] = dry*s.right + wet*rr;
233 reverb.extra_sanitize();
234 left_lo.sanitize();
235 left_hi.sanitize();
236 right_lo.sanitize();
237 right_hi.sanitize();
238 return outputs_mask;
240 void activate();
241 void set_sample_rate(uint32_t sr);
242 void deactivate();
245 class filter_audio_module: public audio_module<filter_metadata>, public line_graph_iface
247 public:
248 float *ins[in_count];
249 float *outs[out_count];
250 float *params[param_count];
251 dsp::biquad_d1<float> left[3], right[3];
252 uint32_t srate;
253 int order;
254 inertia<exponential_ramp> inertia_cutoff, inertia_resonance;
255 once_per_n timer;
256 bool is_active;
258 filter_audio_module()
259 : inertia_cutoff(exponential_ramp(128), 20)
260 , inertia_resonance(exponential_ramp(128), 20)
261 , timer(128)
263 order = 0;
264 is_active = false;
267 void calculate_filter()
269 float freq = inertia_cutoff.get_last();
270 // printf("freq=%g inr.cnt=%d timer.left=%d\n", freq, inertia_cutoff.count, timer.left);
271 // XXXKF this is resonance of a single stage, obviously for three stages, resonant gain will be different
272 float q = inertia_resonance.get_last();
273 // XXXKF this is highly inefficient and should be replaced as soon as I have fast f2i in primitives.h
274 int mode = (int)*params[par_mode];
275 // printf("freq = %f q = %f mode = %d\n", freq, q, mode);
276 if (mode < 3) {
277 order = mode + 1;
278 left[0].set_lp_rbj(freq, pow(q, 1.0 / order), srate);
279 } else {
280 order = mode - 2;
281 left[0].set_hp_rbj(freq, pow(q, 1.0 / order), srate);
283 // XXXKF this is highly inefficient and should be replaced as soon as I have fast f2i in primitives.h
284 int inertia = dsp::fastf2i_drm(*params[par_inertia]);
285 if (inertia != inertia_cutoff.ramp.length()) {
286 inertia_cutoff.ramp.set_length(inertia);
287 inertia_resonance.ramp.set_length(inertia);
290 right[0].copy_coeffs(left[0]);
291 for (int i = 1; i < order; i++) {
292 left[i].copy_coeffs(left[0]);
293 right[i].copy_coeffs(left[0]);
296 void params_changed()
298 inertia_cutoff.set_inertia(*params[par_cutoff]);
299 inertia_resonance.set_inertia(*params[par_resonance]);
300 calculate_filter();
302 void on_timer()
304 inertia_cutoff.step();
305 inertia_resonance.step();
306 calculate_filter();
308 void activate();
309 void set_sample_rate(uint32_t sr);
310 void deactivate();
311 inline int process_channel(dsp::biquad_d1<float> *filter, float *in, float *out, uint32_t numsamples, int inmask) {
312 if (inmask) {
313 switch(order) {
314 case 1:
315 for (uint32_t i = 0; i < numsamples; i++)
316 out[i] = filter[0].process(in[i]);
317 break;
318 case 2:
319 for (uint32_t i = 0; i < numsamples; i++)
320 out[i] = filter[1].process(filter[0].process(in[i]));
321 break;
322 case 3:
323 for (uint32_t i = 0; i < numsamples; i++)
324 out[i] = filter[2].process(filter[1].process(filter[0].process(in[i])));
325 break;
327 } else {
328 if (filter[order - 1].empty())
329 return 0;
330 switch(order) {
331 case 1:
332 for (uint32_t i = 0; i < numsamples; i++)
333 out[i] = filter[0].process_zeroin();
334 break;
335 case 2:
336 if (filter[0].empty())
337 for (uint32_t i = 0; i < numsamples; i++)
338 out[i] = filter[1].process_zeroin();
339 else
340 for (uint32_t i = 0; i < numsamples; i++)
341 out[i] = filter[1].process(filter[0].process_zeroin());
342 break;
343 case 3:
344 if (filter[1].empty())
345 for (uint32_t i = 0; i < numsamples; i++)
346 out[i] = filter[2].process_zeroin();
347 else
348 for (uint32_t i = 0; i < numsamples; i++)
349 out[i] = filter[2].process(filter[1].process(filter[0].process_zeroin()));
350 break;
353 for (int i = 0; i < order; i++)
354 filter[i].sanitize();
355 return filter[order - 1].empty() ? 0 : inmask;
357 uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
358 // printf("sr=%d cutoff=%f res=%f mode=%f\n", srate, *params[par_cutoff], *params[par_resonance], *params[par_mode]);
359 uint32_t ostate = 0;
360 numsamples += offset;
361 while(offset < numsamples) {
362 uint32_t numnow = numsamples - offset;
363 // if inertia's inactive, we can calculate the whole buffer at once
364 if (inertia_cutoff.active() || inertia_resonance.active())
365 numnow = timer.get(numnow);
366 if (outputs_mask & 1) {
367 ostate |= process_channel(left, ins[0] + offset, outs[0] + offset, numnow, inputs_mask & 1);
369 if (outputs_mask & 2) {
370 ostate |= process_channel(right, ins[1] + offset, outs[1] + offset, numnow, inputs_mask & 2);
372 if (timer.elapsed()) {
373 on_timer();
375 offset += numnow;
377 return ostate;
379 bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
380 float freq_gain(int subindex, float freq, float srate);
381 bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
384 class vintage_delay_audio_module: public audio_module<vintage_delay_metadata>
386 public:
387 // 1MB of delay memory per channel... uh, RAM is cheap
388 enum { MAX_DELAY = 262144, ADDR_MASK = MAX_DELAY - 1 };
389 float *ins[in_count];
390 float *outs[out_count];
391 float *params[param_count];
392 float buffers[2][MAX_DELAY];
393 int bufptr, deltime_l, deltime_r, mixmode, medium, old_medium;
394 gain_smoothing amt_left, amt_right, fb_left, fb_right;
395 float dry;
397 dsp::biquad_d2<float> biquad_left[2], biquad_right[2];
399 uint32_t srate;
401 vintage_delay_audio_module()
403 old_medium = -1;
406 void params_changed()
408 float unit = 60.0 * srate / (*params[par_bpm] * *params[par_divide]);
409 deltime_l = dsp::fastf2i_drm(unit * *params[par_time_l]);
410 deltime_r = dsp::fastf2i_drm(unit * *params[par_time_r]);
411 amt_left.set_inertia(*params[par_amount]); amt_right.set_inertia(*params[par_amount]);
412 float fb = *params[par_feedback];
413 dry = *params[par_dryamount];
414 mixmode = dsp::fastf2i_drm(*params[par_mixmode]);
415 medium = dsp::fastf2i_drm(*params[par_medium]);
416 if (mixmode == 0)
418 fb_left.set_inertia(fb);
419 fb_right.set_inertia(pow(fb, *params[par_time_r] / *params[par_time_l]));
420 } else {
421 fb_left.set_inertia(fb);
422 fb_right.set_inertia(fb);
424 if (medium != old_medium)
425 calc_filters();
427 void activate() {
428 bufptr = 0;
430 void deactivate() {
432 void set_sample_rate(uint32_t sr) {
433 srate = sr;
434 old_medium = -1;
435 amt_left.set_sample_rate(sr); amt_right.set_sample_rate(sr);
436 fb_left.set_sample_rate(sr); fb_right.set_sample_rate(sr);
437 params_changed();
439 void calc_filters()
441 // parameters are heavily influenced by gordonjcp and his tape delay unit
442 // although, don't blame him if it sounds bad - I've messed with them too :)
443 biquad_left[0].set_lp_rbj(6000, 0.707, srate);
444 biquad_left[1].set_bp_rbj(4500, 0.250, srate);
445 biquad_right[0].copy_coeffs(biquad_left[0]);
446 biquad_right[1].copy_coeffs(biquad_left[1]);
448 uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
449 uint32_t ostate = 3; // XXXKF optimize!
450 uint32_t end = offset + numsamples;
451 int v = mixmode ? 1 : 0;
452 int orig_bufptr = bufptr;
453 for(uint32_t i = offset; i < end; i++)
455 float in_left = buffers[v][(bufptr - deltime_l) & ADDR_MASK], in_right = buffers[1 - v][(bufptr - deltime_r) & ADDR_MASK], out_left, out_right, del_left, del_right;
456 dsp::sanitize(in_left), dsp::sanitize(in_right);
458 out_left = dry * ins[0][i] + in_left * amt_left.get();
459 out_right = dry * ins[1][i] + in_right * amt_right.get();
460 del_left = ins[0][i] + in_left * fb_left.get();
461 del_right = ins[1][i] + in_right * fb_right.get();
463 outs[0][i] = out_left; outs[1][i] = out_right; buffers[0][bufptr] = del_left; buffers[1][bufptr] = del_right;
464 bufptr = (bufptr + 1) & (MAX_DELAY - 1);
466 if (medium > 0) {
467 bufptr = orig_bufptr;
468 if (medium == 2)
470 for(uint32_t i = offset; i < end; i++)
472 buffers[0][bufptr] = biquad_left[0].process_lp(biquad_left[1].process(buffers[0][bufptr]));
473 buffers[1][bufptr] = biquad_right[0].process_lp(biquad_right[1].process(buffers[1][bufptr]));
474 bufptr = (bufptr + 1) & (MAX_DELAY - 1);
476 biquad_left[0].sanitize();biquad_right[0].sanitize();
477 } else {
478 for(uint32_t i = offset; i < end; i++)
480 buffers[0][bufptr] = biquad_left[1].process(buffers[0][bufptr]);
481 buffers[1][bufptr] = biquad_right[1].process(buffers[1][bufptr]);
482 bufptr = (bufptr + 1) & (MAX_DELAY - 1);
485 biquad_left[1].sanitize();biquad_right[1].sanitize();
488 return ostate;
492 class rotary_speaker_audio_module: public audio_module<rotary_speaker_metadata>
494 public:
495 float *ins[in_count];
496 float *outs[out_count];
497 float *params[param_count];
498 /// Current phases and phase deltas for bass and treble rotors
499 uint32_t phase_l, dphase_l, phase_h, dphase_h;
500 dsp::simple_delay<1024, float> delay;
501 dsp::biquad_d2<float> crossover1l, crossover1r, crossover2l, crossover2r;
502 dsp::simple_delay<8, float> phaseshift;
503 uint32_t srate;
504 int vibrato_mode;
505 /// Current CC1 (Modulation) value, normalized to [0, 1]
506 float mwhl_value;
507 /// Current CC64 (Hold) value, normalized to [0, 1]
508 float hold_value;
509 /// Current rotation speed for bass rotor - automatic mode
510 float aspeed_l;
511 /// Current rotation speed for treble rotor - automatic mode
512 float aspeed_h;
513 /// Desired speed (0=slow, 1=fast) - automatic mode
514 float dspeed;
515 /// Current rotation speed for bass rotor - manual mode
516 float maspeed_l;
517 /// Current rotation speed for treble rotor - manual mode
518 float maspeed_h;
520 rotary_speaker_audio_module();
521 void set_sample_rate(uint32_t sr);
522 void setup();
523 void activate();
524 void deactivate();
526 void params_changed() {
527 set_vibrato();
529 void set_vibrato()
531 vibrato_mode = fastf2i_drm(*params[par_speed]);
532 // manual vibrato - do not recalculate speeds as they're not used anyway
533 if (vibrato_mode == 5)
534 return;
535 if (!vibrato_mode)
536 dspeed = -1;
537 else {
538 float speed = vibrato_mode - 1;
539 if (vibrato_mode == 3)
540 speed = hold_value;
541 if (vibrato_mode == 4)
542 speed = mwhl_value;
543 dspeed = (speed < 0.5f) ? 0 : 1;
545 update_speed();
547 /// Convert RPM speed to delta-phase
548 inline uint32_t rpm2dphase(float rpm)
550 return (uint32_t)((rpm / (60.0 * srate)) * (1 << 30)) << 2;
552 /// Set delta-phase variables based on current calculated (and interpolated) RPM speed
553 void update_speed()
555 float speed_h = aspeed_h >= 0 ? (48 + (400-48) * aspeed_h) : (48 * (1 + aspeed_h));
556 float speed_l = aspeed_l >= 0 ? 40 + (342-40) * aspeed_l : (40 * (1 + aspeed_l));
557 dphase_h = rpm2dphase(speed_h);
558 dphase_l = rpm2dphase(speed_l);
560 void update_speed_manual(float delta)
562 float ts = *params[par_treblespeed];
563 float bs = *params[par_bassspeed];
564 incr_towards(maspeed_h, ts, delta * 200, delta * 200);
565 incr_towards(maspeed_l, bs, delta * 200, delta * 200);
566 dphase_h = rpm2dphase(maspeed_h);
567 dphase_l = rpm2dphase(maspeed_l);
569 /// map a ramp [int] to a sinusoid-like function [0, 65536]
570 static inline int pseudo_sine_scl(int counter)
572 // premature optimization is a root of all evil; it can be done with integers only - but later :)
573 double v = counter * (1.0 / (65536.0 * 32768.0));
574 return 32768 + 32768 * (v - v*v*v) * (1.0 / 0.3849);
576 /// Increase or decrease aspeed towards raspeed, with required negative and positive rate
577 inline bool incr_towards(float &aspeed, float raspeed, float delta_decc, float delta_acc)
579 if (aspeed < raspeed) {
580 aspeed = std::min(raspeed, aspeed + delta_acc);
581 return true;
583 else if (aspeed > raspeed)
585 aspeed = std::max(raspeed, aspeed - delta_decc);
586 return true;
588 return false;
590 uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask)
592 int shift = (int)(300000 * (*params[par_shift])), pdelta = (int)(300000 * (*params[par_spacing]));
593 int md = (int)(100 * (*params[par_moddepth]));
594 float mix = 0.5 * (1.0 - *params[par_micdistance]);
595 float mix2 = *params[par_reflection];
596 float mix3 = mix2 * mix2;
597 for (unsigned int i = 0; i < nsamples; i++) {
598 float in_l = ins[0][i + offset], in_r = ins[1][i + offset];
599 float in_mono = 0.5f * (in_l + in_r);
601 int xl = pseudo_sine_scl(phase_l), yl = pseudo_sine_scl(phase_l + 0x40000000);
602 int xh = pseudo_sine_scl(phase_h), yh = pseudo_sine_scl(phase_h + 0x40000000);
603 // printf("%d %d %d\n", shift, pdelta, shift + pdelta + 20 * xl);
605 // float out_hi_l = in_mono - delay.get_interp_1616(shift + md * xh) + delay.get_interp_1616(shift + md * 65536 + pdelta - md * yh) - delay.get_interp_1616(shift + md * 65536 + pdelta + pdelta - md * xh);
606 // float out_hi_r = in_mono + delay.get_interp_1616(shift + md * 65536 - md * yh) - delay.get_interp_1616(shift + pdelta + md * xh) + delay.get_interp_1616(shift + pdelta + pdelta + md * yh);
607 float out_hi_l = in_mono + delay.get_interp_1616(shift + md * xh) - mix2 * delay.get_interp_1616(shift + md * 65536 + pdelta - md * yh) + mix3 * delay.get_interp_1616(shift + md * 65536 + pdelta + pdelta - md * xh);
608 float out_hi_r = in_mono + delay.get_interp_1616(shift + md * 65536 - md * yh) - mix2 * delay.get_interp_1616(shift + pdelta + md * xh) + mix3 * delay.get_interp_1616(shift + pdelta + pdelta + md * yh);
610 float out_lo_l = in_mono + delay.get_interp_1616(shift + md * xl); // + delay.get_interp_1616(shift + md * 65536 + pdelta - md * yl);
611 float out_lo_r = in_mono + delay.get_interp_1616(shift + md * yl); // - delay.get_interp_1616(shift + pdelta + md * yl);
613 out_hi_l = crossover2l.process(out_hi_l); // sanitize(out_hi_l);
614 out_hi_r = crossover2r.process(out_hi_r); // sanitize(out_hi_r);
615 out_lo_l = crossover1l.process(out_lo_l); // sanitize(out_lo_l);
616 out_lo_r = crossover1r.process(out_lo_r); // sanitize(out_lo_r);
618 float out_l = out_hi_l + out_lo_l;
619 float out_r = out_hi_r + out_lo_r;
621 float mic_l = out_l + mix * (out_r - out_l);
622 float mic_r = out_r + mix * (out_l - out_r);
624 outs[0][i + offset] = mic_l * 0.5f;
625 outs[1][i + offset] = mic_r * 0.5f;
626 delay.put(in_mono);
627 phase_l += dphase_l;
628 phase_h += dphase_h;
630 crossover1l.sanitize();
631 crossover1r.sanitize();
632 crossover2l.sanitize();
633 crossover2r.sanitize();
634 float delta = nsamples * 1.0 / srate;
635 if (vibrato_mode == 5)
636 update_speed_manual(delta);
637 else
639 bool u1 = incr_towards(aspeed_l, dspeed, delta * 0.2, delta * 0.14);
640 bool u2 = incr_towards(aspeed_h, dspeed, delta, delta * 0.5);
641 if (u1 || u2)
642 set_vibrato();
644 return outputs_mask;
646 virtual void control_change(int ctl, int val);
649 /// Compose two filters in series
650 template<class F1, class F2>
651 class filter_compose {
652 public:
653 typedef std::complex<float> cfloat;
654 F1 f1;
655 F2 f2;
656 public:
657 float process(float value) {
658 return f2.process(f1.process(value));
661 cfloat h_z(const cfloat &z) {
662 return f1.h_z(z) * f2.h_z(z);
665 /// Return the filter's gain at frequency freq
666 /// @param freq Frequency to look up
667 /// @param sr Filter sample rate (used to convert frequency to angular frequency)
668 float freq_gain(float freq, float sr)
670 typedef std::complex<double> cfloat;
671 freq *= 2.0 * M_PI / sr;
672 cfloat z = 1.0 / exp(cfloat(0.0, freq));
674 return std::abs(h_z(z));
677 void sanitize() {
678 f1.sanitize();
679 f2.sanitize();
683 /// Compose two filters in parallel
684 template<class F1, class F2>
685 class filter_sum {
686 public:
687 typedef std::complex<double> cfloat;
688 F1 f1;
689 F2 f2;
690 public:
691 float process(float value) {
692 return f2.process(value) + f1.process(value);
695 inline cfloat h_z(const cfloat &z) {
696 return f1.h_z(z) + f2.h_z(z);
699 /// Return the filter's gain at frequency freq
700 /// @param freq Frequency to look up
701 /// @param sr Filter sample rate (used to convert frequency to angular frequency)
702 float freq_gain(float freq, float sr)
704 typedef std::complex<double> cfloat;
705 freq *= 2.0 * M_PI / sr;
706 cfloat z = 1.0 / exp(cfloat(0.0, freq));
708 return std::abs(h_z(z));
711 void sanitize() {
712 f1.sanitize();
713 f2.sanitize();
717 /// A multitap stereo chorus thing - processing
718 class multichorus_audio_module: public audio_module<multichorus_metadata>, public line_graph_iface
720 public:
721 float *ins[in_count];
722 float *outs[out_count];
723 float *params[param_count];
724 uint32_t srate;
725 dsp::multichorus<float, sine_multi_lfo<float, 8>, filter_sum<dsp::biquad_d2<>, dsp::biquad_d2<> >, 4096> left, right;
726 float last_r_phase;
727 float cutoff;
728 bool is_active;
730 public:
731 multichorus_audio_module()
733 is_active = false;
736 void params_changed()
738 // delicious copy-pasta from flanger module - it'd be better to keep it common or something
739 float dry = *params[par_dryamount];
740 float wet = *params[par_amount];
741 float rate = *params[par_rate];
742 float min_delay = *params[par_delay] / 1000.0;
743 float mod_depth = *params[par_depth] / 1000.0;
744 left.set_dry(dry); right.set_dry(dry);
745 left.set_wet(wet); right.set_wet(wet);
746 left.set_rate(rate); right.set_rate(rate);
747 left.set_min_delay(min_delay); right.set_min_delay(min_delay);
748 left.set_mod_depth(mod_depth); right.set_mod_depth(mod_depth);
749 int voices = (int)*params[par_voices];
750 left.lfo.set_voices(voices); right.lfo.set_voices(voices);
751 float vphase = *params[par_vphase] * (1.f / 360.f);
752 left.lfo.vphase = right.lfo.vphase = vphase * (4096 / std::max(voices - 1, 1));
753 float r_phase = *params[par_stereo] * (1.f / 360.f);
754 if (fabs(r_phase - last_r_phase) > 0.0001f) {
755 right.lfo.phase = left.lfo.phase;
756 right.lfo.phase += chorus_phase(r_phase * 4096);
757 last_r_phase = r_phase;
759 left.post.f1.set_bp_rbj(*params[par_freq], *params[par_q], srate);
760 left.post.f2.set_bp_rbj(*params[par_freq2], *params[par_q], srate);
761 right.post.f1.copy_coeffs(left.post.f1);
762 right.post.f2.copy_coeffs(left.post.f2);
764 uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
765 left.process(outs[0] + offset, ins[0] + offset, numsamples);
766 right.process(outs[1] + offset, ins[1] + offset, numsamples);
767 return outputs_mask; // XXXKF allow some delay after input going blank
769 void activate();
770 void deactivate();
771 void set_sample_rate(uint32_t sr);
772 bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
773 float freq_gain(int subindex, float freq, float srate);
774 bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context);
775 bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
778 class compressor_audio_module: public audio_module<compressor_metadata>, public line_graph_iface {
779 private:
780 float linSlope, peak, detected, kneeSqrt, kneeStart, linKneeStart, kneeStop, threshold, ratio, knee, makeup, compressedKneeStop, adjKneeStart;
781 uint32_t clip;
782 aweighter awL, awR;
783 public:
784 float *ins[in_count];
785 float *outs[out_count];
786 float *params[param_count];
787 uint32_t srate;
788 bool is_active;
789 compressor_audio_module();
790 void activate();
791 void deactivate();
792 uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
793 bool bypass = *params[param_bypass] > 0.5f;
795 if(bypass) {
796 int count = numsamples * sizeof(float);
797 memcpy(outs[0], ins[0], count);
798 memcpy(outs[1], ins[1], count);
800 if(params[param_compression] != NULL) {
801 *params[param_compression] = 1.f;
804 if(params[param_clip] != NULL) {
805 *params[param_clip] = 0.f;
808 if(params[param_peak] != NULL) {
809 *params[param_peak] = 0.f;
812 return inputs_mask;
815 bool rms = *params[param_detection] == 0;
816 bool average = *params[param_stereo_link] == 0;
817 bool aweighting = *params[param_aweighting] > 0.5f;
818 float linThreshold = *params[param_threshold];
819 ratio = *params[param_ratio];
820 float attack = *params[param_attack];
821 float attack_coeff = std::min(1.f, 1.f / (attack * srate / 4000.f));
822 float release = *params[param_release];
823 float release_coeff = std::min(1.f, 1.f / (release * srate / 4000.f));
824 makeup = *params[param_makeup];
825 knee = *params[param_knee];
827 float linKneeSqrt = sqrt(knee);
828 linKneeStart = linThreshold / linKneeSqrt;
829 adjKneeStart = linKneeStart*linKneeStart;
830 float linKneeStop = linThreshold * linKneeSqrt;
832 threshold = log(linThreshold);
833 kneeStart = log(linKneeStart);
834 kneeStop = log(linKneeStop);
835 compressedKneeStop = (kneeStop - threshold) / ratio + threshold;
837 numsamples += offset;
839 float compression = 1.f;
841 peak -= peak * 5.f * numsamples / srate;
843 clip -= std::min(clip, numsamples);
845 while(offset < numsamples) {
846 float left = ins[0][offset];
847 float right = ins[1][offset];
849 if(aweighting) {
850 left = awL.process(left);
851 right = awR.process(right);
854 float absample = average ? (fabs(left) + fabs(right)) * 0.5f : std::max(fabs(left), fabs(right));
855 if(rms) absample *= absample;
857 linSlope += (absample - linSlope) * (absample > linSlope ? attack_coeff : release_coeff);
859 float gain = 1.f;
861 if(linSlope > 0.f) {
862 gain = output_gain(linSlope, rms);
865 compression = gain;
866 gain *= makeup;
868 float outL = ins[0][offset] * gain;
869 float outR = ins[1][offset] * gain;
871 outs[0][offset] = outL;
872 outs[1][offset] = outR;
874 ++offset;
876 float maxLR = std::max(fabs(outL), fabs(outR));
878 if(maxLR > 1.f) clip = srate >> 3; /* blink clip LED for 125 ms */
880 if(maxLR > peak) {
881 peak = maxLR;
885 detected = rms ? sqrt(linSlope) : linSlope;
887 if(params[param_compression] != NULL) {
888 *params[param_compression] = compression;
891 if(params[param_clip] != NULL) {
892 *params[param_clip] = clip;
895 if(params[param_peak] != NULL) {
896 *params[param_peak] = peak;
899 return inputs_mask;
902 inline float output_level(float slope) {
903 return slope * output_gain(slope, false) * makeup;
906 inline float output_gain(float linSlope, bool rms) {
907 if(linSlope > (rms ? adjKneeStart : linKneeStart)) {
908 float slope = log(linSlope);
909 if(rms) slope *= 0.5f;
911 float gain = 0.f;
912 float delta = 0.f;
913 if(IS_FAKE_INFINITY(ratio)) {
914 gain = threshold;
915 delta = 0.f;
916 } else {
917 gain = (slope - threshold) / ratio + threshold;
918 delta = 1.f / ratio;
921 if(knee > 1.f && slope < kneeStop) {
922 gain = hermite_interpolation(slope, kneeStart, kneeStop, kneeStart, compressedKneeStop, 1.f, delta);
925 return exp(gain - slope);
928 return 1.f;
931 void set_sample_rate(uint32_t sr);
933 virtual bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
934 virtual bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context);
935 virtual bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
938 extern std::string get_builtin_modules_rdf();
942 #include "modules_synths.h"
944 #endif