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/>.
23 #include "config-api.h"
36 #include <jack/ringbuffer.h>
37 #include <jack/types.h>
38 #include <jack/midiport.h>
39 #include <jack/transport.h>
41 struct cbox_jack_io_impl
43 struct cbox_io_impl ioi
;
45 jack_client_t
*client
;
47 jack_port_t
**outputs
;
49 char *error_str
; // set to non-NULL if client has been booted out by JACK
51 gboolean enable_common_midi_input
;
52 jack_transport_state_t last_transport_state
;
53 gboolean debug_transport
;
55 jack_ringbuffer_t
*rb_autoconnect
;
58 ///////////////////////////////////////////////////////////////////////////////
60 struct cbox_jack_midi_input
62 struct cbox_midi_input hdr
;
63 gchar
*autoconnect_spec
;
65 struct cbox_jack_io_impl
*jii
;
68 struct cbox_jack_midi_output
70 struct cbox_midi_output hdr
;
71 gchar
*autoconnect_spec
;
73 struct cbox_jack_io_impl
*jii
;
76 static struct cbox_midi_input
*cbox_jackio_create_midi_in(struct cbox_io_impl
*impl
, const char *name
, GError
**error
);
77 static struct cbox_midi_output
*cbox_jackio_create_midi_out(struct cbox_io_impl
*impl
, const char *name
, GError
**error
);
78 static void cbox_jackio_destroy_midi_in(struct cbox_io_impl
*ioi
, struct cbox_midi_input
*midiin
);
79 static void cbox_jackio_destroy_midi_out(struct cbox_io_impl
*ioi
, struct cbox_midi_output
*midiout
);
80 static void cbox_jack_midi_output_set_autoconnect(struct cbox_jack_midi_output
*jmo
, const gchar
*autoconnect_spec
);
82 static const char *transport_state_names
[] = {"Stopped", "Rolling", "Looping?", "Starting", "Unknown/invalid#4", "Unknown/invalid#5", "Unknown/invalid#6" };
84 void cbox_jack_midi_input_destroy(struct cbox_jack_midi_input
*jmi
)
88 jack_port_unregister(jmi
->jii
->client
, jmi
->port
);
91 g_free(jmi
->hdr
.name
);
92 g_free(jmi
->autoconnect_spec
);
96 void cbox_jack_midi_output_destroy(struct cbox_jack_midi_output
*jmo
)
100 jack_port_unregister(jmo
->jii
->client
, jmo
->port
);
103 g_free(jmo
->hdr
.name
);
104 g_free(jmo
->autoconnect_spec
);
108 ///////////////////////////////////////////////////////////////////////////////
110 static int copy_midi_data_to_buffer(jack_port_t
*port
, int buffer_size
, struct cbox_midi_buffer
*destination
)
112 void *midi
= jack_port_get_buffer(port
, buffer_size
);
113 uint32_t event_count
= jack_midi_get_event_count(midi
);
115 cbox_midi_buffer_clear(destination
);
116 for (uint32_t i
= 0; i
< event_count
; i
++)
118 jack_midi_event_t event
;
120 if (!jack_midi_event_get(&event
, midi
, i
))
122 if (!cbox_midi_buffer_write_event(destination
, event
.time
, event
.buffer
, event
.size
))
132 ///////////////////////////////////////////////////////////////////////////////
134 static int process_cb(jack_nframes_t nframes
, void *arg
)
136 struct cbox_jack_io_impl
*jii
= arg
;
137 struct cbox_io
*io
= jii
->ioi
.pio
;
138 struct cbox_io_callbacks
*cb
= io
->cb
;
140 io
->io_env
.buffer_size
= nframes
;
141 for (int i
= 0; i
< io
->io_env
.input_count
; i
++)
142 io
->input_buffers
[i
] = jack_port_get_buffer(jii
->inputs
[i
], nframes
);
143 for (int i
= 0; i
< io
->io_env
.output_count
; i
++)
145 io
->output_buffers
[i
] = jack_port_get_buffer(jii
->outputs
[i
], nframes
);
146 for (int j
= 0; j
< nframes
; j
++)
147 io
->output_buffers
[i
][j
] = 0.f
;
149 for (GSList
*p
= io
->midi_inputs
; p
; p
= p
->next
)
151 struct cbox_jack_midi_input
*input
= p
->data
;
152 if (input
->hdr
.output_set
|| input
->hdr
.enable_appsink
)
154 copy_midi_data_to_buffer(input
->port
, io
->io_env
.buffer_size
, &input
->hdr
.buffer
);
155 if (input
->hdr
.enable_appsink
)
156 cbox_midi_appsink_supply(&input
->hdr
.appsink
, &input
->hdr
.buffer
);
159 cbox_midi_buffer_clear(&input
->hdr
.buffer
);
161 if (cb
->on_transport_sync
)
163 jack_transport_state_t state
= jack_transport_query(jii
->client
, NULL
);
164 if (state
!= jii
->last_transport_state
)
167 jack_transport_query(jii
->client
, &pos
);
168 if (jii
->debug_transport
)
169 g_message("JACK transport: incoming state change, state = %s, last state = %s, pos = %d\n", transport_state_names
[state
], transport_state_names
[(int)jii
->last_transport_state
], (int)pos
.frame
);
170 if (state
== JackTransportStopped
)
172 if (cb
->on_transport_sync(cb
->user_data
, ts_stopping
, pos
.frame
))
173 jii
->last_transport_state
= state
;
176 if (state
== JackTransportRolling
&& jii
->last_transport_state
== JackTransportStarting
)
178 if (cb
->on_transport_sync(cb
->user_data
, ts_rolling
, pos
.frame
))
179 jii
->last_transport_state
= state
;
182 jii
->last_transport_state
= state
;
185 cb
->process(cb
->user_data
, io
, nframes
);
186 for (int i
= 0; i
< io
->io_env
.input_count
; i
++)
187 io
->input_buffers
[i
] = NULL
;
188 for (int i
= 0; i
< io
->io_env
.output_count
; i
++)
189 io
->output_buffers
[i
] = NULL
;
190 for (GSList
*p
= io
->midi_outputs
; p
; p
= g_slist_next(p
))
192 struct cbox_jack_midi_output
*midiout
= p
->data
;
194 void *pbuf
= jack_port_get_buffer(midiout
->port
, nframes
);
195 jack_midi_clear_buffer(pbuf
);
197 cbox_midi_merger_render(&midiout
->hdr
.merger
);
198 if (midiout
->hdr
.buffer
.count
)
201 for (int i
= 0; i
< midiout
->hdr
.buffer
.count
; i
++)
203 const struct cbox_midi_event
*event
= cbox_midi_buffer_get_event(&midiout
->hdr
.buffer
, i
);
204 const uint8_t *pdata
= cbox_midi_event_get_data(event
);
205 if ((pdata
[0] & 0xF0) == 0x90 && !pdata
[2] && event
->size
== 3)
207 tmp_data
[0] = pdata
[0] & ~0x10;
208 tmp_data
[1] = pdata
[1];
209 tmp_data
[2] = pdata
[2];
212 if (jack_midi_event_write(pbuf
, event
->time
, pdata
, event
->size
))
214 g_warning("MIDI buffer overflow on JACK output port '%s'", midiout
->hdr
.name
);
223 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
)
226 if (only_connect_port
)
229 right
= jack_port_by_name(client
, use_name
);
230 if (only_connect_port
!= right
)
234 const char *pfrom
= is_cbox_input
? use_name
: port
;
235 const char *pto
= !is_cbox_input
? use_name
: port
;
237 res
= jack_connect(client
, pfrom
, pto
);
240 gboolean suppressed
= FALSE
;
244 suppressed
= cbox_execute_on(fb
, NULL
, "/io/jack/connected", "ss", NULL
, pfrom
, pto
);
246 suppressed
= cbox_execute_on(fb
, NULL
, "/io/jack/connect_failed", "sss", NULL
, pfrom
, pto
, (res
== EEXIST
? "already connected" : "failed"));
249 g_message("Connect: %s %s %s (%s)", port
, is_cbox_input
? "<-" : "->", use_name
, res
== 0 ? "success" : (res
== EEXIST
? "already connected" : "failed"));
252 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
)
254 char *name
, *copy_spec
, *dpos
;
255 const char *use_name
;
257 copy_spec
= g_strdup(orig_spec
);
260 dpos
= strchr(name
, ';');
265 if (use_name
[0] == '#')
268 long portidx
= strtol(use_name
+ 1, &endptr
, 10) - 1;
269 if (endptr
== use_name
+ strlen(use_name
))
271 const char **names
= jack_get_ports(client
, ".*", is_midi
? JACK_DEFAULT_MIDI_TYPE
: JACK_DEFAULT_AUDIO_TYPE
, is_cbox_input
? JackPortIsOutput
: JackPortIsInput
);
273 for (i
= 0; i
< portidx
&& names
[i
]; i
++)
277 autoconnect_port(client
, port
, names
[i
], is_cbox_input
, only_connect_port
, fb
);
279 g_message("Connect: unmatched port index %d", (int)portidx
);
284 else if (use_name
[0] == '~' || use_name
[0] == '*')
286 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
);
288 if (names
&& names
[0])
290 if (use_name
[0] == '*')
293 for (i
= 0; names
[i
]; i
++)
294 autoconnect_port(client
, port
, names
[i
], is_cbox_input
, only_connect_port
, fb
);
297 autoconnect_port(client
, port
, names
[0], is_cbox_input
, only_connect_port
, fb
);
300 g_message("Connect: unmatched port regexp %s", use_name
);
304 autoconnect_port(client
, port
, use_name
, is_cbox_input
, only_connect_port
, fb
);
312 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
)
314 const char *orig_spec
= cbox_config_get_string(cbox_io_section
, config_var
);
316 autoconnect_by_spec(client
, port
, orig_spec
, is_cbox_input
, is_midi
, only_connect_port
, fb
);
319 static void port_connect_cb(jack_port_id_t port
, int registered
, void *arg
)
321 struct cbox_jack_io_impl
*jii
= arg
;
324 jack_port_t
*portobj
= jack_port_by_id(jii
->client
, port
);
326 jack_ringbuffer_write(jii
->rb_autoconnect
, (char *)&portobj
, sizeof(portobj
));
330 static void port_autoconnect(struct cbox_jack_io_impl
*jii
, jack_port_t
*portobj
, struct cbox_command_target
*fb
)
332 struct cbox_io
*io
= jii
->ioi
.pio
;
334 for (int i
= 0; i
< io
->io_env
.output_count
; i
++)
336 gchar
*cbox_port
= g_strdup_printf("%s:out_%d", jii
->client_name
, 1 + i
);
337 gchar
*config_key
= g_strdup_printf("out_%d", 1 + i
);
338 autoconnect_by_var(jii
->client
, cbox_port
, config_key
, 0, 0, portobj
, fb
);
342 for (int i
= 0; i
< io
->io_env
.input_count
; i
++)
344 gchar
*cbox_port
= g_strdup_printf("%s:in_%d", jii
->client_name
, 1 + i
);
345 gchar
*config_key
= g_strdup_printf("in_%d", 1 + i
);
346 autoconnect_by_var(jii
->client
, cbox_port
, config_key
, 1, 0, portobj
, fb
);
350 for (GSList
*p
= io
->midi_outputs
; p
; p
= g_slist_next(p
))
352 struct cbox_jack_midi_output
*midiout
= p
->data
;
353 if (midiout
->autoconnect_spec
)
355 gchar
*cbox_port
= g_strdup_printf("%s:%s", jii
->client_name
, midiout
->hdr
.name
);
356 autoconnect_by_spec(jii
->client
, cbox_port
, midiout
->autoconnect_spec
, 0, 1, portobj
, fb
);
360 for (GSList
*p
= io
->midi_inputs
; p
; p
= g_slist_next(p
))
362 struct cbox_jack_midi_input
*midiin
= p
->data
;
363 if (midiin
->autoconnect_spec
)
365 gchar
*cbox_port
= g_strdup_printf("%s:%s", jii
->client_name
, midiin
->hdr
.name
);
366 autoconnect_by_spec(jii
->client
, cbox_port
, midiin
->autoconnect_spec
, 1, 1, portobj
, fb
);
370 gchar
*cbox_port
= g_strdup_printf("%s:midi", jii
->client_name
);
371 autoconnect_by_var(jii
->client
, cbox_port
, "midi", 1, 1, portobj
, fb
);
375 int cbox_jackio_get_sample_rate(struct cbox_io_impl
*impl
)
377 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
379 return jack_get_sample_rate(jii
->client
);
382 gboolean
cbox_jackio_get_status(struct cbox_io_impl
*impl
, GError
**error
)
384 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
387 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "%s", jii
->error_str
);
391 static void client_shutdown_cb(jack_status_t code
, const char *reason
, void *arg
)
393 struct cbox_jack_io_impl
*jii
= arg
;
394 struct cbox_io
*io
= jii
->ioi
.pio
;
395 jii
->error_str
= g_strdup(reason
);
396 if (io
->cb
&& io
->cb
->on_disconnected
)
397 (io
->cb
->on_disconnected
)(io
->cb
->user_data
);
400 static int sync_cb(jack_transport_state_t state
, jack_position_t
*pos
, void *arg
)
402 struct cbox_jack_io_impl
*jii
= arg
;
403 struct cbox_io
*io
= jii
->ioi
.pio
;
404 gboolean result
= TRUE
;
405 int last_state
= jii
->last_transport_state
;
408 case JackTransportStopped
:
409 result
= io
->cb
->on_transport_sync(io
->cb
->user_data
, ts_stopped
, pos
->frame
);
411 case JackTransportStarting
:
412 jii
->last_transport_state
= JackTransportStarting
;
413 result
= io
->cb
->on_transport_sync(io
->cb
->user_data
, ts_starting
, pos
->frame
);
415 case JackTransportRolling
:
416 result
= io
->cb
->on_transport_sync(io
->cb
->user_data
, ts_rolling
, pos
->frame
);
419 // assume the client is ready
422 if (jii
->debug_transport
)
423 g_message("JACK transport: incoming sync callback, state = %s, last state = %s, pos = %d, result = %d\n", transport_state_names
[state
], transport_state_names
[last_state
], (int)pos
->frame
, result
);
427 gboolean
cbox_jackio_start(struct cbox_io_impl
*impl
, struct cbox_command_target
*fb
, GError
**error
)
429 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
430 struct cbox_io
*io
= jii
->ioi
.pio
;
432 if (io
->cb
->on_transport_sync
)
433 jack_set_sync_callback(jii
->client
, sync_cb
, jii
);
434 jack_set_process_callback(jii
->client
, process_cb
, jii
);
435 jack_set_port_registration_callback(jii
->client
, port_connect_cb
, jii
);
436 jack_on_info_shutdown(jii
->client
, client_shutdown_cb
, jii
);
438 if (io
->cb
->on_started
)
439 io
->cb
->on_started(io
->cb
->user_data
);
441 jack_activate(jii
->client
);
443 if (cbox_config_has_section(cbox_io_section
))
444 port_autoconnect(jii
, NULL
, fb
);
449 gboolean
cbox_jackio_stop(struct cbox_io_impl
*impl
, GError
**error
)
451 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
455 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "%s", jii
->error_str
);
458 jack_deactivate(jii
->client
);
462 void cbox_jackio_poll_ports(struct cbox_io_impl
*impl
, struct cbox_command_target
*fb
)
464 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
466 while (jack_ringbuffer_read_space(jii
->rb_autoconnect
) >= sizeof(jack_port_t
*))
468 jack_port_t
*portobj
;
469 jack_ringbuffer_read(jii
->rb_autoconnect
, (char *)&portobj
, sizeof(portobj
));
470 port_autoconnect(jii
, portobj
, fb
);
474 int cbox_jackio_get_midi_data(struct cbox_io_impl
*impl
, struct cbox_midi_buffer
*destination
)
476 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
477 if (!jii
->enable_common_midi_input
)
479 cbox_midi_buffer_clear(destination
);
483 return copy_midi_data_to_buffer(jii
->midi
, jii
->ioi
.pio
->io_env
.buffer_size
, destination
);
486 void cbox_jackio_destroy(struct cbox_io_impl
*impl
)
488 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
489 struct cbox_io
*io
= impl
->pio
;
494 g_free(jii
->error_str
);
495 jii
->error_str
= NULL
;
499 for (int i
= 0; i
< io
->io_env
.input_count
; i
++)
500 jack_port_unregister(jii
->client
, jii
->inputs
[i
]);
502 for (int i
= 0; i
< io
->io_env
.output_count
; i
++)
503 jack_port_unregister(jii
->client
, jii
->outputs
[i
]);
506 jack_port_unregister(jii
->client
, jii
->midi
);
508 if (jii
->client_name
)
510 free(jii
->client_name
);
511 jii
->client_name
= NULL
;
513 cbox_io_destroy_all_midi_ports(io
);
515 jack_ringbuffer_free(jii
->rb_autoconnect
);
516 jack_client_close(jii
->client
);
521 gboolean
cbox_jackio_cycle(struct cbox_io_impl
*impl
, struct cbox_command_target
*fb
, GError
**error
)
523 struct cbox_io
*io
= impl
->pio
;
524 struct cbox_io_callbacks
*cb
= io
->cb
;
527 // XXXKF use params structure some day
528 if (!cbox_io_init_jack(io
, NULL
, fb
, error
))
531 cbox_io_start(io
, cb
, fb
);
532 if (cb
->on_reconnected
)
533 (cb
->on_reconnected
)(cb
->user_data
);
539 ///////////////////////////////////////////////////////////////////////////////
541 struct cbox_midi_input
*cbox_jackio_create_midi_in(struct cbox_io_impl
*impl
, const char *name
, GError
**error
)
543 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
544 jack_port_t
*port
= jack_port_register(jii
->client
, name
, JACK_DEFAULT_MIDI_TYPE
, JackPortIsInput
, 0);
547 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create input MIDI port '%s'", name
);
550 struct cbox_jack_midi_input
*input
= calloc(1, sizeof(struct cbox_jack_midi_input
));
551 input
->hdr
.name
= g_strdup(name
);
552 input
->hdr
.removing
= FALSE
;
555 cbox_uuid_generate(&input
->hdr
.uuid
);
556 cbox_midi_buffer_init(&input
->hdr
.buffer
);
558 return (struct cbox_midi_input
*)input
;
561 struct cbox_midi_output
*cbox_jackio_create_midi_out(struct cbox_io_impl
*impl
, const char *name
, GError
**error
)
563 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
564 jack_port_t
*port
= jack_port_register(jii
->client
, name
, JACK_DEFAULT_MIDI_TYPE
, JackPortIsOutput
, 0);
567 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create output MIDI port '%s'", name
);
570 struct cbox_jack_midi_output
*output
= calloc(1, sizeof(struct cbox_jack_midi_output
));
571 output
->hdr
.name
= g_strdup(name
);
572 output
->hdr
.removing
= FALSE
;
575 cbox_uuid_generate(&output
->hdr
.uuid
);
576 cbox_midi_buffer_init(&output
->hdr
.buffer
);
577 cbox_midi_merger_init(&output
->hdr
.merger
, &output
->hdr
.buffer
);
579 return (struct cbox_midi_output
*)output
;
582 void cbox_jack_midi_input_set_autoconnect(struct cbox_jack_midi_input
*jmi
, const gchar
*autoconnect_spec
)
584 if (jmi
->autoconnect_spec
)
585 g_free(jmi
->autoconnect_spec
);
586 jmi
->autoconnect_spec
= autoconnect_spec
&& *autoconnect_spec
? g_strdup(autoconnect_spec
) : NULL
;
587 if (jmi
->autoconnect_spec
)
589 gchar
*cbox_port
= g_strdup_printf("%s:%s", jmi
->jii
->client_name
, jmi
->hdr
.name
);
590 autoconnect_by_spec(jmi
->jii
->client
, cbox_port
, jmi
->autoconnect_spec
, 1, 1, NULL
, NULL
);
595 void cbox_jack_midi_output_set_autoconnect(struct cbox_jack_midi_output
*jmo
, const gchar
*autoconnect_spec
)
597 if (jmo
->autoconnect_spec
)
598 g_free(jmo
->autoconnect_spec
);
599 jmo
->autoconnect_spec
= autoconnect_spec
&& *autoconnect_spec
? g_strdup(autoconnect_spec
) : NULL
;
600 if (jmo
->autoconnect_spec
)
602 gchar
*cbox_port
= g_strdup_printf("%s:%s", jmo
->jii
->client_name
, jmo
->hdr
.name
);
603 autoconnect_by_spec(jmo
->jii
->client
, cbox_port
, jmo
->autoconnect_spec
, 0, 1, NULL
, NULL
);
608 void cbox_jackio_destroy_midi_in(struct cbox_io_impl
*ioi
, struct cbox_midi_input
*midiin
)
610 cbox_jack_midi_input_destroy((struct cbox_jack_midi_input
*)midiin
);
613 void cbox_jackio_destroy_midi_out(struct cbox_io_impl
*ioi
, struct cbox_midi_output
*midiout
)
615 cbox_jack_midi_output_destroy((struct cbox_jack_midi_output
*)midiout
);
618 static gboolean
cbox_jack_io_process_cmd(struct cbox_command_target
*ct
, struct cbox_command_target
*fb
, struct cbox_osc_command
*cmd
, GError
**error
)
620 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)ct
->user_data
;
621 struct cbox_io
*io
= jii
->ioi
.pio
;
622 gboolean handled
= FALSE
;
623 if (!strcmp(cmd
->command
, "/status") && !strcmp(cmd
->arg_types
, ""))
625 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
627 return cbox_execute_on(fb
, NULL
, "/client_type", "s", error
, "JACK") &&
628 cbox_execute_on(fb
, NULL
, "/client_name", "s", error
, jii
->client_name
) &&
629 cbox_io_process_cmd(io
, fb
, cmd
, error
, &handled
);
631 else if (!strcmp(cmd
->command
, "/rename_midi_port") && !strcmp(cmd
->arg_types
, "ss"))
633 const char *uuidstr
= CBOX_ARG_S(cmd
, 0);
634 const char *new_name
= CBOX_ARG_S(cmd
, 1);
635 struct cbox_uuid uuid
;
636 if (!cbox_uuid_fromstring(&uuid
, uuidstr
, error
))
638 struct cbox_midi_input
*midiin
= cbox_io_get_midi_input(io
, NULL
, &uuid
);
639 struct cbox_midi_output
*midiout
= cbox_io_get_midi_output(io
, NULL
, &uuid
);
640 if (!midiout
&& !midiin
)
642 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Port '%s' not found", uuidstr
);
645 jack_port_t
*port
= midiout
? ((struct cbox_jack_midi_output
*)midiout
)->port
646 : ((struct cbox_jack_midi_input
*)midiin
)->port
;
647 char **pname
= midiout
? &midiout
->name
: &midiin
->name
;
648 if (0 != jack_port_set_name(port
, new_name
))
650 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot set port name to '%s'", new_name
);
654 *pname
= g_strdup(new_name
);
657 else if (!strcmp(cmd
->command
, "/autoconnect") && !strcmp(cmd
->arg_types
, "ss"))
659 const char *uuidstr
= CBOX_ARG_S(cmd
, 0);
660 const char *spec
= CBOX_ARG_S(cmd
, 1);
661 struct cbox_uuid uuid
;
662 if (!cbox_uuid_fromstring(&uuid
, uuidstr
, error
))
664 struct cbox_midi_output
*midiout
= cbox_io_get_midi_output(io
, NULL
, &uuid
);
667 cbox_jack_midi_output_set_autoconnect((struct cbox_jack_midi_output
*)midiout
, spec
);
670 struct cbox_midi_input
*midiin
= cbox_io_get_midi_input(io
, NULL
, &uuid
);
673 cbox_jack_midi_input_set_autoconnect((struct cbox_jack_midi_input
*)midiin
, spec
);
676 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Port '%s' not found", uuidstr
);
679 else if (!strcmp(cmd
->command
, "/disconnect_midi_port") && !strcmp(cmd
->arg_types
, "s"))
681 const char *uuidstr
= CBOX_ARG_S(cmd
, 0);
682 struct cbox_uuid uuid
;
683 if (!cbox_uuid_fromstring(&uuid
, uuidstr
, error
))
685 struct cbox_midi_input
*midiin
= cbox_io_get_midi_input(io
, NULL
, &uuid
);
686 struct cbox_midi_output
*midiout
= cbox_io_get_midi_output(io
, NULL
, &uuid
);
687 if (!midiout
&& !midiin
)
689 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Port '%s' not found", uuidstr
);
692 jack_port_t
*port
= midiout
? ((struct cbox_jack_midi_output
*)midiout
)->port
693 : ((struct cbox_jack_midi_input
*)midiin
)->port
;
694 jack_port_disconnect(jii
->client
, port
);
697 else if (!strcmp(cmd
->command
, "/port_connect") && !strcmp(cmd
->arg_types
, "ss"))
699 const char *port_from
= CBOX_ARG_S(cmd
, 0);
700 const char *port_to
= CBOX_ARG_S(cmd
, 1);
701 int res
= jack_connect(jii
->client
, port_from
, port_to
);
705 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot connect port '%s' to '%s'", port_from
, port_to
);
708 else if (!strcmp(cmd
->command
, "/port_disconnect") && !strcmp(cmd
->arg_types
, "ss"))
710 const char *port_from
= CBOX_ARG_S(cmd
, 0);
711 const char *port_to
= CBOX_ARG_S(cmd
, 1);
712 int res
= jack_disconnect(jii
->client
, port_from
, port_to
);
714 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot disconnect port '%s' from '%s'", port_from
, port_to
);
717 else if (!strcmp(cmd
->command
, "/get_ports") && !strcmp(cmd
->arg_types
, "ssi"))
719 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
721 const char *mask
= CBOX_ARG_S(cmd
, 0);
722 const char *type
= CBOX_ARG_S(cmd
, 1);
723 uint32_t flags
= CBOX_ARG_I(cmd
, 2);
724 const char** ports
= jack_get_ports(jii
->client
, mask
, type
, flags
);
725 for (int i
= 0; ports
&& ports
[i
]; i
++)
727 if (!cbox_execute_on(fb
, NULL
, "/port", "s", error
, ports
[i
]))
735 gboolean result
= cbox_io_process_cmd(io
, fb
, cmd
, error
, &handled
);
737 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
);
742 ///////////////////////////////////////////////////////////////////////////////
744 static void cbox_jackio_control_transport(struct cbox_io_impl
*impl
, gboolean roll
, uint32_t pos
)
746 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
748 if (jii
->debug_transport
)
749 g_message("JACK transport: control(op=%s, pos=%d)\n", roll
? "roll" : "stop", (int)pos
);
751 jack_transport_state_t state
= jack_transport_query(jii
->client
, NULL
);
752 if (roll
&& state
== JackTransportStopped
)
753 jack_transport_start(jii
->client
);
754 if (!roll
&& state
!= JackTransportStopped
)
755 jack_transport_stop(jii
->client
);
757 if (pos
!= (uint32_t)-1)
758 jack_transport_locate(jii
->client
, pos
);
761 static gboolean
cbox_jackio_get_sync_completed(struct cbox_io_impl
*impl
)
763 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
764 return jack_transport_query(jii
->client
, NULL
) != JackTransportStarting
;
767 ///////////////////////////////////////////////////////////////////////////////
769 gboolean
cbox_io_init_jack(struct cbox_io
*io
, struct cbox_open_params
*const params
, struct cbox_command_target
*fb
, GError
**error
)
771 const char *client_name
= cbox_config_get_string_with_default("io", "client_name", "cbox");
773 jack_client_t
*client
= NULL
;
774 jack_status_t status
= 0;
775 client
= jack_client_open(client_name
, JackNoStartServer
, &status
);
778 if (!cbox_hwcfg_setup_jack())
780 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot set up JACK server configuration based on current hardware");
785 client
= jack_client_open(client_name
, 0, &status
);
789 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create JACK instance");
793 // XXXKF would use a callback instead
794 io
->io_env
.buffer_size
= jack_get_buffer_size(client
);
796 io
->io_env
.input_count
= cbox_config_get_int("io", "inputs", 0);
797 io
->input_buffers
= malloc(sizeof(float *) * io
->io_env
.input_count
);
798 io
->io_env
.output_count
= cbox_config_get_int("io", "outputs", 2);
799 io
->output_buffers
= malloc(sizeof(float *) * io
->io_env
.output_count
);
801 struct cbox_jack_io_impl
*jii
= malloc(sizeof(struct cbox_jack_io_impl
));
802 io
->impl
= &jii
->ioi
;
803 jii
->enable_common_midi_input
= cbox_config_get_int("io", "enable_common_midi_input", 1);
804 jii
->debug_transport
= cbox_config_get_int("debug", "jack_transport", 0);
805 jii
->last_transport_state
= JackTransportStopped
;
807 cbox_command_target_init(&io
->cmd_target
, cbox_jack_io_process_cmd
, jii
);
809 jii
->ioi
.getsampleratefunc
= cbox_jackio_get_sample_rate
;
810 jii
->ioi
.startfunc
= cbox_jackio_start
;
811 jii
->ioi
.stopfunc
= cbox_jackio_stop
;
812 jii
->ioi
.getstatusfunc
= cbox_jackio_get_status
;
813 jii
->ioi
.pollfunc
= cbox_jackio_poll_ports
;
814 jii
->ioi
.cyclefunc
= cbox_jackio_cycle
;
815 jii
->ioi
.getmidifunc
= cbox_jackio_get_midi_data
;
816 jii
->ioi
.createmidiinfunc
= cbox_jackio_create_midi_in
;
817 jii
->ioi
.destroymidiinfunc
= cbox_jackio_destroy_midi_in
;
818 jii
->ioi
.createmidioutfunc
= cbox_jackio_create_midi_out
;
819 jii
->ioi
.destroymidioutfunc
= cbox_jackio_destroy_midi_out
;
820 jii
->ioi
.updatemidiinroutingfunc
= NULL
;
821 jii
->ioi
.controltransportfunc
= cbox_jackio_control_transport
;
822 jii
->ioi
.getsynccompletedfunc
= cbox_jackio_get_sync_completed
;
823 jii
->ioi
.destroyfunc
= cbox_jackio_destroy
;
825 jii
->client_name
= g_strdup(jack_get_client_name(client
));
826 jii
->client
= client
;
827 jii
->rb_autoconnect
= jack_ringbuffer_create(sizeof(jack_port_t
*) * 128);
828 jii
->error_str
= NULL
;
829 io
->io_env
.srate
= jack_get_sample_rate(client
);
831 jii
->inputs
= malloc(sizeof(jack_port_t
*) * io
->io_env
.input_count
);
832 jii
->outputs
= malloc(sizeof(jack_port_t
*) * io
->io_env
.output_count
);
833 for (int i
= 0; i
< io
->io_env
.input_count
; i
++)
834 jii
->inputs
[i
] = NULL
;
835 for (int i
= 0; i
< io
->io_env
.output_count
; i
++)
836 jii
->outputs
[i
] = NULL
;
837 for (int i
= 0; i
< io
->io_env
.input_count
; i
++)
839 gchar
*name
= g_strdup_printf("in_%d", 1 + i
);
840 jii
->inputs
[i
] = jack_port_register(jii
->client
, name
, JACK_DEFAULT_AUDIO_TYPE
, JackPortIsInput
, 0);
843 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create input port %d (%s)", i
, name
);
849 for (int i
= 0; i
< io
->io_env
.output_count
; i
++)
851 gchar
*name
= g_strdup_printf("out_%d", 1 + i
);
852 jii
->outputs
[i
] = jack_port_register(jii
->client
, name
, JACK_DEFAULT_AUDIO_TYPE
, JackPortIsOutput
, 0);
853 if (!jii
->outputs
[i
])
855 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create output port %d (%s)", i
, name
);
861 if (jii
->enable_common_midi_input
)
863 jii
->midi
= jack_port_register(jii
->client
, "midi", JACK_DEFAULT_MIDI_TYPE
, JackPortIsInput
, 0);
866 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create MIDI port");
874 cbox_execute_on(fb
, NULL
, "/io/jack_client_name", "s", NULL
, jii
->client_name
);
876 cbox_io_poll_ports(io
, fb
);
883 for (int i
= 0; i
< io
->io_env
.input_count
; i
++)
884 free(jii
->inputs
[i
]);
889 for (int i
= 0; i
< io
->io_env
.output_count
; i
++)
890 free(jii
->outputs
[i
]);
893 cbox_io_destroy_all_midi_ports(io
);
894 if (jii
->client_name
)
895 free(jii
->client_name
);
896 jack_client_close(jii
->client
);