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/>.
21 #include "config-api.h"
35 CBOX_CLASS_DEFINITION_ROOT(cbox_scene
)
37 static gboolean
cbox_scene_addlayercmd(struct cbox_scene
*s
, struct cbox_command_target
*fb
, struct cbox_osc_command
*cmd
, int cmd_type
, GError
**error
)
39 int pos
= CBOX_ARG_I(cmd
, 0);
40 if (pos
< 0 || pos
> 1 + s
->layer_count
)
42 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
);
49 struct cbox_layer
*layer
= NULL
;
54 layer
= cbox_layer_new_from_config(s
, CBOX_ARG_S(cmd
, 1), error
);
57 layer
= cbox_layer_new_with_instrument(s
, CBOX_ARG_S(cmd
, 1), error
);
61 struct cbox_instrument
*instr
= cbox_scene_create_instrument(s
, CBOX_ARG_S(cmd
, 1), CBOX_ARG_S(cmd
, 2), error
);
64 layer
= cbox_layer_new_with_instrument(s
, CBOX_ARG_S(cmd
, 1), error
);
73 if (!cbox_scene_insert_layer(s
, layer
, pos
, error
))
80 if (!cbox_execute_on(fb
, NULL
, "/uuid", "o", error
, layer
))
86 static gboolean
cbox_scene_process_cmd(struct cbox_command_target
*ct
, struct cbox_command_target
*fb
, struct cbox_osc_command
*cmd
, GError
**error
)
88 struct cbox_scene
*s
= ct
->user_data
;
89 const char *subcommand
= NULL
;
93 if (!strcmp(cmd
->command
, "/transpose") && !strcmp(cmd
->arg_types
, "i"))
95 s
->transpose
= CBOX_ARG_I(cmd
, 0);
98 else if (!strcmp(cmd
->command
, "/load") && !strcmp(cmd
->arg_types
, "s"))
100 if (!cbox_scene_load(s
, CBOX_ARG_S(cmd
, 0), error
))
104 else if (!strcmp(cmd
->command
, "/clear") && !strcmp(cmd
->arg_types
, ""))
109 else if (!strcmp(cmd
->command
, "/add_layer") && !strcmp(cmd
->arg_types
, "is"))
111 return cbox_scene_addlayercmd(s
, fb
, cmd
, 1, error
);
113 else if (!strcmp(cmd
->command
, "/add_instrument_layer") && !strcmp(cmd
->arg_types
, "is"))
115 return cbox_scene_addlayercmd(s
, fb
, cmd
, 2, error
);
117 else if (!strcmp(cmd
->command
, "/add_new_instrument_layer") && !strcmp(cmd
->arg_types
, "iss"))
119 return cbox_scene_addlayercmd(s
, fb
, cmd
, 3, error
);
121 else if (!strcmp(cmd
->command
, "/delete_layer") && !strcmp(cmd
->arg_types
, "i"))
123 int pos
= CBOX_ARG_I(cmd
, 0);
124 if (pos
< 0 || pos
> s
->layer_count
)
126 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
);
130 pos
= s
->layer_count
- 1;
133 struct cbox_layer
*layer
= cbox_scene_remove_layer(s
, pos
);
137 else if (!strcmp(cmd
->command
, "/move_layer") && !strcmp(cmd
->arg_types
, "ii"))
139 int oldpos
= CBOX_ARG_I(cmd
, 0);
140 if (oldpos
< 1 || oldpos
> s
->layer_count
)
142 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Invalid position %d (valid are 1..%d)", oldpos
, s
->layer_count
);
145 int newpos
= CBOX_ARG_I(cmd
, 1);
146 if (newpos
< 1 || newpos
> s
->layer_count
)
148 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Invalid position %d (valid are 1..%d)", newpos
, s
->layer_count
);
151 cbox_scene_move_layer(s
, oldpos
- 1, newpos
- 1);
154 else if (cbox_parse_path_part_int(cmd
, "/layer/", &subcommand
, &index
, 1, s
->layer_count
, error
))
158 return cbox_execute_sub(&s
->layers
[index
- 1]->cmd_target
, fb
, cmd
, subcommand
, error
);
160 else if (cbox_parse_path_part_str(cmd
, "/aux/", &subcommand
, &subobj
, error
))
164 struct cbox_aux_bus
*aux
= cbox_scene_get_aux_bus(s
, subobj
, FALSE
, error
);
168 return cbox_execute_sub(&aux
->cmd_target
, fb
, cmd
, subcommand
, error
);
170 else if (!strncmp(cmd
->command
, "/instr/", 7))
172 const char *obj
= &cmd
->command
[1];
173 const char *pos
= strchr(obj
, '/');
175 pos
= strchr(obj
, '/');
178 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Invalid instrument path '%s'", cmd
->command
);
183 gchar
*name
= g_strndup(obj
, len
);
184 struct cbox_instrument
*instr
= cbox_scene_get_instrument_by_name(s
, name
, FALSE
, error
);
189 return cbox_execute_sub(&instr
->cmd_target
, fb
, cmd
, pos
, error
);
193 cbox_force_error(error
);
194 g_prefix_error(error
, "Cannot access instrument '%s': ", name
);
200 else if (!strcmp(cmd
->command
, "/load_aux") && !strcmp(cmd
->arg_types
, "s"))
202 struct cbox_aux_bus
*bus
= cbox_scene_get_aux_bus(s
, CBOX_ARG_S(cmd
, 0), TRUE
, error
);
207 if (!cbox_execute_on(fb
, NULL
, "/uuid", "o", error
, bus
))
212 else if (!strcmp(cmd
->command
, "/delete_aux") && !strcmp(cmd
->arg_types
, "s"))
214 const char *name
= CBOX_ARG_S(cmd
, 0);
215 struct cbox_aux_bus
*aux
= cbox_scene_get_aux_bus(s
, name
, FALSE
, error
);
221 else if (!strcmp(cmd
->command
, "/status") && !strcmp(cmd
->arg_types
, ""))
223 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
226 if (!cbox_execute_on(fb
, NULL
, "/name", "s", error
, s
->name
) ||
227 !cbox_execute_on(fb
, NULL
, "/title", "s", error
, s
->title
) ||
228 !cbox_execute_on(fb
, NULL
, "/transpose", "i", error
, s
->transpose
) ||
229 !CBOX_OBJECT_DEFAULT_STATUS(s
, fb
, error
))
232 for (int i
= 0; i
< s
->layer_count
; i
++)
234 if (!cbox_execute_on(fb
, NULL
, "/layer", "o", error
, s
->layers
[i
]))
237 for (int i
= 0; i
< s
->instrument_count
; i
++)
239 if (!cbox_execute_on(fb
, NULL
, "/instrument", "sso", error
, s
->instruments
[i
]->module
->instance_name
, s
->instruments
[i
]->module
->engine_name
, s
->instruments
[i
]))
242 for (int i
= 0; i
< s
->aux_bus_count
; i
++)
244 if (!cbox_execute_on(fb
, NULL
, "/aux", "so", error
, s
->aux_buses
[i
]->name
, s
->aux_buses
[i
]))
249 else if (!strcmp(cmd
->command
, "/render_stereo") && !strcmp(cmd
->arg_types
, "i"))
251 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
253 if (s
->rt
&& s
->rt
->io
)
255 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot use render function in real-time mode.");
258 struct cbox_midi_buffer midibuf_song
;
259 cbox_midi_buffer_init(&midibuf_song
);
260 int nframes
= CBOX_ARG_I(cmd
, 0);
261 float *data
= malloc(2 * nframes
* sizeof(float));
262 float *data_i
= malloc(2 * nframes
* sizeof(float));
263 float *buffers
[2] = { data
, data
+ nframes
};
264 for (int i
= 0; i
< nframes
; i
++)
270 cbox_song_playback_render(s
->spb
, &midibuf_song
, nframes
);
271 cbox_scene_render(s
, nframes
, &midibuf_song
, buffers
);
272 for (int i
= 0; i
< nframes
; i
++)
274 data_i
[i
* 2] = buffers
[0][i
];
275 data_i
[i
* 2 + 1] = buffers
[1][i
];
279 if (!cbox_execute_on(fb
, NULL
, "/data", "b", error
, cbox_blob_new_acquire_data(data_i
, nframes
* 2 * sizeof(float))))
284 return cbox_object_default_process_cmd(ct
, fb
, cmd
, error
);
287 gboolean
cbox_scene_load(struct cbox_scene
*s
, const char *name
, GError
**error
)
289 const char *cv
= NULL
;
291 gchar
*section
= g_strdup_printf("scene:%s", name
);
293 if (!cbox_config_has_section(section
))
295 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "No config section for scene '%s'", name
);
301 assert(s
->layers
== NULL
);
302 assert(s
->instruments
== NULL
);
303 assert(s
->aux_buses
== NULL
);
304 assert(s
->layer_count
== 0);
305 assert(s
->instrument_count
== 0);
306 assert(s
->aux_bus_count
== 0);
310 struct cbox_layer
*l
= NULL
;
312 gchar
*sn
= g_strdup_printf("layer%d", i
);
313 cv
= cbox_config_get_string(section
, sn
);
319 l
= cbox_layer_new_from_config(s
, cv
, error
);
323 if (!cbox_scene_add_layer(s
, l
, error
))
327 s
->transpose
= cbox_config_get_int(section
, "transpose", 0);
328 s
->title
= g_strdup(cbox_config_get_string_with_default(section
, "title", ""));
330 cbox_command_target_init(&s
->cmd_target
, cbox_scene_process_cmd
, s
);
331 s
->name
= g_strdup(name
);
339 gboolean
cbox_scene_insert_layer(struct cbox_scene
*scene
, struct cbox_layer
*layer
, int pos
, GError
**error
)
343 struct cbox_instrument
*instrument
= layer
->instrument
;
344 for (i
= 0; i
< instrument
->aux_output_count
; i
++)
346 assert(!instrument
->aux_outputs
[i
]);
347 if (instrument
->aux_output_names
[i
])
349 instrument
->aux_outputs
[i
] = cbox_scene_get_aux_bus(scene
, instrument
->aux_output_names
[i
], TRUE
, error
);
350 if (!instrument
->aux_outputs
[i
])
352 cbox_aux_bus_ref(instrument
->aux_outputs
[i
]);
355 for (i
= 0; i
< scene
->layer_count
; i
++)
357 if (scene
->layers
[i
]->instrument
== layer
->instrument
)
360 if (i
== scene
->layer_count
)
362 layer
->instrument
->scene
= scene
;
363 cbox_rt_array_insert(scene
->rt
, (void ***)&scene
->instruments
, &scene
->instrument_count
, -1, layer
->instrument
);
365 cbox_rt_array_insert(scene
->rt
, (void ***)&scene
->layers
, &scene
->layer_count
, pos
, layer
);
370 gboolean
cbox_scene_add_layer(struct cbox_scene
*scene
, struct cbox_layer
*layer
, GError
**error
)
372 return cbox_scene_insert_layer(scene
, layer
, scene
->layer_count
, error
);
375 struct cbox_layer
*cbox_scene_remove_layer(struct cbox_scene
*scene
, int pos
)
377 struct cbox_layer
*removed
= scene
->layers
[pos
];
378 cbox_rt_array_remove(scene
->rt
, (void ***)&scene
->layers
, &scene
->layer_count
, pos
);
379 cbox_instrument_unref_aux_buses(removed
->instrument
);
384 void cbox_scene_move_layer(struct cbox_scene
*scene
, int oldpos
, int newpos
)
386 if (oldpos
== newpos
)
388 struct cbox_layer
**layers
= malloc(sizeof(struct cbox_layer
*) * scene
->layer_count
);
389 for (int i
= 0; i
< scene
->layer_count
; i
++)
397 s
= (i
< oldpos
|| i
> newpos
) ? i
: i
+ 1;
399 s
= (i
< newpos
|| i
> oldpos
) ? i
: i
- 1;
401 layers
[i
] = scene
->layers
[s
];
403 free(cbox_rt_swap_pointers(scene
->rt
, (void **)&scene
->layers
, layers
));
406 gboolean
cbox_scene_remove_instrument(struct cbox_scene
*scene
, struct cbox_instrument
*instrument
)
408 assert(instrument
->scene
== scene
);
410 for (pos
= 0; pos
< scene
->instrument_count
; pos
++)
412 if (scene
->instruments
[pos
] == instrument
)
414 cbox_rt_array_remove(scene
->rt
, (void ***)&scene
->instruments
, &scene
->instrument_count
, pos
);
415 g_hash_table_remove(scene
->instrument_hash
, instrument
->module
->instance_name
);
416 instrument
->scene
= NULL
;
423 gboolean
cbox_scene_insert_aux_bus(struct cbox_scene
*scene
, struct cbox_aux_bus
*aux_bus
)
425 struct cbox_aux_bus
**aux_buses
= malloc(sizeof(struct cbox_aux_bus
*) * (scene
->aux_bus_count
+ 1));
426 memcpy(aux_buses
, scene
->aux_buses
, sizeof(struct cbox_aux_bus
*) * (scene
->aux_bus_count
));
427 aux_buses
[scene
->aux_bus_count
] = aux_bus
;
428 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));
432 void cbox_scene_remove_aux_bus(struct cbox_scene
*scene
, struct cbox_aux_bus
*removed
)
435 for (int i
= 0; i
< scene
->aux_bus_count
; i
++)
437 if (scene
->aux_buses
[i
] == removed
)
444 for (int i
= 0; i
< scene
->instrument_count
; i
++)
445 cbox_instrument_disconnect_aux_bus(scene
->instruments
[i
], removed
);
447 struct cbox_aux_bus
**aux_buses
= malloc(sizeof(struct cbox_aux_bus
*) * (scene
->aux_bus_count
- 1));
448 memcpy(aux_buses
, scene
->aux_buses
, sizeof(struct cbox_aux_bus
*) * pos
);
449 memcpy(aux_buses
+ pos
, scene
->aux_buses
+ pos
+ 1, sizeof(struct cbox_aux_bus
*) * (scene
->aux_bus_count
- pos
- 1));
450 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));
453 struct cbox_aux_bus
*cbox_scene_get_aux_bus(struct cbox_scene
*scene
, const char *name
, int allow_load
, GError
**error
)
455 for (int i
= 0; i
< scene
->aux_bus_count
; i
++)
457 if (!strcmp(scene
->aux_buses
[i
]->name
, name
))
459 return scene
->aux_buses
[i
];
464 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Aux bus not found: %s", name
);
467 struct cbox_aux_bus
*bus
= cbox_aux_bus_load(scene
, name
, scene
->rt
, error
);
473 static int write_events_to_instrument_ports(struct cbox_scene
*scene
, struct cbox_midi_buffer
*source
)
477 for (i
= 0; i
< scene
->instrument_count
; i
++)
478 cbox_midi_buffer_clear(&scene
->instruments
[i
]->module
->midi_input
);
483 uint32_t event_count
= cbox_midi_buffer_get_count(source
);
484 for (i
= 0; i
< event_count
; i
++)
486 const struct cbox_midi_event
*event
= cbox_midi_buffer_get_event(source
, i
);
488 // XXXKF ignore sysex for now
489 if (event
->size
>= 4)
492 for (int l
= 0; l
< scene
->layer_count
; l
++)
494 struct cbox_layer
*lp
= scene
->layers
[l
];
497 uint8_t data
[4] = {0, 0, 0, 0};
498 memcpy(data
, event
->data_inline
, event
->size
);
499 if (data
[0] < 0xF0) // per-channel messages
501 int cmd
= data
[0] >> 4;
502 // filter on MIDI channel
503 if (lp
->in_channel
>= 0 && lp
->in_channel
!= (data
[0] & 0x0F))
505 // force output channel
506 if (lp
->out_channel
>= 0)
507 data
[0] = (data
[0] & 0xF0) + (lp
->out_channel
& 0x0F);
508 if (cmd
>= 8 && cmd
<= 10)
510 if (cmd
== 10 && lp
->disable_aftertouch
)
513 if (data
[1] < lp
->low_note
|| data
[1] > lp
->high_note
)
516 int transpose
= lp
->transpose
+ (lp
->ignore_scene_transpose
? 0 : scene
->transpose
);
519 int note
= data
[1] + transpose
;
520 if (note
< 0 || note
> 127)
522 data
[1] = (uint8_t)note
;
525 if (lp
->fixed_note
!= -1)
527 data
[1] = (uint8_t)lp
->fixed_note
;
530 else if (cmd
== 11 && data
[1] == 64 && lp
->invert_sustain
)
532 data
[2] = 127 - data
[2];
534 else if (lp
->ignore_program_changes
&& cmd
== 11 && (data
[1] == 0 || data
[1] == 32))
536 else if (cmd
== 13 && lp
->disable_aftertouch
)
538 else if (cmd
== 12 && lp
->ignore_program_changes
)
541 if (!cbox_midi_buffer_write_event(&lp
->instrument
->module
->midi_input
, event
->time
, data
, event
->size
))
551 void cbox_scene_render(struct cbox_scene
*scene
, uint32_t nframes
, struct cbox_midi_buffer
*midibuf_total
, float *output_buffers
[])
555 if (scene
->rt
&& scene
->rt
->io
)
557 struct cbox_io
*io
= scene
->rt
->io
;
558 for (i
= 0; i
< io
->input_count
; i
++)
560 if (IS_RECORDING_SOURCE_CONNECTED(scene
->rec_mono_inputs
[i
]))
561 cbox_recording_source_push(&scene
->rec_mono_inputs
[i
], (const float **)&io
->input_buffers
[i
], nframes
);
563 for (i
= 0; i
< io
->input_count
/ 2; i
++)
565 if (IS_RECORDING_SOURCE_CONNECTED(scene
->rec_stereo_inputs
[i
]))
567 const float *buf
[2] = { io
->input_buffers
[i
* 2], io
->input_buffers
[i
* 2 + 1] };
568 cbox_recording_source_push(&scene
->rec_stereo_inputs
[i
], buf
, nframes
);
573 write_events_to_instrument_ports(scene
, midibuf_total
);
575 for (n
= 0; n
< scene
->aux_bus_count
; n
++)
577 for (i
= 0; i
< nframes
; i
++)
579 scene
->aux_buses
[n
]->input_bufs
[0][i
] = 0.f
;
580 scene
->aux_buses
[n
]->input_bufs
[1][i
] = 0.f
;
584 for (n
= 0; n
< scene
->instrument_count
; n
++)
586 struct cbox_instrument
*instr
= scene
->instruments
[n
];
587 struct cbox_module
*module
= instr
->module
;
588 int event_count
= instr
->module
->midi_input
.count
;
590 uint32_t highwatermark
= 0;
591 cbox_sample_t channels
[CBOX_MAX_AUDIO_PORTS
][CBOX_BLOCK_SIZE
];
592 cbox_sample_t
*outputs
[CBOX_MAX_AUDIO_PORTS
];
593 for (i
= 0; i
< module
->outputs
; i
++)
594 outputs
[i
] = channels
[i
];
596 for (i
= 0; i
< nframes
; i
+= CBOX_BLOCK_SIZE
)
598 if (i
>= highwatermark
)
600 while(cur_event
< event_count
)
602 const struct cbox_midi_event
*event
= cbox_midi_buffer_get_event(&module
->midi_input
, cur_event
);
605 if (event
->time
<= i
)
606 (*module
->process_event
)(module
, cbox_midi_event_get_data(event
), event
->size
);
609 highwatermark
= event
->time
;
619 (*module
->process_block
)(module
, NULL
, outputs
);
620 for (int o
= 0; o
< module
->outputs
/ 2; o
++)
622 struct cbox_instrument_output
*oobj
= &instr
->outputs
[o
];
623 struct cbox_module
*insert
= oobj
->insert
;
624 float gain
= oobj
->gain
;
625 if (IS_RECORDING_SOURCE_CONNECTED(oobj
->rec_dry
))
626 cbox_recording_source_push(&oobj
->rec_dry
, (const float **)(outputs
+ 2 * o
), CBOX_BLOCK_SIZE
);
627 if (insert
&& !insert
->bypass
)
628 (*insert
->process_block
)(insert
, outputs
+ 2 * o
, outputs
+ 2 * o
);
629 if (IS_RECORDING_SOURCE_CONNECTED(oobj
->rec_wet
))
630 cbox_recording_source_push(&oobj
->rec_wet
, (const float **)(outputs
+ 2 * o
), CBOX_BLOCK_SIZE
);
631 float *leftbuf
, *rightbuf
;
632 if (o
< module
->aux_offset
/ 2)
634 int leftch
= oobj
->output_bus
* 2;
635 int rightch
= leftch
+ 1;
636 leftbuf
= output_buffers
[leftch
];
637 rightbuf
= output_buffers
[rightch
];
641 int bus
= o
- module
->aux_offset
/ 2;
642 struct cbox_aux_bus
*busobj
= instr
->aux_outputs
[bus
];
645 leftbuf
= busobj
->input_bufs
[0];
646 rightbuf
= busobj
->input_bufs
[1];
648 for (j
= 0; j
< CBOX_BLOCK_SIZE
; j
++)
650 leftbuf
[i
+ j
] += gain
* channels
[2 * o
][j
];
651 rightbuf
[i
+ j
] += gain
* channels
[2 * o
+ 1][j
];
655 while(cur_event
< event_count
)
657 const struct cbox_midi_event
*event
= cbox_midi_buffer_get_event(&module
->midi_input
, cur_event
);
660 (*module
->process_event
)(module
, cbox_midi_event_get_data(event
), event
->size
);
669 for (n
= 0; n
< scene
->aux_bus_count
; n
++)
671 struct cbox_aux_bus
*bus
= scene
->aux_buses
[n
];
672 float left
[CBOX_BLOCK_SIZE
], right
[CBOX_BLOCK_SIZE
];
673 float *outputs
[2] = {left
, right
};
674 for (i
= 0; i
< nframes
; i
+= CBOX_BLOCK_SIZE
)
677 inputs
[0] = &bus
->input_bufs
[0][i
];
678 inputs
[1] = &bus
->input_bufs
[1][i
];
679 bus
->module
->process_block(bus
->module
, inputs
, outputs
);
680 for (int j
= 0; j
< CBOX_BLOCK_SIZE
; j
++)
682 output_buffers
[0][i
+ j
] += left
[j
];
683 output_buffers
[1][i
+ j
] += right
[j
];
687 if (scene
->rt
&& scene
->rt
->io
)
689 struct cbox_io
*io
= scene
->rt
->io
;
690 // XXXKF this assumes that the buffers are zeroed on start - which isn't true if there are multiple scenes
691 for (i
= 0; i
< io
->output_count
; i
++)
693 if (IS_RECORDING_SOURCE_CONNECTED(scene
->rec_mono_outputs
[i
]))
694 cbox_recording_source_push(&scene
->rec_mono_outputs
[i
], (const float **)&io
->output_buffers
[i
], nframes
);
696 for (i
= 0; i
< io
->output_count
/ 2; i
++)
698 if (IS_RECORDING_SOURCE_CONNECTED(scene
->rec_stereo_outputs
[i
]))
700 const float *buf
[2] = { io
->output_buffers
[i
* 2], io
->output_buffers
[i
* 2 + 1] };
701 cbox_recording_source_push(&scene
->rec_stereo_outputs
[i
], buf
, nframes
);
707 void cbox_scene_clear(struct cbox_scene
*scene
)
710 g_free(scene
->title
);
711 scene
->name
= g_strdup("");
712 scene
->title
= g_strdup("");
713 while(scene
->layer_count
> 0)
715 struct cbox_layer
*layer
= cbox_scene_remove_layer(scene
, 0);
719 while(scene
->aux_bus_count
> 0)
720 CBOX_DELETE(scene
->aux_buses
[scene
->aux_bus_count
- 1]);
723 static struct cbox_instrument
*create_instrument(struct cbox_scene
*scene
, struct cbox_module
*module
)
725 int auxes
= (module
->outputs
- module
->aux_offset
) / 2;
727 struct cbox_instrument
*instr
= malloc(sizeof(struct cbox_instrument
));
728 CBOX_OBJECT_HEADER_INIT(instr
, cbox_instrument
, CBOX_GET_DOCUMENT(scene
));
729 instr
->scene
= scene
;
730 instr
->module
= module
;
731 instr
->outputs
= calloc(module
->outputs
/ 2, sizeof(struct cbox_instrument_output
));
733 instr
->aux_outputs
= calloc(auxes
, sizeof(struct cbox_aux_bus
*));
734 instr
->aux_output_names
= calloc(auxes
, sizeof(char *));
735 instr
->aux_output_count
= auxes
;
737 for (int i
= 0; i
< module
->outputs
/ 2; i
++)
738 cbox_instrument_output_init(&instr
->outputs
[i
], scene
, module
->rt
->io_env
.buffer_size
);
743 struct cbox_instrument
*cbox_scene_create_instrument(struct cbox_scene
*scene
, const char *instrument_name
, const char *engine_name
, GError
**error
)
745 gpointer value
= g_hash_table_lookup(scene
->instrument_hash
, instrument_name
);
748 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Instrument already exists: '%s'", instrument_name
);
752 struct cbox_document
*doc
= CBOX_GET_DOCUMENT(scene
);
753 struct cbox_module_manifest
*mptr
= NULL
;
754 struct cbox_instrument
*instr
= NULL
;
755 struct cbox_module
*module
= NULL
;
757 mptr
= cbox_module_manifest_get_by_name(engine_name
);
760 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "No engine called '%s'", engine_name
);
764 module
= cbox_module_manifest_create_module(mptr
, NULL
, doc
, scene
->rt
, instrument_name
, error
);
767 cbox_force_error(error
);
768 g_prefix_error(error
, "Cannot create engine '%s' for instrument '%s': ", engine_name
, instrument_name
);
772 instr
= create_instrument(scene
, module
);
774 cbox_command_target_init(&instr
->cmd_target
, cbox_instrument_process_cmd
, instr
);
775 g_hash_table_insert(scene
->instrument_hash
, g_strdup(instrument_name
), instr
);
776 CBOX_OBJECT_REGISTER(instr
);
781 struct cbox_instrument
*cbox_scene_get_instrument_by_name(struct cbox_scene
*scene
, const char *name
, gboolean load
, GError
**error
)
783 struct cbox_module_manifest
*mptr
= NULL
;
784 struct cbox_instrument
*instr
= NULL
;
785 struct cbox_module
*module
= NULL
;
786 gchar
*instr_section
= NULL
;
787 gpointer value
= g_hash_table_lookup(scene
->instrument_hash
, name
);
788 const char *cv
, *instr_engine
;
789 struct cbox_document
*doc
= CBOX_GET_DOCUMENT(scene
);
797 instr_section
= g_strdup_printf("instrument:%s", name
);
799 if (!cbox_config_has_section(instr_section
))
801 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "No config section for instrument '%s'", name
);
805 instr_engine
= cbox_config_get_string(instr_section
, "engine");
808 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Engine not specified in instrument '%s'", name
);
812 mptr
= cbox_module_manifest_get_by_name(instr_engine
);
815 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "No engine called '%s'", instr_engine
);
819 // cbox_module_manifest_dump(mptr);
821 module
= cbox_module_manifest_create_module(mptr
, instr_section
, doc
, scene
->rt
, name
, error
);
824 cbox_force_error(error
);
825 g_prefix_error(error
, "Cannot create engine '%s' for instrument '%s': ", instr_engine
, name
);
829 instr
= create_instrument(scene
, module
);
831 for (int i
= 0; i
< module
->outputs
/ 2; i
++)
833 struct cbox_instrument_output
*oobj
= instr
->outputs
+ i
;
835 gchar
*key
= i
== 0 ? g_strdup("output_bus") : g_strdup_printf("output%d_bus", 1 + i
);
836 oobj
->output_bus
= cbox_config_get_int(instr_section
, key
, 1) - 1;
838 key
= i
== 0 ? g_strdup("gain") : g_strdup_printf("gain%d", 1 + i
);
839 oobj
->gain
= cbox_config_get_gain_db(instr_section
, key
, 0);
842 key
= i
== 0 ? g_strdup("insert") : g_strdup_printf("insert%d", 1 + i
);
843 cv
= cbox_config_get_string(instr_section
, key
);
848 oobj
->insert
= cbox_module_new_from_fx_preset(cv
, CBOX_GET_DOCUMENT(scene
), module
->rt
, error
);
851 cbox_force_error(error
);
852 g_prefix_error(error
, "Cannot instantiate effect preset '%s' for instrument '%s': ", cv
, name
);
857 for (int i
= 0; i
< instr
->aux_output_count
; i
++)
859 instr
->aux_outputs
[i
] = NULL
;
861 gchar
*key
= g_strdup_printf("aux%d", 1 + i
);
862 gchar
*value
= cbox_config_get_string(instr_section
, key
);
863 instr
->aux_output_names
[i
] = value
? g_strdup(value
) : NULL
;
867 cbox_command_target_init(&instr
->cmd_target
, cbox_instrument_process_cmd
, instr
);
871 g_hash_table_insert(scene
->instrument_hash
, g_strdup(name
), instr
);
872 CBOX_OBJECT_REGISTER(instr
);
874 // cbox_recording_source_attach(&instr->outputs[0].rec_dry, cbox_recorder_new_stream("output.wav"));
883 static struct cbox_recording_source
*create_rec_sources(struct cbox_scene
*scene
, struct cbox_io
*io
, int count
, int channels
)
885 struct cbox_recording_source
*s
= malloc(sizeof(struct cbox_recording_source
) * count
);
886 for (int i
= 0; i
< count
; i
++)
887 cbox_recording_source_init(&s
[i
], scene
, io
->io_env
.buffer_size
, channels
);
891 static void destroy_rec_sources(struct cbox_recording_source
*s
, int count
)
893 for (int i
= 0; i
< count
; i
++)
894 cbox_recording_source_uninit(&s
[i
]);
898 struct cbox_scene
*cbox_scene_new(struct cbox_document
*document
, struct cbox_rt
*rt
, int owns_rt
)
900 struct cbox_scene
*s
= malloc(sizeof(struct cbox_scene
));
904 CBOX_OBJECT_HEADER_INIT(s
, cbox_scene
, document
);
906 s
->instrument_hash
= g_hash_table_new_full(g_str_hash
, g_str_equal
, g_free
, NULL
);
907 s
->name
= g_strdup("");
908 s
->title
= g_strdup("");
911 s
->instruments
= NULL
;
913 s
->instrument_count
= 0;
914 s
->aux_bus_count
= 0;
915 cbox_command_target_init(&s
->cmd_target
, cbox_scene_process_cmd
, s
);
917 s
->owns_rt
= owns_rt
;
920 if (s
->rt
&& s
->rt
->io
)
922 struct cbox_io
*io
= s
->rt
->io
;
923 s
->rec_mono_inputs
= create_rec_sources(s
, io
, io
->input_count
, 1);
924 s
->rec_stereo_inputs
= create_rec_sources(s
, io
, io
->input_count
/ 2, 2);
925 s
->rec_mono_outputs
= create_rec_sources(s
, io
, io
->output_count
, 1);
926 s
->rec_stereo_outputs
= create_rec_sources(s
, io
, io
->output_count
/ 2, 2);
930 s
->rec_mono_inputs
= NULL
;
931 s
->rec_stereo_inputs
= NULL
;
932 s
->rec_mono_outputs
= NULL
;
933 s
->rec_stereo_outputs
= NULL
;
936 CBOX_OBJECT_REGISTER(s
);
940 static void cbox_scene_destroyfunc(struct cbox_objhdr
*objhdr
)
942 struct cbox_scene
*scene
= CBOX_H2O(objhdr
);
943 cbox_scene_clear(scene
);
945 g_free(scene
->title
);
946 assert(scene
->instrument_count
== 0);
948 free(scene
->aux_buses
);
949 free(scene
->instruments
);
950 g_hash_table_destroy(scene
->instrument_hash
);
951 if (scene
->rt
&& scene
->rt
->io
)
953 struct cbox_io
*io
= scene
->rt
->io
;
954 destroy_rec_sources(scene
->rec_mono_inputs
, io
->input_count
);
955 destroy_rec_sources(scene
->rec_stereo_inputs
, io
->input_count
/ 2);
956 destroy_rec_sources(scene
->rec_mono_outputs
, io
->output_count
);
957 destroy_rec_sources(scene
->rec_stereo_outputs
, io
->output_count
/ 2);
959 if (scene
->owns_rt
&& scene
->rt
)
960 CBOX_DELETE(scene
->rt
);