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
= 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 filter_audio_module
: public audio_module
<filter_metadata
>, public line_graph_iface
248 float *ins
[in_count
];
249 float *outs
[out_count
];
250 float *params
[param_count
];
251 dsp::biquad_d1
<float> left
[3], right
[3];
254 inertia
<exponential_ramp
> inertia_cutoff
, inertia_resonance
;
258 filter_audio_module()
259 : inertia_cutoff(exponential_ramp(128), 20)
260 , inertia_resonance(exponential_ramp(128), 20)
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);
278 left
[0].set_lp_rbj(freq
, pow(q
, 1.0 / order
), srate
);
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
]);
304 inertia_cutoff
.step();
305 inertia_resonance
.step();
309 void set_sample_rate(uint32_t sr
);
311 inline int process_channel(dsp::biquad_d1
<float> *filter
, float *in
, float *out
, uint32_t numsamples
, int inmask
) {
315 for (uint32_t i
= 0; i
< numsamples
; i
++)
316 out
[i
] = filter
[0].process(in
[i
]);
319 for (uint32_t i
= 0; i
< numsamples
; i
++)
320 out
[i
] = filter
[1].process(filter
[0].process(in
[i
]));
323 for (uint32_t i
= 0; i
< numsamples
; i
++)
324 out
[i
] = filter
[2].process(filter
[1].process(filter
[0].process(in
[i
])));
328 if (filter
[order
- 1].empty())
332 for (uint32_t i
= 0; i
< numsamples
; i
++)
333 out
[i
] = filter
[0].process_zeroin();
336 if (filter
[0].empty())
337 for (uint32_t i
= 0; i
< numsamples
; i
++)
338 out
[i
] = filter
[1].process_zeroin();
340 for (uint32_t i
= 0; i
< numsamples
; i
++)
341 out
[i
] = filter
[1].process(filter
[0].process_zeroin());
344 if (filter
[1].empty())
345 for (uint32_t i
= 0; i
< numsamples
; i
++)
346 out
[i
] = filter
[2].process_zeroin();
348 for (uint32_t i
= 0; i
< numsamples
; i
++)
349 out
[i
] = filter
[2].process(filter
[1].process(filter
[0].process_zeroin()));
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]);
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()) {
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
>
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
;
397 dsp::biquad_d2
<float> biquad_left
[2], biquad_right
[2];
401 vintage_delay_audio_module()
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
]);
418 fb_left
.set_inertia(fb
);
419 fb_right
.set_inertia(pow(fb
, *params
[par_time_r
] / *params
[par_time_l
]));
421 fb_left
.set_inertia(fb
);
422 fb_right
.set_inertia(fb
);
424 if (medium
!= old_medium
)
432 void set_sample_rate(uint32_t sr
) {
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
);
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);
467 bufptr
= orig_bufptr
;
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();
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();
492 class rotary_speaker_audio_module
: public audio_module
<rotary_speaker_metadata
>
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
;
505 /// Current CC1 (Modulation) value, normalized to [0, 1]
507 /// Current CC64 (Hold) value, normalized to [0, 1]
509 /// Current rotation speed for bass rotor - automatic mode
511 /// Current rotation speed for treble rotor - automatic mode
513 /// Desired speed (0=slow, 1=fast) - automatic mode
515 /// Current rotation speed for bass rotor - manual mode
517 /// Current rotation speed for treble rotor - manual mode
520 rotary_speaker_audio_module();
521 void set_sample_rate(uint32_t sr
);
526 void params_changed() {
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)
538 float speed
= vibrato_mode
- 1;
539 if (vibrato_mode
== 3)
541 if (vibrato_mode
== 4)
543 dspeed
= (speed
< 0.5f
) ? 0 : 1;
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
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
);
583 else if (aspeed
> raspeed
)
585 aspeed
= std::max(raspeed
, aspeed
- delta_decc
);
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
;
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
);
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);
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
{
653 typedef std::complex<float> cfloat
;
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
));
683 /// Compose two filters in parallel
684 template<class F1
, class F2
>
687 typedef std::complex<double> cfloat
;
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
));
717 /// A multitap stereo chorus thing - processing
718 class multichorus_audio_module
: public audio_module
<multichorus_metadata
>, public line_graph_iface
721 float *ins
[in_count
];
722 float *outs
[out_count
];
723 float *params
[param_count
];
725 dsp::multichorus
<float, sine_multi_lfo
<float, 8>, filter_sum
<dsp::biquad_d2
<>, dsp::biquad_d2
<> >, 4096> left
, right
;
731 multichorus_audio_module()
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
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
{
780 float linSlope
, peak
, detected
, kneeSqrt
, kneeStart
, linKneeStart
, kneeStop
, threshold
, ratio
, knee
, makeup
, compressedKneeStop
, adjKneeStart
;
784 float *ins
[in_count
];
785 float *outs
[out_count
];
786 float *params
[param_count
];
789 compressor_audio_module();
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
;
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
;
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
];
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
);
862 gain
= output_gain(linSlope
, rms
);
868 float outL
= ins
[0][offset
] * gain
;
869 float outR
= ins
[1][offset
] * gain
;
871 outs
[0][offset
] = outL
;
872 outs
[1][offset
] = outR
;
876 float maxLR
= std::max(fabs(outL
), fabs(outR
));
878 if(maxLR
> 1.f
) clip
= srate
>> 3; /* blink clip LED for 125 ms */
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
;
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
;
913 if(IS_FAKE_INFINITY(ratio
)) {
917 gain
= (slope
- threshold
) / ratio
+ threshold
;
921 if(knee
> 1.f
&& slope
< kneeStop
) {
922 gain
= hermite_interpolation(slope
, kneeStart
, kneeStop
, kneeStart
, compressedKneeStop
, 1.f
, delta
);
925 return exp(gain
- slope
);
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"