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
28 #include "multichorus.h"
32 #include "primitives.h"
34 namespace calf_plugins
{
38 struct ladspa_plugin_info
;
41 class amp_audio_module
: public null_audio_module
44 enum { in_count
= 2, out_count
= 2, param_count
= 1, support_midi
= false, require_midi
= false, rt_capable
= true };
49 static parameter_properties param_props
[];
50 uint32_t process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
) {
53 float gain
= *params
[0];
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
;
64 class flanger_audio_module
: public audio_module
<flanger_metadata
>, public line_graph_iface
67 dsp::simple_flanger
<float, 2048> left
, right
;
69 float *outs
[out_count
];
70 float *params
[param_count
];
76 flanger_audio_module() {
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
);
95 if (*params
[par_reset
] >= 0.5) {
97 left
.reset_phase(0.f
);
98 right
.reset_phase(r_phase
);
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
;
110 *params
[par_reset
] = 0.f
;
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
129 float *ins
[in_count
];
130 float *outs
[out_count
];
131 float *params
[param_count
];
135 dsp::simple_phaser
<12> left
, right
;
138 phaser_audio_module() {
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
);
158 if (*params
[par_reset
] >= 0.5) {
160 left
.reset_phase(0.f
);
161 right
.reset_phase(r_phase
);
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
;
173 *params
[par_reset
] = 0.f
;
178 void set_sample_rate(uint32_t sr
);
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
>
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
;
197 gain_smoothing amount
, dryamount
;
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
= (int) (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();
241 void set_sample_rate(uint32_t sr
);
245 class vintage_delay_audio_module
: public audio_module
<vintage_delay_metadata
>
248 // 1MB of delay memory per channel... uh, RAM is cheap
249 enum { MAX_DELAY
= 262144, ADDR_MASK
= MAX_DELAY
- 1 };
250 float *ins
[in_count
];
251 float *outs
[out_count
];
252 float *params
[param_count
];
253 float buffers
[2][MAX_DELAY
];
254 int bufptr
, deltime_l
, deltime_r
, mixmode
, medium
, old_medium
;
255 gain_smoothing amt_left
, amt_right
, fb_left
, fb_right
;
258 dsp::biquad_d2
<float> biquad_left
[2], biquad_right
[2];
262 vintage_delay_audio_module()
267 void params_changed()
269 float unit
= 60.0 * srate
/ (*params
[par_bpm
] * *params
[par_divide
]);
270 deltime_l
= dsp::fastf2i_drm(unit
* *params
[par_time_l
]);
271 deltime_r
= dsp::fastf2i_drm(unit
* *params
[par_time_r
]);
272 amt_left
.set_inertia(*params
[par_amount
]); amt_right
.set_inertia(*params
[par_amount
]);
273 float fb
= *params
[par_feedback
];
274 dry
= *params
[par_dryamount
];
275 mixmode
= dsp::fastf2i_drm(*params
[par_mixmode
]);
276 medium
= dsp::fastf2i_drm(*params
[par_medium
]);
279 fb_left
.set_inertia(fb
);
280 fb_right
.set_inertia(pow(fb
, *params
[par_time_r
] / *params
[par_time_l
]));
282 fb_left
.set_inertia(fb
);
283 fb_right
.set_inertia(fb
);
285 if (medium
!= old_medium
)
293 void set_sample_rate(uint32_t sr
) {
296 amt_left
.set_sample_rate(sr
); amt_right
.set_sample_rate(sr
);
297 fb_left
.set_sample_rate(sr
); fb_right
.set_sample_rate(sr
);
302 // parameters are heavily influenced by gordonjcp and his tape delay unit
303 // although, don't blame him if it sounds bad - I've messed with them too :)
304 biquad_left
[0].set_lp_rbj(6000, 0.707, srate
);
305 biquad_left
[1].set_bp_rbj(4500, 0.250, srate
);
306 biquad_right
[0].copy_coeffs(biquad_left
[0]);
307 biquad_right
[1].copy_coeffs(biquad_left
[1]);
309 uint32_t process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
) {
310 uint32_t ostate
= 3; // XXXKF optimize!
311 uint32_t end
= offset
+ numsamples
;
312 int v
= mixmode
? 1 : 0;
313 int orig_bufptr
= bufptr
;
314 for(uint32_t i
= offset
; i
< end
; i
++)
316 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
;
317 dsp::sanitize(in_left
), dsp::sanitize(in_right
);
319 out_left
= dry
* ins
[0][i
] + in_left
* amt_left
.get();
320 out_right
= dry
* ins
[1][i
] + in_right
* amt_right
.get();
321 del_left
= ins
[0][i
] + in_left
* fb_left
.get();
322 del_right
= ins
[1][i
] + in_right
* fb_right
.get();
324 outs
[0][i
] = out_left
; outs
[1][i
] = out_right
; buffers
[0][bufptr
] = del_left
; buffers
[1][bufptr
] = del_right
;
325 bufptr
= (bufptr
+ 1) & (MAX_DELAY
- 1);
328 bufptr
= orig_bufptr
;
331 for(uint32_t i
= offset
; i
< end
; i
++)
333 buffers
[0][bufptr
] = biquad_left
[0].process_lp(biquad_left
[1].process(buffers
[0][bufptr
]));
334 buffers
[1][bufptr
] = biquad_right
[0].process_lp(biquad_right
[1].process(buffers
[1][bufptr
]));
335 bufptr
= (bufptr
+ 1) & (MAX_DELAY
- 1);
337 biquad_left
[0].sanitize();biquad_right
[0].sanitize();
339 for(uint32_t i
= offset
; i
< end
; i
++)
341 buffers
[0][bufptr
] = biquad_left
[1].process(buffers
[0][bufptr
]);
342 buffers
[1][bufptr
] = biquad_right
[1].process(buffers
[1][bufptr
]);
343 bufptr
= (bufptr
+ 1) & (MAX_DELAY
- 1);
346 biquad_left
[1].sanitize();biquad_right
[1].sanitize();
353 class rotary_speaker_audio_module
: public audio_module
<rotary_speaker_metadata
>
356 float *ins
[in_count
];
357 float *outs
[out_count
];
358 float *params
[param_count
];
359 /// Current phases and phase deltas for bass and treble rotors
360 uint32_t phase_l
, dphase_l
, phase_h
, dphase_h
;
361 dsp::simple_delay
<1024, float> delay
;
362 dsp::biquad_d2
<float> crossover1l
, crossover1r
, crossover2l
, crossover2r
;
363 dsp::simple_delay
<8, float> phaseshift
;
366 /// Current CC1 (Modulation) value, normalized to [0, 1]
368 /// Current CC64 (Hold) value, normalized to [0, 1]
370 /// Current rotation speed for bass rotor - automatic mode
372 /// Current rotation speed for treble rotor - automatic mode
374 /// Desired speed (0=slow, 1=fast) - automatic mode
376 /// Current rotation speed for bass rotor - manual mode
378 /// Current rotation speed for treble rotor - manual mode
381 rotary_speaker_audio_module();
382 void set_sample_rate(uint32_t sr
);
387 void params_changed() {
392 vibrato_mode
= fastf2i_drm(*params
[par_speed
]);
393 // manual vibrato - do not recalculate speeds as they're not used anyway
394 if (vibrato_mode
== 5)
399 float speed
= vibrato_mode
- 1;
400 if (vibrato_mode
== 3)
402 if (vibrato_mode
== 4)
404 dspeed
= (speed
< 0.5f
) ? 0 : 1;
408 /// Convert RPM speed to delta-phase
409 inline uint32_t rpm2dphase(float rpm
)
411 return (uint32_t)((rpm
/ (60.0 * srate
)) * (1 << 30)) << 2;
413 /// Set delta-phase variables based on current calculated (and interpolated) RPM speed
416 float speed_h
= aspeed_h
>= 0 ? (48 + (400-48) * aspeed_h
) : (48 * (1 + aspeed_h
));
417 float speed_l
= aspeed_l
>= 0 ? 40 + (342-40) * aspeed_l
: (40 * (1 + aspeed_l
));
418 dphase_h
= rpm2dphase(speed_h
);
419 dphase_l
= rpm2dphase(speed_l
);
421 void update_speed_manual(float delta
)
423 float ts
= *params
[par_treblespeed
];
424 float bs
= *params
[par_bassspeed
];
425 incr_towards(maspeed_h
, ts
, delta
* 200, delta
* 200);
426 incr_towards(maspeed_l
, bs
, delta
* 200, delta
* 200);
427 dphase_h
= rpm2dphase(maspeed_h
);
428 dphase_l
= rpm2dphase(maspeed_l
);
430 /// map a ramp [int] to a sinusoid-like function [0, 65536]
431 static inline int pseudo_sine_scl(int counter
)
433 // premature optimization is a root of all evil; it can be done with integers only - but later :)
434 double v
= counter
* (1.0 / (65536.0 * 32768.0));
435 return (int) (32768 + 32768 * (v
- v
*v
*v
) * (1.0 / 0.3849));
437 /// Increase or decrease aspeed towards raspeed, with required negative and positive rate
438 inline bool incr_towards(float &aspeed
, float raspeed
, float delta_decc
, float delta_acc
)
440 if (aspeed
< raspeed
) {
441 aspeed
= std::min(raspeed
, aspeed
+ delta_acc
);
444 else if (aspeed
> raspeed
)
446 aspeed
= std::max(raspeed
, aspeed
- delta_decc
);
451 uint32_t process(uint32_t offset
, uint32_t nsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
453 int shift
= (int)(300000 * (*params
[par_shift
])), pdelta
= (int)(300000 * (*params
[par_spacing
]));
454 int md
= (int)(100 * (*params
[par_moddepth
]));
455 float mix
= 0.5 * (1.0 - *params
[par_micdistance
]);
456 float mix2
= *params
[par_reflection
];
457 float mix3
= mix2
* mix2
;
458 for (unsigned int i
= 0; i
< nsamples
; i
++) {
459 float in_l
= ins
[0][i
+ offset
], in_r
= ins
[1][i
+ offset
];
460 float in_mono
= 0.5f
* (in_l
+ in_r
);
462 int xl
= pseudo_sine_scl(phase_l
), yl
= pseudo_sine_scl(phase_l
+ 0x40000000);
463 int xh
= pseudo_sine_scl(phase_h
), yh
= pseudo_sine_scl(phase_h
+ 0x40000000);
464 // printf("%d %d %d\n", shift, pdelta, shift + pdelta + 20 * xl);
466 // 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);
467 // 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);
468 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
);
469 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
);
471 float out_lo_l
= in_mono
+ delay
.get_interp_1616(shift
+ md
* xl
); // + delay.get_interp_1616(shift + md * 65536 + pdelta - md * yl);
472 float out_lo_r
= in_mono
+ delay
.get_interp_1616(shift
+ md
* yl
); // - delay.get_interp_1616(shift + pdelta + md * yl);
474 out_hi_l
= crossover2l
.process(out_hi_l
); // sanitize(out_hi_l);
475 out_hi_r
= crossover2r
.process(out_hi_r
); // sanitize(out_hi_r);
476 out_lo_l
= crossover1l
.process(out_lo_l
); // sanitize(out_lo_l);
477 out_lo_r
= crossover1r
.process(out_lo_r
); // sanitize(out_lo_r);
479 float out_l
= out_hi_l
+ out_lo_l
;
480 float out_r
= out_hi_r
+ out_lo_r
;
482 float mic_l
= out_l
+ mix
* (out_r
- out_l
);
483 float mic_r
= out_r
+ mix
* (out_l
- out_r
);
485 outs
[0][i
+ offset
] = mic_l
* 0.5f
;
486 outs
[1][i
+ offset
] = mic_r
* 0.5f
;
491 crossover1l
.sanitize();
492 crossover1r
.sanitize();
493 crossover2l
.sanitize();
494 crossover2r
.sanitize();
495 float delta
= nsamples
* 1.0 / srate
;
496 if (vibrato_mode
== 5)
497 update_speed_manual(delta
);
500 bool u1
= incr_towards(aspeed_l
, dspeed
, delta
* 0.2, delta
* 0.14);
501 bool u2
= incr_towards(aspeed_h
, dspeed
, delta
, delta
* 0.5);
507 virtual void control_change(int ctl
, int val
);
510 /// Compose two filters in series
511 template<class F1
, class F2
>
512 class filter_compose
{
514 typedef std::complex<float> cfloat
;
518 float process(float value
) {
519 return f2
.process(f1
.process(value
));
522 cfloat
h_z(const cfloat
&z
) {
523 return f1
.h_z(z
) * f2
.h_z(z
);
526 /// Return the filter's gain at frequency freq
527 /// @param freq Frequency to look up
528 /// @param sr Filter sample rate (used to convert frequency to angular frequency)
529 float freq_gain(float freq
, float sr
)
531 typedef std::complex<double> cfloat
;
532 freq
*= 2.0 * M_PI
/ sr
;
533 cfloat z
= 1.0 / exp(cfloat(0.0, freq
));
535 return std::abs(h_z(z
));
544 /// Compose two filters in parallel
545 template<class F1
, class F2
>
548 typedef std::complex<double> cfloat
;
552 float process(float value
) {
553 return f2
.process(value
) + f1
.process(value
);
556 inline cfloat
h_z(const cfloat
&z
) {
557 return f1
.h_z(z
) + f2
.h_z(z
);
560 /// Return the filter's gain at frequency freq
561 /// @param freq Frequency to look up
562 /// @param sr Filter sample rate (used to convert frequency to angular frequency)
563 float freq_gain(float freq
, float sr
)
565 typedef std::complex<double> cfloat
;
566 freq
*= 2.0 * M_PI
/ sr
;
567 cfloat z
= 1.0 / exp(cfloat(0.0, freq
));
569 return std::abs(h_z(z
));
578 template<typename FilterClass
, typename Metadata
>
579 class filter_module_with_inertia
: public FilterClass
582 typedef filter_module_with_inertia inertia_filter_module
;
584 float *ins
[Metadata::in_count
];
585 float *outs
[Metadata::out_count
];
586 float *params
[Metadata::param_count
];
588 inertia
<exponential_ramp
> inertia_cutoff
, inertia_resonance
, inertia_gain
;
592 filter_module_with_inertia()
593 : inertia_cutoff(exponential_ramp(128), 20)
594 , inertia_resonance(exponential_ramp(128), 20)
595 , inertia_gain(exponential_ramp(128), 1.0)
601 void calculate_filter()
603 float freq
= inertia_cutoff
.get_last();
604 // printf("freq=%g inr.cnt=%d timer.left=%d\n", freq, inertia_cutoff.count, timer.left);
605 // XXXKF this is resonance of a single stage, obviously for three stages, resonant gain will be different
606 float q
= inertia_resonance
.get_last();
607 int mode
= dsp::fastf2i_drm(*params
[Metadata::par_mode
]);
608 // printf("freq = %f q = %f mode = %d\n", freq, q, mode);
610 int inertia
= dsp::fastf2i_drm(*params
[Metadata::par_inertia
]);
611 if (inertia
!= inertia_cutoff
.ramp
.length()) {
612 inertia_cutoff
.ramp
.set_length(inertia
);
613 inertia_resonance
.ramp
.set_length(inertia
);
614 inertia_gain
.ramp
.set_length(inertia
);
617 FilterClass::calculate_filter(freq
, q
, mode
, inertia_gain
.get_last());
620 virtual void params_changed()
627 inertia_cutoff
.step();
628 inertia_resonance
.step();
636 FilterClass::filter_activate();
637 timer
= once_per_n(FilterClass::srate
/ 1000);
642 void set_sample_rate(uint32_t sr
)
644 FilterClass::srate
= sr
;
653 uint32_t process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
) {
654 // printf("sr=%d cutoff=%f res=%f mode=%f\n", FilterClass::srate, *params[Metadata::par_cutoff], *params[Metadata::par_resonance], *params[Metadata::par_mode]);
656 numsamples
+= offset
;
657 while(offset
< numsamples
) {
658 uint32_t numnow
= numsamples
- offset
;
659 // if inertia's inactive, we can calculate the whole buffer at once
660 if (inertia_cutoff
.active() || inertia_resonance
.active() || inertia_gain
.active())
661 numnow
= timer
.get(numnow
);
663 if (outputs_mask
& 1) {
664 ostate
|= FilterClass::process_channel(0, ins
[0] + offset
, outs
[0] + offset
, numnow
, inputs_mask
& 1);
666 if (outputs_mask
& 2) {
667 ostate
|= FilterClass::process_channel(1, ins
[1] + offset
, outs
[1] + offset
, numnow
, inputs_mask
& 2);
670 if (timer
.elapsed()) {
679 /// biquad filter module
680 class filter_audio_module
:
681 public audio_module
<filter_metadata
>,
682 public filter_module_with_inertia
<biquad_filter_module
, filter_metadata
>,
683 public line_graph_iface
686 void params_changed()
688 inertia_cutoff
.set_inertia(*params
[par_cutoff
]);
689 inertia_resonance
.set_inertia(*params
[par_resonance
]);
690 inertia_filter_module::params_changed();
695 inertia_filter_module::activate();
698 void set_sample_rate(uint32_t sr
)
700 inertia_filter_module::set_sample_rate(sr
);
706 inertia_filter_module::deactivate();
709 bool get_graph(int index
, int subindex
, float *data
, int points
, cairo_iface
*context
);
710 bool get_gridline(int index
, int subindex
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
);
713 /// A multitap stereo chorus thing - processing
714 class multichorus_audio_module
: public audio_module
<multichorus_metadata
>, public line_graph_iface
717 float *ins
[in_count
];
718 float *outs
[out_count
];
719 float *params
[param_count
];
721 dsp::multichorus
<float, sine_multi_lfo
<float, 8>, filter_sum
<dsp::biquad_d2
<>, dsp::biquad_d2
<> >, 4096> left
, right
;
727 multichorus_audio_module()
732 void params_changed()
734 // delicious copy-pasta from flanger module - it'd be better to keep it common or something
735 float dry
= *params
[par_dryamount
];
736 float wet
= *params
[par_amount
];
737 float rate
= *params
[par_rate
];
738 float min_delay
= *params
[par_delay
] / 1000.0;
739 float mod_depth
= *params
[par_depth
] / 1000.0;
740 left
.set_dry(dry
); right
.set_dry(dry
);
741 left
.set_wet(wet
); right
.set_wet(wet
);
742 left
.set_rate(rate
); right
.set_rate(rate
);
743 left
.set_min_delay(min_delay
); right
.set_min_delay(min_delay
);
744 left
.set_mod_depth(mod_depth
); right
.set_mod_depth(mod_depth
);
745 int voices
= (int)*params
[par_voices
];
746 left
.lfo
.set_voices(voices
); right
.lfo
.set_voices(voices
);
747 float vphase
= *params
[par_vphase
] * (1.f
/ 360.f
);
748 left
.lfo
.vphase
= right
.lfo
.vphase
= vphase
* (4096 / std::max(voices
- 1, 1));
749 float r_phase
= *params
[par_stereo
] * (1.f
/ 360.f
);
750 if (fabs(r_phase
- last_r_phase
) > 0.0001f
) {
751 right
.lfo
.phase
= left
.lfo
.phase
;
752 right
.lfo
.phase
+= chorus_phase(r_phase
* 4096);
753 last_r_phase
= r_phase
;
755 left
.post
.f1
.set_bp_rbj(*params
[par_freq
], *params
[par_q
], srate
);
756 left
.post
.f2
.set_bp_rbj(*params
[par_freq2
], *params
[par_q
], srate
);
757 right
.post
.f1
.copy_coeffs(left
.post
.f1
);
758 right
.post
.f2
.copy_coeffs(left
.post
.f2
);
760 uint32_t process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
) {
761 left
.process(outs
[0] + offset
, ins
[0] + offset
, numsamples
);
762 right
.process(outs
[1] + offset
, ins
[1] + offset
, numsamples
);
763 return outputs_mask
; // XXXKF allow some delay after input going blank
767 void set_sample_rate(uint32_t sr
);
768 bool get_graph(int index
, int subindex
, float *data
, int points
, cairo_iface
*context
);
769 float freq_gain(int subindex
, float freq
, float srate
);
770 bool get_dot(int index
, int subindex
, float &x
, float &y
, int &size
, cairo_iface
*context
);
771 bool get_gridline(int index
, int subindex
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
);
774 class compressor_audio_module
: public audio_module
<compressor_metadata
>, public line_graph_iface
{
776 float linSlope
, peak
, detected
, kneeSqrt
, kneeStart
, linKneeStart
, kneeStop
, threshold
, ratio
, knee
, makeup
, compressedKneeStop
, adjKneeStart
;
780 float *ins
[in_count
];
781 float *outs
[out_count
];
782 float *params
[param_count
];
785 compressor_audio_module();
788 uint32_t process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
);
790 inline float output_level(float slope
) {
791 return slope
* output_gain(slope
, false) * makeup
;
794 inline float output_gain(float linSlope
, bool rms
) {
795 if(linSlope
> (rms
? adjKneeStart
: linKneeStart
)) {
796 float slope
= log(linSlope
);
797 if(rms
) slope
*= 0.5f
;
801 if(IS_FAKE_INFINITY(ratio
)) {
805 gain
= (slope
- threshold
) / ratio
+ threshold
;
809 if(knee
> 1.f
&& slope
< kneeStop
) {
810 gain
= hermite_interpolation(slope
, kneeStart
, kneeStop
, kneeStart
, compressedKneeStop
, 1.f
, delta
);
813 return exp(gain
- slope
);
819 void set_sample_rate(uint32_t sr
);
821 virtual bool get_graph(int index
, int subindex
, float *data
, int points
, cairo_iface
*context
);
822 virtual bool get_dot(int index
, int subindex
, float &x
, float &y
, int &size
, cairo_iface
*context
);
823 virtual bool get_gridline(int index
, int subindex
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
);
826 /// Filterclavier --- MIDI controlled filter by Hans Baier
827 class filterclavier_audio_module
:
828 public audio_module
<filterclavier_metadata
>,
829 public filter_module_with_inertia
<biquad_filter_module
, filterclavier_metadata
>,
830 public line_graph_iface
832 const float min_gain
;
833 const float max_gain
;
839 filterclavier_audio_module()
846 void params_changed()
848 inertia_filter_module::inertia_cutoff
.set_inertia(
849 note_to_hz(last_note
+ *params
[par_transpose
], *params
[par_detune
]));
851 float min_resonance
= param_props
[par_max_resonance
].min
;
852 inertia_filter_module::inertia_resonance
.set_inertia(
853 (float(last_velocity
) / 127.0)
855 * (*params
[par_max_resonance
] - min_resonance
+ 0.001)
858 adjust_gain_according_to_filter_mode(last_velocity
);
860 inertia_filter_module::calculate_filter();
865 inertia_filter_module::activate();
868 void set_sample_rate(uint32_t sr
)
870 inertia_filter_module::set_sample_rate(sr
);
876 inertia_filter_module::deactivate();
880 virtual void note_on(int note
, int vel
)
884 inertia_filter_module::inertia_cutoff
.set_inertia(
885 note_to_hz(note
+ *params
[par_transpose
], *params
[par_detune
]));
887 float min_resonance
= param_props
[par_max_resonance
].min
;
888 inertia_filter_module::inertia_resonance
.set_inertia(
890 // 0.001: if the difference is equal to zero (which happens
891 // when the max_resonance knom is at minimum position
892 // then the filter gain doesnt seem to snap to zero on most note offs
893 * (*params
[par_max_resonance
] - min_resonance
+ 0.001)
896 adjust_gain_according_to_filter_mode(vel
);
898 inertia_filter_module::calculate_filter();
901 virtual void note_off(int note
, int vel
)
903 if (note
== last_note
) {
904 inertia_filter_module::inertia_resonance
.set_inertia(param_props
[par_max_resonance
].min
);
905 inertia_filter_module::inertia_gain
.set_inertia(min_gain
);
906 inertia_filter_module::calculate_filter();
911 bool get_graph(int index
, int subindex
, float *data
, int points
, cairo_iface
*context
);
912 bool get_gridline(int index
, int subindex
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
);
915 void adjust_gain_according_to_filter_mode(int velocity
) {
916 int mode
= dsp::fastf2i_drm(*params
[par_mode
]);
918 // for bandpasses: boost gain for velocities > 0
919 if ( (mode_6db_bp
<= mode
) && (mode
<= mode_18db_bp
) ) {
920 // gain for velocity 0: 1.0
921 // gain for velocity 127: 32.0
922 float mode_max_gain
= max_gain
;
923 // max_gain is right for mode_6db_bp
924 if (mode
== mode_12db_bp
)
925 mode_max_gain
/= 6.0;
926 if (mode
== mode_18db_bp
)
927 mode_max_gain
/= 10.5;
929 inertia_filter_module::inertia_gain
.set_now(
930 (float(velocity
) / 127.0) * (mode_max_gain
- min_gain
) + min_gain
);
932 inertia_filter_module::inertia_gain
.set_now(min_gain
);
937 extern std::string
get_builtin_modules_rdf();
941 #include "modules_synths.h"