1 /* Calf DSP plugin pack
2 * Modulation effect plugins
4 * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others
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 02110-1301 USA
23 #include <calf/giface.h>
24 #include <calf/modules_mod.h>
27 using namespace calf_plugins
;
29 #define SET_IF_CONNECTED(name) if (params[AM::param_##name] != NULL) *params[AM::param_##name] = name;
31 /**********************************************************************
32 * FLANGER by Krzysztof Foltman
33 **********************************************************************/
35 void flanger_audio_module::activate() {
38 last_r_phase
= *params
[par_stereo
] * (1.f
/ 360.f
);
39 left
.reset_phase(0.f
);
40 right
.reset_phase(last_r_phase
);
44 void flanger_audio_module::set_sample_rate(uint32_t sr
) {
50 void flanger_audio_module::deactivate() {
54 void flanger_audio_module::params_changed()
56 float dry
= *params
[par_dryamount
];
57 float wet
= *params
[par_amount
];
58 float rate
= *params
[par_rate
]; // 0.01*pow(1000.0f,*params[par_rate]);
59 float min_delay
= *params
[par_delay
] / 1000.0;
60 float mod_depth
= *params
[par_depth
] / 1000.0;
61 float fb
= *params
[par_fb
];
62 left
.set_dry(dry
); right
.set_dry(dry
);
63 left
.set_wet(wet
); right
.set_wet(wet
);
64 left
.set_rate(rate
); right
.set_rate(rate
);
65 left
.set_min_delay(min_delay
); right
.set_min_delay(min_delay
);
66 left
.set_mod_depth(mod_depth
); right
.set_mod_depth(mod_depth
);
67 left
.set_fb(fb
); right
.set_fb(fb
);
68 float r_phase
= *params
[par_stereo
] * (1.f
/ 360.f
);
70 if (*params
[par_reset
] >= 0.5) {
72 left
.reset_phase(0.f
);
73 right
.reset_phase(r_phase
);
75 if (fabs(r_phase
- last_r_phase
) > 0.0001f
) {
76 right
.phase
= left
.phase
;
77 right
.inc_phase(r_phase
);
78 last_r_phase
= r_phase
;
83 void flanger_audio_module::params_reset()
86 *params
[par_reset
] = 0.f
;
90 bool flanger_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
92 if (!is_active
or !phase
or subindex
>= 2)
94 set_channel_color(context
, subindex
);
95 return ::get_graph(*this, subindex
, data
, points
, 32, 0);
97 bool flanger_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
99 if (!is_active
or phase
)
101 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
, true, 32, 0);
103 bool flanger_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
105 layers
= LG_REALTIME_GRAPH
| (generation
? 0 : LG_CACHE_GRID
);
108 float flanger_audio_module::freq_gain(int subindex
, float freq
) const
110 return (subindex
? right
: left
).freq_gain(freq
, srate
);
114 /**********************************************************************
115 * PHASER by Krzysztof Foltman
116 **********************************************************************/
119 phaser_audio_module::phaser_audio_module()
120 : left(MaxStages
, x1vals
[0], y1vals
[0])
121 , right(MaxStages
, x1vals
[1], y1vals
[1])
126 void phaser_audio_module::set_sample_rate(uint32_t sr
)
133 void phaser_audio_module::activate()
138 last_r_phase
= *params
[par_stereo
] * (1.f
/ 360.f
);
139 left
.reset_phase(0.f
);
140 right
.reset_phase(last_r_phase
);
143 void phaser_audio_module::deactivate()
148 void phaser_audio_module::params_changed()
150 float dry
= *params
[par_dryamount
];
151 float wet
= *params
[par_amount
];
152 float rate
= *params
[par_rate
]; // 0.01*pow(1000.0f,*params[par_rate]);
153 float base_frq
= *params
[par_freq
];
154 float mod_depth
= *params
[par_depth
];
155 float fb
= *params
[par_fb
];
156 int stages
= (int)*params
[par_stages
];
157 left
.set_dry(dry
); right
.set_dry(dry
);
158 left
.set_wet(wet
); right
.set_wet(wet
);
159 left
.set_rate(rate
); right
.set_rate(rate
);
160 left
.set_base_frq(base_frq
); right
.set_base_frq(base_frq
);
161 left
.set_mod_depth(mod_depth
); right
.set_mod_depth(mod_depth
);
162 left
.set_fb(fb
); right
.set_fb(fb
);
163 left
.set_stages(stages
); right
.set_stages(stages
);
164 float r_phase
= *params
[par_stereo
] * (1.f
/ 360.f
);
166 if (*params
[par_reset
] >= 0.5) {
168 left
.reset_phase(0.f
);
169 right
.reset_phase(r_phase
);
171 if (fabs(r_phase
- last_r_phase
) > 0.0001f
) {
172 right
.phase
= left
.phase
;
173 right
.inc_phase(r_phase
);
174 last_r_phase
= r_phase
;
179 void phaser_audio_module::params_reset()
182 *params
[par_reset
] = 0.f
;
186 bool phaser_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
188 if (!is_active
or phase
)
190 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
, true, 32, 0);
192 bool phaser_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
194 if (!is_active
or subindex
>= 2 or !phase
)
196 set_channel_color(context
, subindex
);
197 return ::get_graph(*this, subindex
, data
, points
, 32, 0);
199 bool phaser_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
201 layers
= LG_REALTIME_GRAPH
| (generation
? 0 : LG_CACHE_GRID
);
205 float phaser_audio_module::freq_gain(int subindex
, float freq
) const
207 return (subindex
? right
: left
).freq_gain(freq
, srate
);
211 /**********************************************************************
212 * ROTARY SPEAKER by Krzysztof Foltman
213 **********************************************************************/
215 rotary_speaker_audio_module::rotary_speaker_audio_module()
217 mwhl_value
= hold_value
= 0.f
;
218 phase_h
= phase_l
= 0.f
;
224 void rotary_speaker_audio_module::set_sample_rate(uint32_t sr
)
230 void rotary_speaker_audio_module::setup()
232 crossover1l
.set_lp_rbj(800.f
, 0.7, (float)srate
);
233 crossover1r
.set_lp_rbj(800.f
, 0.7, (float)srate
);
234 crossover2l
.set_hp_rbj(800.f
, 0.7, (float)srate
);
235 crossover2r
.set_hp_rbj(800.f
, 0.7, (float)srate
);
238 void rotary_speaker_audio_module::activate()
240 phase_h
= phase_l
= 0.f
;
241 maspeed_h
= maspeed_l
= 0.f
;
245 void rotary_speaker_audio_module::deactivate()
249 void rotary_speaker_audio_module::control_change(int /*channel*/, int ctl
, int val
)
251 if (vibrato_mode
== 3 && ctl
== 64)
253 hold_value
= val
/ 127.f
;
257 if (vibrato_mode
== 4 && ctl
== 1)
259 mwhl_value
= val
/ 127.f
;
265 void rotary_speaker_audio_module::params_changed()
270 void rotary_speaker_audio_module::set_vibrato()
272 vibrato_mode
= fastf2i_drm(*params
[par_speed
]);
273 // manual vibrato - do not recalculate speeds as they're not used anyway
274 if (vibrato_mode
== 5)
279 float speed
= vibrato_mode
- 1;
280 if (vibrato_mode
== 3)
282 if (vibrato_mode
== 4)
284 dspeed
= (speed
< 0.5f
) ? 0 : 1;
289 /// Convert RPM speed to delta-phase
290 uint32_t rotary_speaker_audio_module::rpm2dphase(float rpm
)
292 return (uint32_t)((rpm
/ (60.0 * srate
)) * (1 << 30)) << 2;
295 /// Set delta-phase variables based on current calculated (and interpolated) RPM speed
296 void rotary_speaker_audio_module::update_speed()
298 float speed_h
= aspeed_h
>= 0 ? (48 + (400-48) * aspeed_h
) : (48 * (1 + aspeed_h
));
299 float speed_l
= aspeed_l
>= 0 ? 40 + (342-40) * aspeed_l
: (40 * (1 + aspeed_l
));
300 dphase_h
= rpm2dphase(speed_h
);
301 dphase_l
= rpm2dphase(speed_l
);
304 void rotary_speaker_audio_module::update_speed_manual(float delta
)
306 float ts
= *params
[par_treblespeed
];
307 float bs
= *params
[par_bassspeed
];
308 incr_towards(maspeed_h
, ts
, delta
* 200, delta
* 200);
309 incr_towards(maspeed_l
, bs
, delta
* 200, delta
* 200);
310 dphase_h
= rpm2dphase(maspeed_h
);
311 dphase_l
= rpm2dphase(maspeed_l
);
314 /// map a ramp [int] to a sinusoid-like function [0, 65536]
315 static inline int pseudo_sine_scl(int counter
)
317 // premature optimization is a root of all evil; it can be done with integers only - but later :)
318 double v
= counter
* (1.0 / (65536.0 * 32768.0));
319 return (int) (32768 + 32768 * (v
- v
*v
*v
) * (1.0 / 0.3849));
322 /// Increase or decrease aspeed towards raspeed, with required negative and positive rate
323 inline bool rotary_speaker_audio_module::incr_towards(float &aspeed
, float raspeed
, float delta_decc
, float delta_acc
)
325 if (aspeed
< raspeed
) {
326 aspeed
= std::min(raspeed
, aspeed
+ delta_acc
);
329 else if (aspeed
> raspeed
)
331 aspeed
= std::max(raspeed
, aspeed
- delta_decc
);
337 uint32_t rotary_speaker_audio_module::process(uint32_t offset
, uint32_t nsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
341 crossover2l
.set_bp_rbj(2000.f
, 0.7, (float)srate
);
342 crossover2r
.copy_coeffs(crossover2l
);
343 damper1l
.set_bp_rbj(1000.f
*pow(4.0, *params
[par_test
]), 0.7, (float)srate
);
344 damper1r
.copy_coeffs(damper1l
);
348 crossover2l
.set_hp_rbj(800.f
, 0.7, (float)srate
);
349 crossover2r
.copy_coeffs(crossover2l
);
351 int shift
= (int)(300000 * (*params
[par_shift
])), pdelta
= (int)(300000 * (*params
[par_spacing
]));
352 int md
= (int)(100 * (*params
[par_moddepth
]));
353 float mix
= 0.5 * (1.0 - *params
[par_micdistance
]);
354 float mix2
= *params
[par_reflection
];
355 float mix3
= mix2
* mix2
;
356 double am_depth
= *params
[par_am_depth
];
357 for (unsigned int i
= 0; i
< nsamples
; i
++) {
358 float in_l
= ins
[0][i
+ offset
], in_r
= ins
[1][i
+ offset
];
359 double in_mono
= atan(0.5f
* (in_l
+ in_r
));
361 int xl
= pseudo_sine_scl(phase_l
), yl
= pseudo_sine_scl(phase_l
+ 0x40000000);
362 int xh
= pseudo_sine_scl(phase_h
), yh
= pseudo_sine_scl(phase_h
+ 0x40000000);
363 // printf("%d %d %d\n", shift, pdelta, shift + pdelta + 20 * xl);
366 // 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);
367 // 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);
368 float fm_hi_l
= 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
);
369 float fm_hi_r
= 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
);
370 float out_hi_l
= lerp(in_mono
, (double)damper1l
.process(fm_hi_l
), lerp(0.5, xh
* 1.0 / 65536.0, am_depth
));
371 float out_hi_r
= lerp(in_mono
, (double)damper1r
.process(fm_hi_r
), lerp(0.5, yh
* 1.0 / 65536.0, am_depth
));
373 float out_lo_l
= lerp(in_mono
, (double)delay
.get_interp_1616(shift
+ (md
* xl
>> 2)), lerp(0.5, yl
* 1.0 / 65536.0, am_depth
)); // + delay.get_interp_1616(shift + md * 65536 + pdelta - md * yl);
374 float out_lo_r
= lerp(in_mono
, (double)delay
.get_interp_1616(shift
+ (md
* yl
>> 2)), lerp(0.5, xl
* 1.0 / 65536.0, am_depth
)); // + delay.get_interp_1616(shift + md * 65536 + pdelta - md * yl);
376 out_hi_l
= crossover2l
.process(out_hi_l
); // sanitize(out_hi_l);
377 out_hi_r
= crossover2r
.process(out_hi_r
); // sanitize(out_hi_r);
378 out_lo_l
= crossover1l
.process(out_lo_l
); // sanitize(out_lo_l);
379 out_lo_r
= crossover1r
.process(out_lo_r
); // sanitize(out_lo_r);
381 float out_l
= out_hi_l
+ out_lo_l
;
382 float out_r
= out_hi_r
+ out_lo_r
;
384 float mic_l
= out_l
+ mix
* (out_r
- out_l
);
385 float mic_r
= out_r
+ mix
* (out_l
- out_r
);
387 outs
[0][i
+ offset
] = mic_l
;
388 outs
[1][i
+ offset
] = mic_r
;
393 crossover1l
.sanitize();
394 crossover1r
.sanitize();
395 crossover2l
.sanitize();
396 crossover2r
.sanitize();
399 float delta
= nsamples
* 1.0 / srate
;
400 if (vibrato_mode
== 5)
401 update_speed_manual(delta
);
404 bool u1
= incr_towards(aspeed_l
, dspeed
, delta
* 0.2, delta
* 0.14);
405 bool u2
= incr_towards(aspeed_h
, dspeed
, delta
, delta
* 0.5);
409 if(params
[par_meter_l
] != NULL
) {
410 *params
[par_meter_l
] = (float)meter_l
/ 65536.0;
412 if(params
[par_meter_h
] != NULL
) {
413 *params
[par_meter_h
] = (float)meter_h
/ 65536.0;
418 /**********************************************************************
419 * MULTI CHORUS by Krzysztof Foltman
420 **********************************************************************/
422 multichorus_audio_module::multichorus_audio_module()
426 freq_old
= freq2_old
= q_old
= -1;
431 void multichorus_audio_module::activate()
437 void multichorus_audio_module::deactivate()
442 void multichorus_audio_module::set_sample_rate(uint32_t sr
) {
449 void multichorus_audio_module::params_changed()
451 // delicious copy-pasta from flanger module - it'd be better to keep it common or something
452 float dry
= *params
[par_dryamount
];
453 float wet
= *params
[par_amount
];
454 float rate
= *params
[par_rate
];
455 float min_delay
= *params
[par_delay
] / 1000.0;
456 float mod_depth
= *params
[par_depth
] / 1000.0;
457 float overlap
= *params
[par_overlap
];
458 left
.set_dry(dry
); right
.set_dry(dry
);
459 left
.set_wet(wet
); right
.set_wet(wet
);
460 left
.set_rate(rate
); right
.set_rate(rate
);
461 left
.set_min_delay(min_delay
); right
.set_min_delay(min_delay
);
462 left
.set_mod_depth(mod_depth
); right
.set_mod_depth(mod_depth
);
463 int voices
= (int)*params
[par_voices
];
464 left
.lfo
.set_voices(voices
); right
.lfo
.set_voices(voices
);
465 left
.lfo
.set_overlap(overlap
);right
.lfo
.set_overlap(overlap
);
466 float vphase
= *params
[par_vphase
] * (1.f
/ 360.f
);
467 left
.lfo
.vphase
= right
.lfo
.vphase
= vphase
* (4096 / std::max(voices
- 1, 1));
468 float r_phase
= *params
[par_stereo
] * (1.f
/ 360.f
);
469 if (fabs(r_phase
- last_r_phase
) > 0.0001f
) {
470 right
.lfo
.phase
= left
.lfo
.phase
;
471 right
.lfo
.phase
+= chorus_phase(r_phase
* 4096);
472 last_r_phase
= r_phase
;
474 if (*params
[par_freq
] != freq_old
or *params
[par_freq2
] != freq2_old
or *params
[par_q
] != q_old
) {
475 left
.post
.f1
.set_bp_rbj(*params
[par_freq
], *params
[par_q
], srate
);
476 left
.post
.f2
.set_bp_rbj(*params
[par_freq2
], *params
[par_q
], srate
);
477 right
.post
.f1
.copy_coeffs(left
.post
.f1
);
478 right
.post
.f2
.copy_coeffs(left
.post
.f2
);
479 freq_old
= *params
[par_freq
];
480 freq2_old
= *params
[par_freq2
];
481 q_old
= *params
[par_q
];
487 uint32_t multichorus_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
489 left
.process(outs
[0] + offset
, ins
[0] + offset
, numsamples
);
490 right
.process(outs
[1] + offset
, ins
[1] + offset
, numsamples
);
491 return outputs_mask
; // XXXKF allow some delay after input going blank
494 bool multichorus_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
497 // frequency response
498 if (index
== par_delay
) {
499 layers
= (generation
? 0 : LG_CACHE_GRID
) | (redraw_graph
? LG_CACHE_GRAPH
: 0) | LG_REALTIME_GRAPH
;
502 if (index
== par_rate
) {
503 layers
= LG_REALTIME_DOT
| (redraw_sine
? LG_CACHE_GRAPH
: 0);
506 if (index
== par_depth
)
507 layers
= LG_REALTIME_DOT
;
511 bool multichorus_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
516 // the filter graph (cached) in frequency response
517 if (index
== par_delay
and subindex
== 2 and !phase
) {
518 context
->set_source_rgba(0.15, 0.2, 0.0, 0.8);
519 redraw_graph
= false;
520 return ::get_graph(*this, subindex
, data
, points
, 64, 0.5);
522 // the realtime graphs in frequency response
523 if (index
== par_delay
and subindex
< 2 and phase
) {
524 set_channel_color(context
, subindex
);
525 context
->set_line_width(1);
526 return ::get_graph(*this, subindex
, data
, points
, 64, 0.5);
529 // the sine curves in modulation display
530 if (index
== par_rate
&& subindex
< (int)*params
[par_voices
] and !phase
) {
531 const sine_multi_lfo
<float, 8> &lfo
= left
.lfo
;
532 for (int i
= 0; i
< points
; i
++) {
533 float _phase
= i
* 2 * M_PI
/ points
;
534 // original -65536 to 65535 value
535 float orig
= subindex
* lfo
.voice_offset
+ ((lfo
.voice_depth
>> (30-13)) * 65536.0 * (0.95 * sin(_phase
) + 1)/ 8192.0) - 65536;
537 data
[i
] = orig
/ 65536.0;
545 bool multichorus_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
547 int voice
= subindex
>> 1;
548 int nvoices
= (int)*params
[par_voices
];
551 or (index
!= par_rate
and index
!= par_depth
)
555 float unit
= (1 - *params
[par_overlap
]);
556 float scw
= 1 + unit
* (nvoices
- 1);
557 const sine_multi_lfo
<float, 8> &lfo
= (subindex
& 1 ? right
: left
).lfo
;
559 // the display with the sine curves
560 if (index
== par_rate
) {
561 x
= (double)(lfo
.phase
+ lfo
.vphase
* voice
) / 4096.0;
562 y
= 0.95 * sin(x
* 2 * M_PI
);
563 y
= (voice
* unit
+ (y
+ 1) / 2) / scw
* 2 - 1;
565 // the tiny dot display
566 if (index
== par_depth
) {
567 double ph
= (double)(lfo
.phase
+ lfo
.vphase
* voice
) / 4096.0;
568 x
= 0.5 + 0.5 * sin(ph
* 2 * M_PI
);
569 y
= subindex
& 1 ? -0.5 : 0.5;
570 x
= (voice
* unit
+ x
) / scw
;
575 bool multichorus_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
577 if (index
== par_delay
and !phase
and is_active
)
578 return get_freq_gridline(subindex
, pos
, vertical
, legend
, context
, true, 64, 0.5);
582 float multichorus_audio_module::freq_gain(int subindex
, float freq
) const
585 return *params
[par_amount
] * left
.post
.freq_gain(freq
, srate
);
586 return (subindex
? right
: left
).freq_gain(freq
, srate
);
589 /**********************************************************************
590 * PULSATOR by Markus Schmidt
591 **********************************************************************/
593 pulsator_audio_module::pulsator_audio_module()
602 void pulsator_audio_module::activate()
609 void pulsator_audio_module::deactivate()
616 void pulsator_audio_module::params_changed()
618 lfoL
.set_params(*params
[param_freq
], *params
[param_mode
], 0.f
, srate
, *params
[param_amount
]);
619 lfoR
.set_params(*params
[param_freq
], *params
[param_mode
], *params
[param_offset
], srate
, *params
[param_amount
]);
621 if (*params
[param_reset
] >= 0.5) {
626 if (*params
[param_mode
] != mode_old
627 or *params
[param_amount
] != amount_old
628 or *params
[param_offset
] != offset_old
630 mode_old
= *params
[param_mode
];
631 amount_old
= *params
[param_amount
];
632 offset_old
= *params
[param_offset
];
637 void pulsator_audio_module::set_sample_rate(uint32_t sr
)
640 int meter
[] = {param_meter_inL
, param_meter_inR
, param_meter_outL
, param_meter_outR
};
641 int clip
[] = {param_clip_inL
, param_clip_inR
, param_clip_outL
, param_clip_outR
};
642 meters
.init(params
, meter
, clip
, 4, sr
);
645 uint32_t pulsator_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
647 bool bypass
= *params
[param_bypass
] > 0.5f
;
648 uint32_t samples
= numsamples
+ offset
;
650 // everything bypassed
651 while(offset
< samples
) {
652 outs
[0][offset
] = ins
[0][offset
];
653 outs
[1][offset
] = ins
[1][offset
];
656 // LFO's should go on
657 lfoL
.advance(numsamples
);
658 lfoR
.advance(numsamples
);
660 float values
[] = {0, 0, 0, 0};
661 meters
.process(values
);
664 while(offset
< samples
) {
665 // cycle through samples
668 float inL
= ins
[0][offset
];
669 float inR
= ins
[1][offset
];
671 inR
*= *params
[param_level_in
];
672 inL
*= *params
[param_level_in
];
674 if(*params
[param_mono
] > 0.5) {
675 inL
= (inL
+ inR
) * 0.5;
681 procL
*= (lfoL
.get_value() * 0.5 + *params
[param_amount
] / 2);
682 procR
*= (lfoR
.get_value() * 0.5 + *params
[param_amount
] / 2);
684 outL
= procL
+ inL
* (1 - *params
[param_amount
]);
685 outR
= procR
+ inR
* (1 - *params
[param_amount
]);
687 outL
*= *params
[param_level_out
];
688 outR
*= *params
[param_level_out
];
691 outs
[0][offset
] = outL
;
692 outs
[1][offset
] = outR
;
701 float values
[] = {inL
, inR
, outL
, outR
};
702 meters
.process(values
);
704 } // cycle trough samples
706 meters
.fall(numsamples
);
710 bool pulsator_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
712 if (!is_active
or phase
or subindex
> 1) {
713 redraw_graph
= false;
716 set_channel_color(context
, subindex
);
717 return (subindex
? lfoR
: lfoL
).get_graph(data
, points
, context
, mode
);
720 bool pulsator_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
722 if (!is_active
or !phase
or subindex
> 1)
724 set_channel_color(context
, subindex
);
725 return (subindex
? lfoR
: lfoL
).get_dot(x
, y
, size
, context
);
728 bool pulsator_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
730 if (phase
or subindex
)
736 bool pulsator_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
738 layers
= LG_REALTIME_DOT
| (generation
? 0 : LG_CACHE_GRID
) | ((redraw_graph
|| !generation
) ? LG_CACHE_GRAPH
: 0);
743 /**********************************************************************
744 * RING MODULATOR by Markus Schmidt
745 **********************************************************************/
747 ringmodulator_audio_module::ringmodulator_audio_module()
753 void ringmodulator_audio_module::activate()
762 void ringmodulator_audio_module::deactivate()
771 void ringmodulator_audio_module::params_changed()
773 lfo1
.set_params(*params
[param_lfo1_freq
],
774 *params
[param_lfo1_mode
],
777 *params
[param_lfo1_amount
]);
779 lfo2
.set_params(*params
[param_lfo2_freq
],
780 *params
[param_lfo2_mode
],
783 *params
[param_lfo2_amount
]);
785 modL
.set_params(*params
[param_mod_freq
] * pow(pow(2, 1.0 / 1200.0), *params
[param_mod_detune
] / 2),
786 *params
[param_mod_mode
],
789 *params
[param_mod_amount
]);
791 modR
.set_params(*params
[param_mod_freq
] * pow(pow(2, 1.0 / 1200.0), *params
[param_mod_detune
] / -2),
792 *params
[param_mod_mode
],
793 *params
[param_mod_phase
],
795 *params
[param_mod_amount
]);
799 if (*params
[param_lfo1_reset
] >= 0.5) {
803 if (*params
[param_lfo2_reset
] >= 0.5) {
808 //redraw_graph = true;
811 void ringmodulator_audio_module::set_sample_rate(uint32_t sr
)
814 int meter
[] = {param_meter_inL
, param_meter_inR
, param_meter_outL
, param_meter_outR
};
815 int clip
[] = {param_clip_inL
, param_clip_inR
, param_clip_outL
, param_clip_outR
};
816 meters
.init(params
, meter
, clip
, 4, sr
);
819 uint32_t ringmodulator_audio_module::process(uint32_t offset
, uint32_t numsamples
, uint32_t inputs_mask
, uint32_t outputs_mask
)
821 bool bypass
= *params
[param_bypass
] > 0.5f
;
822 uint32_t samples
= numsamples
+ offset
;
824 // everything bypassed
825 while(offset
< samples
) {
826 outs
[0][offset
] = ins
[0][offset
];
827 outs
[1][offset
] = ins
[1][offset
];
830 // LFO's should go on
831 lfo1
.advance(numsamples
);
832 lfo1
.advance(numsamples
);
833 modL
.advance(numsamples
);
834 modR
.advance(numsamples
);
836 float values
[] = {0, 0, 0, 0};
837 meters
.process(values
);
840 while(offset
< samples
) {
841 // cycle through samples
844 float inL
= ins
[0][offset
];
845 float inR
= ins
[1][offset
];
848 inR
*= *params
[param_level_in
];
849 inL
*= *params
[param_level_in
];
852 float modulL
= modL
.get_value();
853 float modulR
= modR
.get_value();
855 float procL
= inL
* modulL
;
856 float procR
= inR
* modulR
;
858 //procL *= (lfo1.get_value() * 0.5 + *params[param_amount] / 2);
859 //procR *= (lfo2.get_value() * 0.5 + *params[param_amount] / 2);
861 outL
= procL
+ inL
* (1 - *params
[param_mod_amount
]);
862 outR
= procR
+ inR
* (1 - *params
[param_mod_amount
]);
864 outL
*= *params
[param_level_out
];
865 outR
*= *params
[param_level_out
];
868 outs
[0][offset
] = outL
;
869 outs
[1][offset
] = outR
;
880 float values
[] = {inL
, inR
, outL
, outR
};
881 meters
.process(values
);
883 } // cycle trough samples
885 meters
.fall(numsamples
);
889 bool ringmodulator_audio_module::get_graph(int index
, int subindex
, int phase
, float *data
, int points
, cairo_iface
*context
, int *mode
) const
891 if (!is_active
or phase
or subindex
> 1) {
892 redraw_graph
= false;
895 set_channel_color(context
, subindex
);
896 return (subindex
? lfo2
: lfo1
).get_graph(data
, points
, context
, mode
);
899 bool ringmodulator_audio_module::get_dot(int index
, int subindex
, int phase
, float &x
, float &y
, int &size
, cairo_iface
*context
) const
901 if (!is_active
or !phase
or subindex
> 1)
903 set_channel_color(context
, subindex
);
904 return (subindex
? lfo2
: lfo1
).get_dot(x
, y
, size
, context
);
907 bool ringmodulator_audio_module::get_gridline(int index
, int subindex
, int phase
, float &pos
, bool &vertical
, std::string
&legend
, cairo_iface
*context
) const
909 if (phase
or subindex
)
915 bool ringmodulator_audio_module::get_layers(int index
, int generation
, unsigned int &layers
) const
917 layers
= LG_REALTIME_DOT
| (generation
? 0 : LG_CACHE_GRID
) | ((redraw_graph
|| !generation
) ? LG_CACHE_GRAPH
: 0);