+ Monosynth: Osc Mix modulation destination, use smoothing for xfade value, destinati...
[calf.git] / src / monosynth.cpp
blob693ff47be7c5cfddcf60eb88dc892a8a7a7242be
1 /* Calf DSP Library
2 * Example audio modules - monosynth
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 02110-1301 USA
21 #include <assert.h>
22 #include <memory.h>
23 #include <config.h>
24 #include <complex>
25 #if USE_JACK
26 #include <jack/jack.h>
27 #endif
28 #include <calf/giface.h>
29 #include <calf/modules_synths.h>
31 using namespace dsp;
32 using namespace calf_plugins;
33 using namespace std;
35 float silence[4097];
37 monosynth_audio_module::monosynth_audio_module()
38 : inertia_cutoff(1)
39 , inertia_pitchbend(1)
40 , inertia_pressure(64)
42 for (int i = 0; i < mod_matrix_slots; i++)
44 mod_matrix[i].src1 = modsrc_none;
45 mod_matrix[i].src2 = modsrc_none;
46 mod_matrix[i].amount = 0.f;
47 mod_matrix[i].dest = moddest_none;
51 void monosynth_audio_module::activate() {
52 running = false;
53 output_pos = 0;
54 queue_note_on = -1;
55 stop_count = 0;
56 inertia_pitchbend.set_now(1.f);
57 lfo_bend = 1.0;
58 modwheel_value = 0.f;
59 modwheel_value_int = 0;
60 inertia_cutoff.set_now(*params[par_cutoff]);
61 inertia_pressure.set_now(0);
62 filter.reset();
63 filter2.reset();
64 stack.clear();
65 last_pwshift1 = last_pwshift2 = 0;
68 waveform_family<MONOSYNTH_WAVE_BITS> *monosynth_audio_module::waves;
70 void monosynth_audio_module::precalculate_waves(progress_report_iface *reporter)
72 float data[1 << MONOSYNTH_WAVE_BITS];
73 bandlimiter<MONOSYNTH_WAVE_BITS> bl;
75 if (waves)
76 return;
78 static waveform_family<MONOSYNTH_WAVE_BITS> waves_data[wave_count];
79 waves = waves_data;
81 enum { S = 1 << MONOSYNTH_WAVE_BITS, HS = S / 2, QS = S / 4, QS3 = 3 * QS };
82 float iQS = 1.0 / QS;
84 if (reporter)
85 reporter->report_progress(0, "Precalculating waveforms");
87 // yes these waves don't have really perfect 1/x spectrum because of aliasing
88 // (so what?)
89 for (int i = 0 ; i < HS; i++)
90 data[i] = (float)(i * 1.0 / HS),
91 data[i + HS] = (float)(i * 1.0 / HS - 1.0f);
92 waves[wave_saw].make(bl, data);
94 // this one is dummy, fake and sham, we're using a difference of two sawtooths for square wave due to PWM
95 for (int i = 0 ; i < S; i++)
96 data[i] = (float)(i < HS ? -1.f : 1.f);
97 waves[wave_sqr].make(bl, data, 4);
99 for (int i = 0 ; i < S; i++)
100 data[i] = (float)(i < (64 * S / 2048)? -1.f : 1.f);
101 waves[wave_pulse].make(bl, data);
103 for (int i = 0 ; i < S; i++)
104 data[i] = (float)sin(i * M_PI / HS);
105 waves[wave_sine].make(bl, data);
107 for (int i = 0 ; i < QS; i++) {
108 data[i] = i * iQS,
109 data[i + QS] = 1 - i * iQS,
110 data[i + HS] = - i * iQS,
111 data[i + QS3] = -1 + i * iQS;
113 waves[wave_triangle].make(bl, data);
115 for (int i = 0, j = 1; i < S; i++) {
116 data[i] = -1 + j * 1.0 / HS;
117 if (i == j)
118 j *= 2;
120 waves[wave_varistep].make(bl, data);
122 for (int i = 0; i < S; i++) {
123 data[i] = (min(1.f, (float)(i / 64.f))) * (1.0 - i * 1.0 / S) * (-1 + fmod (i * i * 8/ (S * S * 1.0), 2.0));
125 waves[wave_skewsaw].make(bl, data);
126 for (int i = 0; i < S; i++) {
127 data[i] = (min(1.f, (float)(i / 64.f))) * (1.0 - i * 1.0 / S) * (fmod (i * i * 8/ (S * S * 1.0), 2.0) < 1.0 ? -1.0 : +1.0);
129 waves[wave_skewsqr].make(bl, data);
131 if (reporter)
132 reporter->report_progress(50, "Precalculating waveforms");
134 for (int i = 0; i < S; i++) {
135 if (i < QS3) {
136 float p = i * 1.0 / QS3;
137 data[i] = sin(M_PI * p * p * p);
138 } else {
139 float p = (i - QS3 * 1.0) / QS;
140 data[i] = -0.5 * sin(3 * M_PI * p * p);
143 waves[wave_test1].make(bl, data);
144 for (int i = 0; i < S; i++) {
145 data[i] = exp(-i * 1.0 / HS) * sin(i * M_PI / HS) * cos(2 * M_PI * i / HS);
147 normalize_waveform(data, S);
148 waves[wave_test2].make(bl, data);
149 for (int i = 0; i < S; i++) {
150 //int ii = (i < HS) ? i : S - i;
151 int ii = HS;
152 data[i] = (ii * 1.0 / HS) * sin(i * 3 * M_PI / HS + 2 * M_PI * sin(M_PI / 4 + i * 4 * M_PI / HS)) * sin(i * 5 * M_PI / HS + 2 * M_PI * sin(M_PI / 8 + i * 6 * M_PI / HS));
154 waves[wave_test3].make(bl, data);
155 for (int i = 0; i < S; i++) {
156 data[i] = sin(i * 2 * M_PI / HS + sin(i * 2 * M_PI / HS + 0.5 * M_PI * sin(i * 18 * M_PI / HS)) * sin(i * 1 * M_PI / HS + 0.5 * M_PI * sin(i * 11 * M_PI / HS)));
158 waves[wave_test4].make(bl, data);
159 for (int i = 0; i < S; i++) {
160 data[i] = sin(i * 2 * M_PI / HS + 0.2 * M_PI * sin(i * 13 * M_PI / HS) + 0.1 * M_PI * sin(i * 37 * M_PI / HS)) * sin(i * M_PI / HS + 0.2 * M_PI * sin(i * 15 * M_PI / HS));
162 waves[wave_test5].make(bl, data);
163 for (int i = 0; i < S; i++) {
164 if (i < HS)
165 data[i] = sin(i * 2 * M_PI / HS);
166 else
167 if (i < 3 * S / 4)
168 data[i] = sin(i * 4 * M_PI / HS);
169 else
170 if (i < 7 * S / 8)
171 data[i] = sin(i * 8 * M_PI / HS);
172 else
173 data[i] = sin(i * 8 * M_PI / HS) * (S - i) / (S / 8);
175 waves[wave_test6].make(bl, data);
176 for (int i = 0; i < S; i++) {
177 int j = i >> (MONOSYNTH_WAVE_BITS - 11);
178 data[i] = (j ^ 0x1D0) * 1.0 / HS - 1;
180 waves[wave_test7].make(bl, data);
181 for (int i = 0; i < S; i++) {
182 int j = i >> (MONOSYNTH_WAVE_BITS - 11);
183 data[i] = -1 + 0.66 * (3 & ((j >> 8) ^ (j >> 10) ^ (j >> 6)));
185 waves[wave_test8].make(bl, data);
186 if (reporter)
187 reporter->report_progress(100, "");
191 bool monosynth_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context)
193 monosynth_audio_module::precalculate_waves(NULL);
194 // printf("get_graph %d %p %d wave1=%d wave2=%d\n", index, data, points, wave1, wave2);
195 if (index == par_wave1 || index == par_wave2) {
196 if (subindex)
197 return false;
198 enum { S = 1 << MONOSYNTH_WAVE_BITS };
199 float value = *params[index];
200 int wave = dsp::clip(dsp::fastf2i_drm(value), 0, (int)wave_count - 1);
202 uint32_t shift = index == par_wave1 ? last_pwshift1 : last_pwshift2;
203 if (!running)
204 shift = (int32_t)(0x78000000 * (*params[index == par_wave1 ? par_pw1 : par_pw2]));
205 int flag = (wave == wave_sqr);
207 shift = (flag ? S/2 : 0) + (shift >> (32 - MONOSYNTH_WAVE_BITS));
208 int sign = flag ? -1 : 1;
209 if (wave == wave_sqr)
210 wave = wave_saw;
211 float *waveform = waves[wave].original;
212 for (int i = 0; i < points; i++)
213 data[i] = (sign * waveform[i * S / points] + waveform[(i * S / points + shift) & (S - 1)]) / (sign == -1 ? 1 : 2);
214 return true;
216 if (index == par_filtertype) {
217 if (!running)
218 return false;
219 if (subindex > (is_stereo_filter() ? 1 : 0))
220 return false;
221 for (int i = 0; i < points; i++)
223 typedef complex<double> cfloat;
224 double freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points);
226 dsp::biquad_d1_lerp<float> &f = subindex ? filter2 : filter;
227 float level = f.freq_gain(freq, srate);
228 if (!is_stereo_filter())
229 level *= filter2.freq_gain(freq, srate);
230 level *= fgain;
232 data[i] = log(level) / log(1024.0) + 0.5;
234 return true;
236 return get_static_graph(index, subindex, *params[index], data, points, context);
239 void monosynth_audio_module::calculate_buffer_oscs(float lfo)
241 int flag1 = (wave1 == wave_sqr);
242 int flag2 = (wave2 == wave_sqr);
243 int32_t shift1 = last_pwshift1;
244 int32_t shift2 = last_pwshift2;
245 int32_t shift_target1 = (int32_t)(0x78000000 * dsp::clip11(*params[par_pw1] + lfo * *params[par_lfopw] + 0.01f * moddest[moddest_o1pw]));
246 int32_t shift_target2 = (int32_t)(0x78000000 * dsp::clip11(*params[par_pw2] + lfo * *params[par_lfopw] + 0.01f * moddest[moddest_o2pw]));
247 int32_t shift_delta1 = ((shift_target1 >> 1) - (last_pwshift1 >> 1)) >> (step_shift - 1);
248 int32_t shift_delta2 = ((shift_target2 >> 1) - (last_pwshift2 >> 1)) >> (step_shift - 1);
249 last_lfov = lfo;
250 last_pwshift1 = shift_target1;
251 last_pwshift2 = shift_target2;
253 shift1 += (flag1 << 31);
254 shift2 += (flag2 << 31);
255 float mix1 = 1 - 2 * flag1, mix2 = 1 - 2 * flag2;
257 float new_xfade = dsp::clip<float>(xfade + 0.01f * moddest[moddest_oscmix], 0.f, 1.f);
258 float cur_xfade = last_xfade;
259 float xfade_step = (new_xfade - cur_xfade) * (1.0 / step_size);
261 for (uint32_t i = 0; i < step_size; i++)
263 float osc1val = osc1.get_phaseshifted(shift1, mix1);
264 float osc2val = osc2.get_phaseshifted(shift2, mix2);
265 float wave = osc1val + (osc2val - osc1val) * cur_xfade;
266 buffer[i] = wave;
267 shift1 += shift_delta1;
268 shift2 += shift_delta2;
269 cur_xfade += xfade_step;
271 last_xfade = new_xfade;
274 void monosynth_audio_module::calculate_buffer_ser()
276 filter.big_step(1.0 / step_size);
277 filter2.big_step(1.0 / step_size);
278 for (uint32_t i = 0; i < step_size; i++)
280 float wave = buffer[i] * fgain;
281 wave = filter.process(wave);
282 wave = filter2.process(wave);
283 buffer[i] = wave;
284 fgain += fgain_delta;
288 void monosynth_audio_module::calculate_buffer_single()
290 filter.big_step(1.0 / step_size);
291 for (uint32_t i = 0; i < step_size; i++)
293 float wave = buffer[i] * fgain;
294 wave = filter.process(wave);
295 buffer[i] = wave;
296 fgain += fgain_delta;
300 void monosynth_audio_module::calculate_buffer_stereo()
302 filter.big_step(1.0 / step_size);
303 filter2.big_step(1.0 / step_size);
304 for (uint32_t i = 0; i < step_size; i++)
306 float wave1 = buffer[i] * fgain;
307 float wave2 = phaseshifter.process_ap(wave1);
308 buffer[i] = fgain * filter.process(wave1);
309 buffer2[i] = fgain * filter2.process(wave2);
310 fgain += fgain_delta;
314 void monosynth_audio_module::lookup_waveforms()
316 osc1.waveform = waves[wave1 == wave_sqr ? wave_saw : wave1].get_level(osc1.phasedelta);
317 osc2.waveform = waves[wave2 == wave_sqr ? wave_saw : wave2].get_level(osc2.phasedelta);
318 if (!osc1.waveform) osc1.waveform = silence;
319 if (!osc2.waveform) osc2.waveform = silence;
320 prev_wave1 = wave1;
321 prev_wave2 = wave2;
324 void monosynth_audio_module::delayed_note_on()
326 force_fadeout = false;
327 stop_count = 0;
328 porta_time = 0.f;
329 start_freq = freq;
330 target_freq = freq = 440 * pow(2.0, (queue_note_on - 69) / 12.0);
331 velocity = queue_vel;
332 ampctl = 1.0 + (queue_vel - 1.0) * *params[par_vel2amp];
333 fltctl = 1.0 + (queue_vel - 1.0) * *params[par_vel2filter];
334 set_frequency();
335 lookup_waveforms();
336 lfo_clock = 0.f;
338 if (!running)
340 if (legato >= 2)
341 porta_time = -1.f;
342 last_xfade = xfade;
343 osc1.reset();
344 osc2.reset();
345 filter.reset();
346 filter2.reset();
347 lfo.reset();
348 switch((int)*params[par_oscmode])
350 case 1:
351 osc2.phase = 0x80000000;
352 break;
353 case 2:
354 osc2.phase = 0x40000000;
355 break;
356 case 3:
357 osc1.phase = osc2.phase = 0x40000000;
358 break;
359 case 4:
360 osc1.phase = 0x40000000;
361 osc2.phase = 0xC0000000;
362 break;
363 case 5:
364 // rand() is crap, but I don't have any better RNG in Calf yet
365 osc1.phase = rand() << 16;
366 osc2.phase = rand() << 16;
367 break;
368 default:
369 break;
371 envelope.note_on();
372 running = true;
374 if (legato >= 2 && !gate)
375 porta_time = -1.f;
376 gate = true;
377 stopping = false;
378 if (!(legato & 1) || envelope.released()) {
379 envelope.note_on();
381 envelope.advance();
382 queue_note_on = -1;
383 float modsrc[modsrc_count] = { 1, velocity, inertia_pressure.get_last(), modwheel_value, 0, last_lfov};
384 calculate_modmatrix(modsrc);
387 void monosynth_audio_module::set_sample_rate(uint32_t sr) {
388 srate = sr;
389 crate = sr / step_size;
390 odcr = (float)(1.0 / crate);
391 phaseshifter.set_ap(1000.f, sr);
392 fgain = 0.f;
393 fgain_delta = 0.f;
394 inertia_cutoff.ramp.set_length(crate / 30); // 1/30s
395 inertia_pitchbend.ramp.set_length(crate / 30); // 1/30s
398 void monosynth_audio_module::calculate_modmatrix(float *modsrc)
400 for (int i = 0; i < moddest_count; i++)
401 moddest[i] = 0;
402 for (int i = 0; i < mod_matrix_slots; i++)
404 modulation_entry &slot = mod_matrix[i];
405 if (slot.dest)
406 moddest[slot.dest] += modsrc[slot.src1] * modsrc[slot.src2] * slot.amount;
410 void monosynth_audio_module::calculate_step()
412 if (queue_note_on != -1)
413 delayed_note_on();
414 else if (stopping)
416 running = false;
417 dsp::zero(buffer, step_size);
418 if (is_stereo_filter())
419 dsp::zero(buffer2, step_size);
420 envelope.advance();
421 return;
423 lfo.set_freq(*params[par_lforate], crate);
424 float porta_total_time = *params[par_portamento] * 0.001f;
426 if (porta_total_time >= 0.00101f && porta_time >= 0) {
427 // XXXKF this is criminal, optimize!
428 float point = porta_time / porta_total_time;
429 if (point >= 1.0f) {
430 freq = target_freq;
431 porta_time = -1;
432 } else {
433 freq = start_freq + (target_freq - start_freq) * point;
434 // freq = start_freq * pow(target_freq / start_freq, point);
435 porta_time += odcr;
438 float lfov = lfo.get() * std::min(1.0f, lfo_clock / *params[par_lfodelay]);
439 lfov = lfov * dsp::lerp(1.f, modwheel_value, *params[par_mwhl_lfo]);
440 lfo_clock += odcr;
441 if (fabs(*params[par_lfopitch]) > small_value<float>())
442 lfo_bend = pow(2.0f, *params[par_lfopitch] * lfov * (1.f / 1200.0f));
443 inertia_pitchbend.step();
444 set_frequency();
445 envelope.advance();
446 float env = envelope.value;
448 // mod matrix
449 // this should be optimized heavily; I think I'll do it when MIDI in Ardour 3 gets stable :>
450 float modsrc[modsrc_count] = { 1, velocity, inertia_pressure.get(), modwheel_value, env, lfov};
451 calculate_modmatrix(modsrc);
453 inertia_cutoff.set_inertia(*params[par_cutoff]);
454 cutoff = inertia_cutoff.get() * pow(2.0f, (lfov * *params[par_lfofilter] + env * fltctl * *params[par_envmod] + moddest[moddest_cutoff]) * (1.f / 1200.f));
455 if (*params[par_keyfollow] > 0.01f)
456 cutoff *= pow(freq / 264.f, *params[par_keyfollow]);
457 cutoff = dsp::clip(cutoff , 10.f, 18000.f);
458 float resonance = *params[par_resonance];
459 float e2r = *params[par_envtores];
460 float e2a = *params[par_envtoamp];
461 resonance = resonance * (1 - e2r) + (0.7 + (resonance - 0.7) * env * env) * e2r + moddest[moddest_resonance];
462 float cutoff2 = dsp::clip(cutoff * separation, 10.f, 18000.f);
463 float newfgain = 0.f;
464 if (filter_type != last_filter_type)
466 filter.y2 = filter.y1 = filter.x2 = filter.x1 = filter.y1;
467 filter2.y2 = filter2.y1 = filter2.x2 = filter2.x1 = filter2.y1;
468 last_filter_type = filter_type;
470 switch(filter_type)
472 case flt_lp12:
473 filter.set_lp_rbj(cutoff, resonance, srate);
474 filter2.set_null();
475 newfgain = min(0.7f, 0.7f / resonance) * ampctl;
476 break;
477 case flt_hp12:
478 filter.set_hp_rbj(cutoff, resonance, srate);
479 filter2.set_null();
480 newfgain = min(0.7f, 0.7f / resonance) * ampctl;
481 break;
482 case flt_lp24:
483 filter.set_lp_rbj(cutoff, resonance, srate);
484 filter2.set_lp_rbj(cutoff2, resonance, srate);
485 newfgain = min(0.5f, 0.5f / resonance) * ampctl;
486 break;
487 case flt_lpbr:
488 filter.set_lp_rbj(cutoff, resonance, srate);
489 filter2.set_br_rbj(cutoff2, 1.0 / resonance, srate);
490 newfgain = min(0.5f, 0.5f / resonance) * ampctl;
491 break;
492 case flt_hpbr:
493 filter.set_hp_rbj(cutoff, resonance, srate);
494 filter2.set_br_rbj(cutoff2, 1.0 / resonance, srate);
495 newfgain = min(0.5f, 0.5f / resonance) * ampctl;
496 break;
497 case flt_2lp12:
498 filter.set_lp_rbj(cutoff, resonance, srate);
499 filter2.set_lp_rbj(cutoff2, resonance, srate);
500 newfgain = min(0.7f, 0.7f / resonance) * ampctl;
501 break;
502 case flt_bp6:
503 filter.set_bp_rbj(cutoff, resonance, srate);
504 filter2.set_null();
505 newfgain = ampctl;
506 break;
507 case flt_2bp6:
508 filter.set_bp_rbj(cutoff, resonance, srate);
509 filter2.set_bp_rbj(cutoff2, resonance, srate);
510 newfgain = ampctl;
511 break;
513 float aenv = env;
514 if (*params[par_envtoamp] > 0.f)
515 newfgain *= 1.0 - (1.0 - aenv) * e2a;
516 if (moddest[moddest_attenuation] != 0.f)
517 newfgain *= dsp::clip<float>(1 - moddest[moddest_attenuation] * moddest[moddest_attenuation], 0.f, 1.f);
518 fgain_delta = (newfgain - fgain) * (1.0 / step_size);
519 calculate_buffer_oscs(lfov);
520 switch(filter_type)
522 case flt_lp24:
523 case flt_lpbr:
524 case flt_hpbr: // Oomek's wish
525 calculate_buffer_ser();
526 break;
527 case flt_lp12:
528 case flt_hp12:
529 case flt_bp6:
530 calculate_buffer_single();
531 break;
532 case flt_2lp12:
533 case flt_2bp6:
534 calculate_buffer_stereo();
535 break;
537 if ((envelope.state == adsr::STOP && !gate) || force_fadeout || (envelope.state == adsr::RELEASE && *params[par_envtoamp] <= 0.f))
539 enum { ramp = step_size * 4 };
540 for (int i = 0; i < step_size; i++)
541 buffer[i] *= (ramp - i - stop_count) * (1.0f / ramp);
542 if (is_stereo_filter())
543 for (int i = 0; i < step_size; i++)
544 buffer2[i] *= (ramp - i - stop_count) * (1.0f / ramp);
545 stop_count += step_size;
546 if (stop_count >= ramp)
547 stopping = true;
551 void monosynth_audio_module::note_on(int note, int vel)
553 queue_note_on = note;
554 last_key = note;
555 queue_vel = vel / 127.f;
556 stack.push(note);
559 void monosynth_audio_module::note_off(int note, int vel)
561 stack.pop(note);
562 // If releasing the currently played note, try to get another one from note stack.
563 if (note == last_key) {
564 if (stack.count())
566 last_key = note = stack.nth(stack.count() - 1);
567 start_freq = freq;
568 target_freq = freq = dsp::note_to_hz(note);
569 porta_time = 0;
570 set_frequency();
571 if (!(legato & 1)) {
572 envelope.note_on();
573 stopping = false;
574 running = true;
576 return;
578 gate = false;
579 envelope.note_off();
583 void monosynth_audio_module::channel_pressure(int value)
585 inertia_pressure.set_inertia(value * (1.0 / 127.0));
588 void monosynth_audio_module::control_change(int controller, int value)
590 switch(controller)
592 case 1:
593 modwheel_value_int = (modwheel_value_int & 127) | (value << 7);
594 modwheel_value = modwheel_value_int / 16383.0;
595 break;
596 case 33:
597 modwheel_value_int = (modwheel_value_int & (127 << 7)) | value;
598 modwheel_value = modwheel_value_int / 16383.0;
599 break;
600 case 120: // all sounds off
601 force_fadeout = true;
602 // fall through
603 case 123: // all notes off
604 gate = false;
605 queue_note_on = -1;
606 envelope.note_off();
607 stack.clear();
608 break;
612 void monosynth_audio_module::deactivate()
614 gate = false;
615 running = false;
616 stopping = false;
617 envelope.reset();
618 stack.clear();
621 uint32_t monosynth_audio_module::process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
622 if (!running && queue_note_on == -1) {
623 for (uint32_t i = 0; i < nsamples / step_size; i++)
624 envelope.advance();
625 return 0;
627 uint32_t op = offset;
628 uint32_t op_end = offset + nsamples;
629 while(op < op_end) {
630 if (output_pos == 0) {
631 if (running || queue_note_on != -1)
632 calculate_step();
633 else {
634 envelope.advance();
635 dsp::zero(buffer, step_size);
638 if(op < op_end) {
639 uint32_t ip = output_pos;
640 uint32_t len = std::min(step_size - output_pos, op_end - op);
641 if (is_stereo_filter())
642 for(uint32_t i = 0 ; i < len; i++) {
643 float vol = master.get();
644 outs[0][op + i] = buffer[ip + i] * vol,
645 outs[1][op + i] = buffer2[ip + i] * vol;
647 else
648 for(uint32_t i = 0 ; i < len; i++)
649 outs[0][op + i] = outs[1][op + i] = buffer[ip + i] * master.get();
650 op += len;
651 output_pos += len;
652 if (output_pos == step_size)
653 output_pos = 0;
657 return 3;
660 static const char *monosynth_mod_src_names[] = {
661 "None",
662 "Velocity",
663 "Pressure",
664 "ModWheel",
665 "Envelope",
666 "LFO",
667 NULL
670 static const char *monosynth_mod_dest_names[] = {
671 "None",
672 "Attenuation",
673 "Osc Mix Ratio (%)",
674 "Cutoff [ct]",
675 "Resonance",
676 "O1: Detune [ct]",
677 "O2: Detune [ct]",
678 "O1: PW (%)",
679 "O2: PW (%)",
680 NULL
683 const table_column_info *monosynth_audio_module::get_table_columns(int param)
686 static table_column_info tci[] = {
687 { "Source", TCT_ENUM, 0, 0, 0, monosynth_mod_src_names },
688 { "Modulator", TCT_ENUM, 0, 0, 0, monosynth_mod_src_names },
689 { "Amount", TCT_FLOAT, 0, 1, 1, NULL},
690 { "Destination", TCT_ENUM, 0, 0, 0, monosynth_mod_dest_names },
691 { NULL }
693 return tci;
696 uint32_t monosynth_audio_module::get_table_rows(int param)
698 return mod_matrix_slots;
701 std::string monosynth_audio_module::get_cell(int param, int row, int column)
703 assert(row >= 0 && row < mod_matrix_slots);
704 modulation_entry &slot = mod_matrix[row];
705 switch(column) {
706 case 0: // source 1
707 return monosynth_mod_src_names[slot.src1];
708 case 1: // source 2
709 return monosynth_mod_src_names[slot.src2];
710 case 2: // amount
711 return calf_utils::f2s(slot.amount);
712 case 3: // destination
713 return monosynth_mod_dest_names[slot.dest];
714 default:
715 assert(0);
716 return "";
720 void monosynth_audio_module::set_cell(int param, int row, int column, const std::string &src, std::string &error)
722 assert(row >= 0 && row < mod_matrix_slots);
723 modulation_entry &slot = mod_matrix[row];
724 switch(column) {
725 case 0:
726 case 1:
728 for (int i = 0; monosynth_mod_src_names[i]; i++)
730 if (src == monosynth_mod_src_names[i])
732 if (column == 0)
733 slot.src1 = i;
734 else
735 slot.src2 = i;
736 error.clear();
737 return;
740 error = "Invalid source name";
741 return;
743 case 2:
745 stringstream ss(src);
746 ss >> slot.amount;
747 error.clear();
748 return;
750 case 3:
752 for (int i = 0; monosynth_mod_dest_names[i]; i++)
754 if (src == monosynth_mod_dest_names[i])
756 slot.dest = i;
757 error.clear();
758 return;
761 error = "Invalid destination name";
762 return;