Merge pull request #1 from atsampson/master
[calfbox.git] / scene.c
blob9f450b723aa884723bf60652760dd5d5f707b34a
1 /*
2 Calf Box, an open source musical instrument.
3 Copyright (C) 2010-2011 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 "auxbus.h"
20 #include "config-api.h"
21 #include "engine.h"
22 #include "errors.h"
23 #include "instr.h"
24 #include "io.h"
25 #include "layer.h"
26 #include "master.h"
27 #include "midi.h"
28 #include "module.h"
29 #include "pattern.h"
30 #include "rt.h"
31 #include "scene.h"
32 #include "seq.h"
33 #include <assert.h>
34 #include <glib.h>
36 CBOX_CLASS_DEFINITION_ROOT(cbox_scene)
38 static gboolean cbox_scene_addlayercmd(struct cbox_scene *s, struct cbox_command_target *fb, struct cbox_osc_command *cmd, int cmd_type, GError **error)
40 int pos = CBOX_ARG_I(cmd, 0);
41 if (pos < 0 || pos > 1 + s->layer_count)
43 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Invalid position %d (valid are 1..%d or 0 for append)", pos, 1 + s->layer_count);
44 return FALSE;
46 if (pos == 0)
47 pos = s->layer_count;
48 else
49 pos--;
50 struct cbox_layer *layer = NULL;
52 switch(cmd_type)
54 case 1:
55 layer = cbox_layer_new_from_config(s, CBOX_ARG_S(cmd, 1), error);
56 break;
57 case 2:
58 layer = cbox_layer_new_with_instrument(s, CBOX_ARG_S(cmd, 1), error);
59 break;
60 case 3:
62 struct cbox_instrument *instr = cbox_scene_create_instrument(s, CBOX_ARG_S(cmd, 1), CBOX_ARG_S(cmd, 2), error);
63 if (!instr)
64 return FALSE;
65 layer = cbox_layer_new_with_instrument(s, CBOX_ARG_S(cmd, 1), error);
66 break;
68 default:
69 assert(0);
70 break;
72 if (!layer)
73 return FALSE;
74 if (!cbox_scene_insert_layer(s, layer, pos, error))
76 CBOX_DELETE(layer);
77 return FALSE;
79 if (fb)
81 if (!cbox_execute_on(fb, NULL, "/uuid", "o", error, layer))
82 return FALSE;
84 return TRUE;
87 static gboolean cbox_scene_process_cmd(struct cbox_command_target *ct, struct cbox_command_target *fb, struct cbox_osc_command *cmd, GError **error)
89 struct cbox_scene *s = ct->user_data;
90 const char *subcommand = NULL;
91 char *subobj = NULL;
92 int index = 0;
94 if (!strcmp(cmd->command, "/transpose") && !strcmp(cmd->arg_types, "i"))
96 s->transpose = CBOX_ARG_I(cmd, 0);
97 return TRUE;
99 else if (!strcmp(cmd->command, "/load") && !strcmp(cmd->arg_types, "s"))
101 if (!cbox_scene_load(s, CBOX_ARG_S(cmd, 0), error))
102 return FALSE;
103 return TRUE;
105 else if (!strcmp(cmd->command, "/clear") && !strcmp(cmd->arg_types, ""))
107 cbox_scene_clear(s);
108 return TRUE;
110 else if (!strcmp(cmd->command, "/add_layer") && !strcmp(cmd->arg_types, "is"))
112 return cbox_scene_addlayercmd(s, fb, cmd, 1, error);
114 else if (!strcmp(cmd->command, "/add_instrument_layer") && !strcmp(cmd->arg_types, "is"))
116 return cbox_scene_addlayercmd(s, fb, cmd, 2, error);
118 else if (!strcmp(cmd->command, "/add_new_instrument_layer") && !strcmp(cmd->arg_types, "iss"))
120 return cbox_scene_addlayercmd(s, fb, cmd, 3, error);
122 else if (!strcmp(cmd->command, "/delete_layer") && !strcmp(cmd->arg_types, "i"))
124 int pos = CBOX_ARG_I(cmd, 0);
125 if (pos < 0 || pos > s->layer_count)
127 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Invalid position %d (valid are 1..%d or 0 for last)", pos, s->layer_count);
128 return FALSE;
130 if (pos == 0)
131 pos = s->layer_count - 1;
132 else
133 pos--;
134 struct cbox_layer *layer = cbox_scene_remove_layer(s, pos);
135 CBOX_DELETE(layer);
136 return TRUE;
138 else if (!strcmp(cmd->command, "/move_layer") && !strcmp(cmd->arg_types, "ii"))
140 int oldpos = CBOX_ARG_I(cmd, 0);
141 if (oldpos < 1 || oldpos > s->layer_count)
143 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Invalid position %d (valid are 1..%d)", oldpos, s->layer_count);
144 return FALSE;
146 int newpos = CBOX_ARG_I(cmd, 1);
147 if (newpos < 1 || newpos > s->layer_count)
149 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Invalid position %d (valid are 1..%d)", newpos, s->layer_count);
150 return FALSE;
152 cbox_scene_move_layer(s, oldpos - 1, newpos - 1);
153 return TRUE;
155 else if (cbox_parse_path_part_int(cmd, "/layer/", &subcommand, &index, 1, s->layer_count, error))
157 if (!subcommand)
158 return FALSE;
159 return cbox_execute_sub(&s->layers[index - 1]->cmd_target, fb, cmd, subcommand, error);
161 else if (cbox_parse_path_part_str(cmd, "/aux/", &subcommand, &subobj, error))
163 if (!subcommand)
164 return FALSE;
165 struct cbox_aux_bus *aux = cbox_scene_get_aux_bus(s, subobj, FALSE, error);
166 g_free(subobj);
167 if (!aux)
168 return FALSE;
169 return cbox_execute_sub(&aux->cmd_target, fb, cmd, subcommand, error);
171 else if (!strncmp(cmd->command, "/instr/", 7))
173 const char *obj = &cmd->command[1];
174 const char *pos = strchr(obj, '/');
175 obj = &pos[1];
176 pos = strchr(obj, '/');
177 if (!pos)
179 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Invalid instrument path '%s'", cmd->command);
180 return FALSE;
182 int len = pos - obj;
184 gchar *name = g_strndup(obj, len);
185 struct cbox_instrument *instr = cbox_scene_get_instrument_by_name(s, name, FALSE, error);
186 if (instr)
188 g_free(name);
190 return cbox_execute_sub(&instr->cmd_target, fb, cmd, pos, error);
192 else
194 cbox_force_error(error);
195 g_prefix_error(error, "Cannot access instrument '%s': ", name);
196 g_free(name);
197 return FALSE;
199 return TRUE;
201 else if (!strcmp(cmd->command, "/load_aux") && !strcmp(cmd->arg_types, "s"))
203 struct cbox_aux_bus *bus = cbox_scene_get_aux_bus(s, CBOX_ARG_S(cmd, 0), TRUE, error);
204 if (!bus)
205 return FALSE;
206 if (fb)
208 if (!cbox_execute_on(fb, NULL, "/uuid", "o", error, bus))
209 return FALSE;
211 return TRUE;
213 else if (!strcmp(cmd->command, "/delete_aux") && !strcmp(cmd->arg_types, "s"))
215 const char *name = CBOX_ARG_S(cmd, 0);
216 struct cbox_aux_bus *aux = cbox_scene_get_aux_bus(s, name, FALSE, error);
217 if (!aux)
218 return FALSE;
219 CBOX_DELETE(aux);
220 return TRUE;
222 else if (!strcmp(cmd->command, "/status") && !strcmp(cmd->arg_types, ""))
224 if (!cbox_check_fb_channel(fb, cmd->command, error))
225 return FALSE;
227 if (!cbox_execute_on(fb, NULL, "/name", "s", error, s->name) ||
228 !cbox_execute_on(fb, NULL, "/title", "s", error, s->title) ||
229 !cbox_execute_on(fb, NULL, "/transpose", "i", error, s->transpose) ||
230 !cbox_execute_on(fb, NULL, "/enable_default_song_input", "i", error, s->enable_default_song_input) ||
231 !cbox_execute_on(fb, NULL, "/enable_default_external_input", "i", error, s->enable_default_external_input) ||
232 !CBOX_OBJECT_DEFAULT_STATUS(s, fb, error))
233 return FALSE;
235 for (int i = 0; i < s->layer_count; i++)
237 if (!cbox_execute_on(fb, NULL, "/layer", "o", error, s->layers[i]))
238 return FALSE;
240 for (int i = 0; i < s->instrument_count; i++)
242 if (!cbox_execute_on(fb, NULL, "/instrument", "sso", error, s->instruments[i]->module->instance_name, s->instruments[i]->module->engine_name, s->instruments[i]))
243 return FALSE;
245 for (int i = 0; i < s->aux_bus_count; i++)
247 if (!cbox_execute_on(fb, NULL, "/aux", "so", error, s->aux_buses[i]->name, s->aux_buses[i]))
248 return FALSE;
250 return TRUE;
252 else
253 if (!strcmp(cmd->command, "/send_event") && (!strcmp(cmd->arg_types, "iii") || !strcmp(cmd->arg_types, "ii") || !strcmp(cmd->arg_types, "i")))
255 int mcmd = CBOX_ARG_I(cmd, 0);
256 int arg1 = 0, arg2 = 0;
257 if (cmd->arg_types[1] == 'i')
259 arg1 = CBOX_ARG_I(cmd, 1);
260 if (cmd->arg_types[2] == 'i')
261 arg2 = CBOX_ARG_I(cmd, 2);
263 struct cbox_midi_buffer buf;
264 cbox_midi_buffer_init(&buf);
265 cbox_midi_buffer_write_inline(&buf, 0, mcmd, arg1, arg2);
266 cbox_midi_merger_push(&s->scene_input_merger, &buf, s->rt);
267 return TRUE;
269 else
270 if (!strcmp(cmd->command, "/play_note") && !strcmp(cmd->arg_types, "iii"))
272 int channel = CBOX_ARG_I(cmd, 0);
273 int note = CBOX_ARG_I(cmd, 1);
274 int velocity = CBOX_ARG_I(cmd, 2);
275 struct cbox_midi_buffer buf;
276 cbox_midi_buffer_init(&buf);
277 cbox_midi_buffer_write_inline(&buf, 0, 0x90 + ((channel - 1) & 15), note & 127, velocity & 127);
278 cbox_midi_buffer_write_inline(&buf, 1, 0x80 + ((channel - 1) & 15), note & 127, velocity & 127);
279 cbox_midi_merger_push(&s->scene_input_merger, &buf, s->rt);
280 return TRUE;
282 else
283 if (!strcmp(cmd->command, "/play_pattern") && !strcmp(cmd->arg_types, "sfi"))
285 struct cbox_midi_pattern *pattern = (struct cbox_midi_pattern *)CBOX_ARG_O(cmd, 0, s, cbox_midi_pattern, error);
286 if (!pattern)
287 return FALSE;
289 struct cbox_adhoc_pattern *ap = cbox_adhoc_pattern_new(s->engine, CBOX_ARG_I(cmd, 2), pattern);
290 ap->master->tempo = ap->master->new_tempo = CBOX_ARG_F(cmd, 1);
291 cbox_scene_play_adhoc_pattern(s, ap);
292 return TRUE;
294 else
295 if (!strcmp(cmd->command, "/enable_default_song_input") && !strcmp(cmd->arg_types, "i"))
297 s->enable_default_song_input = CBOX_ARG_I(cmd, 0);
298 return TRUE;
300 else
301 if (!strcmp(cmd->command, "/enable_default_external_input") && !strcmp(cmd->arg_types, "i"))
303 s->enable_default_external_input = CBOX_ARG_I(cmd, 0);
304 return TRUE;
306 else
307 return cbox_object_default_process_cmd(ct, fb, cmd, error);
310 gboolean cbox_scene_load(struct cbox_scene *s, const char *name, GError **error)
312 const char *cv = NULL;
313 int i;
314 gchar *section = g_strdup_printf("scene:%s", name);
316 if (!cbox_config_has_section(section))
318 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "No config section for scene '%s'", name);
319 goto error;
322 cbox_scene_clear(s);
324 assert(s->layers == NULL);
325 assert(s->instruments == NULL);
326 assert(s->aux_buses == NULL);
327 assert(s->layer_count == 0);
328 assert(s->instrument_count == 0);
329 assert(s->aux_bus_count == 0);
331 for (i = 1; ; i++)
333 struct cbox_layer *l = NULL;
335 gchar *sn = g_strdup_printf("layer%d", i);
336 cv = cbox_config_get_string(section, sn);
337 g_free(sn);
339 if (!cv)
340 break;
342 l = cbox_layer_new_from_config(s, cv, error);
343 if (!l)
344 goto error;
346 if (!cbox_scene_add_layer(s, l, error))
347 goto error;
350 s->transpose = cbox_config_get_int(section, "transpose", 0);
351 s->title = g_strdup(cbox_config_get_string_with_default(section, "title", ""));
352 g_free(section);
353 cbox_command_target_init(&s->cmd_target, cbox_scene_process_cmd, s);
354 s->name = g_strdup(name);
355 return TRUE;
357 error:
358 g_free(section);
359 return FALSE;
362 gboolean cbox_scene_insert_layer(struct cbox_scene *scene, struct cbox_layer *layer, int pos, GError **error)
364 int i;
366 struct cbox_instrument *instrument = layer->instrument;
367 for (i = 0; i < instrument->aux_output_count; i++)
369 assert(!instrument->aux_outputs[i]);
370 if (instrument->aux_output_names[i])
372 instrument->aux_outputs[i] = cbox_scene_get_aux_bus(scene, instrument->aux_output_names[i], TRUE, error);
373 if (!instrument->aux_outputs[i])
374 return FALSE;
375 cbox_aux_bus_ref(instrument->aux_outputs[i]);
378 for (i = 0; i < scene->layer_count; i++)
380 if (scene->layers[i]->instrument == layer->instrument)
381 break;
383 if (i == scene->layer_count)
385 layer->instrument->scene = scene;
386 cbox_rt_array_insert(scene->rt, (void ***)&scene->instruments, &scene->instrument_count, -1, layer->instrument);
388 cbox_rt_array_insert(scene->rt, (void ***)&scene->layers, &scene->layer_count, pos, layer);
390 return TRUE;
393 gboolean cbox_scene_add_layer(struct cbox_scene *scene, struct cbox_layer *layer, GError **error)
395 return cbox_scene_insert_layer(scene, layer, scene->layer_count, error);
398 struct cbox_layer *cbox_scene_remove_layer(struct cbox_scene *scene, int pos)
400 struct cbox_layer *removed = scene->layers[pos];
401 cbox_rt_array_remove(scene->rt, (void ***)&scene->layers, &scene->layer_count, pos);
402 cbox_instrument_unref_aux_buses(removed->instrument);
404 return removed;
407 void cbox_scene_move_layer(struct cbox_scene *scene, int oldpos, int newpos)
409 if (oldpos == newpos)
410 return;
411 struct cbox_layer **layers = malloc(sizeof(struct cbox_layer *) * scene->layer_count);
412 for (int i = 0; i < scene->layer_count; i++)
414 int s;
415 if (i == newpos)
416 s = oldpos;
417 else
419 if (oldpos < newpos)
420 s = (i < oldpos || i > newpos) ? i : i + 1;
421 else
422 s = (i < newpos || i > oldpos) ? i : i - 1;
424 layers[i] = scene->layers[s];
426 free(cbox_rt_swap_pointers(scene->rt, (void **)&scene->layers, layers));
429 gboolean cbox_scene_remove_instrument(struct cbox_scene *scene, struct cbox_instrument *instrument)
431 assert(instrument->scene == scene);
432 int pos;
433 for (pos = 0; pos < scene->instrument_count; pos++)
435 if (scene->instruments[pos] == instrument)
437 cbox_rt_array_remove(scene->rt, (void ***)&scene->instruments, &scene->instrument_count, pos);
438 g_hash_table_remove(scene->instrument_hash, instrument->module->instance_name);
439 instrument->scene = NULL;
440 return TRUE;
443 return FALSE;
446 gboolean cbox_scene_insert_aux_bus(struct cbox_scene *scene, struct cbox_aux_bus *aux_bus)
448 struct cbox_aux_bus **aux_buses = malloc(sizeof(struct cbox_aux_bus *) * (scene->aux_bus_count + 1));
449 memcpy(aux_buses, scene->aux_buses, sizeof(struct cbox_aux_bus *) * (scene->aux_bus_count));
450 aux_buses[scene->aux_bus_count] = aux_bus;
451 free(cbox_rt_swap_pointers_and_update_count(scene->rt, (void **)&scene->aux_buses, aux_buses, &scene->aux_bus_count, scene->aux_bus_count + 1));
452 return TRUE;
455 void cbox_scene_remove_aux_bus(struct cbox_scene *scene, struct cbox_aux_bus *removed)
457 int pos = -1;
458 for (int i = 0; i < scene->aux_bus_count; i++)
460 if (scene->aux_buses[i] == removed)
462 pos = i;
463 break;
466 assert(pos != -1);
467 for (int i = 0; i < scene->instrument_count; i++)
468 cbox_instrument_disconnect_aux_bus(scene->instruments[i], removed);
470 struct cbox_aux_bus **aux_buses = malloc(sizeof(struct cbox_aux_bus *) * (scene->aux_bus_count - 1));
471 memcpy(aux_buses, scene->aux_buses, sizeof(struct cbox_aux_bus *) * pos);
472 memcpy(aux_buses + pos, scene->aux_buses + pos + 1, sizeof(struct cbox_aux_bus *) * (scene->aux_bus_count - pos - 1));
473 free(cbox_rt_swap_pointers_and_update_count(scene->rt, (void **)&scene->aux_buses, aux_buses, &scene->aux_bus_count, scene->aux_bus_count - 1));
476 struct cbox_aux_bus *cbox_scene_get_aux_bus(struct cbox_scene *scene, const char *name, int allow_load, GError **error)
478 for (int i = 0; i < scene->aux_bus_count; i++)
480 if (!strcmp(scene->aux_buses[i]->name, name))
482 return scene->aux_buses[i];
485 if (!allow_load)
487 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Aux bus not found: %s", name);
488 return FALSE;
490 struct cbox_aux_bus *bus = cbox_aux_bus_load(scene, name, scene->rt, error);
491 if (!bus)
492 return NULL;
493 return bus;
496 static int write_events_to_instrument_ports(struct cbox_scene *scene, struct cbox_midi_buffer *source)
498 uint32_t i;
500 for (i = 0; i < scene->instrument_count; i++)
501 cbox_midi_buffer_clear(&scene->instruments[i]->module->midi_input);
503 if (!source)
504 return 0;
506 uint32_t event_count = cbox_midi_buffer_get_count(source);
507 for (i = 0; i < event_count; i++)
509 const struct cbox_midi_event *event = cbox_midi_buffer_get_event(source, i);
511 // XXXKF ignore sysex for now
512 if (event->size >= 4)
513 continue;
515 for (int l = 0; l < scene->layer_count; l++)
517 struct cbox_layer *lp = scene->layers[l];
518 if (!lp->enabled)
519 continue;
520 uint8_t data[4] = {0, 0, 0, 0};
521 memcpy(data, event->data_inline, event->size);
522 if (data[0] < 0xF0) // per-channel messages
524 int cmd = data[0] >> 4;
525 // filter on MIDI channel
526 if (lp->in_channel >= 0 && lp->in_channel != (data[0] & 0x0F))
527 continue;
528 // force output channel
529 if (lp->out_channel >= 0)
530 data[0] = (data[0] & 0xF0) + (lp->out_channel & 0x0F);
531 if (cmd >= 8 && cmd <= 10)
533 if (cmd == 10 && lp->disable_aftertouch)
534 continue;
535 // note filter
536 if (data[1] < lp->low_note || data[1] > lp->high_note)
537 continue;
538 // transpose
539 int transpose = lp->transpose + (lp->ignore_scene_transpose ? 0 : scene->transpose);
540 if (transpose)
542 int note = data[1] + transpose;
543 if (note < 0 || note > 127)
544 continue;
545 data[1] = (uint8_t)note;
547 // fixed note
548 if (lp->fixed_note != -1)
550 data[1] = (uint8_t)lp->fixed_note;
553 else if (cmd == 11 && data[1] == 64 && lp->invert_sustain)
555 data[2] = 127 - data[2];
557 else if (lp->ignore_program_changes && cmd == 11 && (data[1] == 0 || data[1] == 32))
558 continue;
559 else if (cmd == 13 && lp->disable_aftertouch)
560 continue;
561 else if (cmd == 12 && lp->ignore_program_changes)
562 continue;
564 if (!cbox_midi_buffer_write_event(&lp->instrument->module->midi_input, event->time, data, event->size))
565 return -i;
566 if (lp->consume)
567 break;
571 return event_count;
574 void cbox_scene_render(struct cbox_scene *scene, uint32_t nframes, float *output_buffers[])
576 int n, i, j;
578 if (scene->rt && scene->rt->io)
580 struct cbox_io *io = scene->rt->io;
581 for (i = 0; i < io->io_env.input_count; i++)
583 if (IS_RECORDING_SOURCE_CONNECTED(scene->rec_mono_inputs[i]))
584 cbox_recording_source_push(&scene->rec_mono_inputs[i], (const float **)&io->input_buffers[i], nframes);
586 for (i = 0; i < io->io_env.input_count / 2; i++)
588 if (IS_RECORDING_SOURCE_CONNECTED(scene->rec_stereo_inputs[i]))
590 const float *buf[2] = { io->input_buffers[i * 2], io->input_buffers[i * 2 + 1] };
591 cbox_recording_source_push(&scene->rec_stereo_inputs[i], buf, nframes);
596 for(struct cbox_adhoc_pattern **ppat = &scene->adhoc_patterns; *ppat; )
598 cbox_midi_buffer_clear(&(*ppat)->output_buffer);
599 if ((*ppat)->completed)
601 struct cbox_adhoc_pattern *retired = *ppat;
602 *ppat = retired->next;
603 retired->next = scene->retired_adhoc_patterns;
604 scene->retired_adhoc_patterns = retired;
606 else
608 cbox_adhoc_pattern_render((*ppat), 0, nframes);
609 ppat = &((*ppat)->next);
613 // XXXKF implement full cleanup, not only the front of the queue
614 if(scene->adhoc_patterns && scene->adhoc_patterns->completed)
616 struct cbox_adhoc_pattern *top = scene->adhoc_patterns;
617 cbox_midi_buffer_clear(&top->output_buffer);
618 scene->adhoc_patterns = top->next;
622 cbox_midi_buffer_clear(&scene->midibuf_total);
623 cbox_midi_merger_render(&scene->scene_input_merger);
625 write_events_to_instrument_ports(scene, &scene->midibuf_total);
627 for (n = 0; n < scene->aux_bus_count; n++)
629 for (i = 0; i < nframes; i ++)
631 scene->aux_buses[n]->input_bufs[0][i] = 0.f;
632 scene->aux_buses[n]->input_bufs[1][i] = 0.f;
636 for (n = 0; n < scene->instrument_count; n++)
638 struct cbox_instrument *instr = scene->instruments[n];
639 struct cbox_module *module = instr->module;
640 int event_count = instr->module->midi_input.count;
641 int cur_event = 0;
642 uint32_t highwatermark = 0;
643 cbox_sample_t channels[CBOX_MAX_AUDIO_PORTS][CBOX_BLOCK_SIZE];
644 cbox_sample_t *outputs[CBOX_MAX_AUDIO_PORTS];
645 for (i = 0; i < module->outputs; i++)
646 outputs[i] = channels[i];
648 for (i = 0; i < nframes; i += CBOX_BLOCK_SIZE)
650 if (i >= highwatermark)
652 while(cur_event < event_count)
654 const struct cbox_midi_event *event = cbox_midi_buffer_get_event(&module->midi_input, cur_event);
655 if (event)
657 if (event->time <= i)
658 (*module->process_event)(module, cbox_midi_event_get_data(event), event->size);
659 else
661 highwatermark = event->time;
662 break;
665 else
666 break;
668 cur_event++;
671 (*module->process_block)(module, NULL, outputs);
672 for (int o = 0; o < module->outputs / 2; o++)
674 struct cbox_instrument_output *oobj = &instr->outputs[o];
675 struct cbox_module *insert = oobj->insert;
676 float gain = oobj->gain;
677 if (IS_RECORDING_SOURCE_CONNECTED(oobj->rec_dry))
678 cbox_recording_source_push(&oobj->rec_dry, (const float **)(outputs + 2 * o), CBOX_BLOCK_SIZE);
679 if (insert && !insert->bypass)
680 (*insert->process_block)(insert, outputs + 2 * o, outputs + 2 * o);
681 if (IS_RECORDING_SOURCE_CONNECTED(oobj->rec_wet))
682 cbox_recording_source_push(&oobj->rec_wet, (const float **)(outputs + 2 * o), CBOX_BLOCK_SIZE);
683 float *leftbuf, *rightbuf;
684 if (o < module->aux_offset / 2)
686 int leftch = oobj->output_bus * 2;
687 int rightch = leftch + 1;
688 leftbuf = output_buffers[leftch];
689 rightbuf = output_buffers[rightch];
691 else
693 int bus = o - module->aux_offset / 2;
694 struct cbox_aux_bus *busobj = instr->aux_outputs[bus];
695 if (busobj == NULL)
696 continue;
697 leftbuf = busobj->input_bufs[0];
698 rightbuf = busobj->input_bufs[1];
700 if (leftbuf && rightbuf)
702 for (j = 0; j < CBOX_BLOCK_SIZE; j++)
704 leftbuf[i + j] += gain * channels[2 * o][j];
705 rightbuf[i + j] += gain * channels[2 * o + 1][j];
708 else
710 for (j = 0; j < CBOX_BLOCK_SIZE; j++)
712 if (leftbuf)
713 leftbuf[i + j] += gain * channels[2 * o][j];
714 if (rightbuf)
715 rightbuf[i + j] += gain * channels[2 * o + 1][j];
720 while(cur_event < event_count)
722 const struct cbox_midi_event *event = cbox_midi_buffer_get_event(&module->midi_input, cur_event);
723 if (event)
725 (*module->process_event)(module, cbox_midi_event_get_data(event), event->size);
727 else
728 break;
730 cur_event++;
734 for (n = 0; n < scene->aux_bus_count; n++)
736 struct cbox_aux_bus *bus = scene->aux_buses[n];
737 float left[CBOX_BLOCK_SIZE], right[CBOX_BLOCK_SIZE];
738 float *outputs[2] = {left, right};
739 for (i = 0; i < nframes; i += CBOX_BLOCK_SIZE)
741 float *inputs[2];
742 inputs[0] = &bus->input_bufs[0][i];
743 inputs[1] = &bus->input_bufs[1][i];
744 bus->module->process_block(bus->module, inputs, outputs);
745 for (int j = 0; j < CBOX_BLOCK_SIZE; j++)
747 output_buffers[0][i + j] += left[j];
748 output_buffers[1][i + j] += right[j];
753 int output_count = scene->engine->io_env.output_count;
754 // XXXKF this assumes that the buffers are zeroed on start - which isn't true if there are multiple scenes
755 for (i = 0; i < output_count; i++)
757 if (IS_RECORDING_SOURCE_CONNECTED(scene->rec_mono_outputs[i]))
758 cbox_recording_source_push(&scene->rec_mono_outputs[i], (const float **)&output_buffers[i], nframes);
760 for (i = 0; i < output_count / 2; i++)
762 if (IS_RECORDING_SOURCE_CONNECTED(scene->rec_stereo_outputs[i]))
764 const float *buf[2] = { output_buffers[i * 2], output_buffers[i * 2 + 1] };
765 cbox_recording_source_push(&scene->rec_stereo_outputs[i], buf, nframes);
770 void cbox_scene_clear(struct cbox_scene *scene)
772 g_free(scene->name);
773 g_free(scene->title);
774 scene->name = g_strdup("");
775 scene->title = g_strdup("");
776 while(scene->layer_count > 0)
778 struct cbox_layer *layer = cbox_scene_remove_layer(scene, 0);
779 CBOX_DELETE(layer);
782 while(scene->aux_bus_count > 0)
783 CBOX_DELETE(scene->aux_buses[scene->aux_bus_count - 1]);
786 static struct cbox_instrument *create_instrument(struct cbox_scene *scene, struct cbox_module *module)
788 int auxes = (module->outputs - module->aux_offset) / 2;
790 struct cbox_instrument *instr = malloc(sizeof(struct cbox_instrument));
791 CBOX_OBJECT_HEADER_INIT(instr, cbox_instrument, CBOX_GET_DOCUMENT(scene));
792 instr->scene = scene;
793 instr->module = module;
794 instr->outputs = calloc(module->outputs / 2, sizeof(struct cbox_instrument_output));
795 instr->refcount = 0;
796 instr->aux_outputs = calloc(auxes, sizeof(struct cbox_aux_bus *));
797 instr->aux_output_names = calloc(auxes, sizeof(char *));
798 instr->aux_output_count = auxes;
800 for (int i = 0; i < module->outputs / 2; i ++)
801 cbox_instrument_output_init(&instr->outputs[i], scene, module->engine->io_env.buffer_size);
803 return instr;
806 struct cbox_instrument *cbox_scene_create_instrument(struct cbox_scene *scene, const char *instrument_name, const char *engine_name, GError **error)
808 gpointer value = g_hash_table_lookup(scene->instrument_hash, instrument_name);
809 if (value)
811 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Instrument already exists: '%s'", instrument_name);
812 return NULL;
815 struct cbox_document *doc = CBOX_GET_DOCUMENT(scene);
816 struct cbox_module_manifest *mptr = NULL;
817 struct cbox_instrument *instr = NULL;
818 struct cbox_module *module = NULL;
820 mptr = cbox_module_manifest_get_by_name(engine_name);
821 if (!mptr)
823 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "No engine called '%s'", engine_name);
824 return NULL;
827 module = cbox_module_manifest_create_module(mptr, NULL, doc, scene->rt, scene->engine, instrument_name, error);
828 if (!module)
830 cbox_force_error(error);
831 g_prefix_error(error, "Cannot create engine '%s' for instrument '%s': ", engine_name, instrument_name);
832 return NULL;
835 instr = create_instrument(scene, module);
837 cbox_command_target_init(&instr->cmd_target, cbox_instrument_process_cmd, instr);
838 g_hash_table_insert(scene->instrument_hash, g_strdup(instrument_name), instr);
839 CBOX_OBJECT_REGISTER(instr);
841 return instr;
844 struct cbox_instrument *cbox_scene_get_instrument_by_name(struct cbox_scene *scene, const char *name, gboolean load, GError **error)
846 struct cbox_module_manifest *mptr = NULL;
847 struct cbox_instrument *instr = NULL;
848 struct cbox_module *module = NULL;
849 gchar *instr_section = NULL;
850 gpointer value = g_hash_table_lookup(scene->instrument_hash, name);
851 const char *cv, *instr_engine;
852 struct cbox_document *doc = CBOX_GET_DOCUMENT(scene);
853 assert(scene);
855 if (value)
856 return value;
857 if (!load)
858 return NULL;
860 instr_section = g_strdup_printf("instrument:%s", name);
862 if (!cbox_config_has_section(instr_section))
864 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "No config section for instrument '%s'", name);
865 goto error;
868 instr_engine = cbox_config_get_string(instr_section, "engine");
869 if (!instr_engine)
871 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Engine not specified in instrument '%s'", name);
872 goto error;
875 mptr = cbox_module_manifest_get_by_name(instr_engine);
876 if (!mptr)
878 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "No engine called '%s'", instr_engine);
879 goto error;
882 // cbox_module_manifest_dump(mptr);
884 module = cbox_module_manifest_create_module(mptr, instr_section, doc, scene->rt, scene->engine, name, error);
885 if (!module)
887 cbox_force_error(error);
888 g_prefix_error(error, "Cannot create engine '%s' for instrument '%s': ", instr_engine, name);
889 goto error;
892 instr = create_instrument(scene, module);
894 for (int i = 0; i < module->outputs / 2; i ++)
896 struct cbox_instrument_output *oobj = instr->outputs + i;
898 gchar *key = i == 0 ? g_strdup("output_bus") : g_strdup_printf("output%d_bus", 1 + i);
899 oobj->output_bus = cbox_config_get_int(instr_section, key, 1) - 1;
900 g_free(key);
901 key = i == 0 ? g_strdup("gain") : g_strdup_printf("gain%d", 1 + i);
902 oobj->gain = cbox_config_get_gain_db(instr_section, key, 0);
903 g_free(key);
905 key = i == 0 ? g_strdup("insert") : g_strdup_printf("insert%d", 1 + i);
906 cv = cbox_config_get_string(instr_section, key);
907 g_free(key);
909 if (cv)
911 oobj->insert = cbox_module_new_from_fx_preset(cv, CBOX_GET_DOCUMENT(scene), module->rt, scene->engine, error);
912 if (!oobj->insert)
914 cbox_force_error(error);
915 g_prefix_error(error, "Cannot instantiate effect preset '%s' for instrument '%s': ", cv, name);
920 for (int i = 0; i < instr->aux_output_count; i++)
922 instr->aux_outputs[i] = NULL;
924 gchar *key = g_strdup_printf("aux%d", 1 + i);
925 gchar *value = cbox_config_get_string(instr_section, key);
926 instr->aux_output_names[i] = value ? g_strdup(value) : NULL;
927 g_free(key);
930 cbox_command_target_init(&instr->cmd_target, cbox_instrument_process_cmd, instr);
932 free(instr_section);
934 g_hash_table_insert(scene->instrument_hash, g_strdup(name), instr);
935 CBOX_OBJECT_REGISTER(instr);
937 // cbox_recording_source_attach(&instr->outputs[0].rec_dry, cbox_recorder_new_stream("output.wav"));
939 return instr;
941 error:
942 free(instr_section);
943 return NULL;
946 static struct cbox_recording_source *create_rec_sources(struct cbox_scene *scene, int buffer_size, int count, int channels)
948 struct cbox_recording_source *s = malloc(sizeof(struct cbox_recording_source) * count);
949 for (int i = 0; i < count; i++)
950 cbox_recording_source_init(&s[i], scene, buffer_size, channels);
951 return s;
954 static void destroy_rec_sources(struct cbox_recording_source *s, int count)
956 for (int i = 0; i < count; i++)
957 cbox_recording_source_uninit(&s[i]);
958 free(s);
961 struct cbox_scene *cbox_scene_new(struct cbox_document *document, struct cbox_engine *engine)
963 struct cbox_scene *s = malloc(sizeof(struct cbox_scene));
964 if (!s)
965 return NULL;
967 CBOX_OBJECT_HEADER_INIT(s, cbox_scene, document);
968 s->engine = engine;
969 s->rt = engine ? engine->rt : NULL;
970 s->instrument_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
971 s->name = g_strdup("");
972 s->title = g_strdup("");
973 s->layers = NULL;
974 s->aux_buses = NULL;
975 s->instruments = NULL;
976 s->layer_count = 0;
977 s->instrument_count = 0;
978 s->aux_bus_count = 0;
979 cbox_command_target_init(&s->cmd_target, cbox_scene_process_cmd, s);
980 s->transpose = 0;
981 s->connected_inputs = NULL;
982 s->connected_input_count = 0;
983 s->enable_default_song_input = TRUE;
984 s->enable_default_external_input = TRUE;
986 cbox_midi_buffer_init(&s->midibuf_total);
987 cbox_midi_merger_init(&s->scene_input_merger, &s->midibuf_total);
989 int buffer_size = engine->io_env.buffer_size;
990 s->rec_mono_inputs = create_rec_sources(s, buffer_size, engine->io_env.input_count, 1);
991 s->rec_stereo_inputs = create_rec_sources(s, buffer_size, engine->io_env.input_count / 2, 2);
992 s->rec_mono_outputs = create_rec_sources(s, buffer_size, engine->io_env.output_count, 1);
993 s->rec_stereo_outputs = create_rec_sources(s, buffer_size, engine->io_env.output_count / 2, 2);
994 s->adhoc_patterns = NULL;
995 s->retired_adhoc_patterns = NULL;
997 CBOX_OBJECT_REGISTER(s);
999 cbox_engine_add_scene(s->engine, s);
1000 cbox_scene_update_connected_inputs(s);
1001 return s;
1004 void cbox_scene_update_connected_inputs(struct cbox_scene *scene)
1006 if (!scene->rt || !scene->rt->io)
1007 return;
1009 // This is called when a MIDI Input port has been created, connected/disconnected
1010 // or is about to be removed (and then the removing flag will be set)
1011 for (int i = 0; i < scene->connected_input_count; )
1013 struct cbox_midi_input *input = scene->connected_inputs[i];
1014 if (input->removing || !cbox_uuid_equal(&input->output, &scene->_obj_hdr.instance_uuid))
1016 cbox_midi_merger_disconnect(&scene->scene_input_merger, &input->buffer, scene->rt);
1017 cbox_rt_array_remove(scene->rt, (void ***)&scene->connected_inputs, &scene->connected_input_count, i);
1019 else
1020 i++;
1022 for (GSList *p = scene->rt->io->midi_inputs; p; p = p->next)
1024 struct cbox_midi_input *input = p->data;
1025 if (cbox_uuid_equal(&input->output, &scene->_obj_hdr.instance_uuid))
1027 gboolean found = FALSE;
1028 for (int i = 0; i < scene->connected_input_count; i++)
1030 if (scene->connected_inputs[i] == input)
1032 found = TRUE;
1033 break;
1036 if (!found)
1038 cbox_midi_merger_connect(&scene->scene_input_merger, &input->buffer, scene->rt);
1039 cbox_rt_array_insert(scene->rt, (void ***)&scene->connected_inputs, &scene->connected_input_count, -1, input);
1043 if (scene->enable_default_song_input)
1045 cbox_midi_merger_connect(&scene->scene_input_merger, &scene->engine->midibuf_aux, scene->rt);
1046 cbox_midi_merger_connect(&scene->scene_input_merger, &scene->engine->midibuf_song, scene->rt);
1048 else
1050 cbox_midi_merger_disconnect(&scene->scene_input_merger, &scene->engine->midibuf_aux, scene->rt);
1051 cbox_midi_merger_disconnect(&scene->scene_input_merger, &scene->engine->midibuf_song, scene->rt);
1054 if (scene->enable_default_external_input)
1055 cbox_midi_merger_connect(&scene->scene_input_merger, &scene->engine->midibuf_jack, scene->rt);
1056 else
1057 cbox_midi_merger_disconnect(&scene->scene_input_merger, &scene->engine->midibuf_jack, scene->rt);
1061 static void free_adhoc_pattern_list(struct cbox_scene *scene, struct cbox_adhoc_pattern *ap)
1063 while(ap)
1065 struct cbox_adhoc_pattern *tmp = ap;
1066 ap = ap->next;
1067 tmp->next = NULL;
1068 cbox_midi_merger_disconnect(&scene->scene_input_merger, &ap->output_buffer, scene->rt);
1069 cbox_adhoc_pattern_destroy(tmp);
1073 struct play_adhoc_pattern_arg
1075 struct cbox_scene *scene;
1076 struct cbox_adhoc_pattern *ap;
1077 struct cbox_adhoc_pattern *retired;
1080 static int play_adhoc_pattern_execute(void *arg_)
1082 struct play_adhoc_pattern_arg *arg = arg_;
1084 if (arg->ap)
1086 struct cbox_adhoc_pattern *ap = arg->scene->adhoc_patterns;
1088 // If there is already an adhoc pattern with a given non-zero id, stop it
1089 // and release all the pending notes. Retry until all the notes are
1090 // released.
1091 if (arg->ap->id)
1093 while(ap && ap->id != arg->ap->id)
1094 ap = ap->next;
1095 if (ap)
1097 ap->completed = TRUE;
1098 if (ap->active_notes.channels_active)
1099 return 0;
1103 arg->ap->next = arg->scene->adhoc_patterns;
1104 arg->scene->adhoc_patterns = arg->ap;
1106 arg->retired = arg->scene->retired_adhoc_patterns;
1107 arg->scene->retired_adhoc_patterns = NULL;
1108 // XXXKF should convert pattern length into sample position instead of assuming 0x7FFFFFFF (though it likely doesn't matter)
1109 cbox_midi_clip_playback_set_pattern(&arg->ap->playback, arg->ap->pattern_playback, 0, 0x7FFFFFFF, 0, 0);
1110 return 1;
1113 void cbox_scene_play_adhoc_pattern(struct cbox_scene *scene, struct cbox_adhoc_pattern *ap)
1115 static struct cbox_rt_cmd_definition cmd = { NULL, play_adhoc_pattern_execute, NULL };
1116 struct play_adhoc_pattern_arg arg = { scene, ap, NULL };
1117 cbox_midi_merger_connect(&scene->scene_input_merger, &ap->output_buffer, scene->rt);
1118 cbox_rt_execute_cmd_sync(scene->rt, &cmd, &arg);
1119 if (arg.retired)
1120 free_adhoc_pattern_list(scene, arg.retired);
1123 gboolean cbox_scene_move_instrument_to(struct cbox_scene *scene, struct cbox_instrument *instrument, struct cbox_scene *new_scene, int dstpos, GError **error)
1125 int lcount = 0;
1126 if (dstpos == -1)
1127 dstpos = new_scene->layer_count;
1128 for (int i = 0; i < scene->layer_count; i++)
1130 if (scene->layers[i]->instrument == instrument)
1131 lcount++;
1133 if (!lcount)
1135 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Instrument '%s' not found in source scene", instrument->module->instance_name);
1136 return FALSE;
1138 if (cbox_scene_get_instrument_by_name(new_scene, instrument->module->instance_name, FALSE, NULL))
1140 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Instrument '%s' already exists in target scene", instrument->module->instance_name);
1141 return FALSE;
1144 struct cbox_layer **new_src_layers = malloc(sizeof(struct cbox_layer *) * (scene->layer_count - lcount));
1145 struct cbox_layer **new_dst_layers = malloc(sizeof(struct cbox_layer *) * (new_scene->layer_count + lcount));
1146 int srcidx = 0, dstidx = 0;
1147 memcpy(&new_dst_layers[dstidx], new_scene->layers, dstpos * sizeof(struct cbox_layer **));
1148 dstidx = dstpos;
1149 for (int i = 0; i < scene->layer_count; i++)
1151 if (scene->layers[i]->instrument != instrument)
1152 new_src_layers[srcidx++] = scene->layers[i];
1153 else
1154 new_dst_layers[dstidx++] = scene->layers[i];
1156 memcpy(&new_dst_layers[dstidx], new_scene->layers, (new_scene->layer_count - dstpos) * sizeof(struct cbox_layer **));
1157 dstidx += new_scene->layer_count;
1159 free(cbox_rt_swap_pointers_and_update_count(scene->rt, (void **)&scene->layers, new_src_layers, &scene->layer_count, srcidx));
1160 cbox_rt_array_remove_by_value(scene->rt, (void ***)&scene->instruments, &scene->instrument_count, instrument);
1162 cbox_rt_array_insert(scene->rt, (void ***)&new_scene->instruments, &new_scene->instrument_count, -1, instrument);
1163 free(cbox_rt_swap_pointers_and_update_count(new_scene->rt, (void **)&new_scene->layers, new_dst_layers, &new_scene->layer_count, dstidx));
1165 return TRUE;
1168 static void cbox_scene_destroyfunc(struct cbox_objhdr *objhdr)
1170 struct cbox_scene *scene = CBOX_H2O(objhdr);
1171 cbox_midi_merger_disconnect(&scene->scene_input_merger, &scene->engine->midibuf_aux, scene->rt);
1172 cbox_midi_merger_disconnect(&scene->scene_input_merger, &scene->engine->midibuf_jack, scene->rt);
1173 cbox_midi_merger_disconnect(&scene->scene_input_merger, &scene->engine->midibuf_song, scene->rt);
1174 cbox_engine_remove_scene(scene->engine, scene);
1175 cbox_scene_clear(scene);
1176 g_free(scene->name);
1177 g_free(scene->title);
1178 assert(scene->instrument_count == 0);
1179 free(scene->layers);
1180 free(scene->aux_buses);
1181 free(scene->instruments);
1182 g_hash_table_destroy(scene->instrument_hash);
1183 free(scene->connected_inputs);
1185 destroy_rec_sources(scene->rec_mono_inputs, scene->engine->io_env.input_count);
1186 destroy_rec_sources(scene->rec_stereo_inputs, scene->engine->io_env.input_count / 2);
1187 destroy_rec_sources(scene->rec_mono_outputs, scene->engine->io_env.output_count);
1188 destroy_rec_sources(scene->rec_stereo_outputs, scene->engine->io_env.output_count / 2);
1190 free_adhoc_pattern_list(scene, scene->retired_adhoc_patterns);
1191 free_adhoc_pattern_list(scene, scene->adhoc_patterns);
1192 cbox_midi_merger_close(&scene->scene_input_merger);
1193 free(scene);