+ Monosynth: filter cutoff inertia backported from 0.0.19
[calf.git] / src / monosynth.cpp
blob93bbfd51339f5431ce3470180e71ca2ff9735843
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., 59 Temple Place, Suite 330,
19 * Boston, MA 02111-1307, 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(exponential_ramp(1))
42 void monosynth_audio_module::activate() {
43 running = false;
44 output_pos = 0;
45 queue_note_on = -1;
46 stop_count = 0;
47 pitchbend = 1.f;
48 filter.reset();
49 filter2.reset();
50 stack.clear();
53 waveform_family<MONOSYNTH_WAVE_BITS> *monosynth_audio_module::waves;
55 void monosynth_audio_module::precalculate_waves(progress_report_iface *reporter)
57 float data[1 << MONOSYNTH_WAVE_BITS];
58 bandlimiter<MONOSYNTH_WAVE_BITS> bl;
60 if (waves)
61 return;
63 static waveform_family<MONOSYNTH_WAVE_BITS> waves_data[wave_count];
64 waves = waves_data;
66 enum { S = 1 << MONOSYNTH_WAVE_BITS, HS = S / 2, QS = S / 4, QS3 = 3 * QS };
67 float iQS = 1.0 / QS;
69 if (reporter)
70 reporter->report_progress(0, "Precalculating waveforms");
72 // yes these waves don't have really perfect 1/x spectrum because of aliasing
73 // (so what?)
74 for (int i = 0 ; i < HS; i++)
75 data[i] = (float)(i * 1.0 / HS),
76 data[i + HS] = (float)(i * 1.0 / HS - 1.0f);
77 waves[wave_saw].make(bl, data);
79 for (int i = 0 ; i < S; i++)
80 data[i] = (float)(i < HS ? -1.f : 1.f);
81 waves[wave_sqr].make(bl, data);
83 for (int i = 0 ; i < S; i++)
84 data[i] = (float)(i < (64 * S / 2048)? -1.f : 1.f);
85 waves[wave_pulse].make(bl, data);
87 // XXXKF sure this is a waste of space, this will be fixed some day by better bandlimiter
88 for (int i = 0 ; i < S; i++)
89 data[i] = (float)sin(i * M_PI / HS);
90 waves[wave_sine].make(bl, data);
92 for (int i = 0 ; i < QS; i++) {
93 data[i] = i * iQS,
94 data[i + QS] = 1 - i * iQS,
95 data[i + HS] = - i * iQS,
96 data[i + QS3] = -1 + i * iQS;
98 waves[wave_triangle].make(bl, data);
100 for (int i = 0, j = 1; i < S; i++) {
101 data[i] = -1 + j * 1.0 / HS;
102 if (i == j)
103 j *= 2;
105 waves[wave_varistep].make(bl, data);
107 for (int i = 0; i < S; i++) {
108 data[i] = (min(1.f, (float)(i / 64.f))) * (1.0 - i * 1.0 / S) * (-1 + fmod (i * i / 262144.0, 2.0));
110 waves[wave_skewsaw].make(bl, data);
111 for (int i = 0; i < S; i++) {
112 data[i] = (min(1.f, (float)(i / 64.f))) * (1.0 - i * 1.0 / S) * (fmod (i * i / 262144.0, 2.0) < 1.0 ? -1.0 : +1.0);
114 waves[wave_skewsqr].make(bl, data);
116 if (reporter)
117 reporter->report_progress(50, "Precalculating waveforms");
119 for (int i = 0; i < S; i++) {
120 if (i < QS3) {
121 float p = i * 1.0 / QS3;
122 data[i] = sin(M_PI * p * p * p);
123 } else {
124 float p = (i - QS3 * 1.0) / QS;
125 data[i] = -0.5 * sin(3 * M_PI * p * p);
128 waves[wave_test1].make(bl, data);
129 for (int i = 0; i < S; i++) {
130 data[i] = exp(-i * 1.0 / HS) * sin(i * M_PI / HS) * cos(2 * M_PI * i / HS);
132 normalize_waveform(data, S);
133 waves[wave_test2].make(bl, data);
134 for (int i = 0; i < S; i++) {
135 //int ii = (i < HS) ? i : S - i;
136 int ii = HS;
137 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));
139 waves[wave_test3].make(bl, data);
140 for (int i = 0; i < S; i++) {
141 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)));
143 waves[wave_test4].make(bl, data);
144 for (int i = 0; i < S; i++) {
145 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));
147 waves[wave_test5].make(bl, data);
148 for (int i = 0; i < S; i++) {
149 if (i < HS)
150 data[i] = sin(i * 2 * M_PI / HS);
151 else
152 if (i < 3 * S / 4)
153 data[i] = sin(i * 4 * M_PI / HS);
154 else
155 if (i < 7 * S / 8)
156 data[i] = sin(i * 8 * M_PI / HS);
157 else
158 data[i] = sin(i * 8 * M_PI / HS) * (S - i) / (S / 8);
160 waves[wave_test6].make(bl, data);
161 for (int i = 0; i < S; i++) {
162 int j = i >> (MONOSYNTH_WAVE_BITS - 11);
163 data[i] = (j ^ 0x1D0) * 1.0 / HS - 1;
165 waves[wave_test7].make(bl, data);
166 for (int i = 0; i < S; i++) {
167 int j = i >> (MONOSYNTH_WAVE_BITS - 11);
168 data[i] = -1 + 0.66 * (3 & ((j >> 8) ^ (j >> 10) ^ (j >> 6)));
170 waves[wave_test8].make(bl, data);
171 if (reporter)
172 reporter->report_progress(100, "");
176 bool monosynth_audio_module::get_static_graph(int index, int subindex, float value, float *data, int points, cairo_iface *context)
178 monosynth_audio_module::precalculate_waves(NULL);
179 if (index == par_wave1 || index == par_wave2) {
180 if (subindex)
181 return false;
182 enum { S = 1 << MONOSYNTH_WAVE_BITS };
183 int wave = dsp::clip(dsp::fastf2i_drm(value), 0, (int)wave_count - 1);
185 float *waveform = waves[wave].original;
186 for (int i = 0; i < points; i++)
187 data[i] = waveform[i * S / points];
188 return true;
190 return false;
193 bool monosynth_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context)
195 monosynth_audio_module::precalculate_waves(NULL);
196 // printf("get_graph %d %p %d wave1=%d wave2=%d\n", index, data, points, wave1, wave2);
197 if (index == par_filtertype) {
198 if (!running)
199 return false;
200 if (subindex > (is_stereo_filter() ? 1 : 0))
201 return false;
202 for (int i = 0; i < points; i++)
204 typedef complex<double> cfloat;
205 double freq = 20.0 * pow (20000.0 / 20.0, i * 1.0 / points);
207 dsp::biquad_d1_lerp<float> &f = subindex ? filter2 : filter;
208 float level = f.freq_gain(freq, srate);
209 if (!is_stereo_filter())
210 level *= filter2.freq_gain(freq, srate);
211 level *= fgain;
213 data[i] = log(level) / log(1024.0) + 0.5;
215 return true;
217 return get_static_graph(index, subindex, *params[index], data, points, context);
220 void monosynth_audio_module::calculate_buffer_ser()
222 filter.big_step(1.0 / step_size);
223 filter2.big_step(1.0 / step_size);
224 for (uint32_t i = 0; i < step_size; i++)
226 float osc1val = osc1.get();
227 float osc2val = osc2.get();
228 float wave = fgain * (osc1val + (osc2val - osc1val) * xfade);
229 wave = filter.process(wave);
230 wave = filter2.process(wave);
231 buffer[i] = wave;
232 fgain += fgain_delta;
236 void monosynth_audio_module::calculate_buffer_single()
238 filter.big_step(1.0 / step_size);
239 for (uint32_t i = 0; i < step_size; i++)
241 float osc1val = osc1.get();
242 float osc2val = osc2.get();
243 float wave = fgain * (osc1val + (osc2val - osc1val) * xfade);
244 wave = filter.process(wave);
245 buffer[i] = wave;
246 fgain += fgain_delta;
250 void monosynth_audio_module::calculate_buffer_stereo()
252 filter.big_step(1.0 / step_size);
253 filter2.big_step(1.0 / step_size);
254 for (uint32_t i = 0; i < step_size; i++)
256 float osc1val = osc1.get();
257 float osc2val = osc2.get();
258 float wave1 = osc1val + (osc2val - osc1val) * xfade;
259 float wave2 = phaseshifter.process_ap(wave1);
260 buffer[i] = fgain * filter.process(wave1);
261 buffer2[i] = fgain * filter2.process(wave2);
262 fgain += fgain_delta;
266 void monosynth_audio_module::delayed_note_on()
268 force_fadeout = false;
269 stop_count = 0;
270 porta_time = 0.f;
271 start_freq = freq;
272 target_freq = freq = 440 * pow(2.0, (queue_note_on - 69) / 12.0);
273 ampctl = 1.0 + (queue_vel - 1.0) * *params[par_vel2amp];
274 fltctl = 1.0 + (queue_vel - 1.0) * *params[par_vel2filter];
275 set_frequency();
276 osc1.waveform = waves[wave1].get_level(osc1.phasedelta);
277 osc2.waveform = waves[wave2].get_level(osc2.phasedelta);
278 if (!osc1.waveform) osc1.waveform = silence;
279 if (!osc2.waveform) osc2.waveform = silence;
281 if (!running)
283 if (legato >= 2)
284 porta_time = -1.f;
285 osc1.reset();
286 osc2.reset();
287 filter.reset();
288 filter2.reset();
289 switch((int)*params[par_oscmode])
291 case 1:
292 osc2.phase = 0x80000000;
293 break;
294 case 2:
295 osc2.phase = 0x40000000;
296 break;
297 case 3:
298 osc1.phase = osc2.phase = 0x40000000;
299 break;
300 case 4:
301 osc1.phase = 0x40000000;
302 osc2.phase = 0xC0000000;
303 break;
304 case 5:
305 // rand() is crap, but I don't have any better RNG in Calf yet
306 osc1.phase = rand() << 16;
307 osc2.phase = rand() << 16;
308 break;
309 default:
310 break;
312 envelope.note_on();
313 running = true;
315 if (legato >= 2 && !gate)
316 porta_time = -1.f;
317 gate = true;
318 stopping = false;
319 if (!(legato & 1) || envelope.released()) {
320 envelope.note_on();
322 envelope.advance();
323 queue_note_on = -1;
326 void monosynth_audio_module::set_sample_rate(uint32_t sr) {
327 srate = sr;
328 crate = sr / step_size;
329 odcr = (float)(1.0 / crate);
330 phaseshifter.set_ap(1000.f, sr);
331 fgain = 0.f;
332 fgain_delta = 0.f;
333 inertia_cutoff.ramp.set_length(crate / 30); // 1/30s
336 void monosynth_audio_module::calculate_step()
338 if (queue_note_on != -1)
339 delayed_note_on();
340 else if (stopping)
342 running = false;
343 dsp::zero(buffer, step_size);
344 if (is_stereo_filter())
345 dsp::zero(buffer2, step_size);
346 return;
348 float porta_total_time = *params[par_portamento] * 0.001f;
350 if (porta_total_time >= 0.00101f && porta_time >= 0) {
351 // XXXKF this is criminal, optimize!
352 float point = porta_time / porta_total_time;
353 if (point >= 1.0f) {
354 freq = target_freq;
355 porta_time = -1;
356 } else {
357 freq = start_freq + (target_freq - start_freq) * point;
358 // freq = start_freq * pow(target_freq / start_freq, point);
359 porta_time += odcr;
362 set_frequency();
363 envelope.advance();
364 float env = envelope.value;
365 inertia_cutoff.set_inertia(*params[par_cutoff]);
366 cutoff = inertia_cutoff.get() * pow(2.0f, env * fltctl * *params[par_envmod] * (1.f / 1200.f));
367 if (*params[par_keyfollow] > 0.01f)
368 cutoff *= pow(freq / 264.f, *params[par_keyfollow]);
369 cutoff = dsp::clip(cutoff , 10.f, 18000.f);
370 float resonance = *params[par_resonance];
371 float e2r = *params[par_envtores];
372 float e2a = *params[par_envtoamp];
373 resonance = resonance * (1 - e2r) + (0.7 + (resonance - 0.7) * env * env) * e2r;
374 float cutoff2 = dsp::clip(cutoff * separation, 10.f, 18000.f);
375 float newfgain = 0.f;
376 if (filter_type != last_filter_type)
378 filter.y2 = filter.y1 = filter.x2 = filter.x1 = filter.y1;
379 filter2.y2 = filter2.y1 = filter2.x2 = filter2.x1 = filter2.y1;
380 last_filter_type = filter_type;
382 switch(filter_type)
384 case flt_lp12:
385 filter.set_lp_rbj(cutoff, resonance, srate);
386 filter2.set_null();
387 newfgain = min(0.7f, 0.7f / resonance) * ampctl;
388 break;
389 case flt_hp12:
390 filter.set_hp_rbj(cutoff, resonance, srate);
391 filter2.set_null();
392 newfgain = min(0.7f, 0.7f / resonance) * ampctl;
393 break;
394 case flt_lp24:
395 filter.set_lp_rbj(cutoff, resonance, srate);
396 filter2.set_lp_rbj(cutoff2, resonance, srate);
397 newfgain = min(0.5f, 0.5f / resonance) * ampctl;
398 break;
399 case flt_lpbr:
400 filter.set_lp_rbj(cutoff, resonance, srate);
401 filter2.set_br_rbj(cutoff2, 1.0 / resonance, srate);
402 newfgain = min(0.5f, 0.5f / resonance) * ampctl;
403 break;
404 case flt_hpbr:
405 filter.set_hp_rbj(cutoff, resonance, srate);
406 filter2.set_br_rbj(cutoff2, 1.0 / resonance, srate);
407 newfgain = min(0.5f, 0.5f / resonance) * ampctl;
408 break;
409 case flt_2lp12:
410 filter.set_lp_rbj(cutoff, resonance, srate);
411 filter2.set_lp_rbj(cutoff2, resonance, srate);
412 newfgain = min(0.7f, 0.7f / resonance) * ampctl;
413 break;
414 case flt_bp6:
415 filter.set_bp_rbj(cutoff, resonance, srate);
416 filter2.set_null();
417 newfgain = ampctl;
418 break;
419 case flt_2bp6:
420 filter.set_bp_rbj(cutoff, resonance, srate);
421 filter2.set_bp_rbj(cutoff2, resonance, srate);
422 newfgain = ampctl;
423 break;
425 float aenv = env;
426 /* isn't as good as expected
427 if (e2a > 1.0) { // extra-steep release on amplitude envelope only
428 if (envelope.state == adsr::RELEASE && env < envelope.sustain) {
429 aenv -= (envelope.sustain - env) * (e2a - 1.0);
430 if (aenv < 0.f) aenv = 0.f;
431 printf("aenv = %f\n", aenv);
433 e2a = 1.0;
436 newfgain *= 1.0 - (1.0 - aenv) * e2a;
437 fgain_delta = (newfgain - fgain) * (1.0 / step_size);
438 switch(filter_type)
440 case flt_lp24:
441 case flt_lpbr:
442 case flt_hpbr: // Oomek's wish
443 calculate_buffer_ser();
444 break;
445 case flt_lp12:
446 case flt_hp12:
447 case flt_bp6:
448 calculate_buffer_single();
449 break;
450 case flt_2lp12:
451 case flt_2bp6:
452 calculate_buffer_stereo();
453 break;
455 if (envelope.state == adsr::STOP || force_fadeout)
457 enum { ramp = step_size * 4 };
458 for (int i = 0; i < step_size; i++)
459 buffer[i] *= (ramp - i - stop_count) * (1.0f / ramp);
460 if (is_stereo_filter())
461 for (int i = 0; i < step_size; i++)
462 buffer2[i] *= (ramp - i - stop_count) * (1.0f / ramp);
463 stop_count += step_size;
464 if (stop_count >= ramp)
465 stopping = true;
469 void monosynth_audio_module::note_on(int note, int vel)
471 queue_note_on = note;
472 last_key = note;
473 queue_vel = vel / 127.f;
474 stack.push(note);
477 void monosynth_audio_module::note_off(int note, int vel)
479 stack.pop(note);
480 // If releasing the currently played note, try to get another one from note stack.
481 if (note == last_key) {
482 if (stack.count())
484 last_key = note = stack.nth(stack.count() - 1);
485 start_freq = freq;
486 target_freq = freq = dsp::note_to_hz(note);
487 porta_time = 0;
488 set_frequency();
489 if (!(legato & 1)) {
490 envelope.note_on();
491 stopping = false;
492 running = true;
494 return;
496 gate = false;
497 envelope.note_off();
502 void monosynth_audio_module::control_change(int controller, int value)
504 switch(controller)
506 case 120: // all sounds off
507 force_fadeout = true;
508 // fall through
509 case 123: // all notes off
510 gate = false;
511 queue_note_on = -1;
512 envelope.note_off();
513 stack.clear();
514 break;
518 void monosynth_audio_module::deactivate()
520 gate = false;
521 running = false;
522 stopping = false;
523 envelope.reset();
524 stack.clear();