Button: emit slopes (fix for stuck modulaor plug-ins)
[calf.git] / src / modules_mod.cpp
blob6b26540e9dc989bc17ecdebb9509e89165e7a92f
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
21 #include <limits.h>
22 #include <memory.h>
23 #include <calf/giface.h>
24 #include <calf/modules_mod.h>
26 using namespace dsp;
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() {
36 left.reset();
37 right.reset();
38 last_r_phase = *params[par_stereo] * (1.f / 360.f);
39 left.reset_phase(0.f);
40 right.reset_phase(last_r_phase);
41 is_active = true;
44 void flanger_audio_module::set_sample_rate(uint32_t sr) {
45 srate = sr;
46 left.setup(sr);
47 right.setup(sr);
50 void flanger_audio_module::deactivate() {
51 is_active = false;
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);
69 clear_reset = false;
70 if (*params[par_reset] >= 0.5) {
71 clear_reset = true;
72 left.reset_phase(0.f);
73 right.reset_phase(r_phase);
74 } else {
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()
85 if (clear_reset) {
86 *params[par_reset] = 0.f;
87 clear_reset = false;
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)
93 return false;
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)
100 return false;
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);
106 return true;
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])
123 is_active = false;
126 void phaser_audio_module::set_sample_rate(uint32_t sr)
128 srate = sr;
129 left.setup(sr);
130 right.setup(sr);
133 void phaser_audio_module::activate()
135 is_active = true;
136 left.reset();
137 right.reset();
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()
145 is_active = false;
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);
165 clear_reset = false;
166 if (*params[par_reset] >= 0.5) {
167 clear_reset = true;
168 left.reset_phase(0.f);
169 right.reset_phase(r_phase);
170 } else {
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()
181 if (clear_reset) {
182 *params[par_reset] = 0.f;
183 clear_reset = false;
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)
189 return false;
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)
195 return false;
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);
202 return true;
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;
219 aspeed_l = 1.f;
220 aspeed_h = 1.f;
221 dspeed = 0.f;
224 void rotary_speaker_audio_module::set_sample_rate(uint32_t sr)
226 srate = sr;
227 setup();
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;
242 setup();
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;
254 set_vibrato();
255 return;
257 if (vibrato_mode == 4 && ctl == 1)
259 mwhl_value = val / 127.f;
260 set_vibrato();
261 return;
265 void rotary_speaker_audio_module::params_changed()
267 set_vibrato();
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)
275 return;
276 if (!vibrato_mode)
277 dspeed = -1;
278 else {
279 float speed = vibrato_mode - 1;
280 if (vibrato_mode == 3)
281 speed = hold_value;
282 if (vibrato_mode == 4)
283 speed = mwhl_value;
284 dspeed = (speed < 0.5f) ? 0 : 1;
286 update_speed();
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);
327 return true;
329 else if (aspeed > raspeed)
331 aspeed = std::max(raspeed, aspeed - delta_decc);
332 return true;
334 return false;
337 uint32_t rotary_speaker_audio_module::process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask)
339 if (true)
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);
346 else
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);
364 meter_l = xl;
365 meter_h = xh;
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;
389 delay.put(in_mono);
390 phase_l += dphase_l;
391 phase_h += dphase_h;
393 crossover1l.sanitize();
394 crossover1r.sanitize();
395 crossover2l.sanitize();
396 crossover2r.sanitize();
397 damper1l.sanitize();
398 damper1r.sanitize();
399 float delta = nsamples * 1.0 / srate;
400 if (vibrato_mode == 5)
401 update_speed_manual(delta);
402 else
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);
406 if (u1 || u2)
407 set_vibrato();
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;
415 return outputs_mask;
418 /**********************************************************************
419 * MULTI CHORUS by Krzysztof Foltman
420 **********************************************************************/
422 multichorus_audio_module::multichorus_audio_module()
424 is_active = false;
425 last_r_phase = -1;
426 freq_old = freq2_old = q_old = -1;
427 redraw_graph = true;
428 redraw_sine = true;
431 void multichorus_audio_module::activate()
433 is_active = true;
434 params_changed();
437 void multichorus_audio_module::deactivate()
439 is_active = false;
442 void multichorus_audio_module::set_sample_rate(uint32_t sr) {
443 srate = sr;
444 last_r_phase = -1;
445 left.setup(sr);
446 right.setup(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];
482 redraw_graph = true;
484 redraw_sine = true;
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
496 layers = 0;
497 // frequency response
498 if (index == par_delay) {
499 layers = (generation ? 0 : LG_CACHE_GRID) | (redraw_graph ? LG_CACHE_GRAPH : 0) | LG_REALTIME_GRAPH;
501 // sine display
502 if (index == par_rate) {
503 layers = LG_REALTIME_DOT | (redraw_sine ? LG_CACHE_GRAPH : 0);
505 // dot display
506 if (index == par_depth)
507 layers = LG_REALTIME_DOT;
508 return true;
511 bool multichorus_audio_module::get_graph(int index, int subindex, int phase, float *data, int points, cairo_iface *context, int *mode) const
513 if (!is_active)
514 return false;
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;
536 // scale to -1..1
537 data[i] = orig / 65536.0;
539 return true;
541 redraw_sine = false;
542 return false;
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];
549 if (!is_active
550 or !phase
551 or (index != par_rate and index != par_depth)
552 or voice >= nvoices)
553 return false;
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;
572 return true;
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);
579 return false;
582 float multichorus_audio_module::freq_gain(int subindex, float freq) const
584 if (subindex == 2)
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()
595 is_active = false;
596 srate = 0;
597 mode_old = -1;
598 amount_old = -1;
599 offset_old = -1;
602 void pulsator_audio_module::activate()
604 is_active = true;
605 lfoL.activate();
606 lfoR.activate();
607 params_changed();
609 void pulsator_audio_module::deactivate()
611 is_active = false;
612 lfoL.deactivate();
613 lfoR.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]);
620 clear_reset = false;
621 if (*params[param_reset] >= 0.5) {
622 clear_reset = true;
623 lfoL.set_phase(0.f);
624 lfoR.set_phase(0.f);
626 if (*params[param_mode] != mode_old
627 or *params[param_amount] != amount_old
628 or *params[param_offset] != offset_old
629 or clear_reset) {
630 mode_old = *params[param_mode];
631 amount_old = *params[param_amount];
632 offset_old = *params[param_offset];
633 redraw_graph = true;
635 printf("%f\n", *params[param_reset]);
638 void pulsator_audio_module::set_sample_rate(uint32_t sr)
640 srate = sr;
641 int meter[] = {param_meter_inL, param_meter_inR, param_meter_outL, param_meter_outR};
642 int clip[] = {param_clip_inL, param_clip_inR, param_clip_outL, param_clip_outR};
643 meters.init(params, meter, clip, 4, sr);
646 uint32_t pulsator_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
648 bool bypassed = bypass.update(*params[param_bypass] > 0.5f, numsamples);
649 uint32_t samples = numsamples + offset;
650 if(bypassed) {
651 // everything bypassed
652 while(offset < samples) {
653 outs[0][offset] = ins[0][offset];
654 outs[1][offset] = ins[1][offset];
655 ++offset;
657 // LFO's should go on
658 lfoL.advance(numsamples);
659 lfoR.advance(numsamples);
661 float values[] = {0, 0, 0, 0};
662 meters.process(values);
663 } else {
664 // process
665 uint32_t orig_offset = offset;
666 while(offset < samples) {
667 // cycle through samples
668 float outL = 0.f;
669 float outR = 0.f;
670 float inL = ins[0][offset];
671 float inR = ins[1][offset];
672 // in level
673 inR *= *params[param_level_in];
674 inL *= *params[param_level_in];
676 if(*params[param_mono] > 0.5) {
677 inL = (inL + inR) * 0.5;
678 inR = inL;
680 float procL = inL;
681 float procR = inR;
683 procL *= (lfoL.get_value() * 0.5 + *params[param_amount] / 2);
684 procR *= (lfoR.get_value() * 0.5 + *params[param_amount] / 2);
686 outL = procL + inL * (1 - *params[param_amount]);
687 outR = procR + inR * (1 - *params[param_amount]);
689 outL *= *params[param_level_out];
690 outR *= *params[param_level_out];
692 // send to output
693 outs[0][offset] = outL;
694 outs[1][offset] = outR;
696 // next sample
697 ++offset;
699 // advance lfo's
700 lfoL.advance(1);
701 lfoR.advance(1);
703 float values[] = {inL, inR, outL, outR};
704 meters.process(values);
706 } // cycle trough samples
707 bypass.crossfade(ins, outs, 2, orig_offset, numsamples);
709 meters.fall(numsamples);
710 return outputs_mask;
713 bool pulsator_audio_module::get_graph(int index, int subindex, int phase, float *data, int points, cairo_iface *context, int *mode) const
715 if (!is_active or phase or subindex > 1) {
716 redraw_graph = false;
717 return false;
719 set_channel_color(context, subindex);
720 return (subindex ? lfoR : lfoL).get_graph(data, points, context, mode);
723 bool pulsator_audio_module::get_dot(int index, int subindex, int phase, float &x, float &y, int &size, cairo_iface *context) const
725 if (!is_active or !phase or subindex > 1)
726 return false;
727 set_channel_color(context, subindex);
728 return (subindex ? lfoR : lfoL).get_dot(x, y, size, context);
731 bool pulsator_audio_module::get_gridline(int index, int subindex, int phase, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const
733 if (phase or subindex)
734 return false;
735 pos = 0;
736 vertical = false;
737 return true;
739 bool pulsator_audio_module::get_layers(int index, int generation, unsigned int &layers) const
741 layers = LG_REALTIME_DOT | (generation ? 0 : LG_CACHE_GRID) | ((redraw_graph || !generation) ? LG_CACHE_GRAPH : 0);
742 return true;
746 /**********************************************************************
747 * RING MODULATOR by Markus Schmidt
748 **********************************************************************/
750 ringmodulator_audio_module::ringmodulator_audio_module()
752 is_active = false;
753 srate = 0;
756 void ringmodulator_audio_module::activate()
758 is_active = true;
759 lfo1.activate();
760 lfo2.activate();
761 modL.activate();
762 modR.activate();
763 params_changed();
765 void ringmodulator_audio_module::deactivate()
767 is_active = false;
768 lfo1.deactivate();
769 lfo2.deactivate();
770 modL.deactivate();
771 modR.deactivate();
774 void ringmodulator_audio_module::params_changed()
776 lfo1.set_params(*params[param_lfo1_freq], *params[param_lfo1_mode], 0, srate, 1);
777 lfo2.set_params(*params[param_lfo2_freq], *params[param_lfo2_mode], 0, srate, 1);
778 modL.set_params(*params[param_mod_freq] * pow(pow(2, 1.0 / 1200.0), *params[param_mod_detune] / 2),
779 *params[param_mod_mode], 0, srate, 1);
780 modR.set_params(*params[param_mod_freq] * pow(pow(2, 1.0 / 1200.0), *params[param_mod_detune] / -2),
781 *params[param_mod_mode], *params[param_mod_phase], srate, 1);
783 clear_reset = false;
785 if (*params[param_lfo1_reset] >= 0.5) {
786 clear_reset = true;
787 lfo1.set_phase(0.f);
789 if (*params[param_lfo2_reset] >= 0.5) {
790 clear_reset = true;
791 lfo2.set_phase(0.f);
794 //redraw_graph = true;
797 void ringmodulator_audio_module::set_sample_rate(uint32_t sr)
799 srate = sr;
800 int meter[] = {param_meter_inL, param_meter_inR, param_meter_outL, param_meter_outR};
801 int clip[] = {param_clip_inL, param_clip_inR, param_clip_outL, param_clip_outR};
802 meters.init(params, meter, clip, 4, sr);
805 uint32_t ringmodulator_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
807 bool bypassed = bypass.update(*params[param_bypass] > 0.5f, numsamples);
808 uint32_t samples = numsamples + offset;
809 float led1 = 0;
810 float led2 = 0;
811 if(bypassed) {
812 // everything bypassed
813 while(offset < samples) {
814 outs[0][offset] = ins[0][offset];
815 outs[1][offset] = ins[1][offset];
816 ++offset;
818 // LFO's should go on
819 lfo1.advance(numsamples);
820 lfo1.advance(numsamples);
821 modL.advance(numsamples);
822 modR.advance(numsamples);
824 float values[] = {0, 0, 0, 0};
825 meters.process(values);
826 } else {
827 // process
828 uint32_t orig_offset = offset;
829 while(offset < samples) {
830 // cycle through samples
832 // set oscillators
833 // mod frequency
834 float freq = 0;
835 if (*params[param_lfo1_mod_freq_active] > 0.5) {
836 freq = (*params[param_lfo1_mod_freq_hi]
837 - *params[param_lfo1_mod_freq_lo])
838 * ((lfo1.get_value() + 1) / 2.)
839 + *params[param_lfo1_mod_freq_lo];
840 modL.set_freq(freq);
841 modR.set_freq(freq);
843 // mod detune
844 if (*params[param_lfo1_mod_detune_active] > 0.5) {
845 float detune = (*params[param_lfo1_mod_detune_hi]
846 - *params[param_lfo1_mod_detune_lo])
847 * ((lfo1.get_value() + 1) / 2.)
848 + *params[param_lfo1_mod_detune_lo];
849 modL.set_freq((freq ? freq : *params[param_mod_freq]) * pow(pow(2, 1.0 / 1200.0), detune / 2));
850 modR.set_freq((freq ? freq : *params[param_mod_freq]) * pow(pow(2, 1.0 / 1200.0), detune / -2));
852 // lfo1 frequency
853 if (*params[param_lfo2_lfo1_freq_active] > 0.5) {
854 lfo1.set_freq((*params[param_lfo2_lfo1_freq_hi]
855 - *params[param_lfo2_lfo1_freq_lo])
856 * ((lfo2.get_value() + 1) / 2.)
857 + *params[param_lfo2_lfo1_freq_lo]);
859 // mod amount
860 float mod_amount = *params[param_mod_amount];
861 if (*params[param_lfo2_mod_amount_active] > 0.5) {
862 mod_amount = (*params[param_lfo2_mod_amount_hi]
863 - *params[param_lfo2_mod_amount_lo])
864 * ((lfo2.get_value() + 1) / 2.)
865 + *params[param_lfo2_mod_amount_lo];
868 float outL = 0.f;
869 float outR = 0.f;
870 float inL = ins[0][offset];
871 float inR = ins[1][offset];
873 // in level
874 inR *= *params[param_level_in];
875 inL *= *params[param_level_in];
877 // modulator
878 float modulL = modL.get_value() * mod_amount;
879 float modulR = modR.get_value() * mod_amount;
881 float procL = inL * modulL;
882 float procR = inR * modulR;
884 outL = *params[param_mod_listen] > 0.5 ? modulL : procL + inL * (1 - mod_amount);
885 outR = *params[param_mod_listen] > 0.5 ? modulR : procR + inR * (1 - mod_amount);
887 outL *= *params[param_level_out];
888 outR *= *params[param_level_out];
890 // send to output
891 outs[0][offset] = outL;
892 outs[1][offset] = outR;
894 // next sample
895 ++offset;
897 // leds
898 led1 = std::max(led1, lfo1.get_value() / 2 + 0.5f);
899 led2 = std::max(led2, lfo2.get_value() / 2 + 0.5f);
901 // advance lfo's
902 lfo1.advance(1);
903 lfo2.advance(1);
904 modL.advance(1);
905 modR.advance(1);
907 float values[] = {inL, inR, outL, outR};
908 meters.process(values);
910 } // cycle trough samples
911 bypass.crossfade(ins, outs, 2, orig_offset, numsamples);
913 *params[param_lfo1_activity] = led1;
914 *params[param_lfo2_activity] = led2;
915 meters.fall(numsamples);
916 return outputs_mask;
919 bool ringmodulator_audio_module::get_graph(int index, int subindex, int phase, float *data, int points, cairo_iface *context, int *mode) const
921 if (!is_active or phase or subindex > 1) {
922 redraw_graph = false;
923 return false;
925 set_channel_color(context, subindex);
926 return (subindex ? lfo2 : lfo1).get_graph(data, points, context, mode);
929 bool ringmodulator_audio_module::get_dot(int index, int subindex, int phase, float &x, float &y, int &size, cairo_iface *context) const
931 if (!is_active or !phase or subindex > 1)
932 return false;
933 set_channel_color(context, subindex);
934 return (subindex ? lfo2 : lfo1).get_dot(x, y, size, context);
937 bool ringmodulator_audio_module::get_gridline(int index, int subindex, int phase, float &pos, bool &vertical, std::string &legend, cairo_iface *context) const
939 if (phase or subindex)
940 return false;
941 pos = 0;
942 vertical = false;
943 return true;
945 bool ringmodulator_audio_module::get_layers(int index, int generation, unsigned int &layers) const
947 layers = LG_REALTIME_DOT | (generation ? 0 : LG_CACHE_GRID) | ((redraw_graph || !generation) ? LG_CACHE_GRAPH : 0);
948 return true;