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/>.
20 #include "config-api.h"
24 #include "onepole-int.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];
50 struct tonewheel_organ_module
52 struct cbox_module module
;
54 uint32_t frequency
[91];
57 uint64_t upper_manual
, lower_manual
;
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
;
63 int enable_percussion
, enable_vibrato_upper
, enable_vibrato_lower
, vibrato_mode
, vibrato_mix
, percussion_3rd
;
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
)
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);
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
;
103 int cmd
= data
[0] >> 4;
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;
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
)
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;
127 drawbars
[8] = data
[2] * 8 / 127;
129 m
->do_filter
= data
[2] >= 64;
133 m
->vibrato_mix
= data
[2] > 0;
135 // cbox_onepole_set_lowpass(&m->filter_overdrive_coeffs, hz2w(data[2] * 10000 / 127, 44100.0));
140 static inline int check_keymask(uint64_t keymasks
, int note
)
142 if (note
< 0 || note
> 127)
144 if (note
>= 24 && note
< 36)
145 return 0 != (keymasks
& (1 << (note
- 24)));
146 if (note
>= 36 && note
< 36 + 61)
147 return 0 != (keymasks
& (1ULL << (note
- 36)));
151 static inline int tonegenidx_pedals(int note
, int shift
)
153 if (note
< 24 || note
> 24 + 11)
160 static inline int tonegenidx(int note
, int shift
)
162 // ignore everything below the lowest key
168 // harmonic foldback in the first octave of the manual
169 if (note
< 12 && shift
< 12)
172 while (note
+ shift
> 90)
178 static int drawbar_amp_mapping
[9] = { 0, 1, 2, 3, 4, 6, 8, 11, 16 };
180 static void calc_crosstalk(int *wheel1
, int *wheel2
)
188 static int compress_amp(int iamp
, int scaling
)
191 iamp
= 512 + 3 * ((iamp
- 512) >> 2);
192 return (iamp
* scaling
) >> 10;
195 static void set_tonewheels(struct tonewheel_organ_module
*m
, int tonegens
[2][92])
198 int pshift
= m
->percussion_3rd
? 24 + 7 : 24;
200 int upper_manual_drawbar_amp
[9], lower_manual_drawbar_amp
[9];
202 for (i
= 0; i
< 9; i
++)
204 upper_manual_drawbar_amp
[i
] = drawbar_amp_mapping
[m
->upper_manual_drawbar_settings
[i
]] * 8;
205 lower_manual_drawbar_amp
[i
] = drawbar_amp_mapping
[m
->lower_manual_drawbar_settings
[i
]] * 8;
208 memset(tonegens
, 0, 2 * 92 * sizeof(tonegens
[0][0]));
210 for (n
= 24; n
< 24 + 12; n
++)
212 if (check_keymask(m
->pedalmasks
, n
))
214 tonegens
[0][tonegenidx_pedals(n
, 0)] += 3 * 16 * m
->pedal_drawbar_settings
[0];
215 tonegens
[0][tonegenidx_pedals(n
, 12)] += 3 * 16 * m
->pedal_drawbar_settings
[1];
219 for (n
= 36; n
< 36 + 61; n
++)
221 if (check_keymask(m
->upper_manual
, n
))
223 int tgf
= m
->enable_vibrato_upper
;
224 for (i
= 0; i
< 9; i
++)
226 int tg
= tonegenidx(n
, drawbars
[i
]);
227 tonegens
[tgf
][tg
] += upper_manual_drawbar_amp
[i
];
229 if (m
->percussion
> 0)
230 tonegens
[0][tonegenidx(n
, pshift
)] += m
->percussion
* 10;
232 if (check_keymask(m
->lower_manual
, n
))
234 int tgf
= m
->enable_vibrato_lower
;
235 for (i
= 0; i
< 9; i
++)
237 int tg
= tonegenidx(n
, drawbars
[i
]);
238 tonegens
[tgf
][tg
] += lower_manual_drawbar_amp
[i
];
242 for (n
= 0; n
< 91; n
++)
244 int scaling
= m
->amp_scaling
[n
];
245 tonegens
[0][n
] = compress_amp(tonegens
[0][n
], scaling
);
246 tonegens
[1][n
] = compress_amp(tonegens
[1][n
], scaling
);
248 for (n
= 0; n
< 36; n
++)
250 calc_crosstalk(&tonegens
[0][n
], &tonegens
[0][n
+ 48]);
251 calc_crosstalk(&tonegens
[1][n
], &tonegens
[1][n
+ 48]);
255 void tonewheel_organ_process_block(struct cbox_module
*module
, cbox_sample_t
**inputs
, cbox_sample_t
**outputs
)
257 struct tonewheel_organ_module
*m
= (struct tonewheel_organ_module
*)module
;
259 //float a01, b1, x1, y1, x, q;
262 static const uint32_t frac_mask
= (1 << 21) - 1;
264 int internal_out_for_vibrato
[CBOX_BLOCK_SIZE
];
265 int internal_out
[CBOX_BLOCK_SIZE
];
267 for (i
= 0; i
< CBOX_BLOCK_SIZE
; i
++)
270 internal_out_for_vibrato
[i
] = 0;
272 // 91 tonewheels + 1 dummy
274 set_tonewheels(m
, tonegens
);
275 if (m
->percussion
> 0)
276 m
->percussion
*= 0.99f
;
277 for (n
= 0; n
< 91; n
++)
279 if (tonegens
[0][n
] > 0 || tonegens
[1][n
])
281 int iamp1
, iamp2
, scaling
;
283 iamp1
= tonegens
[0][n
];
284 iamp2
= tonegens
[1][n
];
286 int *table
= n
< 12 ? complex_table
: sine_table
;
287 uint32_t phase
= m
->phase
[n
];
288 for (i
= 0; i
< CBOX_BLOCK_SIZE
; i
++)
290 uint32_t pos
= phase
>> 21;
291 int val0
= table
[(pos
- 1) & 2047];
292 int val1
= table
[pos
];
293 // phase & frac_mask has 21 bits of resolution, but we only have 14 bits of headroom here
294 int frac_14bit
= (phase
& frac_mask
) >> (21-14);
295 int val
= (val1
* frac_14bit
+ val0
* ((1 << 14) - frac_14bit
)) >> 14;
296 internal_out
[i
] += val
* iamp1
>> 3;
297 internal_out_for_vibrato
[i
] += val
* iamp2
>> 3;
298 phase
+= m
->frequency
[n
];
301 m
->phase
[n
] += m
->frequency
[n
] * CBOX_BLOCK_SIZE
;
304 static const int v1
[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 8 };
305 static const int v2
[] = { 0, 1, 2, 4, 6, 8, 9, 10, 12 };
306 static const int v3
[] = { 0, 1, 3, 6, 11, 12, 15, 17, 18, 18, 18 };
307 static const int *vtypes
[] = { v1
, v2
, v3
};
308 const int *dmap
= vtypes
[m
->vibrato_mode
];
309 int32_t mix
= m
->vibrato_mix
;
310 for (i
= 0; i
< CBOX_BLOCK_SIZE
; i
++)
312 int x0
= internal_out_for_vibrato
[i
] >> 1;
316 for (n
= 0; n
< 18; n
++)
318 struct biquad
*bq
= &m
->scanner_delay
[n
];
320 accum
+= (x0
+ (bq
->x1
<< 1) + bq
->x2
) * scanner_a0
;
321 accum
-= bq
->y1
* scanner_b1
;
322 accum
-= bq
->y2
* scanner_b2
;
329 delay
[1 + n
] = x0
= accum
;
331 m
->vibrato_phase
+= m
->vibrato_dphase
;
333 uint32_t vphase
= m
->vibrato_phase
;
334 if (vphase
>= 0x80000000)
336 uint32_t vphint
= vphase
>> 28;
340 accum
+= delay
[dmap
[vphint
]] * ((1ULL << 28) - (vphase
& ~0xF0000000));
341 accum
+= delay
[dmap
[vphint
+ 1]] * (vphase
& ~0xF0000000ULL
);
344 internal_out
[i
] += (accum
>> 28) + mix
* delay
[0];
347 int32_t filtered
[CBOX_BLOCK_SIZE
];
348 cbox_onepole_process_to(&m
->filter_overdrive
, &m
->filter_overdrive_coeffs
, internal_out
, filtered
);
350 for (i
= 0; i
< CBOX_BLOCK_SIZE
; i
++)
352 int value
= filtered
[i
] >> 9;
353 int sign
= (value
>= 0 ? 1 : -1);
358 if (value
> 8192 * 8 - 2 * 8)
359 value
= 8192 * 8 - 2 * 8;
361 a
= distortion_table
[idx
];
362 b
= distortion_table
[idx
+ 1];
363 internal_out
[i
] = (internal_out
[i
] >> 11) + sign
* (a
+ ((b
- a
) * (value
& 7) >> 3));
364 //internal_out[i] = 32767 * value2;
367 int prev
= internal_out
[0];
368 cbox_onepole_process(&m
->filter_anticlick
, &m
->filter_anticlick_coeffs
, internal_out
);
370 for (i
= 0; i
< CBOX_BLOCK_SIZE
; i
++)
372 float value
= internal_out
[i
] * (1.0 / 32768.0);
373 outputs
[1][i
] = outputs
[0][i
] = value
;
377 static void biquad_init(struct biquad
*bq
)
379 bq
->x1
= bq
->y1
= bq
->x2
= bq
->y2
= 0;
382 static void read_drawbars(int *drawbars
, int count
, const char *registration
)
386 memset(drawbars
, 0, count
* sizeof(int));
387 for (i
= 0; i
< count
; i
++)
389 if (!registration
[i
])
391 g_error("registration too short: %s (%d digits required)", registration
, count
);
394 if (registration
[i
] < '0' || registration
[i
] > '8')
396 g_error("registration invalid: %s (%c is not in 0..8)", registration
, registration
[i
]);
399 drawbars
[i
] = registration
[i
] - '0';
403 static void tonewheel_organ_destroyfunc(struct cbox_module
*module
)
407 #define SINGLE_SETTING(flag, max, field) \
408 else if (!strcmp(cmd->command, flag) && !strcmp(cmd->arg_types, "i")) \
410 int setting = CBOX_ARG_I(cmd, 0); \
411 if (setting >= 0 && setting <= max) \
412 m->field = setting; \
416 gboolean tonewheel_organ_process_cmd(struct cbox_command_target *ct, struct cbox_command_target *fb, struct cbox_osc_command *cmd, GError **error)
418 struct tonewheel_organ_module
*m
= ct
->user_data
;
419 if (!strcmp(cmd
->command
, "/status") && !strcmp(cmd
->arg_types
, ""))
421 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
423 for (int i
= 0; i
< 9; i
++)
425 if (!cbox_execute_on(fb
, NULL
, "/upper_drawbar", "ii", error
, i
, m
->upper_manual_drawbar_settings
[i
]))
427 if (!cbox_execute_on(fb
, NULL
, "/lower_drawbar", "ii", error
, i
, m
->lower_manual_drawbar_settings
[i
]))
430 for (int i
= 0; i
< 2; i
++)
432 if (!cbox_execute_on(fb
, NULL
, "/pedal_drawbar", "ii", error
, i
, m
->pedal_drawbar_settings
[i
]))
435 return cbox_execute_on(fb
, NULL
, "/upper_vibrato", "i", error
, m
->enable_vibrato_upper
) &&
436 cbox_execute_on(fb
, NULL
, "/lower_vibrato", "i", error
, m
->enable_vibrato_lower
) &&
437 cbox_execute_on(fb
, NULL
, "/vibrato_mode", "i", error
, m
->vibrato_mode
) &&
438 cbox_execute_on(fb
, NULL
, "/vibrato_chorus", "i", error
, m
->vibrato_mix
) &&
439 cbox_execute_on(fb
, NULL
, "/percussion_enable", "i", error
, m
->enable_percussion
) &&
440 cbox_execute_on(fb
, NULL
, "/percussion_3rd", "i", error
, m
->percussion_3rd
) &&
441 CBOX_OBJECT_DEFAULT_STATUS(&m
->module
, fb
, error
);
443 else if (!strcmp(cmd
->command
, "/upper_drawbar") && !strcmp(cmd
->arg_types
, "ii"))
445 int drawbar
= CBOX_ARG_I(cmd
, 0);
446 int setting
= CBOX_ARG_I(cmd
, 1);
447 if (drawbar
>= 0 && drawbar
<= 8 && setting
>= 0 && setting
<= 8)
448 m
->upper_manual_drawbar_settings
[drawbar
] = setting
;
451 else if (!strcmp(cmd
->command
, "/lower_drawbar") && !strcmp(cmd
->arg_types
, "ii"))
453 int drawbar
= CBOX_ARG_I(cmd
, 0);
454 int setting
= CBOX_ARG_I(cmd
, 1);
455 if (drawbar
>= 0 && drawbar
<= 8 && setting
>= 0 && setting
<= 8)
456 m
->lower_manual_drawbar_settings
[drawbar
] = setting
;
459 SINGLE_SETTING("/upper_vibrato", 1, enable_vibrato_upper
)
460 SINGLE_SETTING("/lower_vibrato", 1, enable_vibrato_lower
)
461 SINGLE_SETTING("/vibrato_mode", 2, vibrato_mode
)
462 SINGLE_SETTING("/vibrato_chorus", 1, vibrato_mix
)
463 SINGLE_SETTING("/percussion_enable", 1, enable_percussion
)
464 SINGLE_SETTING("/percussion_3rd", 1, percussion_3rd
)
466 return cbox_object_default_process_cmd(ct
, fb
, cmd
, error
);
470 MODULE_CREATE_FUNCTION(tonewheel_organ
)
472 static int inited
= 0;
474 const char *vibrato_mode
;
477 for (i
= 0; i
< 2048; i
++)
479 float ph
= i
* M_PI
/ 1024;
480 sine_table
[i
] = (int)(32000 * sin(ph
));
481 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));
483 for (i
= 0; i
< 8192; i
++)
485 float value
= atan(sqrt(i
* (4.0 / 8192)));
486 distortion_table
[i
] = ((int)(i
* 2 + 32767 * value
* value
)) >> 1;
491 struct tonewheel_organ_module
*m
= malloc(sizeof(struct tonewheel_organ_module
));
492 CALL_MODULE_INIT(m
, 0, 2, tonewheel_organ
);
493 srate
= m
->module
.srate
;
494 m
->module
.process_event
= tonewheel_organ_process_event
;
495 m
->module
.process_block
= tonewheel_organ_process_block
;
496 cbox_onepole_reset(&m
->filter_anticlick
);
497 cbox_onepole_reset(&m
->filter_overdrive
);
498 cbox_onepole_set_lowpass(&m
->filter_anticlick_coeffs
, hz2w(180.0, srate
));
499 cbox_onepole_set_lowpass(&m
->filter_overdrive_coeffs
, hz2w(2500.0, srate
));
503 m
->vibrato_phase
= 0;
504 read_drawbars(m
->upper_manual_drawbar_settings
, 9, cbox_config_get_string_with_default(cfg_section
, "upper_drawbars", "888000000"));
505 read_drawbars(m
->lower_manual_drawbar_settings
, 9, cbox_config_get_string_with_default(cfg_section
, "lower_drawbars", "888800000"));
506 read_drawbars(m
->pedal_drawbar_settings
, 2, cbox_config_get_string_with_default(cfg_section
, "pedal_drawbars", "82"));
507 m
->enable_percussion
= cbox_config_get_int(cfg_section
, "percussion", 1);
508 m
->enable_vibrato_upper
= cbox_config_get_int(cfg_section
, "vibrato_upper", 1);
509 m
->enable_vibrato_lower
= cbox_config_get_int(cfg_section
, "vibrato_lower", 0);
510 m
->percussion_3rd
= cbox_config_get_int(cfg_section
, "percussion_3rd", 1);
511 m
->vibrato_dphase
= (int)(6.6 / srate
* 65536 * 65536);
513 vibrato_mode
= cbox_config_get_string_with_default(cfg_section
, "vibrato_mode", "c3");
514 if (vibrato_mode
[0] == 'c')
516 else if (vibrato_mode
[0] == 'v')
520 g_error("Unknown vibrato mode: %s (allowed: v1, v2, v3, c1, c2, c3)", vibrato_mode
);
523 if (vibrato_mode
[1] >= '1' && vibrato_mode
[1] <= '3')
524 m
->vibrato_mode
= vibrato_mode
[1] - '1';
527 g_error("Unknown vibrato mode: %s (allowed: v1, v2, v3, c1, c2, c3)", vibrato_mode
);
531 for (i
= 0; i
< 18; i
++)
533 biquad_init(&m
->scanner_delay
[i
]);
535 for (i
= 0; i
< 91; i
++)
537 float freq_hz
= 440 * pow(2.0, (i
- 45) / 12.0);
538 float scaling
= freq_hz
/ 120.0;
542 scaling
= 24 + ((scaling
- 24) / 2.5);
543 m
->frequency
[i
] = (uint32_t)(freq_hz
* 65536 * 65536 / srate
);
545 m
->amp_scaling
[i
] = (int)(1024 * scaling
);
554 struct cbox_module_keyrange_metadata tonewheel_organ_keyranges
[] = {
555 { 0, 24, 35, "Pedal keyboard" },
556 { 1, 36, 36 + 60, "Upper Manual" },
557 { 2, 36, 36 + 60, "Lower Manual" },
560 struct cbox_module_livecontroller_metadata tonewheel_organ_controllers
[] = {
561 { 0, cmlc_onoffcc
, 93, "Vib/Chr", NULL
},
563 { 1, cmlc_continuouscc
, 21, "Upper Drawbar 1", NULL
},
564 { 1, cmlc_continuouscc
, 22, "Upper Drawbar 2", NULL
},
565 { 1, cmlc_continuouscc
, 23, "Upper Drawbar 3", NULL
},
566 { 1, cmlc_continuouscc
, 24, "Upper Drawbar 4", NULL
},
567 { 1, cmlc_continuouscc
, 25, "Upper Drawbar 5", NULL
},
568 { 1, cmlc_continuouscc
, 26, "Upper Drawbar 6", NULL
},
569 { 1, cmlc_continuouscc
, 27, "Upper Drawbar 7", NULL
},
570 { 1, cmlc_continuouscc
, 28, "Upper Drawbar 8", NULL
},
571 { 1, cmlc_continuouscc
, 29, "Upper Drawbar 9", NULL
},
573 { 2, cmlc_continuouscc
, 21, "Lower Drawbar 1", NULL
},
574 { 2, cmlc_continuouscc
, 22, "Lower Drawbar 2", NULL
},
575 { 2, cmlc_continuouscc
, 23, "Lower Drawbar 3", NULL
},
576 { 2, cmlc_continuouscc
, 24, "Lower Drawbar 4", NULL
},
577 { 2, cmlc_continuouscc
, 25, "Lower Drawbar 5", NULL
},
578 { 2, cmlc_continuouscc
, 26, "Lower Drawbar 6", NULL
},
579 { 2, cmlc_continuouscc
, 27, "Lower Drawbar 7", NULL
},
580 { 2, cmlc_continuouscc
, 28, "Lower Drawbar 8", NULL
},
581 { 2, cmlc_continuouscc
, 29, "Lower Drawbar 9", NULL
},
584 DEFINE_MODULE(tonewheel_organ
, 0, 2)