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/>.
35 CBOX_CLASS_DEFINITION_ROOT(cbox_rt
)
37 struct cbox_rt_cmd_instance
39 struct cbox_rt_cmd_definition
*definition
;
44 static gboolean
cbox_rt_process_cmd(struct cbox_command_target
*ct
, struct cbox_command_target
*fb
, struct cbox_osc_command
*cmd
, GError
**error
)
46 struct cbox_rt
*rt
= ct
->user_data
;
47 if (!strcmp(cmd
->command
, "/status") && !strcmp(cmd
->arg_types
, ""))
49 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
53 GError
*cerror
= NULL
;
54 if (cbox_io_get_disconnect_status(rt
->io
, &cerror
))
56 return cbox_execute_on(fb
, NULL
, "/audio_channels", "ii", error
, rt
->io
->input_count
, rt
->io
->output_count
) &&
57 cbox_execute_on(fb
, NULL
, "/state", "is", error
, 1, "OK") &&
58 CBOX_OBJECT_DEFAULT_STATUS(rt
, fb
, error
);
62 return cbox_execute_on(fb
, NULL
, "/audio_channels", "ii", error
, rt
->io
->input_count
, rt
->io
->output_count
) &&
63 cbox_execute_on(fb
, NULL
, "/state", "is", error
, -1, cerror
? cerror
->message
: "Unknown error") &&
64 CBOX_OBJECT_DEFAULT_STATUS(rt
, fb
, error
);
68 return cbox_execute_on(fb
, NULL
, "/audio_channels", "ii", error
, 0, 2) &&
69 cbox_execute_on(fb
, NULL
, "/state", "is", error
, 0, "Offline") &&
70 CBOX_OBJECT_DEFAULT_STATUS(rt
, fb
, error
);
72 else if (!strcmp(cmd
->command
, "/cycle") && !strcmp(cmd
->arg_types
, ""))
74 if (rt
->io
&& !cbox_io_get_disconnect_status(rt
->io
, NULL
))
76 return cbox_io_cycle(rt
->io
, fb
, error
);
81 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Already connected");
83 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot cycle connection in off-line mode");
88 return cbox_object_default_process_cmd(ct
, fb
, cmd
, error
);
91 struct cbox_rt
*cbox_rt_new(struct cbox_document
*doc
)
93 struct cbox_rt
*rt
= malloc(sizeof(struct cbox_rt
));
94 CBOX_OBJECT_HEADER_INIT(rt
, cbox_rt
, doc
);
97 rt
->rb_execute
= jack_ringbuffer_create(sizeof(struct cbox_rt_cmd_instance
) * RT_CMD_QUEUE_ITEMS
);
98 rt
->rb_cleanup
= jack_ringbuffer_create(sizeof(struct cbox_rt_cmd_instance
) * RT_CMD_QUEUE_ITEMS
* 2);
100 rt
->master
= cbox_master_new(rt
);
101 rt
->master
->song
= cbox_song_new(CBOX_GET_DOCUMENT(rt
));
103 rt
->disconnected
= FALSE
;
106 cbox_midi_buffer_init(&rt
->midibuf_aux
);
107 cbox_midi_buffer_init(&rt
->midibuf_jack
);
108 cbox_midi_buffer_init(&rt
->midibuf_song
);
109 cbox_midi_buffer_init(&rt
->midibuf_total
);
110 cbox_midi_merger_init(&rt
->scene_input_merger
, &rt
->midibuf_total
);
112 cbox_midi_merger_connect(&rt
->scene_input_merger
, &rt
->midibuf_aux
, NULL
);
113 cbox_midi_merger_connect(&rt
->scene_input_merger
, &rt
->midibuf_jack
, NULL
);
114 cbox_midi_merger_connect(&rt
->scene_input_merger
, &rt
->midibuf_song
, NULL
);
116 cbox_command_target_init(&rt
->cmd_target
, cbox_rt_process_cmd
, rt
);
117 CBOX_OBJECT_REGISTER(rt
);
118 cbox_document_set_service(doc
, "rt", &rt
->_obj_hdr
);
123 struct cbox_objhdr
*cbox_rt_newfunc(struct cbox_class
*class_ptr
, struct cbox_document
*doc
)
128 void cbox_rt_destroyfunc(struct cbox_objhdr
*obj_ptr
)
132 static void cbox_rt_on_disconnected(void *user_data
)
134 struct cbox_rt
*rt
= user_data
;
135 rt
->disconnected
= TRUE
;
138 static void cbox_rt_on_reconnected(void *user_data
)
140 struct cbox_rt
*rt
= user_data
;
141 rt
->disconnected
= FALSE
;
144 static void cbox_rt_process(void *user_data
, struct cbox_io
*io
, uint32_t nframes
)
146 struct cbox_rt
*rt
= user_data
;
147 struct cbox_module
*effect
= rt
->effect
;
148 struct cbox_rt_cmd_instance cmd
;
152 cbox_midi_buffer_clear(&rt
->midibuf_aux
);
153 cbox_midi_buffer_clear(&rt
->midibuf_song
);
154 cbox_midi_buffer_clear(&rt
->midibuf_total
);
155 cbox_io_get_midi_data(io
, &rt
->midibuf_jack
);
157 // Process command queue, needs MIDI aux buf to work
159 while(cost
< RT_MAX_COST_PER_CALL
&& jack_ringbuffer_peek(rt
->rb_execute
, (char *)&cmd
, sizeof(cmd
)))
161 int result
= (cmd
.definition
->execute
)(cmd
.user_data
);
165 jack_ringbuffer_read_advance(rt
->rb_execute
, sizeof(cmd
));
166 if (cmd
.definition
->cleanup
|| !cmd
.is_async
)
168 jack_ringbuffer_write(rt
->rb_cleanup
, (const char *)&cmd
, sizeof(cmd
));
172 // Combine various sources of events (song, non-RT thread, JACK input)
173 if (rt
->scene
&& rt
->scene
->spb
)
174 cbox_song_playback_render(rt
->scene
->spb
, &rt
->midibuf_song
, nframes
);
176 cbox_midi_merger_render(&rt
->scene_input_merger
);
179 cbox_scene_render(rt
->scene
, nframes
, &rt
->midibuf_total
, io
->output_buffers
);
181 // Process "master" effect
184 for (i
= 0; i
< nframes
; i
+= CBOX_BLOCK_SIZE
)
186 cbox_sample_t left
[CBOX_BLOCK_SIZE
], right
[CBOX_BLOCK_SIZE
];
187 cbox_sample_t
*in_bufs
[2] = {io
->output_buffers
[0] + i
, io
->output_buffers
[1] + i
};
188 cbox_sample_t
*out_bufs
[2] = {left
, right
};
189 (*effect
->process_block
)(effect
, in_bufs
, out_bufs
);
190 for (j
= 0; j
< CBOX_BLOCK_SIZE
; j
++)
192 io
->output_buffers
[0][i
+ j
] = left
[j
];
193 io
->output_buffers
[1][i
+ j
] = right
[j
];
200 void cbox_rt_set_io(struct cbox_rt
*rt
, struct cbox_io
*io
)
202 assert(!rt
->started
);
206 rt
->srate
= cbox_io_get_sample_rate(io
);
207 rt
->buffer_size
= cbox_io_get_buffer_size(io
);
208 cbox_master_set_sample_rate(rt
->master
, rt
->srate
);
217 void cbox_rt_set_offline(struct cbox_rt
*rt
, int sample_rate
, int buffer_size
)
219 assert(!rt
->started
);
221 rt
->srate
= sample_rate
;
222 rt
->buffer_size
= buffer_size
;
223 cbox_master_set_sample_rate(rt
->master
, rt
->srate
);
226 void cbox_rt_start(struct cbox_rt
*rt
, struct cbox_command_target
*fb
)
231 rt
->cbs
= malloc(sizeof(struct cbox_io_callbacks
));
232 rt
->cbs
->user_data
= rt
;
233 rt
->cbs
->process
= cbox_rt_process
;
234 rt
->cbs
->on_disconnected
= cbox_rt_on_disconnected
;
235 rt
->cbs
->on_reconnected
= cbox_rt_on_reconnected
;
237 cbox_io_start(rt
->io
, rt
->cbs
, fb
);
241 void cbox_rt_stop(struct cbox_rt
*rt
)
246 cbox_io_stop(rt
->io
);
253 void cbox_rt_handle_cmd_queue(struct cbox_rt
*rt
)
255 struct cbox_rt_cmd_instance cmd
;
257 while(jack_ringbuffer_read(rt
->rb_cleanup
, (char *)&cmd
, sizeof(cmd
)))
259 cmd
.definition
->cleanup(cmd
.user_data
);
263 static void wait_write_space(jack_ringbuffer_t
*rb
)
266 while (jack_ringbuffer_write_space(rb
) < sizeof(struct cbox_rt_cmd_instance
))
268 // wait until some space frees up in the execute queue
273 fprintf(stderr
, "Execute queue full, waiting...\n");
279 void cbox_rt_execute_cmd_sync(struct cbox_rt
*rt
, struct cbox_rt_cmd_definition
*def
, void *user_data
)
281 struct cbox_rt_cmd_instance cmd
;
284 if (def
->prepare(user_data
))
287 // No realtime thread - do it all in the main thread
288 if (!rt
->started
|| rt
->disconnected
)
290 def
->execute(user_data
);
292 def
->cleanup(user_data
);
296 memset(&cmd
, 0, sizeof(cmd
));
297 cmd
.definition
= def
;
298 cmd
.user_data
= user_data
;
301 wait_write_space(rt
->rb_execute
);
302 jack_ringbuffer_write(rt
->rb_execute
, (const char *)&cmd
, sizeof(cmd
));
305 struct cbox_rt_cmd_instance cmd2
;
307 if (jack_ringbuffer_read_space(rt
->rb_cleanup
) < sizeof(cmd2
))
309 // still no result in cleanup queue - wait
313 jack_ringbuffer_read(rt
->rb_cleanup
, (char *)&cmd2
, sizeof(cmd2
));
314 if (!memcmp(&cmd
, &cmd2
, sizeof(cmd
)))
317 def
->cleanup(user_data
);
320 // async command - clean it up
321 if (cmd2
.definition
->cleanup
)
322 cmd2
.definition
->cleanup(cmd2
.user_data
);
326 void cbox_rt_execute_cmd_async(struct cbox_rt
*rt
, struct cbox_rt_cmd_definition
*def
, void *user_data
)
328 struct cbox_rt_cmd_instance cmd
= { def
, user_data
, 1 };
332 if (def
->prepare(user_data
))
335 // No realtime thread - do it all in the main thread
338 def
->execute(user_data
);
340 def
->cleanup(user_data
);
344 wait_write_space(rt
->rb_execute
);
345 jack_ringbuffer_write(rt
->rb_execute
, (const char *)&cmd
, sizeof(cmd
));
347 // will be cleaned up by next sync call or by cbox_rt_cmd_handle_queue
350 ////////////////////////////////////////////////////////////////////////////////////////
352 struct set_song_command
355 struct cbox_song_playback
*new_song
, *old_song
;
359 static int set_song_command_execute(void *user_data
)
361 struct set_song_command
*cmd
= user_data
;
363 if (cmd
->rt
->scene
&& cmd
->rt
->scene
->spb
&&
364 cbox_song_playback_active_notes_release(cmd
->rt
->scene
->spb
, &cmd
->rt
->midibuf_aux
) < 0)
366 cmd
->old_song
= cmd
->rt
->master
->spb
;
368 cmd
->rt
->scene
->spb
= cmd
->new_song
;
369 cmd
->rt
->master
->spb
= cmd
->new_song
;
372 if (cmd
->new_time_ppqn
== -1)
373 cbox_song_playback_seek_samples(cmd
->rt
->master
->spb
, cmd
->old_song
? cmd
->old_song
->song_pos_samples
: 0);
375 cbox_song_playback_seek_ppqn(cmd
->rt
->master
->spb
, cmd
->new_time_ppqn
, FALSE
);
381 void cbox_rt_update_song(struct cbox_rt
*rt
, int new_pos_ppqn
)
383 static struct cbox_rt_cmd_definition def
= { .prepare
= NULL
, .execute
= set_song_command_execute
, .cleanup
= NULL
};
385 struct set_song_command cmd
= { rt
, cbox_song_playback_new(rt
->master
->song
, rt
->master
), NULL
, new_pos_ppqn
};
386 cbox_rt_execute_cmd_sync(rt
, &def
, &cmd
);
388 cbox_song_playback_destroy(cmd
.old_song
);
391 ////////////////////////////////////////////////////////////////////////////////////////
393 void cbox_rt_update_song_playback(struct cbox_rt
*rt
)
395 cbox_rt_update_song(rt
, -1);
398 ////////////////////////////////////////////////////////////////////////////////////////
400 struct send_events_command
404 struct cbox_midi_buffer
*buffer
;
409 static int send_events_command_execute(void *user_data
)
411 struct send_events_command
*cmd
= user_data
;
414 if (cmd
->pos
>= cbox_midi_buffer_get_count(cmd
->buffer
))
417 int last_time
= cbox_midi_buffer_get_last_event_time(&cmd
->rt
->midibuf_aux
);
418 while (cmd
->pos
< cbox_midi_buffer_get_count(cmd
->buffer
))
420 struct cbox_midi_event
*event
= cbox_midi_buffer_get_event(cmd
->buffer
, cmd
->pos
);
421 int time
= event
->time
- cmd
->time_delta
;
422 if (time
< last_time
)
424 cbox_midi_buffer_copy_event(&cmd
->rt
->midibuf_aux
, event
, time
);
427 assert(cmd
->rt
->buffer_size
);
428 cmd
->time_delta
+= cmd
->rt
->buffer_size
;
430 return (cmd
->pos
>= cbox_midi_buffer_get_count(cmd
->buffer
)) ? 1 : 0;
433 void cbox_rt_send_events(struct cbox_rt
*rt
, struct cbox_midi_buffer
*buffer
)
435 if (cbox_midi_buffer_get_count(buffer
) == 0)
438 static struct cbox_rt_cmd_definition def
= { .prepare
= NULL
, .execute
= send_events_command_execute
, .cleanup
= NULL
};
440 struct send_events_command cmd
= { rt
, buffer
, 0, 0 };
442 cbox_rt_execute_cmd_sync(rt
, &def
, &cmd
);
445 ////////////////////////////////////////////////////////////////////////////////////////
447 struct swap_pointers_command
456 static int swap_pointers_command_execute(void *user_data
)
458 struct swap_pointers_command
*cmd
= user_data
;
460 cmd
->old_value
= *cmd
->ptr
;
461 *cmd
->ptr
= cmd
->new_value
;
463 *cmd
->pcount
= cmd
->new_count
;
468 void *cbox_rt_swap_pointers(struct cbox_rt
*rt
, void **ptr
, void *new_value
)
472 static struct cbox_rt_cmd_definition scdef
= { .prepare
= NULL
, .execute
= swap_pointers_command_execute
, .cleanup
= NULL
};
474 struct swap_pointers_command sc
= { ptr
, NULL
, new_value
, NULL
, 0 };
476 cbox_rt_execute_cmd_sync(rt
, &scdef
, &sc
);
480 void *old_ptr
= *ptr
;
486 void *cbox_rt_swap_pointers_and_update_count(struct cbox_rt
*rt
, void **ptr
, void *new_value
, int *pcount
, int new_count
)
490 static struct cbox_rt_cmd_definition scdef
= { .prepare
= NULL
, .execute
= swap_pointers_command_execute
, .cleanup
= NULL
};
492 struct swap_pointers_command sc
= { ptr
, NULL
, new_value
, pcount
, new_count
};
494 cbox_rt_execute_cmd_sync(rt
, &scdef
, &sc
);
500 void *old_ptr
= *ptr
;
507 void cbox_rt_array_insert(struct cbox_rt
*rt
, void ***ptr
, int *pcount
, int index
, void *new_value
)
510 assert(index
<= *pcount
);
511 assert(*pcount
>= 0);
512 void **new_array
= stm_array_clone_insert(*ptr
, *pcount
, index
, new_value
);
513 free(cbox_rt_swap_pointers_and_update_count(rt
, (void **)ptr
, new_array
, pcount
, *pcount
+ 1));
516 void *cbox_rt_array_remove(struct cbox_rt
*rt
, void ***ptr
, int *pcount
, int index
)
521 assert(index
< *pcount
);
523 void *p
= (*ptr
)[index
];
524 void **new_array
= stm_array_clone_remove(*ptr
, *pcount
, index
);
525 free(cbox_rt_swap_pointers_and_update_count(rt
, (void **)ptr
, new_array
, pcount
, *pcount
- 1));
529 ////////////////////////////////////////////////////////////////////////////////////////
531 struct cbox_scene
*cbox_rt_set_scene(struct cbox_rt
*rt
, struct cbox_scene
*scene
)
534 scene
->spb
= rt
->master
->spb
;
535 return cbox_rt_swap_pointers(rt
, (void **)&rt
->scene
, scene
);
538 ////////////////////////////////////////////////////////////////////////////////////////
540 int cbox_rt_get_sample_rate(struct cbox_rt
*rt
)
546 int cbox_rt_get_buffer_size(struct cbox_rt
*rt
)
548 assert(rt
->buffer_size
);
549 return rt
->buffer_size
;
552 ////////////////////////////////////////////////////////////////////////////////////////
554 void cbox_rt_destroy(struct cbox_rt
*rt
)
556 if (rt
->master
->song
)
557 CBOX_DELETE(rt
->master
->song
);
558 jack_ringbuffer_free(rt
->rb_execute
);
559 jack_ringbuffer_free(rt
->rb_cleanup
);
561 cbox_master_destroy(rt
->master
);
564 cbox_midi_merger_close(&rt
->scene_input_merger
);