+ Vintage Delay: attempt at fixing the delay initialization problem after startup...
[calf.git] / src / calf / modules.h
blob7b06f7f95ed7ee7422de33fc2caf174ca4aa61b6
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 <limits.h>
26 #include "biquad.h"
27 #include "inertia.h"
28 #include "audio_fx.h"
29 #include "multichorus.h"
30 #include "giface.h"
31 #include "metadata.h"
32 #include "loudness.h"
33 #include "primitives.h"
35 namespace calf_plugins {
37 using namespace dsp;
39 struct ladspa_plugin_info;
41 #if 0
42 class amp_audio_module: public null_audio_module
44 public:
45 enum { in_count = 2, out_count = 2, param_count = 1, support_midi = false, require_midi = false, rt_capable = true };
46 float *ins[2];
47 float *outs[2];
48 float *params[1];
49 uint32_t srate;
50 static parameter_properties param_props[];
51 uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
52 if (!inputs_mask)
53 return 0;
54 float gain = *params[0];
55 numsamples += offset;
56 for (uint32_t i = offset; i < numsamples; i++) {
57 outs[0][i] = ins[0][i] * gain;
58 outs[1][i] = ins[1][i] * gain;
60 return inputs_mask;
63 #endif
65 class frequency_response_line_graph: public line_graph_iface
67 public:
68 bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
69 virtual int get_changed_offsets(int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline);
72 class flanger_audio_module: public audio_module<flanger_metadata>, public frequency_response_line_graph
74 public:
75 dsp::simple_flanger<float, 2048> left, right;
76 float *ins[in_count];
77 float *outs[out_count];
78 float *params[param_count];
79 uint32_t srate;
80 bool clear_reset;
81 float last_r_phase;
82 bool is_active;
83 public:
84 flanger_audio_module() {
85 is_active = false;
87 void set_sample_rate(uint32_t sr);
88 void params_changed() {
89 float dry = *params[par_dryamount];
90 float wet = *params[par_amount];
91 float rate = *params[par_rate]; // 0.01*pow(1000.0f,*params[par_rate]);
92 float min_delay = *params[par_delay] / 1000.0;
93 float mod_depth = *params[par_depth] / 1000.0;
94 float fb = *params[par_fb];
95 left.set_dry(dry); right.set_dry(dry);
96 left.set_wet(wet); right.set_wet(wet);
97 left.set_rate(rate); right.set_rate(rate);
98 left.set_min_delay(min_delay); right.set_min_delay(min_delay);
99 left.set_mod_depth(mod_depth); right.set_mod_depth(mod_depth);
100 left.set_fb(fb); right.set_fb(fb);
101 float r_phase = *params[par_stereo] * (1.f / 360.f);
102 clear_reset = false;
103 if (*params[par_reset] >= 0.5) {
104 clear_reset = true;
105 left.reset_phase(0.f);
106 right.reset_phase(r_phase);
107 } else {
108 if (fabs(r_phase - last_r_phase) > 0.0001f) {
109 right.phase = left.phase;
110 right.inc_phase(r_phase);
111 last_r_phase = r_phase;
115 void params_reset()
117 if (clear_reset) {
118 *params[par_reset] = 0.f;
119 clear_reset = false;
122 void activate();
123 void deactivate();
124 uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
125 left.process(outs[0] + offset, ins[0] + offset, nsamples);
126 right.process(outs[1] + offset, ins[1] + offset, nsamples);
127 return outputs_mask; // XXXKF allow some delay after input going blank
129 bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
130 float freq_gain(int subindex, float freq, float srate);
133 class phaser_audio_module: public audio_module<phaser_metadata>, public frequency_response_line_graph
135 public:
136 float *ins[in_count];
137 float *outs[out_count];
138 float *params[param_count];
139 uint32_t srate;
140 bool clear_reset;
141 float last_r_phase;
142 dsp::simple_phaser<12> left, right;
143 bool is_active;
144 public:
145 phaser_audio_module() {
146 is_active = false;
148 void params_changed() {
149 float dry = *params[par_dryamount];
150 float wet = *params[par_amount];
151 float rate = *params[par_rate]; // 0.01*pow(1000.0f,*params[par_rate]);
152 float base_frq = *params[par_freq];
153 float mod_depth = *params[par_depth];
154 float fb = *params[par_fb];
155 int stages = (int)*params[par_stages];
156 left.set_dry(dry); right.set_dry(dry);
157 left.set_wet(wet); right.set_wet(wet);
158 left.set_rate(rate); right.set_rate(rate);
159 left.set_base_frq(base_frq); right.set_base_frq(base_frq);
160 left.set_mod_depth(mod_depth); right.set_mod_depth(mod_depth);
161 left.set_fb(fb); right.set_fb(fb);
162 left.set_stages(stages); right.set_stages(stages);
163 float r_phase = *params[par_stereo] * (1.f / 360.f);
164 clear_reset = false;
165 if (*params[par_reset] >= 0.5) {
166 clear_reset = true;
167 left.reset_phase(0.f);
168 right.reset_phase(r_phase);
169 } else {
170 if (fabs(r_phase - last_r_phase) > 0.0001f) {
171 right.phase = left.phase;
172 right.inc_phase(r_phase);
173 last_r_phase = r_phase;
177 void params_reset()
179 if (clear_reset) {
180 *params[par_reset] = 0.f;
181 clear_reset = false;
184 void activate();
185 void set_sample_rate(uint32_t sr);
186 void deactivate();
187 uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
188 left.process(outs[0] + offset, ins[0] + offset, nsamples);
189 right.process(outs[1] + offset, ins[1] + offset, nsamples);
190 return outputs_mask; // XXXKF allow some delay after input going blank
192 bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
193 bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
194 float freq_gain(int subindex, float freq, float srate);
197 class reverb_audio_module: public audio_module<reverb_metadata>
199 public:
200 dsp::reverb<float> reverb;
201 dsp::simple_delay<16384, stereo_sample<float> > pre_delay;
202 dsp::onepole<float> left_lo, right_lo, left_hi, right_hi;
203 uint32_t srate;
204 gain_smoothing amount, dryamount;
205 int predelay_amt;
206 float *ins[in_count];
207 float *outs[out_count];
208 float *params[param_count];
210 void params_changed() {
211 //reverb.set_time(0.5*pow(8.0f, *params[par_decay]));
212 //reverb.set_cutoff(2000*pow(10.0f, *params[par_hfdamp]));
213 reverb.set_type_and_diffusion(fastf2i_drm(*params[par_roomsize]), *params[par_diffusion]);
214 reverb.set_time(*params[par_decay]);
215 reverb.set_cutoff(*params[par_hfdamp]);
216 amount.set_inertia(*params[par_amount]);
217 dryamount.set_inertia(*params[par_dry]);
218 left_lo.set_lp(dsp::clip(*params[par_treblecut], 20.f, (float)(srate * 0.49f)), srate);
219 left_hi.set_hp(dsp::clip(*params[par_basscut], 20.f, (float)(srate * 0.49f)), srate);
220 right_lo.copy_coeffs(left_lo);
221 right_hi.copy_coeffs(left_hi);
222 predelay_amt = (int) (srate * (*params[par_predelay]) * (1.0f / 1000.0f) + 1);
224 uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
225 numsamples += offset;
227 for (uint32_t i = offset; i < numsamples; i++) {
228 float dry = dryamount.get();
229 float wet = amount.get();
230 stereo_sample<float> s(ins[0][i], ins[1][i]);
231 stereo_sample<float> s2 = pre_delay.process(s, predelay_amt);
233 float rl = s2.left, rr = s2.right;
234 rl = left_lo.process(left_hi.process(rl));
235 rr = right_lo.process(right_hi.process(rr));
236 reverb.process(rl, rr);
237 outs[0][i] = dry*s.left + wet*rl;
238 outs[1][i] = dry*s.right + wet*rr;
240 reverb.extra_sanitize();
241 left_lo.sanitize();
242 left_hi.sanitize();
243 right_lo.sanitize();
244 right_hi.sanitize();
245 return outputs_mask;
247 void activate();
248 void set_sample_rate(uint32_t sr);
249 void deactivate();
252 class vintage_delay_audio_module: public audio_module<vintage_delay_metadata>
254 public:
255 // 1MB of delay memory per channel... uh, RAM is cheap
256 enum { MAX_DELAY = 262144, ADDR_MASK = MAX_DELAY - 1 };
257 float *ins[in_count];
258 float *outs[out_count];
259 float *params[param_count];
260 float buffers[2][MAX_DELAY];
261 int bufptr, deltime_l, deltime_r, mixmode, medium, old_medium;
262 /// number of table entries written (value is only important when it is less than MAX_DELAY, which means that the buffer hasn't been totally filled yet)
263 int age;
265 gain_smoothing amt_left, amt_right, fb_left, fb_right;
266 float dry;
268 dsp::biquad_d2<float> biquad_left[2], biquad_right[2];
270 uint32_t srate;
272 vintage_delay_audio_module()
274 old_medium = -1;
275 for (int i = 0; i < MAX_DELAY; i++) {
276 buffers[0][i] = 0.f;
277 buffers[1][i] = 0.f;
281 void params_changed()
283 float unit = 60.0 * srate / (*params[par_bpm] * *params[par_divide]);
284 deltime_l = dsp::fastf2i_drm(unit * *params[par_time_l]);
285 deltime_r = dsp::fastf2i_drm(unit * *params[par_time_r]);
286 amt_left.set_inertia(*params[par_amount]); amt_right.set_inertia(*params[par_amount]);
287 float fb = *params[par_feedback];
288 dry = *params[par_dryamount];
289 mixmode = dsp::fastf2i_drm(*params[par_mixmode]);
290 medium = dsp::fastf2i_drm(*params[par_medium]);
291 if (mixmode == 0)
293 fb_left.set_inertia(fb);
294 fb_right.set_inertia(pow(fb, *params[par_time_r] / *params[par_time_l]));
295 } else {
296 fb_left.set_inertia(fb);
297 fb_right.set_inertia(fb);
299 if (medium != old_medium)
300 calc_filters();
302 void activate() {
303 bufptr = 0;
304 age = 0;
306 void deactivate() {
308 void set_sample_rate(uint32_t sr) {
309 srate = sr;
310 old_medium = -1;
311 amt_left.set_sample_rate(sr); amt_right.set_sample_rate(sr);
312 fb_left.set_sample_rate(sr); fb_right.set_sample_rate(sr);
313 params_changed();
315 void calc_filters()
317 // parameters are heavily influenced by gordonjcp and his tape delay unit
318 // although, don't blame him if it sounds bad - I've messed with them too :)
319 biquad_left[0].set_lp_rbj(6000, 0.707, srate);
320 biquad_left[1].set_bp_rbj(4500, 0.250, srate);
321 biquad_right[0].copy_coeffs(biquad_left[0]);
322 biquad_right[1].copy_coeffs(biquad_left[1]);
324 uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
325 uint32_t ostate = 3; // XXXKF optimize!
326 uint32_t end = offset + numsamples;
327 int v = mixmode ? 1 : 0;
328 int orig_bufptr = bufptr;
329 for(uint32_t i = offset; i < end; i++)
331 float out_left, out_right, del_left, del_right;
332 // if the buffer hasn't been cleared yet (after activation), pretend we've read zeros
334 if (deltime_l >= age) {
335 del_left = ins[0][i];
336 out_left = dry * del_left;
337 amt_left.step();
338 fb_left.step();
340 else
342 float in_left = buffers[v][(bufptr - deltime_l) & ADDR_MASK];
343 dsp::sanitize(in_left);
344 out_left = dry * ins[0][i] + in_left * amt_left.get();
345 del_left = ins[0][i] + in_left * fb_left.get();
347 if (deltime_r >= age) {
348 del_right = ins[1][i];
349 out_right = dry * del_right;
350 amt_right.step();
351 fb_right.step();
353 else
355 float in_right = buffers[1 - v][(bufptr - deltime_r) & ADDR_MASK];
356 dsp::sanitize(in_right);
357 out_right = dry * ins[1][i] + in_right * amt_right.get();
358 del_right = ins[1][i] + in_right * fb_right.get();
361 age++;
362 outs[0][i] = out_left; outs[1][i] = out_right; buffers[0][bufptr] = del_left; buffers[1][bufptr] = del_right;
363 bufptr = (bufptr + 1) & (MAX_DELAY - 1);
365 if (age >= MAX_DELAY)
366 age = MAX_DELAY;
367 if (medium > 0) {
368 bufptr = orig_bufptr;
369 if (medium == 2)
371 for(uint32_t i = offset; i < end; i++)
373 buffers[0][bufptr] = biquad_left[0].process_lp(biquad_left[1].process(buffers[0][bufptr]));
374 buffers[1][bufptr] = biquad_right[0].process_lp(biquad_right[1].process(buffers[1][bufptr]));
375 bufptr = (bufptr + 1) & (MAX_DELAY - 1);
377 biquad_left[0].sanitize();biquad_right[0].sanitize();
378 } else {
379 for(uint32_t i = offset; i < end; i++)
381 buffers[0][bufptr] = biquad_left[1].process(buffers[0][bufptr]);
382 buffers[1][bufptr] = biquad_right[1].process(buffers[1][bufptr]);
383 bufptr = (bufptr + 1) & (MAX_DELAY - 1);
386 biquad_left[1].sanitize();biquad_right[1].sanitize();
389 return ostate;
393 class rotary_speaker_audio_module: public audio_module<rotary_speaker_metadata>
395 public:
396 float *ins[in_count];
397 float *outs[out_count];
398 float *params[param_count];
399 /// Current phases and phase deltas for bass and treble rotors
400 uint32_t phase_l, dphase_l, phase_h, dphase_h;
401 dsp::simple_delay<1024, float> delay;
402 dsp::biquad_d2<float> crossover1l, crossover1r, crossover2l, crossover2r;
403 dsp::simple_delay<8, float> phaseshift;
404 uint32_t srate;
405 int vibrato_mode;
406 /// Current CC1 (Modulation) value, normalized to [0, 1]
407 float mwhl_value;
408 /// Current CC64 (Hold) value, normalized to [0, 1]
409 float hold_value;
410 /// Current rotation speed for bass rotor - automatic mode
411 float aspeed_l;
412 /// Current rotation speed for treble rotor - automatic mode
413 float aspeed_h;
414 /// Desired speed (0=slow, 1=fast) - automatic mode
415 float dspeed;
416 /// Current rotation speed for bass rotor - manual mode
417 float maspeed_l;
418 /// Current rotation speed for treble rotor - manual mode
419 float maspeed_h;
421 rotary_speaker_audio_module();
422 void set_sample_rate(uint32_t sr);
423 void setup();
424 void activate();
425 void deactivate();
427 void params_changed() {
428 set_vibrato();
430 void set_vibrato()
432 vibrato_mode = fastf2i_drm(*params[par_speed]);
433 // manual vibrato - do not recalculate speeds as they're not used anyway
434 if (vibrato_mode == 5)
435 return;
436 if (!vibrato_mode)
437 dspeed = -1;
438 else {
439 float speed = vibrato_mode - 1;
440 if (vibrato_mode == 3)
441 speed = hold_value;
442 if (vibrato_mode == 4)
443 speed = mwhl_value;
444 dspeed = (speed < 0.5f) ? 0 : 1;
446 update_speed();
448 /// Convert RPM speed to delta-phase
449 inline uint32_t rpm2dphase(float rpm)
451 return (uint32_t)((rpm / (60.0 * srate)) * (1 << 30)) << 2;
453 /// Set delta-phase variables based on current calculated (and interpolated) RPM speed
454 void update_speed()
456 float speed_h = aspeed_h >= 0 ? (48 + (400-48) * aspeed_h) : (48 * (1 + aspeed_h));
457 float speed_l = aspeed_l >= 0 ? 40 + (342-40) * aspeed_l : (40 * (1 + aspeed_l));
458 dphase_h = rpm2dphase(speed_h);
459 dphase_l = rpm2dphase(speed_l);
461 void update_speed_manual(float delta)
463 float ts = *params[par_treblespeed];
464 float bs = *params[par_bassspeed];
465 incr_towards(maspeed_h, ts, delta * 200, delta * 200);
466 incr_towards(maspeed_l, bs, delta * 200, delta * 200);
467 dphase_h = rpm2dphase(maspeed_h);
468 dphase_l = rpm2dphase(maspeed_l);
470 /// map a ramp [int] to a sinusoid-like function [0, 65536]
471 static inline int pseudo_sine_scl(int counter)
473 // premature optimization is a root of all evil; it can be done with integers only - but later :)
474 double v = counter * (1.0 / (65536.0 * 32768.0));
475 return (int) (32768 + 32768 * (v - v*v*v) * (1.0 / 0.3849));
477 /// Increase or decrease aspeed towards raspeed, with required negative and positive rate
478 inline bool incr_towards(float &aspeed, float raspeed, float delta_decc, float delta_acc)
480 if (aspeed < raspeed) {
481 aspeed = std::min(raspeed, aspeed + delta_acc);
482 return true;
484 else if (aspeed > raspeed)
486 aspeed = std::max(raspeed, aspeed - delta_decc);
487 return true;
489 return false;
491 uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask)
493 int shift = (int)(300000 * (*params[par_shift])), pdelta = (int)(300000 * (*params[par_spacing]));
494 int md = (int)(100 * (*params[par_moddepth]));
495 float mix = 0.5 * (1.0 - *params[par_micdistance]);
496 float mix2 = *params[par_reflection];
497 float mix3 = mix2 * mix2;
498 for (unsigned int i = 0; i < nsamples; i++) {
499 float in_l = ins[0][i + offset], in_r = ins[1][i + offset];
500 float in_mono = 0.5f * (in_l + in_r);
502 int xl = pseudo_sine_scl(phase_l), yl = pseudo_sine_scl(phase_l + 0x40000000);
503 int xh = pseudo_sine_scl(phase_h), yh = pseudo_sine_scl(phase_h + 0x40000000);
504 // printf("%d %d %d\n", shift, pdelta, shift + pdelta + 20 * xl);
506 // 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);
507 // 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);
508 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);
509 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);
511 float out_lo_l = in_mono + delay.get_interp_1616(shift + md * xl); // + delay.get_interp_1616(shift + md * 65536 + pdelta - md * yl);
512 float out_lo_r = in_mono + delay.get_interp_1616(shift + md * yl); // - delay.get_interp_1616(shift + pdelta + md * yl);
514 out_hi_l = crossover2l.process(out_hi_l); // sanitize(out_hi_l);
515 out_hi_r = crossover2r.process(out_hi_r); // sanitize(out_hi_r);
516 out_lo_l = crossover1l.process(out_lo_l); // sanitize(out_lo_l);
517 out_lo_r = crossover1r.process(out_lo_r); // sanitize(out_lo_r);
519 float out_l = out_hi_l + out_lo_l;
520 float out_r = out_hi_r + out_lo_r;
522 float mic_l = out_l + mix * (out_r - out_l);
523 float mic_r = out_r + mix * (out_l - out_r);
525 outs[0][i + offset] = mic_l * 0.5f;
526 outs[1][i + offset] = mic_r * 0.5f;
527 delay.put(in_mono);
528 phase_l += dphase_l;
529 phase_h += dphase_h;
531 crossover1l.sanitize();
532 crossover1r.sanitize();
533 crossover2l.sanitize();
534 crossover2r.sanitize();
535 float delta = nsamples * 1.0 / srate;
536 if (vibrato_mode == 5)
537 update_speed_manual(delta);
538 else
540 bool u1 = incr_towards(aspeed_l, dspeed, delta * 0.2, delta * 0.14);
541 bool u2 = incr_towards(aspeed_h, dspeed, delta, delta * 0.5);
542 if (u1 || u2)
543 set_vibrato();
545 return outputs_mask;
547 virtual void control_change(int ctl, int val);
550 /// Compose two filters in series
551 template<class F1, class F2>
552 class filter_compose {
553 public:
554 typedef std::complex<float> cfloat;
555 F1 f1;
556 F2 f2;
557 public:
558 float process(float value) {
559 return f2.process(f1.process(value));
562 cfloat h_z(const cfloat &z) {
563 return f1.h_z(z) * f2.h_z(z);
566 /// Return the filter's gain at frequency freq
567 /// @param freq Frequency to look up
568 /// @param sr Filter sample rate (used to convert frequency to angular frequency)
569 float freq_gain(float freq, float sr)
571 typedef std::complex<double> cfloat;
572 freq *= 2.0 * M_PI / sr;
573 cfloat z = 1.0 / exp(cfloat(0.0, freq));
575 return std::abs(h_z(z));
578 void sanitize() {
579 f1.sanitize();
580 f2.sanitize();
584 /// Compose two filters in parallel
585 template<class F1, class F2>
586 class filter_sum {
587 public:
588 typedef std::complex<double> cfloat;
589 F1 f1;
590 F2 f2;
591 public:
592 float process(float value) {
593 return f2.process(value) + f1.process(value);
596 inline cfloat h_z(const cfloat &z) {
597 return f1.h_z(z) + f2.h_z(z);
600 /// Return the filter's gain at frequency freq
601 /// @param freq Frequency to look up
602 /// @param sr Filter sample rate (used to convert frequency to angular frequency)
603 float freq_gain(float freq, float sr)
605 typedef std::complex<double> cfloat;
606 freq *= 2.0 * M_PI / sr;
607 cfloat z = 1.0 / exp(cfloat(0.0, freq));
609 return std::abs(h_z(z));
612 void sanitize() {
613 f1.sanitize();
614 f2.sanitize();
618 template<typename FilterClass, typename Metadata>
619 class filter_module_with_inertia: public FilterClass
621 public:
622 typedef filter_module_with_inertia inertia_filter_module;
624 float *ins[Metadata::in_count];
625 float *outs[Metadata::out_count];
626 float *params[Metadata::param_count];
628 inertia<exponential_ramp> inertia_cutoff, inertia_resonance, inertia_gain;
629 once_per_n timer;
630 bool is_active;
631 volatile int last_generation, last_calculated_generation;
633 filter_module_with_inertia()
634 : inertia_cutoff(exponential_ramp(128), 20)
635 , inertia_resonance(exponential_ramp(128), 20)
636 , inertia_gain(exponential_ramp(128), 1.0)
637 , timer(128)
639 is_active = false;
642 void calculate_filter()
644 float freq = inertia_cutoff.get_last();
645 // printf("freq=%g inr.cnt=%d timer.left=%d\n", freq, inertia_cutoff.count, timer.left);
646 // XXXKF this is resonance of a single stage, obviously for three stages, resonant gain will be different
647 float q = inertia_resonance.get_last();
648 int mode = dsp::fastf2i_drm(*params[Metadata::par_mode]);
649 // printf("freq = %f q = %f mode = %d\n", freq, q, mode);
651 int inertia = dsp::fastf2i_drm(*params[Metadata::par_inertia]);
652 if (inertia != inertia_cutoff.ramp.length()) {
653 inertia_cutoff.ramp.set_length(inertia);
654 inertia_resonance.ramp.set_length(inertia);
655 inertia_gain.ramp.set_length(inertia);
658 FilterClass::calculate_filter(freq, q, mode, inertia_gain.get_last());
661 virtual void params_changed()
663 calculate_filter();
666 void on_timer()
668 int gen = last_generation;
669 inertia_cutoff.step();
670 inertia_resonance.step();
671 inertia_gain.step();
672 calculate_filter();
673 last_calculated_generation = gen;
676 void activate()
678 params_changed();
679 FilterClass::filter_activate();
680 timer = once_per_n(FilterClass::srate / 1000);
681 timer.start();
682 is_active = true;
685 void set_sample_rate(uint32_t sr)
687 FilterClass::srate = sr;
691 void deactivate()
693 is_active = false;
696 uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
697 // printf("sr=%d cutoff=%f res=%f mode=%f\n", FilterClass::srate, *params[Metadata::par_cutoff], *params[Metadata::par_resonance], *params[Metadata::par_mode]);
698 uint32_t ostate = 0;
699 numsamples += offset;
700 while(offset < numsamples) {
701 uint32_t numnow = numsamples - offset;
702 // if inertia's inactive, we can calculate the whole buffer at once
703 if (inertia_cutoff.active() || inertia_resonance.active() || inertia_gain.active())
704 numnow = timer.get(numnow);
706 if (outputs_mask & 1) {
707 ostate |= FilterClass::process_channel(0, ins[0] + offset, outs[0] + offset, numnow, inputs_mask & 1);
709 if (outputs_mask & 2) {
710 ostate |= FilterClass::process_channel(1, ins[1] + offset, outs[1] + offset, numnow, inputs_mask & 2);
713 if (timer.elapsed()) {
714 on_timer();
716 offset += numnow;
718 return ostate;
722 /// biquad filter module
723 class filter_audio_module:
724 public audio_module<filter_metadata>,
725 public filter_module_with_inertia<biquad_filter_module, filter_metadata>,
726 public frequency_response_line_graph
728 float old_cutoff, old_resonance, old_mode;
729 public:
730 filter_audio_module()
732 last_generation = 0;
734 void params_changed()
736 inertia_cutoff.set_inertia(*params[par_cutoff]);
737 inertia_resonance.set_inertia(*params[par_resonance]);
738 inertia_filter_module::params_changed();
741 void activate()
743 inertia_filter_module::activate();
746 void set_sample_rate(uint32_t sr)
748 inertia_filter_module::set_sample_rate(sr);
752 void deactivate()
754 inertia_filter_module::deactivate();
757 bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
758 int get_changed_offsets(int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline);
761 /// A multitap stereo chorus thing - processing
762 class multichorus_audio_module: public audio_module<multichorus_metadata>, public frequency_response_line_graph
764 public:
765 float *ins[in_count];
766 float *outs[out_count];
767 float *params[param_count];
768 uint32_t srate;
769 dsp::multichorus<float, sine_multi_lfo<float, 8>, filter_sum<dsp::biquad_d2<>, dsp::biquad_d2<> >, 4096> left, right;
770 float last_r_phase;
771 float cutoff;
772 bool is_active;
774 public:
775 multichorus_audio_module()
777 is_active = false;
780 void params_changed()
782 // delicious copy-pasta from flanger module - it'd be better to keep it common or something
783 float dry = *params[par_dryamount];
784 float wet = *params[par_amount];
785 float rate = *params[par_rate];
786 float min_delay = *params[par_delay] / 1000.0;
787 float mod_depth = *params[par_depth] / 1000.0;
788 left.set_dry(dry); right.set_dry(dry);
789 left.set_wet(wet); right.set_wet(wet);
790 left.set_rate(rate); right.set_rate(rate);
791 left.set_min_delay(min_delay); right.set_min_delay(min_delay);
792 left.set_mod_depth(mod_depth); right.set_mod_depth(mod_depth);
793 int voices = (int)*params[par_voices];
794 left.lfo.set_voices(voices); right.lfo.set_voices(voices);
795 float vphase = *params[par_vphase] * (1.f / 360.f);
796 left.lfo.vphase = right.lfo.vphase = vphase * (4096 / std::max(voices - 1, 1));
797 float r_phase = *params[par_stereo] * (1.f / 360.f);
798 if (fabs(r_phase - last_r_phase) > 0.0001f) {
799 right.lfo.phase = left.lfo.phase;
800 right.lfo.phase += chorus_phase(r_phase * 4096);
801 last_r_phase = r_phase;
803 left.post.f1.set_bp_rbj(*params[par_freq], *params[par_q], srate);
804 left.post.f2.set_bp_rbj(*params[par_freq2], *params[par_q], srate);
805 right.post.f1.copy_coeffs(left.post.f1);
806 right.post.f2.copy_coeffs(left.post.f2);
808 uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
809 left.process(outs[0] + offset, ins[0] + offset, numsamples);
810 right.process(outs[1] + offset, ins[1] + offset, numsamples);
811 return outputs_mask; // XXXKF allow some delay after input going blank
813 void activate();
814 void deactivate();
815 void set_sample_rate(uint32_t sr);
816 bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
817 float freq_gain(int subindex, float freq, float srate);
818 bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context);
819 bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
822 class compressor_audio_module: public audio_module<compressor_metadata>, public line_graph_iface {
823 private:
824 float linSlope, peak, detected, kneeSqrt, kneeStart, linKneeStart, kneeStop, threshold, ratio, knee, makeup, compressedKneeStop, adjKneeStart;
825 float old_threshold, old_ratio, old_knee, old_makeup, old_bypass;
826 int last_generation;
827 uint32_t clip;
828 aweighter awL, awR;
829 public:
830 float *ins[in_count];
831 float *outs[out_count];
832 float *params[param_count];
833 uint32_t srate;
834 bool is_active;
835 compressor_audio_module();
836 void activate();
837 void deactivate();
838 uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
840 inline float output_level(float slope) {
841 return slope * output_gain(slope, false) * makeup;
844 inline float output_gain(float linSlope, bool rms) {
845 if(linSlope > (rms ? adjKneeStart : linKneeStart)) {
846 float slope = log(linSlope);
847 if(rms) slope *= 0.5f;
849 float gain = 0.f;
850 float delta = 0.f;
851 if(IS_FAKE_INFINITY(ratio)) {
852 gain = threshold;
853 delta = 0.f;
854 } else {
855 gain = (slope - threshold) / ratio + threshold;
856 delta = 1.f / ratio;
859 if(knee > 1.f && slope < kneeStop) {
860 gain = hermite_interpolation(slope, kneeStart, kneeStop, kneeStart, compressedKneeStop, 1.f, delta);
863 return exp(gain - slope);
866 return 1.f;
869 void set_sample_rate(uint32_t sr);
871 virtual bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
872 virtual bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context);
873 virtual bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
875 virtual int get_changed_offsets(int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline)
877 subindex_graph = 0;
878 subindex_dot = 0;
879 subindex_gridline = generation ? INT_MAX : 0;
881 if (fabs(threshold-old_threshold) + fabs(ratio - old_ratio) + fabs(knee - old_knee) + fabs( makeup - old_makeup) + fabs( *params[param_bypass] - old_bypass) > 0.01f)
883 old_threshold = threshold;
884 old_ratio = ratio;
885 old_knee = knee;
886 old_makeup = makeup;
887 old_bypass = *params[param_bypass];
888 last_generation++;
891 if (generation == last_generation)
892 subindex_graph = 2;
893 return last_generation;
897 /// Filterclavier --- MIDI controlled filter by Hans Baier
898 class filterclavier_audio_module:
899 public audio_module<filterclavier_metadata>,
900 public filter_module_with_inertia<biquad_filter_module, filterclavier_metadata>,
901 public frequency_response_line_graph
903 const float min_gain;
904 const float max_gain;
906 int last_note;
907 int last_velocity;
909 public:
910 filterclavier_audio_module()
912 min_gain(1.0),
913 max_gain(32.0),
914 last_note(-1),
915 last_velocity(-1) {}
917 void params_changed()
919 inertia_filter_module::inertia_cutoff.set_inertia(
920 note_to_hz(last_note + *params[par_transpose], *params[par_detune]));
922 float min_resonance = param_props[par_max_resonance].min;
923 inertia_filter_module::inertia_resonance.set_inertia(
924 (float(last_velocity) / 127.0)
925 // 0.001: see below
926 * (*params[par_max_resonance] - min_resonance + 0.001)
927 + min_resonance);
929 adjust_gain_according_to_filter_mode(last_velocity);
931 inertia_filter_module::calculate_filter();
934 void activate()
936 inertia_filter_module::activate();
939 void set_sample_rate(uint32_t sr)
941 inertia_filter_module::set_sample_rate(sr);
945 void deactivate()
947 inertia_filter_module::deactivate();
950 /// MIDI control
951 virtual void note_on(int note, int vel)
953 last_note = note;
954 last_velocity = vel;
955 inertia_filter_module::inertia_cutoff.set_inertia(
956 note_to_hz(note + *params[par_transpose], *params[par_detune]));
958 float min_resonance = param_props[par_max_resonance].min;
959 inertia_filter_module::inertia_resonance.set_inertia(
960 (float(vel) / 127.0)
961 // 0.001: if the difference is equal to zero (which happens
962 // when the max_resonance knom is at minimum position
963 // then the filter gain doesnt seem to snap to zero on most note offs
964 * (*params[par_max_resonance] - min_resonance + 0.001)
965 + min_resonance);
967 adjust_gain_according_to_filter_mode(vel);
969 inertia_filter_module::calculate_filter();
972 virtual void note_off(int note, int vel)
974 if (note == last_note) {
975 inertia_filter_module::inertia_resonance.set_inertia(param_props[par_max_resonance].min);
976 inertia_filter_module::inertia_gain.set_inertia(min_gain);
977 inertia_filter_module::calculate_filter();
978 last_velocity = 0;
982 bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
984 private:
985 void adjust_gain_according_to_filter_mode(int velocity) {
986 int mode = dsp::fastf2i_drm(*params[par_mode]);
988 // for bandpasses: boost gain for velocities > 0
989 if ( (mode_6db_bp <= mode) && (mode <= mode_18db_bp) ) {
990 // gain for velocity 0: 1.0
991 // gain for velocity 127: 32.0
992 float mode_max_gain = max_gain;
993 // max_gain is right for mode_6db_bp
994 if (mode == mode_12db_bp)
995 mode_max_gain /= 6.0;
996 if (mode == mode_18db_bp)
997 mode_max_gain /= 10.5;
999 inertia_filter_module::inertia_gain.set_now(
1000 (float(velocity) / 127.0) * (mode_max_gain - min_gain) + min_gain);
1001 } else {
1002 inertia_filter_module::inertia_gain.set_now(min_gain);
1007 extern std::string get_builtin_modules_rdf();
1011 #include "modules_synths.h"
1013 #endif