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/>.
20 #include "config-api.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
;
42 jack_port_t
**outputs
;
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
;
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
)
75 if (only_connect_port
)
78 right
= jack_port_by_name(client
, use_name
);
79 if (only_connect_port
!= right
)
84 res
= jack_connect(client
, use_name
, port
);
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
;
95 orig_name
= cbox_config_get_string(cbox_io_section
, config_var
);
100 dpos
= strchr(name
, ';');
105 if (use_name
[0] == '#')
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
);
113 for (i
= 0; i
< portidx
&& names
[i
]; i
++)
117 autoconnect_port(client
, port
, names
[i
], is_cbox_input
, only_connect_port
);
119 g_message("Connect: unmatched port index %d", (int)portidx
);
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] == '*')
133 for (i
= 0; names
[i
]; i
++)
134 autoconnect_port(client
, port
, names
[i
], is_cbox_input
, only_connect_port
);
137 autoconnect_port(client
, port
, names
[0], is_cbox_input
, only_connect_port
);
140 g_message("Connect: unmatched port regexp %s", use_name
);
144 autoconnect_port(client
, port
, use_name
, is_cbox_input
, only_connect_port
);
152 static void port_connect_cb(jack_port_id_t port
, int registered
, void *arg
)
154 struct cbox_jack_io_impl
*jii
= arg
;
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
);
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
);
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
;
198 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "%s", jii
->error_str
);
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
);
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
;
232 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "%s", jii
->error_str
);
235 jack_deactivate(jii
->client
);
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
271 memcpy(data
, event
.buffer
, event
.size
);
272 if (!cbox_midi_buffer_write_event(destination
, event
.time
, data
, event
.size
))
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
;
290 g_free(jii
->error_str
);
291 jii
->error_str
= NULL
;
295 for (int i
= 0; i
< io
->output_count
; i
++)
296 jack_port_unregister(jii
->client
, jii
->outputs
[i
]);
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
;
312 // XXXKF use params structure some day
313 if (!cbox_io_init_jack(io
, NULL
, error
))
316 cbox_io_start(io
, cb
);
317 if (cb
->on_reconnected
)
318 (cb
->on_reconnected
)(cb
->user_data
);
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
);
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");
340 client
= jack_client_open("cbox", 0, &status
);
344 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create JACK instance");
348 // XXXKF would use a callback instead
349 io
->buffer_size
= jack_get_buffer_size(client
);
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
;
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);
385 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create input port %d (%s)", i
, 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
);
403 jii
->midi
= jack_port_register(jii
->client
, "midi", JACK_DEFAULT_MIDI_TYPE
, JackPortIsInput
, 0);
407 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create MIDI port");
411 cbox_io_poll_ports(io
);
418 for (int i
= 0; i
< io
->input_count
; i
++)
419 free(jii
->inputs
[i
]);
424 for (int i
= 0; i
< io
->output_count
; i
++)
425 free(jii
->outputs
[i
]);
428 jack_client_close(jii
->client
);