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"
33 #include <jack/ringbuffer.h>
34 #include <jack/types.h>
35 #include <jack/midiport.h>
37 struct cbox_jack_io_impl
39 struct cbox_io_impl ioi
;
41 jack_client_t
*client
;
43 jack_port_t
**outputs
;
45 char *error_str
; // set to non-NULL if client has been booted out by JACK
48 jack_ringbuffer_t
*rb_autoconnect
;
51 ///////////////////////////////////////////////////////////////////////////////
53 struct cbox_jack_midi_input
55 struct cbox_midi_input hdr
;
56 gchar
*autoconnect_spec
;
58 struct cbox_jack_io_impl
*jii
;
61 struct cbox_jack_midi_output
63 struct cbox_midi_output hdr
;
64 gchar
*autoconnect_spec
;
66 struct cbox_jack_io_impl
*jii
;
69 static struct cbox_midi_input
*cbox_jackio_create_midi_in(struct cbox_io_impl
*impl
, const char *name
, GError
**error
);
70 static struct cbox_midi_output
*cbox_jackio_create_midi_out(struct cbox_io_impl
*impl
, const char *name
, GError
**error
);
71 static void cbox_jackio_destroy_midi_in(struct cbox_io_impl
*ioi
, struct cbox_midi_input
*midiin
);
72 static void cbox_jackio_destroy_midi_out(struct cbox_io_impl
*ioi
, struct cbox_midi_output
*midiout
);
73 static void cbox_jack_midi_output_set_autoconnect(struct cbox_jack_midi_output
*jmo
, const gchar
*autoconnect_spec
);
75 void cbox_jack_midi_input_destroy(struct cbox_jack_midi_input
*jmi
)
79 jack_port_unregister(jmi
->jii
->client
, jmi
->port
);
82 g_free(jmi
->hdr
.name
);
83 g_free(jmi
->autoconnect_spec
);
87 void cbox_jack_midi_output_destroy(struct cbox_jack_midi_output
*jmo
)
91 jack_port_unregister(jmo
->jii
->client
, jmo
->port
);
94 g_free(jmo
->hdr
.name
);
95 g_free(jmo
->autoconnect_spec
);
99 ///////////////////////////////////////////////////////////////////////////////
101 static int process_cb(jack_nframes_t nframes
, void *arg
)
103 struct cbox_jack_io_impl
*jii
= arg
;
104 struct cbox_io
*io
= jii
->ioi
.pio
;
105 struct cbox_io_callbacks
*cb
= io
->cb
;
107 io
->buffer_size
= nframes
;
108 for (int i
= 0; i
< io
->input_count
; i
++)
109 io
->input_buffers
[i
] = jack_port_get_buffer(jii
->inputs
[i
], nframes
);
110 for (int i
= 0; i
< io
->output_count
; i
++)
112 io
->output_buffers
[i
] = jack_port_get_buffer(jii
->outputs
[i
], nframes
);
113 for (int j
= 0; j
< nframes
; j
++)
114 io
->output_buffers
[i
][j
] = 0.f
;
116 cb
->process(cb
->user_data
, io
, nframes
);
117 for (int i
= 0; i
< io
->input_count
; i
++)
118 io
->input_buffers
[i
] = NULL
;
119 for (int i
= 0; i
< io
->output_count
; i
++)
120 io
->output_buffers
[i
] = NULL
;
121 for (GSList
*p
= io
->midi_outputs
; p
; p
= g_slist_next(p
))
123 struct cbox_jack_midi_output
*midiout
= p
->data
;
125 void *pbuf
= jack_port_get_buffer(midiout
->port
, nframes
);
126 jack_midi_clear_buffer(pbuf
);
128 cbox_midi_merger_render(&midiout
->hdr
.merger
);
129 if (midiout
->hdr
.buffer
.count
)
132 for (int i
= 0; i
< midiout
->hdr
.buffer
.count
; i
++)
134 const struct cbox_midi_event
*event
= cbox_midi_buffer_get_event(&midiout
->hdr
.buffer
, i
);
135 const uint8_t *pdata
= cbox_midi_event_get_data(event
);
136 if ((pdata
[0] & 0xF0) == 0x90 && !pdata
[2] && event
->size
== 3)
138 tmp_data
[0] = pdata
[0] & ~0x10;
139 tmp_data
[1] = pdata
[1];
140 tmp_data
[2] = pdata
[2];
143 if (jack_midi_event_write(pbuf
, event
->time
, pdata
, event
->size
))
145 g_warning("MIDI buffer overflow on JACK output port '%s'", midiout
->hdr
.name
);
154 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
, struct cbox_command_target
*fb
)
157 if (only_connect_port
)
160 right
= jack_port_by_name(client
, use_name
);
161 if (only_connect_port
!= right
)
165 const char *pfrom
= is_cbox_input
? use_name
: port
;
166 const char *pto
= !is_cbox_input
? use_name
: port
;
168 res
= jack_connect(client
, pfrom
, pto
);
171 gboolean suppressed
= FALSE
;
175 suppressed
= cbox_execute_on(fb
, NULL
, "/io/jack/connected", "ss", NULL
, pfrom
, pto
);
177 suppressed
= cbox_execute_on(fb
, NULL
, "/io/jack/connect_failed", "sss", NULL
, pfrom
, pto
, (res
== EEXIST
? "already connected" : "failed"));
180 g_message("Connect: %s %s %s (%s)", port
, is_cbox_input
? "<-" : "->", use_name
, res
== 0 ? "success" : (res
== EEXIST
? "already connected" : "failed"));
183 static void autoconnect_by_spec(jack_client_t
*client
, const char *port
, const char *orig_spec
, int is_cbox_input
, int is_midi
, const jack_port_t
*only_connect_port
, struct cbox_command_target
*fb
)
185 char *name
, *copy_spec
, *dpos
;
186 const char *use_name
;
188 copy_spec
= g_strdup(orig_spec
);
191 dpos
= strchr(name
, ';');
196 if (use_name
[0] == '#')
199 long portidx
= strtol(use_name
+ 1, &endptr
, 10) - 1;
200 if (endptr
== use_name
+ strlen(use_name
))
202 const char **names
= jack_get_ports(client
, ".*", is_midi
? JACK_DEFAULT_MIDI_TYPE
: JACK_DEFAULT_AUDIO_TYPE
, is_cbox_input
? JackPortIsOutput
: JackPortIsInput
);
204 for (i
= 0; i
< portidx
&& names
[i
]; i
++)
208 autoconnect_port(client
, port
, names
[i
], is_cbox_input
, only_connect_port
, fb
);
210 g_message("Connect: unmatched port index %d", (int)portidx
);
215 else if (use_name
[0] == '~' || use_name
[0] == '*')
217 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
);
219 if (names
&& names
[0])
221 if (use_name
[0] == '*')
224 for (i
= 0; names
[i
]; i
++)
225 autoconnect_port(client
, port
, names
[i
], is_cbox_input
, only_connect_port
, fb
);
228 autoconnect_port(client
, port
, names
[0], is_cbox_input
, only_connect_port
, fb
);
231 g_message("Connect: unmatched port regexp %s", use_name
);
235 autoconnect_port(client
, port
, use_name
, is_cbox_input
, only_connect_port
, fb
);
243 static void autoconnect_by_var(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
, struct cbox_command_target
*fb
)
245 const char *orig_spec
= cbox_config_get_string(cbox_io_section
, config_var
);
247 autoconnect_by_spec(client
, port
, orig_spec
, is_cbox_input
, is_midi
, only_connect_port
, fb
);
250 static void port_connect_cb(jack_port_id_t port
, int registered
, void *arg
)
252 struct cbox_jack_io_impl
*jii
= arg
;
255 jack_port_t
*portobj
= jack_port_by_id(jii
->client
, port
);
257 jack_ringbuffer_write(jii
->rb_autoconnect
, (char *)&portobj
, sizeof(portobj
));
261 static void port_autoconnect(struct cbox_jack_io_impl
*jii
, jack_port_t
*portobj
, struct cbox_command_target
*fb
)
263 struct cbox_io
*io
= jii
->ioi
.pio
;
265 for (int i
= 0; i
< io
->output_count
; i
++)
267 gchar
*cbox_port
= g_strdup_printf("%s:out_%d", jii
->client_name
, 1 + i
);
268 gchar
*config_key
= g_strdup_printf("out_%d", 1 + i
);
269 autoconnect_by_var(jii
->client
, cbox_port
, config_key
, 0, 0, portobj
, fb
);
273 for (int i
= 0; i
< io
->input_count
; i
++)
275 gchar
*cbox_port
= g_strdup_printf("%s:in_%d", jii
->client_name
, 1 + i
);
276 gchar
*config_key
= g_strdup_printf("in_%d", 1 + i
);
277 autoconnect_by_var(jii
->client
, cbox_port
, config_key
, 1, 0, portobj
, fb
);
281 for (GSList
*p
= io
->midi_outputs
; p
; p
= g_slist_next(p
))
283 struct cbox_jack_midi_output
*midiout
= p
->data
;
284 if (midiout
->autoconnect_spec
)
286 gchar
*cbox_port
= g_strdup_printf("%s:%s", jii
->client_name
, midiout
->hdr
.name
);
287 autoconnect_by_spec(jii
->client
, cbox_port
, midiout
->autoconnect_spec
, 0, 1, portobj
, fb
);
291 for (GSList
*p
= io
->midi_inputs
; p
; p
= g_slist_next(p
))
293 struct cbox_jack_midi_input
*midiin
= p
->data
;
294 if (midiin
->autoconnect_spec
)
296 gchar
*cbox_port
= g_strdup_printf("%s:%s", jii
->client_name
, midiin
->hdr
.name
);
297 autoconnect_by_spec(jii
->client
, cbox_port
, midiin
->autoconnect_spec
, 1, 1, portobj
, fb
);
301 gchar
*cbox_port
= g_strdup_printf("%s:midi", jii
->client_name
);
302 autoconnect_by_var(jii
->client
, cbox_port
, "midi", 1, 1, portobj
, fb
);
306 int cbox_jackio_get_sample_rate(struct cbox_io_impl
*impl
)
308 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
310 return jack_get_sample_rate(jii
->client
);
313 gboolean
cbox_jackio_get_status(struct cbox_io_impl
*impl
, GError
**error
)
315 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
318 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "%s", jii
->error_str
);
322 static void client_shutdown_cb(jack_status_t code
, const char *reason
, void *arg
)
324 struct cbox_jack_io_impl
*jii
= arg
;
325 struct cbox_io
*io
= jii
->ioi
.pio
;
326 jii
->error_str
= g_strdup(reason
);
327 if (io
->cb
&& io
->cb
->on_disconnected
)
328 (io
->cb
->on_disconnected
)(io
->cb
->user_data
);
331 gboolean
cbox_jackio_start(struct cbox_io_impl
*impl
, struct cbox_command_target
*fb
, GError
**error
)
333 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
335 jack_set_process_callback(jii
->client
, process_cb
, jii
);
336 jack_set_port_registration_callback(jii
->client
, port_connect_cb
, jii
);
337 jack_on_info_shutdown(jii
->client
, client_shutdown_cb
, jii
);
338 jack_activate(jii
->client
);
340 if (cbox_config_has_section(cbox_io_section
))
341 port_autoconnect(jii
, NULL
, fb
);
346 gboolean
cbox_jackio_stop(struct cbox_io_impl
*impl
, GError
**error
)
348 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
352 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "%s", jii
->error_str
);
355 jack_deactivate(jii
->client
);
359 void cbox_jackio_poll_ports(struct cbox_io_impl
*impl
, struct cbox_command_target
*fb
)
361 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
363 while (jack_ringbuffer_read_space(jii
->rb_autoconnect
) >= sizeof(jack_port_t
*))
365 jack_port_t
*portobj
;
366 jack_ringbuffer_read(jii
->rb_autoconnect
, (char *)&portobj
, sizeof(portobj
));
367 port_autoconnect(jii
, portobj
, fb
);
371 int cbox_jackio_get_midi_data(struct cbox_io_impl
*impl
, struct cbox_midi_buffer
*destination
)
373 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
375 jack_port_t
*port
= jii
->midi
;
376 void *midi
= jack_port_get_buffer(port
, jii
->ioi
.pio
->buffer_size
);
377 uint32_t event_count
= jack_midi_get_event_count(midi
);
379 cbox_midi_buffer_clear(destination
);
380 for (uint32_t i
= 0; i
< event_count
; i
++)
382 jack_midi_event_t event
;
384 if (!jack_midi_event_get(&event
, midi
, i
))
386 if (!cbox_midi_buffer_write_event(destination
, event
.time
, event
.buffer
, event
.size
))
396 void cbox_jackio_destroy(struct cbox_io_impl
*impl
)
398 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
399 struct cbox_io
*io
= impl
->pio
;
404 g_free(jii
->error_str
);
405 jii
->error_str
= NULL
;
409 for (int i
= 0; i
< io
->input_count
; i
++)
410 jack_port_unregister(jii
->client
, jii
->inputs
[i
]);
412 for (int i
= 0; i
< io
->output_count
; i
++)
413 jack_port_unregister(jii
->client
, jii
->outputs
[i
]);
416 jack_port_unregister(jii
->client
, jii
->midi
);
418 if (jii
->client_name
)
420 free(jii
->client_name
);
421 jii
->client_name
= NULL
;
423 cbox_io_destroy_all_midi_ports(io
);
425 jack_ringbuffer_free(jii
->rb_autoconnect
);
426 jack_client_close(jii
->client
);
431 gboolean
cbox_jackio_cycle(struct cbox_io_impl
*impl
, struct cbox_command_target
*fb
, GError
**error
)
433 struct cbox_io
*io
= impl
->pio
;
434 struct cbox_io_callbacks
*cb
= io
->cb
;
437 // XXXKF use params structure some day
438 if (!cbox_io_init_jack(io
, NULL
, fb
, error
))
441 cbox_io_start(io
, cb
, fb
);
442 if (cb
->on_reconnected
)
443 (cb
->on_reconnected
)(cb
->user_data
);
449 ///////////////////////////////////////////////////////////////////////////////
451 struct cbox_midi_input
*cbox_jackio_create_midi_in(struct cbox_io_impl
*impl
, const char *name
, GError
**error
)
453 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
454 jack_port_t
*port
= jack_port_register(jii
->client
, name
, JACK_DEFAULT_MIDI_TYPE
, JackPortIsInput
, 0);
457 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create input MIDI port '%s'", name
);
460 struct cbox_jack_midi_input
*input
= calloc(1, sizeof(struct cbox_jack_midi_input
));
461 input
->hdr
.name
= g_strdup(name
);
462 input
->hdr
.removing
= FALSE
;
465 cbox_uuid_generate(&input
->hdr
.uuid
);
466 cbox_midi_buffer_init(&input
->hdr
.buffer
);
468 return (struct cbox_midi_input
*)input
;
471 struct cbox_midi_output
*cbox_jackio_create_midi_out(struct cbox_io_impl
*impl
, const char *name
, GError
**error
)
473 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
474 jack_port_t
*port
= jack_port_register(jii
->client
, name
, JACK_DEFAULT_MIDI_TYPE
, JackPortIsOutput
, 0);
477 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create output MIDI port '%s'", name
);
480 struct cbox_jack_midi_output
*output
= calloc(1, sizeof(struct cbox_jack_midi_output
));
481 output
->hdr
.name
= g_strdup(name
);
482 output
->hdr
.removing
= FALSE
;
485 cbox_uuid_generate(&output
->hdr
.uuid
);
486 cbox_midi_buffer_init(&output
->hdr
.buffer
);
487 cbox_midi_merger_init(&output
->hdr
.merger
, &output
->hdr
.buffer
);
489 return (struct cbox_midi_output
*)output
;
492 void cbox_jack_midi_input_set_autoconnect(struct cbox_jack_midi_input
*jmi
, const gchar
*autoconnect_spec
)
494 if (jmi
->autoconnect_spec
)
495 g_free(jmi
->autoconnect_spec
);
496 jmi
->autoconnect_spec
= autoconnect_spec
&& *autoconnect_spec
? g_strdup(autoconnect_spec
) : NULL
;
497 if (jmi
->autoconnect_spec
)
499 gchar
*cbox_port
= g_strdup_printf("%s:%s", jmi
->jii
->client_name
, jmi
->hdr
.name
);
500 autoconnect_by_spec(jmi
->jii
->client
, cbox_port
, jmi
->autoconnect_spec
, 1, 1, NULL
, NULL
);
505 void cbox_jack_midi_output_set_autoconnect(struct cbox_jack_midi_output
*jmo
, const gchar
*autoconnect_spec
)
507 if (jmo
->autoconnect_spec
)
508 g_free(jmo
->autoconnect_spec
);
509 jmo
->autoconnect_spec
= autoconnect_spec
&& *autoconnect_spec
? g_strdup(autoconnect_spec
) : NULL
;
510 if (jmo
->autoconnect_spec
)
512 gchar
*cbox_port
= g_strdup_printf("%s:%s", jmo
->jii
->client_name
, jmo
->hdr
.name
);
513 autoconnect_by_spec(jmo
->jii
->client
, cbox_port
, jmo
->autoconnect_spec
, 0, 1, NULL
, NULL
);
518 void cbox_jackio_destroy_midi_in(struct cbox_io_impl
*ioi
, struct cbox_midi_input
*midiin
)
520 cbox_jack_midi_input_destroy((struct cbox_jack_midi_input
*)midiin
);
523 void cbox_jackio_destroy_midi_out(struct cbox_io_impl
*ioi
, struct cbox_midi_output
*midiout
)
525 cbox_jack_midi_output_destroy((struct cbox_jack_midi_output
*)midiout
);
528 static gboolean
cbox_jack_io_process_cmd(struct cbox_command_target
*ct
, struct cbox_command_target
*fb
, struct cbox_osc_command
*cmd
, GError
**error
)
530 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)ct
->user_data
;
531 struct cbox_io
*io
= jii
->ioi
.pio
;
532 gboolean handled
= FALSE
;
533 if (!strcmp(cmd
->command
, "/status") && !strcmp(cmd
->arg_types
, ""))
535 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
537 return cbox_execute_on(fb
, NULL
, "/client_type", "s", error
, "JACK") &&
538 cbox_execute_on(fb
, NULL
, "/client_name", "s", error
, jii
->client_name
) &&
539 cbox_io_process_cmd(io
, fb
, cmd
, error
, &handled
);
541 else if (!strcmp(cmd
->command
, "/rename_midi_port") && !strcmp(cmd
->arg_types
, "ss"))
543 const char *uuidstr
= CBOX_ARG_S(cmd
, 0);
544 const char *new_name
= CBOX_ARG_S(cmd
, 1);
545 struct cbox_uuid uuid
;
546 if (!cbox_uuid_fromstring(&uuid
, uuidstr
, error
))
548 struct cbox_midi_input
*midiin
= cbox_io_get_midi_input(io
, NULL
, &uuid
);
549 struct cbox_midi_output
*midiout
= cbox_io_get_midi_output(io
, NULL
, &uuid
);
550 if (!midiout
&& !midiin
)
552 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Port '%s' not found", uuidstr
);
555 jack_port_t
*port
= midiout
? ((struct cbox_jack_midi_output
*)midiout
)->port
556 : ((struct cbox_jack_midi_input
*)midiin
)->port
;
557 char **pname
= midiout
? &midiout
->name
: &midiin
->name
;
558 if (0 != jack_port_set_name(port
, new_name
))
560 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot set port name to '%s'", new_name
);
564 *pname
= g_strdup(new_name
);
567 else if (!strcmp(cmd
->command
, "/autoconnect") && !strcmp(cmd
->arg_types
, "ss"))
569 const char *uuidstr
= CBOX_ARG_S(cmd
, 0);
570 const char *spec
= CBOX_ARG_S(cmd
, 1);
571 struct cbox_uuid uuid
;
572 if (!cbox_uuid_fromstring(&uuid
, uuidstr
, error
))
574 struct cbox_midi_output
*midiout
= cbox_io_get_midi_output(io
, NULL
, &uuid
);
577 cbox_jack_midi_output_set_autoconnect((struct cbox_jack_midi_output
*)midiout
, spec
);
580 struct cbox_midi_input
*midiin
= cbox_io_get_midi_input(io
, NULL
, &uuid
);
583 cbox_jack_midi_input_set_autoconnect((struct cbox_jack_midi_input
*)midiin
, spec
);
586 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Port '%s' not found", uuidstr
);
589 else if (!strcmp(cmd
->command
, "/disconnect_midi_port") && !strcmp(cmd
->arg_types
, "s"))
591 const char *uuidstr
= CBOX_ARG_S(cmd
, 0);
592 struct cbox_uuid uuid
;
593 if (!cbox_uuid_fromstring(&uuid
, uuidstr
, error
))
595 struct cbox_midi_input
*midiin
= cbox_io_get_midi_input(io
, NULL
, &uuid
);
596 struct cbox_midi_output
*midiout
= cbox_io_get_midi_output(io
, NULL
, &uuid
);
597 if (!midiout
&& !midiin
)
599 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Port '%s' not found", uuidstr
);
602 jack_port_t
*port
= midiout
? ((struct cbox_jack_midi_output
*)midiout
)->port
603 : ((struct cbox_jack_midi_input
*)midiin
)->port
;
604 jack_port_disconnect(jii
->client
, port
);
607 else if (!strcmp(cmd
->command
, "/port_connect") && !strcmp(cmd
->arg_types
, "ss"))
609 const char *port_from
= CBOX_ARG_S(cmd
, 0);
610 const char *port_to
= CBOX_ARG_S(cmd
, 1);
611 int res
= jack_connect(jii
->client
, port_from
, port_to
);
615 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot connect port '%s' to '%s'", port_from
, port_to
);
618 else if (!strcmp(cmd
->command
, "/port_disconnect") && !strcmp(cmd
->arg_types
, "ss"))
620 const char *port_from
= CBOX_ARG_S(cmd
, 0);
621 const char *port_to
= CBOX_ARG_S(cmd
, 1);
622 int res
= jack_disconnect(jii
->client
, port_from
, port_to
);
624 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot disconnect port '%s' from '%s'", port_from
, port_to
);
627 else if (!strcmp(cmd
->command
, "/get_ports") && !strcmp(cmd
->arg_types
, "ssi"))
629 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
631 const char *mask
= CBOX_ARG_S(cmd
, 0);
632 const char *type
= CBOX_ARG_S(cmd
, 1);
633 uint32_t flags
= CBOX_ARG_I(cmd
, 2);
634 const char** ports
= jack_get_ports(jii
->client
, mask
, type
, flags
);
635 for (int i
= 0; ports
&& ports
[i
]; i
++)
637 if (!cbox_execute_on(fb
, NULL
, "/port", "s", error
, ports
[i
]))
645 gboolean result
= cbox_io_process_cmd(io
, fb
, cmd
, error
, &handled
);
647 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Unknown combination of target path and argument: '%s', '%s'", cmd
->command
, cmd
->arg_types
);
652 ///////////////////////////////////////////////////////////////////////////////
654 gboolean
cbox_io_init_jack(struct cbox_io
*io
, struct cbox_open_params
*const params
, struct cbox_command_target
*fb
, GError
**error
)
656 const char *client_name
= cbox_config_get_string_with_default("io", "client_name", "cbox");
658 jack_client_t
*client
= NULL
;
659 jack_status_t status
= 0;
660 client
= jack_client_open(client_name
, JackNoStartServer
, &status
);
663 if (!cbox_hwcfg_setup_jack())
665 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot set up JACK server configuration based on current hardware");
670 client
= jack_client_open(client_name
, 0, &status
);
674 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create JACK instance");
678 // XXXKF would use a callback instead
679 io
->buffer_size
= jack_get_buffer_size(client
);
681 io
->input_count
= cbox_config_get_int("io", "inputs", 0);
682 io
->input_buffers
= malloc(sizeof(float *) * io
->input_count
);
683 io
->output_count
= cbox_config_get_int("io", "outputs", 2);
684 io
->output_buffers
= malloc(sizeof(float *) * io
->output_count
);
686 struct cbox_jack_io_impl
*jii
= malloc(sizeof(struct cbox_jack_io_impl
));
687 io
->impl
= &jii
->ioi
;
689 cbox_command_target_init(&io
->cmd_target
, cbox_jack_io_process_cmd
, jii
);
691 jii
->ioi
.getsampleratefunc
= cbox_jackio_get_sample_rate
;
692 jii
->ioi
.startfunc
= cbox_jackio_start
;
693 jii
->ioi
.stopfunc
= cbox_jackio_stop
;
694 jii
->ioi
.getstatusfunc
= cbox_jackio_get_status
;
695 jii
->ioi
.pollfunc
= cbox_jackio_poll_ports
;
696 jii
->ioi
.cyclefunc
= cbox_jackio_cycle
;
697 jii
->ioi
.getmidifunc
= cbox_jackio_get_midi_data
;
698 jii
->ioi
.createmidiinfunc
= cbox_jackio_create_midi_in
;
699 jii
->ioi
.destroymidiinfunc
= cbox_jackio_destroy_midi_in
;
700 jii
->ioi
.createmidioutfunc
= cbox_jackio_create_midi_out
;
701 jii
->ioi
.destroymidioutfunc
= cbox_jackio_destroy_midi_out
;
702 jii
->ioi
.destroyfunc
= cbox_jackio_destroy
;
704 jii
->client_name
= g_strdup(jack_get_client_name(client
));
705 jii
->client
= client
;
706 jii
->rb_autoconnect
= jack_ringbuffer_create(sizeof(jack_port_t
*) * 128);
707 jii
->error_str
= NULL
;
709 jii
->inputs
= malloc(sizeof(jack_port_t
*) * io
->input_count
);
710 jii
->outputs
= malloc(sizeof(jack_port_t
*) * io
->output_count
);
711 for (int i
= 0; i
< io
->input_count
; i
++)
712 jii
->inputs
[i
] = NULL
;
713 for (int i
= 0; i
< io
->output_count
; i
++)
714 jii
->outputs
[i
] = NULL
;
715 for (int i
= 0; i
< io
->input_count
; i
++)
717 gchar
*name
= g_strdup_printf("in_%d", 1 + i
);
718 jii
->inputs
[i
] = jack_port_register(jii
->client
, name
, JACK_DEFAULT_AUDIO_TYPE
, JackPortIsInput
, 0);
721 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create input port %d (%s)", i
, name
);
727 for (int i
= 0; i
< io
->output_count
; i
++)
729 gchar
*name
= g_strdup_printf("out_%d", 1 + i
);
730 jii
->outputs
[i
] = jack_port_register(jii
->client
, name
, JACK_DEFAULT_AUDIO_TYPE
, JackPortIsOutput
, 0);
731 if (!jii
->outputs
[i
])
733 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create output port %d (%s)", i
, name
);
739 jii
->midi
= jack_port_register(jii
->client
, "midi", JACK_DEFAULT_MIDI_TYPE
, JackPortIsInput
, 0);
743 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create MIDI port");
747 cbox_execute_on(fb
, NULL
, "/io/jack_client_name", "s", NULL
, jii
->client_name
);
749 cbox_io_poll_ports(io
, fb
);
756 for (int i
= 0; i
< io
->input_count
; i
++)
757 free(jii
->inputs
[i
]);
762 for (int i
= 0; i
< io
->output_count
; i
++)
763 free(jii
->outputs
[i
]);
766 cbox_io_destroy_all_midi_ports(io
);
767 if (jii
->client_name
)
768 free(jii
->client_name
);
769 jack_client_close(jii
->client
);