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
);
115 uint32_t event_count
= jack_midi_get_event_count(midi
);
117 cbox_midi_buffer_clear(destination
);
118 for (uint32_t i
= 0; i
< event_count
; i
++)
120 jack_midi_event_t event
;
122 if (!jack_midi_event_get(&event
, midi
, i
))
124 if (!cbox_midi_buffer_write_event(destination
, event
.time
, event
.buffer
, event
.size
))
134 ///////////////////////////////////////////////////////////////////////////////
136 static int process_cb(jack_nframes_t nframes
, void *arg
)
138 struct cbox_jack_io_impl
*jii
= arg
;
139 struct cbox_io
*io
= jii
->ioi
.pio
;
140 struct cbox_io_callbacks
*cb
= io
->cb
;
142 io
->io_env
.buffer_size
= nframes
;
143 for (int i
= 0; i
< io
->io_env
.input_count
; i
++)
144 io
->input_buffers
[i
] = jack_port_get_buffer(jii
->inputs
[i
], nframes
);
145 for (int i
= 0; i
< io
->io_env
.output_count
; i
++)
147 io
->output_buffers
[i
] = jack_port_get_buffer(jii
->outputs
[i
], nframes
);
148 if (!io
->output_buffers
[i
])
150 for (int j
= 0; j
< nframes
; j
++)
151 io
->output_buffers
[i
][j
] = 0.f
;
153 for (GSList
*p
= io
->midi_inputs
; p
; p
= p
->next
)
155 struct cbox_jack_midi_input
*input
= p
->data
;
156 if (input
->hdr
.output_set
|| input
->hdr
.enable_appsink
)
158 copy_midi_data_to_buffer(input
->port
, io
->io_env
.buffer_size
, &input
->hdr
.buffer
);
159 if (input
->hdr
.enable_appsink
)
160 cbox_midi_appsink_supply(&input
->hdr
.appsink
, &input
->hdr
.buffer
);
163 cbox_midi_buffer_clear(&input
->hdr
.buffer
);
165 if (cb
->on_transport_sync
)
167 jack_transport_state_t state
= jack_transport_query(jii
->client
, NULL
);
168 if (state
!= jii
->last_transport_state
)
171 jack_transport_query(jii
->client
, &pos
);
172 if (jii
->debug_transport
)
173 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
);
174 if (state
== JackTransportStopped
)
176 if (cb
->on_transport_sync(cb
->user_data
, ts_stopping
, pos
.frame
))
177 jii
->last_transport_state
= state
;
180 if (state
== JackTransportRolling
&& jii
->last_transport_state
== JackTransportStarting
)
182 if (cb
->on_transport_sync(cb
->user_data
, ts_rolling
, pos
.frame
))
183 jii
->last_transport_state
= state
;
186 jii
->last_transport_state
= state
;
189 cb
->process(cb
->user_data
, io
, nframes
);
190 for (int i
= 0; i
< io
->io_env
.input_count
; i
++)
191 io
->input_buffers
[i
] = NULL
;
192 for (int i
= 0; i
< io
->io_env
.output_count
; i
++)
193 io
->output_buffers
[i
] = NULL
;
194 for (GSList
*p
= io
->midi_outputs
; p
; p
= g_slist_next(p
))
196 struct cbox_jack_midi_output
*midiout
= p
->data
;
198 void *pbuf
= jack_port_get_buffer(midiout
->port
, nframes
);
199 jack_midi_clear_buffer(pbuf
);
201 cbox_midi_merger_render(&midiout
->hdr
.merger
);
202 if (midiout
->hdr
.buffer
.count
)
205 for (int i
= 0; i
< midiout
->hdr
.buffer
.count
; i
++)
207 const struct cbox_midi_event
*event
= cbox_midi_buffer_get_event(&midiout
->hdr
.buffer
, i
);
208 const uint8_t *pdata
= cbox_midi_event_get_data(event
);
209 if ((pdata
[0] & 0xF0) == 0x90 && !pdata
[2] && event
->size
== 3)
211 tmp_data
[0] = pdata
[0] & ~0x10;
212 tmp_data
[1] = pdata
[1];
213 tmp_data
[2] = pdata
[2];
216 if (jack_midi_event_write(pbuf
, event
->time
, pdata
, event
->size
))
218 g_warning("MIDI buffer overflow on JACK output port '%s'", midiout
->hdr
.name
);
227 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
)
230 if (only_connect_port
)
233 right
= jack_port_by_name(client
, use_name
);
234 if (only_connect_port
!= right
)
238 const char *pfrom
= is_cbox_input
? use_name
: port
;
239 const char *pto
= !is_cbox_input
? use_name
: port
;
241 res
= jack_connect(client
, pfrom
, pto
);
244 gboolean suppressed
= FALSE
;
248 suppressed
= cbox_execute_on(fb
, NULL
, "/io/jack/connected", "ss", NULL
, pfrom
, pto
);
250 suppressed
= cbox_execute_on(fb
, NULL
, "/io/jack/connect_failed", "sss", NULL
, pfrom
, pto
, (res
== EEXIST
? "already connected" : "failed"));
253 g_message("Connect: %s %s %s (%s)", port
, is_cbox_input
? "<-" : "->", use_name
, res
== 0 ? "success" : (res
== EEXIST
? "already connected" : "failed"));
256 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
)
258 char *name
, *copy_spec
, *dpos
;
259 const char *use_name
;
261 copy_spec
= g_strdup(orig_spec
);
264 dpos
= strchr(name
, ';');
269 if (use_name
[0] == '#')
272 long portidx
= strtol(use_name
+ 1, &endptr
, 10) - 1;
273 if (endptr
== use_name
+ strlen(use_name
))
275 const char **names
= jack_get_ports(client
, ".*", is_midi
? JACK_DEFAULT_MIDI_TYPE
: JACK_DEFAULT_AUDIO_TYPE
, is_cbox_input
? JackPortIsOutput
: JackPortIsInput
);
276 // Client killed by JACK
280 for (i
= 0; i
< portidx
&& names
[i
]; i
++)
284 autoconnect_port(client
, port
, names
[i
], is_cbox_input
, only_connect_port
, fb
);
286 g_message("Connect: unmatched port index %d", (int)portidx
);
291 else if (use_name
[0] == '~' || use_name
[0] == '*')
293 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
);
294 // Client killed by JACK
298 if (names
&& names
[0])
300 if (use_name
[0] == '*')
303 for (i
= 0; names
[i
]; i
++)
304 autoconnect_port(client
, port
, names
[i
], is_cbox_input
, only_connect_port
, fb
);
307 autoconnect_port(client
, port
, names
[0], is_cbox_input
, only_connect_port
, fb
);
310 g_message("Connect: unmatched port regexp %s", use_name
);
314 autoconnect_port(client
, port
, use_name
, is_cbox_input
, only_connect_port
, fb
);
322 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
)
324 const char *orig_spec
= cbox_config_get_string(cbox_io_section
, config_var
);
326 autoconnect_by_spec(client
, port
, orig_spec
, is_cbox_input
, is_midi
, only_connect_port
, fb
);
329 static void port_connect_cb(jack_port_id_t port
, int registered
, void *arg
)
331 struct cbox_jack_io_impl
*jii
= arg
;
334 jack_port_t
*portobj
= jack_port_by_id(jii
->client
, port
);
336 jack_ringbuffer_write(jii
->rb_autoconnect
, (char *)&portobj
, sizeof(portobj
));
340 static void port_autoconnect(struct cbox_jack_io_impl
*jii
, jack_port_t
*portobj
, struct cbox_command_target
*fb
)
342 struct cbox_io
*io
= jii
->ioi
.pio
;
344 for (int i
= 0; i
< io
->io_env
.output_count
; i
++)
346 gchar
*cbox_port
= g_strdup_printf("%s:out_%d", jii
->client_name
, 1 + i
);
347 gchar
*config_key
= g_strdup_printf("out_%d", 1 + i
);
348 autoconnect_by_var(jii
->client
, cbox_port
, config_key
, 0, 0, portobj
, fb
);
352 for (int i
= 0; i
< io
->io_env
.input_count
; i
++)
354 gchar
*cbox_port
= g_strdup_printf("%s:in_%d", jii
->client_name
, 1 + i
);
355 gchar
*config_key
= g_strdup_printf("in_%d", 1 + i
);
356 autoconnect_by_var(jii
->client
, cbox_port
, config_key
, 1, 0, portobj
, fb
);
360 for (GSList
*p
= io
->midi_outputs
; p
; p
= g_slist_next(p
))
362 struct cbox_jack_midi_output
*midiout
= p
->data
;
363 if (midiout
->autoconnect_spec
)
365 gchar
*cbox_port
= g_strdup_printf("%s:%s", jii
->client_name
, midiout
->hdr
.name
);
366 autoconnect_by_spec(jii
->client
, cbox_port
, midiout
->autoconnect_spec
, 0, 1, portobj
, fb
);
370 for (GSList
*p
= io
->midi_inputs
; p
; p
= g_slist_next(p
))
372 struct cbox_jack_midi_input
*midiin
= p
->data
;
373 if (midiin
->autoconnect_spec
)
375 gchar
*cbox_port
= g_strdup_printf("%s:%s", jii
->client_name
, midiin
->hdr
.name
);
376 autoconnect_by_spec(jii
->client
, cbox_port
, midiin
->autoconnect_spec
, 1, 1, portobj
, fb
);
380 gchar
*cbox_port
= g_strdup_printf("%s:midi", jii
->client_name
);
381 autoconnect_by_var(jii
->client
, cbox_port
, "midi", 1, 1, portobj
, fb
);
385 int cbox_jackio_get_sample_rate(struct cbox_io_impl
*impl
)
387 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
389 return jack_get_sample_rate(jii
->client
);
392 gboolean
cbox_jackio_get_status(struct cbox_io_impl
*impl
, GError
**error
)
394 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
397 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "%s", jii
->error_str
);
401 static void client_shutdown_cb(jack_status_t code
, const char *reason
, void *arg
)
403 struct cbox_jack_io_impl
*jii
= arg
;
404 struct cbox_io
*io
= jii
->ioi
.pio
;
405 jii
->error_str
= g_strdup(reason
);
406 if (io
->cb
&& io
->cb
->on_disconnected
)
407 (io
->cb
->on_disconnected
)(io
->cb
->user_data
);
410 static int sync_cb(jack_transport_state_t state
, jack_position_t
*pos
, void *arg
)
412 struct cbox_jack_io_impl
*jii
= arg
;
413 struct cbox_io
*io
= jii
->ioi
.pio
;
414 gboolean result
= TRUE
;
415 int last_state
= jii
->last_transport_state
;
418 case JackTransportStopped
:
419 result
= io
->cb
->on_transport_sync(io
->cb
->user_data
, ts_stopped
, pos
->frame
);
421 case JackTransportStarting
:
422 jii
->last_transport_state
= JackTransportStarting
;
423 result
= io
->cb
->on_transport_sync(io
->cb
->user_data
, ts_starting
, pos
->frame
);
425 case JackTransportRolling
:
426 result
= io
->cb
->on_transport_sync(io
->cb
->user_data
, ts_rolling
, pos
->frame
);
429 // assume the client is ready
432 if (jii
->debug_transport
)
433 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
);
437 gboolean
cbox_jackio_start(struct cbox_io_impl
*impl
, struct cbox_command_target
*fb
, GError
**error
)
439 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
440 struct cbox_io
*io
= jii
->ioi
.pio
;
442 if (io
->cb
->on_transport_sync
)
443 jack_set_sync_callback(jii
->client
, sync_cb
, jii
);
444 jack_set_process_callback(jii
->client
, process_cb
, jii
);
445 jack_set_port_registration_callback(jii
->client
, port_connect_cb
, jii
);
446 jack_on_info_shutdown(jii
->client
, client_shutdown_cb
, jii
);
448 if (io
->cb
->on_started
)
449 io
->cb
->on_started(io
->cb
->user_data
);
451 jack_activate(jii
->client
);
453 if (cbox_config_has_section(cbox_io_section
))
454 port_autoconnect(jii
, NULL
, fb
);
459 gboolean
cbox_jackio_stop(struct cbox_io_impl
*impl
, GError
**error
)
461 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
465 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "%s", jii
->error_str
);
468 jack_deactivate(jii
->client
);
472 void cbox_jackio_poll_ports(struct cbox_io_impl
*impl
, struct cbox_command_target
*fb
)
474 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
476 while (jack_ringbuffer_read_space(jii
->rb_autoconnect
) >= sizeof(jack_port_t
*))
478 jack_port_t
*portobj
;
479 jack_ringbuffer_read(jii
->rb_autoconnect
, (char *)&portobj
, sizeof(portobj
));
480 port_autoconnect(jii
, portobj
, fb
);
484 int cbox_jackio_get_midi_data(struct cbox_io_impl
*impl
, struct cbox_midi_buffer
*destination
)
486 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
487 if (!jii
->enable_common_midi_input
)
489 cbox_midi_buffer_clear(destination
);
493 return copy_midi_data_to_buffer(jii
->midi
, jii
->ioi
.pio
->io_env
.buffer_size
, destination
);
496 void cbox_jackio_destroy(struct cbox_io_impl
*impl
)
498 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
499 struct cbox_io
*io
= impl
->pio
;
504 g_free(jii
->error_str
);
505 jii
->error_str
= NULL
;
509 for (int i
= 0; i
< io
->io_env
.input_count
; i
++)
510 jack_port_unregister(jii
->client
, jii
->inputs
[i
]);
512 for (int i
= 0; i
< io
->io_env
.output_count
; i
++)
513 jack_port_unregister(jii
->client
, jii
->outputs
[i
]);
516 jack_port_unregister(jii
->client
, jii
->midi
);
518 if (jii
->client_name
)
520 free(jii
->client_name
);
521 jii
->client_name
= NULL
;
523 cbox_io_destroy_all_midi_ports(io
);
525 jack_ringbuffer_free(jii
->rb_autoconnect
);
526 jack_client_close(jii
->client
);
531 gboolean
cbox_jackio_cycle(struct cbox_io_impl
*impl
, struct cbox_command_target
*fb
, GError
**error
)
533 struct cbox_io
*io
= impl
->pio
;
534 struct cbox_io_callbacks
*cb
= io
->cb
;
537 // XXXKF use params structure some day
538 if (!cbox_io_init_jack(io
, NULL
, fb
, error
))
541 cbox_io_start(io
, cb
, fb
);
542 if (cb
->on_reconnected
)
543 (cb
->on_reconnected
)(cb
->user_data
);
549 ///////////////////////////////////////////////////////////////////////////////
551 struct cbox_midi_input
*cbox_jackio_create_midi_in(struct cbox_io_impl
*impl
, const char *name
, GError
**error
)
553 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
554 jack_port_t
*port
= jack_port_register(jii
->client
, name
, JACK_DEFAULT_MIDI_TYPE
, JackPortIsInput
, 0);
557 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create input MIDI port '%s'", name
);
560 struct cbox_jack_midi_input
*input
= calloc(1, sizeof(struct cbox_jack_midi_input
));
561 input
->hdr
.name
= g_strdup(name
);
562 input
->hdr
.removing
= FALSE
;
565 cbox_uuid_generate(&input
->hdr
.uuid
);
566 cbox_midi_buffer_init(&input
->hdr
.buffer
);
568 return (struct cbox_midi_input
*)input
;
571 struct cbox_midi_output
*cbox_jackio_create_midi_out(struct cbox_io_impl
*impl
, const char *name
, GError
**error
)
573 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
574 jack_port_t
*port
= jack_port_register(jii
->client
, name
, JACK_DEFAULT_MIDI_TYPE
, JackPortIsOutput
, 0);
577 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create output MIDI port '%s'", name
);
580 struct cbox_jack_midi_output
*output
= calloc(1, sizeof(struct cbox_jack_midi_output
));
581 output
->hdr
.name
= g_strdup(name
);
582 output
->hdr
.removing
= FALSE
;
585 cbox_uuid_generate(&output
->hdr
.uuid
);
586 cbox_midi_buffer_init(&output
->hdr
.buffer
);
587 cbox_midi_merger_init(&output
->hdr
.merger
, &output
->hdr
.buffer
);
589 return (struct cbox_midi_output
*)output
;
592 void cbox_jack_midi_input_set_autoconnect(struct cbox_jack_midi_input
*jmi
, const gchar
*autoconnect_spec
)
594 if (jmi
->autoconnect_spec
)
595 g_free(jmi
->autoconnect_spec
);
596 jmi
->autoconnect_spec
= autoconnect_spec
&& *autoconnect_spec
? g_strdup(autoconnect_spec
) : NULL
;
597 if (jmi
->autoconnect_spec
)
599 gchar
*cbox_port
= g_strdup_printf("%s:%s", jmi
->jii
->client_name
, jmi
->hdr
.name
);
600 autoconnect_by_spec(jmi
->jii
->client
, cbox_port
, jmi
->autoconnect_spec
, 1, 1, NULL
, NULL
);
605 void cbox_jack_midi_output_set_autoconnect(struct cbox_jack_midi_output
*jmo
, const gchar
*autoconnect_spec
)
607 if (jmo
->autoconnect_spec
)
608 g_free(jmo
->autoconnect_spec
);
609 jmo
->autoconnect_spec
= autoconnect_spec
&& *autoconnect_spec
? g_strdup(autoconnect_spec
) : NULL
;
610 if (jmo
->autoconnect_spec
)
612 gchar
*cbox_port
= g_strdup_printf("%s:%s", jmo
->jii
->client_name
, jmo
->hdr
.name
);
613 autoconnect_by_spec(jmo
->jii
->client
, cbox_port
, jmo
->autoconnect_spec
, 0, 1, NULL
, NULL
);
618 void cbox_jackio_destroy_midi_in(struct cbox_io_impl
*ioi
, struct cbox_midi_input
*midiin
)
620 cbox_jack_midi_input_destroy((struct cbox_jack_midi_input
*)midiin
);
623 void cbox_jackio_destroy_midi_out(struct cbox_io_impl
*ioi
, struct cbox_midi_output
*midiout
)
625 cbox_jack_midi_output_destroy((struct cbox_jack_midi_output
*)midiout
);
628 static gboolean
cbox_jack_io_process_cmd(struct cbox_command_target
*ct
, struct cbox_command_target
*fb
, struct cbox_osc_command
*cmd
, GError
**error
)
630 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)ct
->user_data
;
631 struct cbox_io
*io
= jii
->ioi
.pio
;
632 gboolean handled
= FALSE
;
633 if (!strcmp(cmd
->command
, "/status") && !strcmp(cmd
->arg_types
, ""))
635 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
637 return cbox_execute_on(fb
, NULL
, "/client_type", "s", error
, "JACK") &&
638 cbox_execute_on(fb
, NULL
, "/client_name", "s", error
, jii
->client_name
) &&
639 cbox_io_process_cmd(io
, fb
, cmd
, error
, &handled
);
641 else if (!strcmp(cmd
->command
, "/rename_midi_port") && !strcmp(cmd
->arg_types
, "ss"))
643 const char *uuidstr
= CBOX_ARG_S(cmd
, 0);
644 const char *new_name
= CBOX_ARG_S(cmd
, 1);
645 struct cbox_uuid uuid
;
646 if (!cbox_uuid_fromstring(&uuid
, uuidstr
, error
))
648 struct cbox_midi_input
*midiin
= cbox_io_get_midi_input(io
, NULL
, &uuid
);
649 struct cbox_midi_output
*midiout
= cbox_io_get_midi_output(io
, NULL
, &uuid
);
650 if (!midiout
&& !midiin
)
652 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Port '%s' not found", uuidstr
);
655 jack_port_t
*port
= midiout
? ((struct cbox_jack_midi_output
*)midiout
)->port
656 : ((struct cbox_jack_midi_input
*)midiin
)->port
;
657 char **pname
= midiout
? &midiout
->name
: &midiin
->name
;
658 if (0 != jack_port_set_name(port
, new_name
))
660 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot set port name to '%s'", new_name
);
664 *pname
= g_strdup(new_name
);
667 else if (!strcmp(cmd
->command
, "/autoconnect") && !strcmp(cmd
->arg_types
, "ss"))
669 const char *uuidstr
= CBOX_ARG_S(cmd
, 0);
670 const char *spec
= CBOX_ARG_S(cmd
, 1);
671 struct cbox_uuid uuid
;
672 if (!cbox_uuid_fromstring(&uuid
, uuidstr
, error
))
674 struct cbox_midi_output
*midiout
= cbox_io_get_midi_output(io
, NULL
, &uuid
);
677 cbox_jack_midi_output_set_autoconnect((struct cbox_jack_midi_output
*)midiout
, spec
);
680 struct cbox_midi_input
*midiin
= cbox_io_get_midi_input(io
, NULL
, &uuid
);
683 cbox_jack_midi_input_set_autoconnect((struct cbox_jack_midi_input
*)midiin
, spec
);
686 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Port '%s' not found", uuidstr
);
689 else if (!strcmp(cmd
->command
, "/disconnect_midi_port") && !strcmp(cmd
->arg_types
, "s"))
691 const char *uuidstr
= CBOX_ARG_S(cmd
, 0);
692 struct cbox_uuid uuid
;
693 if (!cbox_uuid_fromstring(&uuid
, uuidstr
, error
))
695 struct cbox_midi_input
*midiin
= cbox_io_get_midi_input(io
, NULL
, &uuid
);
696 struct cbox_midi_output
*midiout
= cbox_io_get_midi_output(io
, NULL
, &uuid
);
697 if (!midiout
&& !midiin
)
699 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Port '%s' not found", uuidstr
);
702 jack_port_t
*port
= midiout
? ((struct cbox_jack_midi_output
*)midiout
)->port
703 : ((struct cbox_jack_midi_input
*)midiin
)->port
;
704 jack_port_disconnect(jii
->client
, port
);
707 else if (!strcmp(cmd
->command
, "/port_connect") && !strcmp(cmd
->arg_types
, "ss"))
709 const char *port_from
= CBOX_ARG_S(cmd
, 0);
710 const char *port_to
= CBOX_ARG_S(cmd
, 1);
711 int res
= jack_connect(jii
->client
, port_from
, port_to
);
715 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot connect port '%s' to '%s'", port_from
, port_to
);
718 else if (!strcmp(cmd
->command
, "/port_disconnect") && !strcmp(cmd
->arg_types
, "ss"))
720 const char *port_from
= CBOX_ARG_S(cmd
, 0);
721 const char *port_to
= CBOX_ARG_S(cmd
, 1);
722 int res
= jack_disconnect(jii
->client
, port_from
, port_to
);
724 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot disconnect port '%s' from '%s'", port_from
, port_to
);
727 else if (!strcmp(cmd
->command
, "/get_connected_ports") && !strcmp(cmd
->arg_types
, "s"))
729 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
731 const char *name
= CBOX_ARG_S(cmd
, 0);
732 jack_port_t
*port
= jack_port_by_name(jii
->client
, name
);
735 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Port '%s' not found", name
);
738 const char** ports
= jack_port_get_all_connections(jii
->client
, port
);
739 for (int i
= 0; ports
&& ports
[i
]; i
++)
741 if (!cbox_execute_on(fb
, NULL
, "/port", "s", error
, ports
[i
]))
747 else if (!strcmp(cmd
->command
, "/get_ports") && !strcmp(cmd
->arg_types
, "ssi"))
749 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
751 const char *mask
= CBOX_ARG_S(cmd
, 0);
752 const char *type
= CBOX_ARG_S(cmd
, 1);
753 uint32_t flags
= CBOX_ARG_I(cmd
, 2);
754 const char** ports
= jack_get_ports(jii
->client
, mask
, type
, flags
);
755 for (int i
= 0; ports
&& ports
[i
]; i
++)
757 if (!cbox_execute_on(fb
, NULL
, "/port", "s", error
, ports
[i
]))
765 gboolean result
= cbox_io_process_cmd(io
, fb
, cmd
, error
, &handled
);
767 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
);
772 ///////////////////////////////////////////////////////////////////////////////
774 static void cbox_jackio_control_transport(struct cbox_io_impl
*impl
, gboolean roll
, uint32_t pos
)
776 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
778 if (jii
->debug_transport
)
779 g_message("JACK transport: control(op=%s, pos=%d)\n", roll
? "roll" : "stop", (int)pos
);
781 jack_transport_state_t state
= jack_transport_query(jii
->client
, NULL
);
782 if (roll
&& state
== JackTransportStopped
)
783 jack_transport_start(jii
->client
);
784 if (!roll
&& state
!= JackTransportStopped
)
785 jack_transport_stop(jii
->client
);
787 if (pos
!= (uint32_t)-1)
788 jack_transport_locate(jii
->client
, pos
);
791 static gboolean
cbox_jackio_get_sync_completed(struct cbox_io_impl
*impl
)
793 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
794 return jack_transport_query(jii
->client
, NULL
) != JackTransportStarting
;
797 ///////////////////////////////////////////////////////////////////////////////
799 gboolean
cbox_io_init_jack(struct cbox_io
*io
, struct cbox_open_params
*const params
, struct cbox_command_target
*fb
, GError
**error
)
801 const char *client_name
= cbox_config_get_string_with_default("io", "client_name", "cbox");
803 jack_client_t
*client
= NULL
;
804 jack_status_t status
= 0;
805 client
= jack_client_open(client_name
, JackNoStartServer
, &status
);
808 if (!cbox_hwcfg_setup_jack())
810 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot set up JACK server configuration based on current hardware");
815 client
= jack_client_open(client_name
, 0, &status
);
819 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create JACK instance");
823 // XXXKF would use a callback instead
824 io
->io_env
.buffer_size
= jack_get_buffer_size(client
);
826 io
->io_env
.input_count
= cbox_config_get_int("io", "inputs", 0);
827 io
->input_buffers
= malloc(sizeof(float *) * io
->io_env
.input_count
);
828 io
->io_env
.output_count
= cbox_config_get_int("io", "outputs", 2);
829 io
->output_buffers
= malloc(sizeof(float *) * io
->io_env
.output_count
);
831 struct cbox_jack_io_impl
*jii
= malloc(sizeof(struct cbox_jack_io_impl
));
832 io
->impl
= &jii
->ioi
;
833 jii
->enable_common_midi_input
= cbox_config_get_int("io", "enable_common_midi_input", 1);
834 jii
->debug_transport
= cbox_config_get_int("debug", "jack_transport", 0);
835 jii
->last_transport_state
= JackTransportStopped
;
837 cbox_command_target_init(&io
->cmd_target
, cbox_jack_io_process_cmd
, jii
);
839 jii
->ioi
.getsampleratefunc
= cbox_jackio_get_sample_rate
;
840 jii
->ioi
.startfunc
= cbox_jackio_start
;
841 jii
->ioi
.stopfunc
= cbox_jackio_stop
;
842 jii
->ioi
.getstatusfunc
= cbox_jackio_get_status
;
843 jii
->ioi
.pollfunc
= cbox_jackio_poll_ports
;
844 jii
->ioi
.cyclefunc
= cbox_jackio_cycle
;
845 jii
->ioi
.getmidifunc
= cbox_jackio_get_midi_data
;
846 jii
->ioi
.createmidiinfunc
= cbox_jackio_create_midi_in
;
847 jii
->ioi
.destroymidiinfunc
= cbox_jackio_destroy_midi_in
;
848 jii
->ioi
.createmidioutfunc
= cbox_jackio_create_midi_out
;
849 jii
->ioi
.destroymidioutfunc
= cbox_jackio_destroy_midi_out
;
850 jii
->ioi
.updatemidiinroutingfunc
= NULL
;
851 jii
->ioi
.controltransportfunc
= cbox_jackio_control_transport
;
852 jii
->ioi
.getsynccompletedfunc
= cbox_jackio_get_sync_completed
;
853 jii
->ioi
.destroyfunc
= cbox_jackio_destroy
;
855 jii
->client_name
= g_strdup(jack_get_client_name(client
));
856 jii
->client
= client
;
857 jii
->rb_autoconnect
= jack_ringbuffer_create(sizeof(jack_port_t
*) * 128);
858 jii
->error_str
= NULL
;
859 io
->io_env
.srate
= jack_get_sample_rate(client
);
861 jii
->inputs
= malloc(sizeof(jack_port_t
*) * io
->io_env
.input_count
);
862 jii
->outputs
= malloc(sizeof(jack_port_t
*) * io
->io_env
.output_count
);
863 for (int i
= 0; i
< io
->io_env
.input_count
; i
++)
864 jii
->inputs
[i
] = NULL
;
865 for (int i
= 0; i
< io
->io_env
.output_count
; i
++)
866 jii
->outputs
[i
] = NULL
;
867 for (int i
= 0; i
< io
->io_env
.input_count
; i
++)
869 gchar
*name
= g_strdup_printf("in_%d", 1 + i
);
870 jii
->inputs
[i
] = jack_port_register(jii
->client
, name
, JACK_DEFAULT_AUDIO_TYPE
, JackPortIsInput
, 0);
873 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create input port %d (%s)", i
, name
);
879 for (int i
= 0; i
< io
->io_env
.output_count
; i
++)
881 gchar
*name
= g_strdup_printf("out_%d", 1 + i
);
882 jii
->outputs
[i
] = jack_port_register(jii
->client
, name
, JACK_DEFAULT_AUDIO_TYPE
, JackPortIsOutput
, 0);
883 if (!jii
->outputs
[i
])
885 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create output port %d (%s)", i
, name
);
891 if (jii
->enable_common_midi_input
)
893 jii
->midi
= jack_port_register(jii
->client
, "midi", JACK_DEFAULT_MIDI_TYPE
, JackPortIsInput
, 0);
896 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create MIDI port");
904 cbox_execute_on(fb
, NULL
, "/io/jack_client_name", "s", NULL
, jii
->client_name
);
906 cbox_io_poll_ports(io
, fb
);
913 for (int i
= 0; i
< io
->io_env
.input_count
; i
++)
914 free(jii
->inputs
[i
]);
919 for (int i
= 0; i
< io
->io_env
.output_count
; i
++)
920 free(jii
->outputs
[i
]);
923 cbox_io_destroy_all_midi_ports(io
);
924 if (jii
->client_name
)
925 free(jii
->client_name
);
926 jack_client_close(jii
->client
);