Merge pull request #1 from atsampson/master
[calfbox.git] / tonewheel.c
blobdd76053cad337696789a252f7af4a88a3551945a
1 /*
2 Calf Box, an open source musical instrument.
3 Copyright (C) 2010 Krzysztof Foltman
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "config.h"
20 #include "config-api.h"
21 #include "cmd.h"
22 #include "dspmath.h"
23 #include "module.h"
24 #include "onepole-int.h"
25 #include <glib.h>
26 #include <malloc.h>
27 #include <math.h>
28 #include <memory.h>
29 #include <stdio.h>
30 #include <stdlib.h>
32 // a0 a1 a2 b1 b2 for scanner vibrato filter @4kHz with sr=44.1: 0.057198 0.114396 0.057198 -1.218829 0.447620
34 static int64_t scanner_a0 = (int64_t)(0.057198 * 1048576);
35 static int64_t scanner_b1 = (int64_t)(-1.218829 * 1048576);
36 static int64_t scanner_b2 = (int64_t)(0.447620 * 1048576);
38 static int sine_table[2048];
39 static int complex_table[2048];
40 static int distortion_table[8192];
42 struct biquad
44 int x1;
45 int y1;
46 int x2;
47 int y2;
50 struct tonewheel_organ_module
52 struct cbox_module module;
54 uint32_t frequency[91];
55 uint32_t phase[91];
56 uint64_t pedalmasks;
57 uint64_t upper_manual, lower_manual;
58 int amp_scaling[91];
59 struct biquad scanner_delay[18];
60 struct cbox_onepole_state filter_anticlick, filter_overdrive;
61 struct cbox_onepole_coeffs filter_anticlick_coeffs, filter_overdrive_coeffs;
62 float percussion;
63 int enable_percussion, enable_vibrato_upper, enable_vibrato_lower, vibrato_mode, vibrato_mix, percussion_3rd;
64 int do_filter;
65 int cc91;
66 uint32_t vibrato_phase, vibrato_dphase;
68 int pedal_drawbar_settings[2];
69 int upper_manual_drawbar_settings[9];
70 int lower_manual_drawbar_settings[9];
73 static const int drawbars[9] = {0, 19, 12, 24, 24 + 7, 36, 36 + 4, 36 + 7, 48};
75 static void set_keymask(struct tonewheel_organ_module *m, int channel, int key, int value)
77 uint64_t mask = 0;
78 uint64_t *manual = NULL;
79 if (key >= 24 && key < 36)
81 mask = 1 << (key - 24);
82 manual = &m->pedalmasks;
84 else if (key >= 36 && key < 36 + 61)
86 manual = (channel == 0) ? &m->upper_manual : &m->lower_manual;
87 mask = ((int64_t)1) << (key - 36);
89 else
90 return;
92 if (value)
93 *manual |= mask;
94 else
95 *manual &= ~mask;
98 void tonewheel_organ_process_event(struct cbox_module *module, const uint8_t *data, uint32_t len)
100 struct tonewheel_organ_module *m = (struct tonewheel_organ_module *)module;
101 if (len > 0)
103 int cmd = data[0] >> 4;
104 if (cmd == 9 && data[2])
106 int channel = data[0] & 0x0F;
107 int key = data[1] & 127;
108 set_keymask(m, channel, key, 1);
109 if (m->percussion < 0 && key >= 36 && m->enable_percussion && channel == 0)
110 m->percussion = 16.0;
112 if (cmd == 8 || (cmd == 9 && !data[2]))
114 int channel = data[0] & 0x0F;
115 int key = data[1] & 127;
116 set_keymask(m, channel, key, 0);
118 if (channel == 0 && !m->upper_manual)
119 m->percussion = -1;
121 if (cmd == 11)
123 int *drawbars = (data[0] & 0xF0) != 0 ? m->lower_manual_drawbar_settings : m->upper_manual_drawbar_settings;
124 if (data[1] >= 21 && data[1] <= 29)
125 drawbars[data[1] - 21] = data[2] * 8 / 127;
126 if (data[1] == 82)
127 drawbars[8] = data[2] * 8 / 127;
128 if (data[1] == 64)
129 m->do_filter = data[2] >= 64;
130 if (data[1] == 91)
131 m->cc91 = data[2];
132 if (data[1] == 93)
133 m->vibrato_mix = data[2] > 0;
134 if (data[1] == 120 || data[1] == 123)
136 for (int i = 24; i < 36 + 61; i++)
137 set_keymask(m, data[0] & 0xF, i, 0);
139 //if (data[1] == 6)
140 // cbox_onepole_set_lowpass(&m->filter_overdrive_coeffs, hz2w(data[2] * 10000 / 127, 44100.0));
145 static inline int check_keymask(uint64_t keymasks, int note)
147 if (note < 0 || note > 127)
148 return 0;
149 if (note >= 24 && note < 36)
150 return 0 != (keymasks & (1 << (note - 24)));
151 if (note >= 36 && note < 36 + 61)
152 return 0 != (keymasks & (1ULL << (note - 36)));
153 return 0;
156 static inline int tonegenidx_pedals(int note, int shift)
158 if (note < 24 || note > 24 + 11)
159 return 91;
161 note -= 24;
162 return note + shift;
165 static inline int tonegenidx(int note, int shift)
167 // ignore everything below the lowest key
168 if (note < 36)
169 return 91;
171 note -= 36;
173 // harmonic foldback in the first octave of the manual
174 if (note < 12 && shift < 12)
175 return note + 12;
177 while (note + shift > 90)
178 note -= 12;
180 return note + shift;
183 static int drawbar_amp_mapping[9] = { 0, 1, 2, 3, 4, 6, 8, 11, 16 };
185 static void calc_crosstalk(int *wheel1, int *wheel2)
187 int w1 = *wheel1;
188 int w2 = *wheel2;
189 *wheel1 += w2 >> 9;
190 *wheel2 += w1 >> 9;
193 static int compress_amp(int iamp, int scaling)
195 if (iamp > 512)
196 iamp = 512 + 3 * ((iamp - 512) >> 2);
197 return (iamp * scaling) >> 10;
200 static void set_tonewheels(struct tonewheel_organ_module *m, int tonegens[2][92])
202 int n, i;
203 int pshift = m->percussion_3rd ? 24 + 7 : 24;
205 int upper_manual_drawbar_amp[9], lower_manual_drawbar_amp[9];
207 for (i = 0; i < 9; i++)
209 upper_manual_drawbar_amp[i] = drawbar_amp_mapping[m->upper_manual_drawbar_settings[i]] * 8;
210 lower_manual_drawbar_amp[i] = drawbar_amp_mapping[m->lower_manual_drawbar_settings[i]] * 8;
213 memset(tonegens, 0, 2 * 92 * sizeof(tonegens[0][0]));
214 // pedalboard
215 for (n = 24; n < 24 + 12; n++)
217 if (check_keymask(m->pedalmasks, n))
219 tonegens[0][tonegenidx_pedals(n, 0)] += 3 * 16 * m->pedal_drawbar_settings[0];
220 tonegens[0][tonegenidx_pedals(n, 12)] += 3 * 16 * m->pedal_drawbar_settings[1];
223 // manual
224 for (n = 36; n < 36 + 61; n++)
226 if (check_keymask(m->upper_manual, n))
228 int tgf = m->enable_vibrato_upper;
229 for (i = 0; i < 9; i++)
231 int tg = tonegenidx(n, drawbars[i]);
232 tonegens[tgf][tg] += upper_manual_drawbar_amp[i];
234 if (m->percussion > 0)
235 tonegens[0][tonegenidx(n, pshift)] += m->percussion * 10;
237 if (check_keymask(m->lower_manual, n))
239 int tgf = m->enable_vibrato_lower;
240 for (i = 0; i < 9; i++)
242 int tg = tonegenidx(n, drawbars[i]);
243 tonegens[tgf][tg] += lower_manual_drawbar_amp[i];
247 for (n = 0; n < 91; n++)
249 int scaling = m->amp_scaling[n];
250 tonegens[0][n] = compress_amp(tonegens[0][n], scaling);
251 tonegens[1][n] = compress_amp(tonegens[1][n], scaling);
253 for (n = 0; n < 36; n++)
255 calc_crosstalk(&tonegens[0][n], &tonegens[0][n + 48]);
256 calc_crosstalk(&tonegens[1][n], &tonegens[1][n + 48]);
260 void tonewheel_organ_process_block(struct cbox_module *module, cbox_sample_t **inputs, cbox_sample_t **outputs)
262 struct tonewheel_organ_module *m = (struct tonewheel_organ_module *)module;
263 int n, i;
265 static const uint32_t frac_mask = (1 << 21) - 1;
267 int internal_out_for_vibrato[CBOX_BLOCK_SIZE];
268 int internal_out[CBOX_BLOCK_SIZE];
270 for (i = 0; i < CBOX_BLOCK_SIZE; i++)
272 internal_out[i] = 0;
273 internal_out_for_vibrato[i] = 0;
275 // 91 tonewheels + 1 dummy
276 int tonegens[2][92];
277 set_tonewheels(m, tonegens);
278 if (m->percussion > 0)
279 m->percussion *= 0.99f;
280 for (n = 0; n < 91; n++)
282 if (tonegens[0][n] > 0 || tonegens[1][n])
284 int iamp1, iamp2;
286 iamp1 = tonegens[0][n];
287 iamp2 = tonegens[1][n];
289 int *table = n < 12 ? complex_table : sine_table;
290 uint32_t phase = m->phase[n];
291 for (i = 0; i < CBOX_BLOCK_SIZE; i++)
293 uint32_t pos = phase >> 21;
294 int val0 = table[(pos - 1) & 2047];
295 int val1 = table[pos];
296 // phase & frac_mask has 21 bits of resolution, but we only have 14 bits of headroom here
297 int frac_14bit = (phase & frac_mask) >> (21-14);
298 int val = (val1 * frac_14bit + val0 * ((1 << 14) - frac_14bit)) >> 14;
299 internal_out[i] += val * iamp1 >> 3;
300 internal_out_for_vibrato[i] += val * iamp2 >> 3;
301 phase += m->frequency[n];
304 m->phase[n] += m->frequency[n] * CBOX_BLOCK_SIZE;
307 static const int v1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 8 };
308 static const int v2[] = { 0, 1, 2, 4, 6, 8, 9, 10, 12 };
309 static const int v3[] = { 0, 1, 3, 6, 11, 12, 15, 17, 18, 18, 18 };
310 static const int *vtypes[] = { v1, v2, v3 };
311 const int *dmap = vtypes[m->vibrato_mode];
312 int32_t mix = m->vibrato_mix;
313 for (i = 0; i < CBOX_BLOCK_SIZE; i++)
315 int x0 = internal_out_for_vibrato[i] >> 1;
316 int delay[19];
317 int64_t accum;
318 delay[0] = x0;
319 for (n = 0; n < 18; n++)
321 struct biquad *bq = &m->scanner_delay[n];
322 accum = 0;
323 accum += (x0 + (bq->x1 << 1) + bq->x2) * scanner_a0;
324 accum -= bq->y1 * scanner_b1;
325 accum -= bq->y2 * scanner_b2;
326 accum = accum >> 20;
327 bq->x2 = bq->x1;
328 bq->x1 = x0;
329 bq->y2 = bq->y1;
330 bq->y1 = accum;
332 delay[1 + n] = x0 = accum;
334 m->vibrato_phase += m->vibrato_dphase;
336 uint32_t vphase = m->vibrato_phase;
337 if (vphase >= 0x80000000)
338 vphase = ~vphase;
339 uint32_t vphint = vphase >> 28;
341 accum = 0;
343 accum += delay[dmap[vphint]] * ((1ULL << 28) - (vphase & ~0xF0000000));
344 accum += delay[dmap[vphint + 1]] * (vphase & ~0xF0000000ULL);
347 internal_out[i] += (accum >> 28) + mix * delay[0];
350 int32_t filtered[CBOX_BLOCK_SIZE];
351 cbox_onepole_process_to(&m->filter_overdrive, &m->filter_overdrive_coeffs, internal_out, filtered);
353 for (i = 0; i < CBOX_BLOCK_SIZE; i++)
355 int value = filtered[i] >> 9;
356 int sign = (value >= 0 ? 1 : -1);
357 int a, b, idx;
359 value = abs(value);
360 if (value > 8192 * 8 - 2 * 8)
361 value = 8192 * 8 - 2 * 8;
362 idx = value >> 3;
363 a = distortion_table[idx];
364 b = distortion_table[idx + 1];
365 internal_out[i] = (internal_out[i] >> 11) + sign * (a + ((b - a) * (value & 7) >> 3));
366 //internal_out[i] = 32767 * value2;
369 cbox_onepole_process(&m->filter_anticlick, &m->filter_anticlick_coeffs, internal_out);
371 for (i = 0; i < CBOX_BLOCK_SIZE; i++)
373 float value = internal_out[i] * (1.0 / 32768.0);
374 outputs[1][i] = outputs[0][i] = value;
378 static void biquad_init(struct biquad *bq)
380 bq->x1 = bq->y1 = bq->x2 = bq->y2 = 0;
383 static void read_drawbars(int *drawbars, int count, const char *registration)
385 int i;
387 memset(drawbars, 0, count * sizeof(int));
388 for (i = 0; i < count; i++)
390 if (!registration[i])
392 g_error("registration too short: %s (%d digits required)", registration, count);
393 break;
395 if (registration[i] < '0' || registration[i] > '8')
397 g_error("registration invalid: %s (%c is not in 0..8)", registration, registration[i]);
398 break;
400 drawbars[i] = registration[i] - '0';
404 static void tonewheel_organ_destroyfunc(struct cbox_module *module)
408 #define SINGLE_SETTING(flag, max, field) \
409 else if (!strcmp(cmd->command, flag) && !strcmp(cmd->arg_types, "i")) \
411 int setting = CBOX_ARG_I(cmd, 0); \
412 if (setting >= 0 && setting <= max) \
413 m->field = setting; \
414 return TRUE; \
417 gboolean tonewheel_organ_process_cmd(struct cbox_command_target *ct, struct cbox_command_target *fb, struct cbox_osc_command *cmd, GError **error)
419 struct tonewheel_organ_module *m = ct->user_data;
420 if (!strcmp(cmd->command, "/status") && !strcmp(cmd->arg_types, ""))
422 if (!cbox_check_fb_channel(fb, cmd->command, error))
423 return FALSE;
424 for (int i = 0; i < 9; i++)
426 if (!cbox_execute_on(fb, NULL, "/upper_drawbar", "ii", error, i, m->upper_manual_drawbar_settings[i]))
427 return FALSE;
428 if (!cbox_execute_on(fb, NULL, "/lower_drawbar", "ii", error, i, m->lower_manual_drawbar_settings[i]))
429 return FALSE;
431 for (int i = 0; i < 2; i++)
433 if (!cbox_execute_on(fb, NULL, "/pedal_drawbar", "ii", error, i, m->pedal_drawbar_settings[i]))
434 return FALSE;
436 return cbox_execute_on(fb, NULL, "/upper_vibrato", "i", error, m->enable_vibrato_upper) &&
437 cbox_execute_on(fb, NULL, "/lower_vibrato", "i", error, m->enable_vibrato_lower) &&
438 cbox_execute_on(fb, NULL, "/vibrato_mode", "i", error, m->vibrato_mode) &&
439 cbox_execute_on(fb, NULL, "/vibrato_chorus", "i", error, m->vibrato_mix) &&
440 cbox_execute_on(fb, NULL, "/percussion_enable", "i", error, m->enable_percussion) &&
441 cbox_execute_on(fb, NULL, "/percussion_3rd", "i", error, m->percussion_3rd) &&
442 CBOX_OBJECT_DEFAULT_STATUS(&m->module, fb, error);
444 else if (!strcmp(cmd->command, "/upper_drawbar") && !strcmp(cmd->arg_types, "ii"))
446 int drawbar = CBOX_ARG_I(cmd, 0);
447 int setting = CBOX_ARG_I(cmd, 1);
448 if (drawbar >= 0 && drawbar <= 8 && setting >= 0 && setting <= 8)
449 m->upper_manual_drawbar_settings[drawbar] = setting;
450 return TRUE;
452 else if (!strcmp(cmd->command, "/lower_drawbar") && !strcmp(cmd->arg_types, "ii"))
454 int drawbar = CBOX_ARG_I(cmd, 0);
455 int setting = CBOX_ARG_I(cmd, 1);
456 if (drawbar >= 0 && drawbar <= 8 && setting >= 0 && setting <= 8)
457 m->lower_manual_drawbar_settings[drawbar] = setting;
458 return TRUE;
460 SINGLE_SETTING("/upper_vibrato", 1, enable_vibrato_upper)
461 SINGLE_SETTING("/lower_vibrato", 1, enable_vibrato_lower)
462 SINGLE_SETTING("/vibrato_mode", 2, vibrato_mode)
463 SINGLE_SETTING("/vibrato_chorus", 1, vibrato_mix)
464 SINGLE_SETTING("/percussion_enable", 1, enable_percussion)
465 SINGLE_SETTING("/percussion_3rd", 1, percussion_3rd)
466 else
467 return cbox_object_default_process_cmd(ct, fb, cmd, error);
468 return TRUE;
471 MODULE_CREATE_FUNCTION(tonewheel_organ)
473 static int inited = 0;
474 int i, srate;
475 const char *vibrato_mode;
476 if (!inited)
478 for (i = 0; i < 2048; i++)
480 float ph = i * M_PI / 1024;
481 sine_table[i] = (int)(32000 * sin(ph));
482 complex_table[i] = (int)(32000 * (sin(ph) + sin(3 * ph) / 3 + sin(5 * ph) / 5 + sin(7 * ph) / 7 + sin(9 * ph) / 9 + sin(11 * ph) / 11));
484 for (i = 0; i < 8192; i++)
486 float value = atan(sqrt(i * (4.0 / 8192)));
487 distortion_table[i] = ((int)(i * 2 + 32767 * value * value)) >> 1;
489 inited = 1;
492 struct tonewheel_organ_module *m = malloc(sizeof(struct tonewheel_organ_module));
493 CALL_MODULE_INIT(m, 0, 2, tonewheel_organ);
494 srate = m->module.srate;
495 m->module.process_event = tonewheel_organ_process_event;
496 m->module.process_block = tonewheel_organ_process_block;
497 cbox_onepole_reset(&m->filter_anticlick);
498 cbox_onepole_reset(&m->filter_overdrive);
499 cbox_onepole_set_lowpass(&m->filter_anticlick_coeffs, hz2w(180.0, srate));
500 cbox_onepole_set_lowpass(&m->filter_overdrive_coeffs, hz2w(2500.0, srate));
501 m->percussion = -1;
502 m->do_filter = 0;
503 m->cc91 = 0;
504 m->vibrato_phase = 0;
505 read_drawbars(m->upper_manual_drawbar_settings, 9, cbox_config_get_string_with_default(cfg_section, "upper_drawbars", "888000000"));
506 read_drawbars(m->lower_manual_drawbar_settings, 9, cbox_config_get_string_with_default(cfg_section, "lower_drawbars", "888800000"));
507 read_drawbars(m->pedal_drawbar_settings, 2, cbox_config_get_string_with_default(cfg_section, "pedal_drawbars", "82"));
508 m->enable_percussion = cbox_config_get_int(cfg_section, "percussion", 1);
509 m->enable_vibrato_upper = cbox_config_get_int(cfg_section, "vibrato_upper", 1);
510 m->enable_vibrato_lower = cbox_config_get_int(cfg_section, "vibrato_lower", 0);
511 m->percussion_3rd = cbox_config_get_int(cfg_section, "percussion_3rd", 1);
512 m->vibrato_dphase = (int)(6.6 / srate * 65536 * 65536);
514 vibrato_mode = cbox_config_get_string_with_default(cfg_section, "vibrato_mode", "c3");
515 if (vibrato_mode[0] == 'c')
516 m->vibrato_mix = 1;
517 else if (vibrato_mode[0] == 'v')
518 m->vibrato_mix = 0;
519 else
521 g_error("Unknown vibrato mode: %s (allowed: v1, v2, v3, c1, c2, c3)", vibrato_mode);
522 m->vibrato_mix = 0;
524 if (vibrato_mode[1] >= '1' && vibrato_mode[1] <= '3')
525 m->vibrato_mode = vibrato_mode[1] - '1';
526 else
528 g_error("Unknown vibrato mode: %s (allowed: v1, v2, v3, c1, c2, c3)", vibrato_mode);
529 m->vibrato_mode = 2;
532 for (i = 0; i < 18; i++)
534 biquad_init(&m->scanner_delay[i]);
536 for (i = 0; i < 91; i++)
538 float freq_hz = 440 * pow(2.0, (i - 45) / 12.0);
539 float scaling = freq_hz / 120.0;
540 if (scaling < 1)
541 scaling = 1;
542 if (scaling > 24)
543 scaling = 24 + ((scaling - 24) / 2.5);
544 m->frequency[i] = (uint32_t)(freq_hz * 65536 * 65536 / srate);
545 m->phase[i] = 0;
546 m->amp_scaling[i] = (int)(1024 * scaling);
548 m->upper_manual = 0;
549 m->lower_manual = 0;
550 m->pedalmasks = 0;
552 return &m->module;
555 struct cbox_module_keyrange_metadata tonewheel_organ_keyranges[] = {
556 { 0, 24, 35, "Pedal keyboard" },
557 { 1, 36, 36 + 60, "Upper Manual" },
558 { 2, 36, 36 + 60, "Lower Manual" },
561 struct cbox_module_livecontroller_metadata tonewheel_organ_controllers[] = {
562 { 0, cmlc_onoffcc, 93, "Vib/Chr", NULL},
564 { 1, cmlc_continuouscc, 21, "Upper Drawbar 1", NULL},
565 { 1, cmlc_continuouscc, 22, "Upper Drawbar 2", NULL},
566 { 1, cmlc_continuouscc, 23, "Upper Drawbar 3", NULL},
567 { 1, cmlc_continuouscc, 24, "Upper Drawbar 4", NULL},
568 { 1, cmlc_continuouscc, 25, "Upper Drawbar 5", NULL},
569 { 1, cmlc_continuouscc, 26, "Upper Drawbar 6", NULL},
570 { 1, cmlc_continuouscc, 27, "Upper Drawbar 7", NULL},
571 { 1, cmlc_continuouscc, 28, "Upper Drawbar 8", NULL},
572 { 1, cmlc_continuouscc, 29, "Upper Drawbar 9", NULL},
574 { 2, cmlc_continuouscc, 21, "Lower Drawbar 1", NULL},
575 { 2, cmlc_continuouscc, 22, "Lower Drawbar 2", NULL},
576 { 2, cmlc_continuouscc, 23, "Lower Drawbar 3", NULL},
577 { 2, cmlc_continuouscc, 24, "Lower Drawbar 4", NULL},
578 { 2, cmlc_continuouscc, 25, "Lower Drawbar 5", NULL},
579 { 2, cmlc_continuouscc, 26, "Lower Drawbar 6", NULL},
580 { 2, cmlc_continuouscc, 27, "Lower Drawbar 7", NULL},
581 { 2, cmlc_continuouscc, 28, "Lower Drawbar 8", NULL},
582 { 2, cmlc_continuouscc, 29, "Lower Drawbar 9", NULL},
585 DEFINE_MODULE(tonewheel_organ, 0, 2)