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;
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
)
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;
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);
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)
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)));
156 static inline int tonegenidx_pedals(int note
, int shift
)
158 if (note
< 24 || note
> 24 + 11)
165 static inline int tonegenidx(int note
, int shift
)
167 // ignore everything below the lowest key
173 // harmonic foldback in the first octave of the manual
174 if (note
< 12 && shift
< 12)
177 while (note
+ shift
> 90)
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
)
193 static int compress_amp(int iamp
, int scaling
)
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])
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]));
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];
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
;
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
++)
273 internal_out_for_vibrato
[i
] = 0;
275 // 91 tonewheels + 1 dummy
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
])
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;
319 for (n
= 0; n
< 18; n
++)
321 struct biquad
*bq
= &m
->scanner_delay
[n
];
323 accum
+= (x0
+ (bq
->x1
<< 1) + bq
->x2
) * scanner_a0
;
324 accum
-= bq
->y1
* scanner_b1
;
325 accum
-= bq
->y2
* scanner_b2
;
332 delay
[1 + n
] = x0
= accum
;
334 m
->vibrato_phase
+= m
->vibrato_dphase
;
336 uint32_t vphase
= m
->vibrato_phase
;
337 if (vphase
>= 0x80000000)
339 uint32_t vphint
= vphase
>> 28;
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);
360 if (value
> 8192 * 8 - 2 * 8)
361 value
= 8192 * 8 - 2 * 8;
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
)
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
);
395 if (registration
[i
] < '0' || registration
[i
] > '8')
397 g_error("registration invalid: %s (%c is not in 0..8)", registration
, registration
[i
]);
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; \
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
))
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
]))
428 if (!cbox_execute_on(fb
, NULL
, "/lower_drawbar", "ii", error
, i
, m
->lower_manual_drawbar_settings
[i
]))
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
]))
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
;
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
;
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
)
467 return cbox_object_default_process_cmd(ct
, fb
, cmd
, error
);
471 MODULE_CREATE_FUNCTION(tonewheel_organ
)
473 static int inited
= 0;
475 const char *vibrato_mode
;
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;
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
));
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')
517 else if (vibrato_mode
[0] == 'v')
521 g_error("Unknown vibrato mode: %s (allowed: v1, v2, v3, c1, c2, c3)", vibrato_mode
);
524 if (vibrato_mode
[1] >= '1' && vibrato_mode
[1] <= '3')
525 m
->vibrato_mode
= vibrato_mode
[1] - '1';
528 g_error("Unknown vibrato mode: %s (allowed: v1, v2, v3, c1, c2, c3)", vibrato_mode
);
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;
543 scaling
= 24 + ((scaling
- 24) / 2.5);
544 m
->frequency
[i
] = (uint32_t)(freq_hz
* 65536 * 65536 / srate
);
546 m
->amp_scaling
[i
] = (int)(1024 * scaling
);
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)