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
29 #include "multichorus.h"
33 #include "primitives.h"
35 namespace calf_plugins
{
39 struct ladspa_plugin_info
;
42 class amp_audio_module
: public null_audio_module
45 enum { in_count
= 2, out_count
= 2, param_count
= 1, support_midi
= false, require_midi
= false, rt_capable
= true };
50 static parameter_properties param_props
[];
51 uint32_t process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
) {
54 float gain
= *params
[0];
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
;
65 class frequency_response_line_graph
: public line_graph_iface
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
75 dsp::simple_flanger
<float, 2048> left
, right
;
77 float *outs
[out_count
];
78 float *params
[param_count
];
84 flanger_audio_module() {
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
);
103 if (*params
[par_reset
] >= 0.5) {
105 left
.reset_phase(0.f
);
106 right
.reset_phase(r_phase
);
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
;
118 *params
[par_reset
] = 0.f
;
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
136 float *ins
[in_count
];
137 float *outs
[out_count
];
138 float *params
[param_count
];
142 dsp::simple_phaser
<12> left
, right
;
145 phaser_audio_module() {
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
);
165 if (*params
[par_reset
] >= 0.5) {
167 left
.reset_phase(0.f
);
168 right
.reset_phase(r_phase
);
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
;
180 *params
[par_reset
] = 0.f
;
185 void set_sample_rate(uint32_t sr
);
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
>
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
;
204 gain_smoothing amount
, dryamount
;
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();
248 void set_sample_rate(uint32_t sr
);
252 class vintage_delay_audio_module
: public audio_module
<vintage_delay_metadata
>
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)
265 gain_smoothing amt_left
, amt_right
, fb_left
, fb_right
;
268 dsp::biquad_d2
<float> biquad_left
[2], biquad_right
[2];
272 vintage_delay_audio_module()
275 for (int i
= 0; i
< MAX_DELAY
; i
++) {
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
]);
293 fb_left
.set_inertia(fb
);
294 fb_right
.set_inertia(pow(fb
, *params
[par_time_r
] / *params
[par_time_l
]));
296 fb_left
.set_inertia(fb
);
297 fb_right
.set_inertia(fb
);
299 if (medium
!= old_medium
)
308 void set_sample_rate(uint32_t sr
) {
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
);
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
;
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
;
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();
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
)
368 bufptr
= orig_bufptr
;
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();
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();
393 class rotary_speaker_audio_module
: public audio_module
<rotary_speaker_metadata
>
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
;
406 /// Current CC1 (Modulation) value, normalized to [0, 1]
408 /// Current CC64 (Hold) value, normalized to [0, 1]
410 /// Current rotation speed for bass rotor - automatic mode
412 /// Current rotation speed for treble rotor - automatic mode
414 /// Desired speed (0=slow, 1=fast) - automatic mode
416 /// Current rotation speed for bass rotor - manual mode
418 /// Current rotation speed for treble rotor - manual mode
421 rotary_speaker_audio_module();
422 void set_sample_rate(uint32_t sr
);
427 void params_changed() {
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)
439 float speed
= vibrato_mode
- 1;
440 if (vibrato_mode
== 3)
442 if (vibrato_mode
== 4)
444 dspeed
= (speed
< 0.5f
) ? 0 : 1;
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
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
);
484 else if (aspeed
> raspeed
)
486 aspeed
= std::max(raspeed
, aspeed
- delta_decc
);
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
;
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
);
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);
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
{
554 typedef std::complex<float> cfloat
;
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
));
584 /// Compose two filters in parallel
585 template<class F1
, class F2
>
588 typedef std::complex<double> cfloat
;
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
));
618 template<typename FilterClass
, typename Metadata
>
619 class filter_module_with_inertia
: public FilterClass
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
;
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)
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()
668 int gen
= last_generation
;
669 inertia_cutoff
.step();
670 inertia_resonance
.step();
673 last_calculated_generation
= gen
;
679 FilterClass::filter_activate();
680 timer
= once_per_n(FilterClass::srate
/ 1000);
685 void set_sample_rate(uint32_t sr
)
687 FilterClass::srate
= sr
;
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]);
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()) {
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
;
730 filter_audio_module()
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();
743 inertia_filter_module::activate();
746 void set_sample_rate(uint32_t sr
)
748 inertia_filter_module::set_sample_rate(sr
);
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
765 float *ins
[in_count
];
766 float *outs
[out_count
];
767 float *params
[param_count
];
769 dsp::multichorus
<float, sine_multi_lfo
<float, 8>, filter_sum
<dsp::biquad_d2
<>, dsp::biquad_d2
<> >, 4096> left
, right
;
775 multichorus_audio_module()
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
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
{
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
;
830 float *ins
[in_count
];
831 float *outs
[out_count
];
832 float *params
[param_count
];
835 compressor_audio_module();
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
;
851 if(IS_FAKE_INFINITY(ratio
)) {
855 gain
= (slope
- threshold
) / ratio
+ threshold
;
859 if(knee
> 1.f
&& slope
< kneeStop
) {
860 gain
= hermite_interpolation(slope
, kneeStart
, kneeStop
, kneeStart
, compressedKneeStop
, 1.f
, delta
);
863 return exp(gain
- slope
);
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
)
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
;
887 old_bypass
= *params
[param_bypass
];
891 if (generation
== last_generation
)
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
;
910 filterclavier_audio_module()
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)
926 * (*params
[par_max_resonance
] - min_resonance
+ 0.001)
929 adjust_gain_according_to_filter_mode(last_velocity
);
931 inertia_filter_module::calculate_filter();
936 inertia_filter_module::activate();
939 void set_sample_rate(uint32_t sr
)
941 inertia_filter_module::set_sample_rate(sr
);
947 inertia_filter_module::deactivate();
951 virtual void note_on(int note
, int 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(
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)
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();
982 bool get_graph(int index
, int subindex
, float *data
, int points
, cairo_iface
*context
);
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
);
1002 inertia_filter_module::inertia_gain
.set_now(min_gain
);
1007 extern std::string
get_builtin_modules_rdf();
1011 #include "modules_synths.h"