Free built-in waveforms and their bandlimited copies on exit.
[calfbox.git] / jackio.c
blobf2b870f8f4a08f4fbb21161f385939d54f74ed2e
1 /*
2 Calf Box, an open source musical instrument.
3 Copyright (C) 2010-2012 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 "config.h"
20 #include "config-api.h"
21 #include "errors.h"
22 #include "hwcfg.h"
23 #include "io.h"
24 #include "meter.h"
25 #include "midi.h"
26 #include "recsrc.h"
28 #include <errno.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <glib.h>
32 #include <jack/ringbuffer.h>
33 #include <jack/types.h>
34 #include <jack/midiport.h>
36 struct cbox_jack_io_impl
38 struct cbox_io_impl ioi;
40 jack_client_t *client;
41 jack_port_t **inputs;
42 jack_port_t **outputs;
43 jack_port_t *midi;
44 char *error_str; // set to non-NULL if client has been booted out by JACK
46 jack_ringbuffer_t *rb_autoconnect;
49 static int process_cb(jack_nframes_t nframes, void *arg)
51 struct cbox_jack_io_impl *jii = arg;
52 struct cbox_io *io = jii->ioi.pio;
53 struct cbox_io_callbacks *cb = io->cb;
55 io->buffer_size = nframes;
56 for (int i = 0; i < io->input_count; i++)
57 io->input_buffers[i] = jack_port_get_buffer(jii->inputs[i], nframes);
58 for (int i = 0; i < io->output_count; i++)
60 io->output_buffers[i] = jack_port_get_buffer(jii->outputs[i], nframes);
61 for (int j = 0; j < nframes; j ++)
62 io->output_buffers[i][j] = 0.f;
64 cb->process(cb->user_data, io, nframes);
65 for (int i = 0; i < io->input_count; i++)
66 io->input_buffers[i] = NULL;
67 for (int i = 0; i < io->output_count; i++)
68 io->output_buffers[i] = NULL;
69 return 0;
72 static void autoconnect_port(jack_client_t *client, const char *port, const char *use_name, int is_cbox_input, const jack_port_t *only_connect_port)
74 int res;
75 if (only_connect_port)
77 jack_port_t *right;
78 right = jack_port_by_name(client, use_name);
79 if (only_connect_port != right)
80 return;
83 if (is_cbox_input)
84 res = jack_connect(client, use_name, port);
85 else
86 res = jack_connect(client, port, use_name);
87 g_message("Connect: %s %s %s (%s)", port, is_cbox_input ? "<-" : "->", use_name, res == 0 ? "success" : (res == EEXIST ? "already connected" : "failed"));
90 static void autoconnect(jack_client_t *client, const char *port, const char *config_var, int is_cbox_input, int is_midi, const jack_port_t *only_connect_port)
92 char *name, *orig_name, *dpos;
93 const char *use_name;
95 orig_name = cbox_config_get_string(cbox_io_section, config_var);
96 if (orig_name)
98 name = orig_name;
99 do {
100 dpos = strchr(name, ';');
101 if (dpos)
102 *dpos = '\0';
104 use_name = name;
105 if (use_name[0] == '#')
107 char *endptr = NULL;
108 long portidx = strtol(use_name + 1, &endptr, 10) - 1;
109 if (endptr == use_name + strlen(use_name))
111 const char **names = jack_get_ports(client, ".*", is_midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE, is_cbox_input ? JackPortIsOutput : JackPortIsInput);
112 int i;
113 for (i = 0; i < portidx && names[i]; i++)
116 if (names[i])
117 autoconnect_port(client, port, names[i], is_cbox_input, only_connect_port);
118 else
119 g_message("Connect: unmatched port index %d", (int)portidx);
121 jack_free(names);
124 else if (use_name[0] == '~' || use_name[0] == '*')
126 const char **names = jack_get_ports(client, use_name + 1, is_midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE, is_cbox_input ? JackPortIsOutput : JackPortIsInput);
128 if (names && names[0])
130 if (use_name[0] == '*')
132 int i;
133 for (i = 0; names[i]; i++)
134 autoconnect_port(client, port, names[i], is_cbox_input, only_connect_port);
136 else
137 autoconnect_port(client, port, names[0], is_cbox_input, only_connect_port);
139 else
140 g_message("Connect: unmatched port regexp %s", use_name);
141 jack_free(names);
143 else
144 autoconnect_port(client, port, use_name, is_cbox_input, only_connect_port);
146 if (dpos)
147 name = dpos + 1;
148 } while(dpos);
152 static void port_connect_cb(jack_port_id_t port, int registered, void *arg)
154 struct cbox_jack_io_impl *jii = arg;
155 if (registered)
157 jack_port_t *portobj = jack_port_by_id(jii->client, port);
159 jack_ringbuffer_write(jii->rb_autoconnect, (uint8_t *)&portobj, sizeof(portobj));
163 static void port_autoconnect(struct cbox_jack_io_impl *jii, jack_port_t *portobj)
165 struct cbox_io *io = jii->ioi.pio;
167 for (int i = 0; i < io->output_count; i++)
169 gchar *cbox_port = g_strdup_printf("cbox:out_%d", 1 + i);
170 gchar *config_key = g_strdup_printf("out_%d", 1 + i);
171 autoconnect(jii->client, cbox_port, config_key, 0, 0, portobj);
172 g_free(cbox_port);
173 g_free(config_key);
175 for (int i = 0; i < io->input_count; i++)
177 gchar *cbox_port = g_strdup_printf("cbox:in_%d", 1 + i);
178 gchar *config_key = g_strdup_printf("in_%d", 1 + i);
179 autoconnect(jii->client, cbox_port, config_key, 1, 0, portobj);
180 g_free(cbox_port);
181 g_free(config_key);
183 autoconnect(jii->client, "cbox:midi", "midi", 1, 1, portobj);
186 int cbox_jackio_get_sample_rate(struct cbox_io_impl *impl)
188 struct cbox_jack_io_impl *jii = (struct cbox_jack_io_impl *)impl;
190 return jack_get_sample_rate(jii->client);
193 gboolean cbox_jackio_get_status(struct cbox_io_impl *impl, GError **error)
195 struct cbox_jack_io_impl *jii = (struct cbox_jack_io_impl *)impl;
196 if (!jii->error_str)
197 return TRUE;
198 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "%s", jii->error_str);
199 return FALSE;
202 static void client_shutdown_cb(jack_status_t code, const char *reason, void *arg)
204 struct cbox_jack_io_impl *jii = arg;
205 struct cbox_io *io = jii->ioi.pio;
206 jii->error_str = g_strdup(reason);
207 if (io->cb && io->cb->on_disconnected)
208 (io->cb->on_disconnected)(io->cb->user_data);
211 gboolean cbox_jackio_start(struct cbox_io_impl *impl, GError **error)
213 struct cbox_jack_io_impl *jii = (struct cbox_jack_io_impl *)impl;
215 jack_set_process_callback(jii->client, process_cb, jii);
216 jack_set_port_registration_callback(jii->client, port_connect_cb, jii);
217 jack_on_info_shutdown(jii->client, client_shutdown_cb, jii);
218 jack_activate(jii->client);
220 if (cbox_config_has_section(cbox_io_section))
221 port_autoconnect(jii, NULL);
223 return TRUE;
226 gboolean cbox_jackio_stop(struct cbox_io_impl *impl, GError **error)
228 struct cbox_jack_io_impl *jii = (struct cbox_jack_io_impl *)impl;
230 if (jii->error_str)
232 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "%s", jii->error_str);
233 return FALSE;
235 jack_deactivate(jii->client);
236 return TRUE;
239 void cbox_jackio_poll_ports(struct cbox_io_impl *impl)
241 struct cbox_jack_io_impl *jii = (struct cbox_jack_io_impl *)impl;
243 while (jack_ringbuffer_read_space(jii->rb_autoconnect) >= sizeof(jack_port_t *))
245 jack_port_t *portobj;
246 jack_ringbuffer_read(jii->rb_autoconnect, (uint8_t *)&portobj, sizeof(portobj));
247 port_autoconnect(jii, portobj);
251 int cbox_jackio_get_midi_data(struct cbox_io_impl *impl, struct cbox_midi_buffer *destination)
253 struct cbox_jack_io_impl *jii = (struct cbox_jack_io_impl *)impl;
255 jack_port_t *port = jii->midi;
256 void *midi = jack_port_get_buffer(port, jii->ioi.pio->buffer_size);
257 uint32_t event_count = jack_midi_get_event_count(midi);
259 cbox_midi_buffer_clear(destination);
260 for (uint32_t i = 0; i < event_count; i++)
262 jack_midi_event_t event;
264 if (!jack_midi_event_get(&event, midi, i))
266 // XXXKF ignore sysex for now
267 if (event.size >= 4)
268 continue;
270 uint8_t data[4];
271 memcpy(data, event.buffer, event.size);
272 if (!cbox_midi_buffer_write_event(destination, event.time, data, event.size))
273 return -i;
275 else
276 return -i;
279 return event_count;
282 void cbox_jackio_destroy(struct cbox_io_impl *impl)
284 struct cbox_jack_io_impl *jii = (struct cbox_jack_io_impl *)impl;
285 struct cbox_io *io = impl->pio;
286 if (jii->client)
288 if (jii->error_str)
290 g_free(jii->error_str);
291 jii->error_str = NULL;
293 else
295 for (int i = 0; i < io->output_count; i++)
296 jack_port_unregister(jii->client, jii->outputs[i]);
297 if (jii->midi)
298 jack_port_unregister(jii->client, jii->midi);
301 jack_ringbuffer_free(jii->rb_autoconnect);
302 jack_client_close(jii->client);
306 gboolean cbox_jackio_cycle(struct cbox_io_impl *impl, GError **error)
308 struct cbox_io *io = impl->pio;
309 struct cbox_io_callbacks *cb = io->cb;
310 cbox_io_close(io);
312 // XXXKF use params structure some day
313 if (!cbox_io_init_jack(io, NULL, error))
314 return FALSE;
316 cbox_io_start(io, cb);
317 if (cb->on_reconnected)
318 (cb->on_reconnected)(cb->user_data);
319 return TRUE;
324 ///////////////////////////////////////////////////////////////////////////////
326 gboolean cbox_io_init_jack(struct cbox_io *io, struct cbox_open_params *const params, GError **error)
328 jack_client_t *client = NULL;
329 jack_status_t status = 0;
330 client = jack_client_open("cbox", JackNoStartServer, &status);
331 if (client == NULL)
333 if (!cbox_hwcfg_setup_jack())
335 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Cannot set up JACK server configuration based on current hardware");
336 return FALSE;
339 status = 0;
340 client = jack_client_open("cbox", 0, &status);
342 if (client == NULL)
344 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Cannot create JACK instance");
345 return FALSE;
348 // XXXKF would use a callback instead
349 io->buffer_size = jack_get_buffer_size(client);
350 io->cb = NULL;
351 io->input_count = cbox_config_get_int("io", "inputs", 0);
352 io->input_buffers = malloc(sizeof(float *) * io->input_count);
353 io->output_count = cbox_config_get_int("io", "outputs", 2);
354 io->output_buffers = malloc(sizeof(float *) * io->output_count);
356 struct cbox_jack_io_impl *jii = malloc(sizeof(struct cbox_jack_io_impl));
357 io->impl = &jii->ioi;
359 jii->ioi.pio = io;
360 jii->ioi.getsampleratefunc = cbox_jackio_get_sample_rate;
361 jii->ioi.startfunc = cbox_jackio_start;
362 jii->ioi.stopfunc = cbox_jackio_stop;
363 jii->ioi.getstatusfunc = cbox_jackio_get_status;
364 jii->ioi.pollfunc = cbox_jackio_poll_ports;
365 jii->ioi.cyclefunc = cbox_jackio_cycle;
366 jii->ioi.getmidifunc = cbox_jackio_get_midi_data;
367 jii->ioi.destroyfunc = cbox_jackio_destroy;
369 jii->client = client;
370 jii->rb_autoconnect = jack_ringbuffer_create(sizeof(jack_port_t *) * 128);
371 jii->error_str = NULL;
373 jii->inputs = malloc(sizeof(jack_port_t *) * io->input_count);
374 jii->outputs = malloc(sizeof(jack_port_t *) * io->output_count);
375 for (int i = 0; i < io->input_count; i++)
376 jii->inputs[i] = NULL;
377 for (int i = 0; i < io->output_count; i++)
378 jii->outputs[i] = NULL;
379 for (int i = 0; i < io->input_count; i++)
381 gchar *name = g_strdup_printf("in_%d", 1 + i);
382 jii->inputs[i] = jack_port_register(jii->client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
383 if (!jii->inputs[i])
385 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Cannot create input port %d (%s)", i, name);
386 g_free(name);
387 goto cleanup;
389 g_free(name);
391 for (int i = 0; i < io->output_count; i++)
393 gchar *name = g_strdup_printf("out_%d", 1 + i);
394 jii->outputs[i] = jack_port_register(jii->client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
395 if (!jii->outputs[i])
397 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Cannot create output port %d (%s)", i, name);
398 g_free(name);
399 goto cleanup;
401 g_free(name);
403 jii->midi = jack_port_register(jii->client, "midi", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
405 if (!jii->midi)
407 g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Cannot create MIDI port");
408 return FALSE;
411 cbox_io_poll_ports(io);
413 return TRUE;
415 cleanup:
416 if (jii->inputs)
418 for (int i = 0; i < io->input_count; i++)
419 free(jii->inputs[i]);
420 free(jii->inputs);
422 if (jii->outputs)
424 for (int i = 0; i < io->output_count; i++)
425 free(jii->outputs[i]);
426 free(jii->outputs);
428 jack_client_close(jii->client);
429 free(jii);
430 io->impl = NULL;
431 return FALSE;