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., 51 Franklin Street, Fifth Floor,
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);
316
// parameters are heavily influenced by gordonjcp and his tape delay unit
317
// although, don't blame him if it sounds bad - I've messed with them too :)
318
biquad_left[0].set_lp_rbj(6000, 0.707, srate);
319
biquad_left[1].set_bp_rbj(4500, 0.250, srate);
320
biquad_right[0].copy_coeffs(biquad_left[0]);
321
biquad_right[1].copy_coeffs(biquad_left[1]);
323
uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
324
uint32_t ostate = 3; // XXXKF optimize!
325
uint32_t end = offset + numsamples;
326
int v = mixmode ? 1 : 0;
327
int orig_bufptr = bufptr;
328
for(uint32_t i = offset; i < end; i++)
330
float out_left, out_right, del_left, del_right;
331
// if the buffer hasn't been cleared yet (after activation), pretend we've read zeros
333
if (deltime_l >= age) {
334
del_left = ins[0][i];
335
out_left = dry * del_left;
341
float in_left = buffers[v][(bufptr - deltime_l) & ADDR_MASK];
342
dsp::sanitize(in_left);
343
out_left = dry * ins[0][i] + in_left * amt_left.get();
344
del_left = ins[0][i] + in_left * fb_left.get();
346
if (deltime_r >= age) {
347
del_right = ins[1][i];
348
out_right = dry * del_right;
354
float in_right = buffers[1 - v][(bufptr - deltime_r) & ADDR_MASK];
355
dsp::sanitize(in_right);
356
out_right = dry * ins[1][i] + in_right * amt_right.get();
357
del_right = ins[1][i] + in_right * fb_right.get();
361
outs[0][i] = out_left; outs[1][i] = out_right; buffers[0][bufptr] = del_left; buffers[1][bufptr] = del_right;
362
bufptr = (bufptr + 1) & (MAX_DELAY - 1);
364
if (age >= MAX_DELAY)
367
bufptr = orig_bufptr;
370
for(uint32_t i = offset; i < end; i++)
372
buffers[0][bufptr] = biquad_left[0].process_lp(biquad_left[1].process(buffers[0][bufptr]));
373
buffers[1][bufptr] = biquad_right[0].process_lp(biquad_right[1].process(buffers[1][bufptr]));
374
bufptr = (bufptr + 1) & (MAX_DELAY - 1);
376
biquad_left[0].sanitize();biquad_right[0].sanitize();
378
for(uint32_t i = offset; i < end; i++)
380
buffers[0][bufptr] = biquad_left[1].process(buffers[0][bufptr]);
381
buffers[1][bufptr] = biquad_right[1].process(buffers[1][bufptr]);
382
bufptr = (bufptr + 1) & (MAX_DELAY - 1);
385
biquad_left[1].sanitize();biquad_right[1].sanitize();
392
class rotary_speaker_audio_module: public audio_module<rotary_speaker_metadata>
395
float *ins[in_count];
396
float *outs[out_count];
397
float *params[param_count];
398
/// Current phases and phase deltas for bass and treble rotors
399
uint32_t phase_l, dphase_l, phase_h, dphase_h;
400
dsp::simple_delay<1024, float> delay;
401
dsp::biquad_d2<float> crossover1l, crossover1r, crossover2l, crossover2r;
402
dsp::simple_delay<8, float> phaseshift;
405
/// Current CC1 (Modulation) value, normalized to [0, 1]
407
/// Current CC64 (Hold) value, normalized to [0, 1]
409
/// Current rotation speed for bass rotor - automatic mode
411
/// Current rotation speed for treble rotor - automatic mode
413
/// Desired speed (0=slow, 1=fast) - automatic mode
415
/// Current rotation speed for bass rotor - manual mode
417
/// Current rotation speed for treble rotor - manual mode
420
rotary_speaker_audio_module();
421
void set_sample_rate(uint32_t sr);
426
void params_changed() {
431
vibrato_mode = fastf2i_drm(*params[par_speed]);
432
// manual vibrato - do not recalculate speeds as they're not used anyway
433
if (vibrato_mode == 5)
438
float speed = vibrato_mode - 1;
439
if (vibrato_mode == 3)
441
if (vibrato_mode == 4)
443
dspeed = (speed < 0.5f) ? 0 : 1;
447
/// Convert RPM speed to delta-phase
448
inline uint32_t rpm2dphase(float rpm)
450
return (uint32_t)((rpm / (60.0 * srate)) * (1 << 30)) << 2;
452
/// Set delta-phase variables based on current calculated (and interpolated) RPM speed
455
float speed_h = aspeed_h >= 0 ? (48 + (400-48) * aspeed_h) : (48 * (1 + aspeed_h));
456
float speed_l = aspeed_l >= 0 ? 40 + (342-40) * aspeed_l : (40 * (1 + aspeed_l));
457
dphase_h = rpm2dphase(speed_h);
458
dphase_l = rpm2dphase(speed_l);
460
void update_speed_manual(float delta)
462
float ts = *params[par_treblespeed];
463
float bs = *params[par_bassspeed];
464
incr_towards(maspeed_h, ts, delta * 200, delta * 200);
465
incr_towards(maspeed_l, bs, delta * 200, delta * 200);
466
dphase_h = rpm2dphase(maspeed_h);
467
dphase_l = rpm2dphase(maspeed_l);
469
/// map a ramp [int] to a sinusoid-like function [0, 65536]
470
static inline int pseudo_sine_scl(int counter)
472
// premature optimization is a root of all evil; it can be done with integers only - but later :)
473
double v = counter * (1.0 / (65536.0 * 32768.0));
474
return (int) (32768 + 32768 * (v - v*v*v) * (1.0 / 0.3849));
476
/// Increase or decrease aspeed towards raspeed, with required negative and positive rate
477
inline bool incr_towards(float &aspeed, float raspeed, float delta_decc, float delta_acc)
479
if (aspeed < raspeed) {
480
aspeed = std::min(raspeed, aspeed + delta_acc);
483
else if (aspeed > raspeed)
485
aspeed = std::max(raspeed, aspeed - delta_decc);
490
uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask)
492
int shift = (int)(300000 * (*params[par_shift])), pdelta = (int)(300000 * (*params[par_spacing]));
493
int md = (int)(100 * (*params[par_moddepth]));
494
float mix = 0.5 * (1.0 - *params[par_micdistance]);
495
float mix2 = *params[par_reflection];
496
float mix3 = mix2 * mix2;
497
for (unsigned int i = 0; i < nsamples; i++) {
498
float in_l = ins[0][i + offset], in_r = ins[1][i + offset];
499
float in_mono = 0.5f * (in_l + in_r);
501
int xl = pseudo_sine_scl(phase_l), yl = pseudo_sine_scl(phase_l + 0x40000000);
502
int xh = pseudo_sine_scl(phase_h), yh = pseudo_sine_scl(phase_h + 0x40000000);
503
// printf("%d %d %d\n", shift, pdelta, shift + pdelta + 20 * xl);
505
// 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);
506
// 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);
507
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);
508
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);
510
float out_lo_l = in_mono + delay.get_interp_1616(shift + md * xl); // + delay.get_interp_1616(shift + md * 65536 + pdelta - md * yl);
511
float out_lo_r = in_mono + delay.get_interp_1616(shift + md * yl); // - delay.get_interp_1616(shift + pdelta + md * yl);
513
out_hi_l = crossover2l.process(out_hi_l); // sanitize(out_hi_l);
514
out_hi_r = crossover2r.process(out_hi_r); // sanitize(out_hi_r);
515
out_lo_l = crossover1l.process(out_lo_l); // sanitize(out_lo_l);
516
out_lo_r = crossover1r.process(out_lo_r); // sanitize(out_lo_r);
518
float out_l = out_hi_l + out_lo_l;
519
float out_r = out_hi_r + out_lo_r;
521
float mic_l = out_l + mix * (out_r - out_l);
522
float mic_r = out_r + mix * (out_l - out_r);
524
outs[0][i + offset] = mic_l * 0.5f;
525
outs[1][i + offset] = mic_r * 0.5f;
530
crossover1l.sanitize();
531
crossover1r.sanitize();
532
crossover2l.sanitize();
533
crossover2r.sanitize();
534
float delta = nsamples * 1.0 / srate;
535
if (vibrato_mode == 5)
536
update_speed_manual(delta);
539
bool u1 = incr_towards(aspeed_l, dspeed, delta * 0.2, delta * 0.14);
540
bool u2 = incr_towards(aspeed_h, dspeed, delta, delta * 0.5);
546
virtual void control_change(int ctl, int val);
549
/// Compose two filters in series
550
template<class F1, class F2>
551
class filter_compose {
553
typedef std::complex<float> cfloat;
557
float process(float value) {
558
return f2.process(f1.process(value));
561
cfloat h_z(const cfloat &z) {
562
return f1.h_z(z) * f2.h_z(z);
565
/// Return the filter's gain at frequency freq
566
/// @param freq Frequency to look up
567
/// @param sr Filter sample rate (used to convert frequency to angular frequency)
568
float freq_gain(float freq, float sr)
570
typedef std::complex<double> cfloat;
571
freq *= 2.0 * M_PI / sr;
572
cfloat z = 1.0 / exp(cfloat(0.0, freq));
574
return std::abs(h_z(z));
583
/// Compose two filters in parallel
584
template<class F1, class F2>
587
typedef std::complex<double> cfloat;
591
float process(float value) {
592
return f2.process(value) + f1.process(value);
595
inline cfloat h_z(const cfloat &z) {
596
return f1.h_z(z) + f2.h_z(z);
599
/// Return the filter's gain at frequency freq
600
/// @param freq Frequency to look up
601
/// @param sr Filter sample rate (used to convert frequency to angular frequency)
602
float freq_gain(float freq, float sr)
604
typedef std::complex<double> cfloat;
605
freq *= 2.0 * M_PI / sr;
606
cfloat z = 1.0 / exp(cfloat(0.0, freq));
608
return std::abs(h_z(z));
617
template<typename FilterClass, typename Metadata>
618
class filter_module_with_inertia: public FilterClass
621
typedef filter_module_with_inertia inertia_filter_module;
623
float *ins[Metadata::in_count];
624
float *outs[Metadata::out_count];
625
float *params[Metadata::param_count];
627
inertia<exponential_ramp> inertia_cutoff, inertia_resonance, inertia_gain;
630
volatile int last_generation, last_calculated_generation;
632
filter_module_with_inertia()
633
: inertia_cutoff(exponential_ramp(128), 20)
634
, inertia_resonance(exponential_ramp(128), 20)
635
, inertia_gain(exponential_ramp(128), 1.0)
641
void calculate_filter()
643
float freq = inertia_cutoff.get_last();
644
// printf("freq=%g inr.cnt=%d timer.left=%d\n", freq, inertia_cutoff.count, timer.left);
645
// XXXKF this is resonance of a single stage, obviously for three stages, resonant gain will be different
646
float q = inertia_resonance.get_last();
647
int mode = dsp::fastf2i_drm(*params[Metadata::par_mode]);
648
// printf("freq = %f q = %f mode = %d\n", freq, q, mode);
650
int inertia = dsp::fastf2i_drm(*params[Metadata::par_inertia]);
651
if (inertia != inertia_cutoff.ramp.length()) {
652
inertia_cutoff.ramp.set_length(inertia);
653
inertia_resonance.ramp.set_length(inertia);
654
inertia_gain.ramp.set_length(inertia);
657
FilterClass::calculate_filter(freq, q, mode, inertia_gain.get_last());
660
virtual void params_changed()
667
int gen = last_generation;
668
inertia_cutoff.step();
669
inertia_resonance.step();
672
last_calculated_generation = gen;
678
FilterClass::filter_activate();
679
timer = once_per_n(FilterClass::srate / 1000);
684
void set_sample_rate(uint32_t sr)
686
FilterClass::srate = sr;
695
uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
696
// 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
numsamples += offset;
699
while(offset < numsamples) {
700
uint32_t numnow = numsamples - offset;
701
// if inertia's inactive, we can calculate the whole buffer at once
702
if (inertia_cutoff.active() || inertia_resonance.active() || inertia_gain.active())
703
numnow = timer.get(numnow);
705
if (outputs_mask & 1) {
706
ostate |= FilterClass::process_channel(0, ins[0] + offset, outs[0] + offset, numnow, inputs_mask & 1);
708
if (outputs_mask & 2) {
709
ostate |= FilterClass::process_channel(1, ins[1] + offset, outs[1] + offset, numnow, inputs_mask & 2);
712
if (timer.elapsed()) {
721
/// biquad filter module
722
class filter_audio_module:
723
public audio_module<filter_metadata>,
724
public filter_module_with_inertia<biquad_filter_module, filter_metadata>,
725
public frequency_response_line_graph
727
float old_cutoff, old_resonance, old_mode;
729
filter_audio_module()
733
void params_changed()
735
inertia_cutoff.set_inertia(*params[par_cutoff]);
736
inertia_resonance.set_inertia(*params[par_resonance]);
737
inertia_filter_module::params_changed();
742
inertia_filter_module::activate();
745
void set_sample_rate(uint32_t sr)
747
inertia_filter_module::set_sample_rate(sr);
753
inertia_filter_module::deactivate();
756
bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
757
int get_changed_offsets(int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline);
760
/// A multitap stereo chorus thing - processing
761
class multichorus_audio_module: public audio_module<multichorus_metadata>, public frequency_response_line_graph
764
float *ins[in_count];
765
float *outs[out_count];
766
float *params[param_count];
768
dsp::multichorus<float, sine_multi_lfo<float, 8>, filter_sum<dsp::biquad_d2<>, dsp::biquad_d2<> >, 4096> left, right;
774
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
float overlap = *params[par_overlap];
789
left.set_dry(dry); right.set_dry(dry);
790
left.set_wet(wet); right.set_wet(wet);
791
left.set_rate(rate); right.set_rate(rate);
792
left.set_min_delay(min_delay); right.set_min_delay(min_delay);
793
left.set_mod_depth(mod_depth); right.set_mod_depth(mod_depth);
794
int voices = (int)*params[par_voices];
795
left.lfo.set_voices(voices); right.lfo.set_voices(voices);
796
left.lfo.set_overlap(overlap);right.lfo.set_overlap(overlap);
797
float vphase = *params[par_vphase] * (1.f / 360.f);
798
left.lfo.vphase = right.lfo.vphase = vphase * (4096 / std::max(voices - 1, 1));
799
float r_phase = *params[par_stereo] * (1.f / 360.f);
800
if (fabs(r_phase - last_r_phase) > 0.0001f) {
801
right.lfo.phase = left.lfo.phase;
802
right.lfo.phase += chorus_phase(r_phase * 4096);
803
last_r_phase = r_phase;
805
left.post.f1.set_bp_rbj(*params[par_freq], *params[par_q], srate);
806
left.post.f2.set_bp_rbj(*params[par_freq2], *params[par_q], srate);
807
right.post.f1.copy_coeffs(left.post.f1);
808
right.post.f2.copy_coeffs(left.post.f2);
810
uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
811
left.process(outs[0] + offset, ins[0] + offset, numsamples);
812
right.process(outs[1] + offset, ins[1] + offset, numsamples);
813
return outputs_mask; // XXXKF allow some delay after input going blank
817
void set_sample_rate(uint32_t sr);
818
bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
819
float freq_gain(int subindex, float freq, float srate);
820
bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context);
821
bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
824
class compressor_audio_module: public audio_module<compressor_metadata>, public line_graph_iface {
826
float linSlope, peak, detected, kneeSqrt, kneeStart, linKneeStart, kneeStop, threshold, ratio, knee, makeup, compressedKneeStop, adjKneeStart;
827
float old_threshold, old_ratio, old_knee, old_makeup, old_bypass;
831
biquad_d2<float> bpL, bpR;
833
float *ins[in_count];
834
float *outs[out_count];
835
float *params[param_count];
838
compressor_audio_module();
841
uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
843
inline float output_level(float slope) {
844
return slope * output_gain(slope, false) * makeup;
847
inline float output_gain(float linSlope, bool rms) {
848
if(linSlope > (rms ? adjKneeStart : linKneeStart)) {
849
float slope = log(linSlope);
850
if(rms) slope *= 0.5f;
854
if(IS_FAKE_INFINITY(ratio)) {
858
gain = (slope - threshold) / ratio + threshold;
862
if(knee > 1.f && slope < kneeStop) {
863
gain = hermite_interpolation(slope, kneeStart, kneeStop, kneeStart, compressedKneeStop, 1.f, delta);
866
return exp(gain - slope);
872
void set_sample_rate(uint32_t sr);
874
virtual bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
875
virtual bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context);
876
virtual bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
878
virtual int get_changed_offsets(int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline)
882
subindex_gridline = generation ? INT_MAX : 0;
884
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)
886
old_threshold = threshold;
890
old_bypass = *params[param_bypass];
894
if (generation == last_generation)
896
return last_generation;
900
/// Filterclavier --- MIDI controlled filter by Hans Baier
901
class filterclavier_audio_module:
902
public audio_module<filterclavier_metadata>,
903
public filter_module_with_inertia<biquad_filter_module, filterclavier_metadata>,
904
public frequency_response_line_graph
906
const float min_gain;
907
const float max_gain;
913
filterclavier_audio_module()
920
void params_changed()
922
inertia_filter_module::inertia_cutoff.set_inertia(
923
note_to_hz(last_note + *params[par_transpose], *params[par_detune]));
925
float min_resonance = param_props[par_max_resonance].min;
926
inertia_filter_module::inertia_resonance.set_inertia(
927
(float(last_velocity) / 127.0)
929
* (*params[par_max_resonance] - min_resonance + 0.001)
932
adjust_gain_according_to_filter_mode(last_velocity);
934
inertia_filter_module::calculate_filter();
939
inertia_filter_module::activate();
942
void set_sample_rate(uint32_t sr)
944
inertia_filter_module::set_sample_rate(sr);
950
inertia_filter_module::deactivate();
954
virtual void note_on(int note, int vel)
958
inertia_filter_module::inertia_cutoff.set_inertia(
959
note_to_hz(note + *params[par_transpose], *params[par_detune]));
961
float min_resonance = param_props[par_max_resonance].min;
962
inertia_filter_module::inertia_resonance.set_inertia(
964
// 0.001: if the difference is equal to zero (which happens
965
// when the max_resonance knom is at minimum position
966
// then the filter gain doesnt seem to snap to zero on most note offs
967
* (*params[par_max_resonance] - min_resonance + 0.001)
970
adjust_gain_according_to_filter_mode(vel);
972
inertia_filter_module::calculate_filter();
975
virtual void note_off(int note, int vel)
977
if (note == last_note) {
978
inertia_filter_module::inertia_resonance.set_inertia(param_props[par_max_resonance].min);
979
inertia_filter_module::inertia_gain.set_inertia(min_gain);
980
inertia_filter_module::calculate_filter();
985
bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
988
void adjust_gain_according_to_filter_mode(int velocity) {
989
int mode = dsp::fastf2i_drm(*params[par_mode]);
991
// for bandpasses: boost gain for velocities > 0
992
if ( (mode_6db_bp <= mode) && (mode <= mode_18db_bp) ) {
993
// gain for velocity 0: 1.0
994
// gain for velocity 127: 32.0
995
float mode_max_gain = max_gain;
996
// max_gain is right for mode_6db_bp
997
if (mode == mode_12db_bp)
998
mode_max_gain /= 6.0;
999
if (mode == mode_18db_bp)
1000
mode_max_gain /= 10.5;
1002
inertia_filter_module::inertia_gain.set_now(
1003
(float(velocity) / 127.0) * (mode_max_gain - min_gain) + min_gain);
1005
inertia_filter_module::inertia_gain.set_now(min_gain);
1010
extern std::string get_builtin_modules_rdf();
1014
#include "modules_synths.h"