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 void cbox_jack_midi_input_destroy(struct cbox_jack_midi_input
*jmi
)
86 jack_port_unregister(jmi
->jii
->client
, jmi
->port
);
89 g_free(jmi
->hdr
.name
);
90 g_free(jmi
->autoconnect_spec
);
94 void cbox_jack_midi_output_destroy(struct cbox_jack_midi_output
*jmo
)
98 jack_port_unregister(jmo
->jii
->client
, jmo
->port
);
101 g_free(jmo
->hdr
.name
);
102 g_free(jmo
->autoconnect_spec
);
106 ///////////////////////////////////////////////////////////////////////////////
108 static int copy_midi_data_to_buffer(jack_port_t
*port
, int buffer_size
, struct cbox_midi_buffer
*destination
)
110 void *midi
= jack_port_get_buffer(port
, buffer_size
);
111 uint32_t event_count
= jack_midi_get_event_count(midi
);
113 cbox_midi_buffer_clear(destination
);
114 for (uint32_t i
= 0; i
< event_count
; i
++)
116 jack_midi_event_t event
;
118 if (!jack_midi_event_get(&event
, midi
, i
))
120 if (!cbox_midi_buffer_write_event(destination
, event
.time
, event
.buffer
, event
.size
))
130 ///////////////////////////////////////////////////////////////////////////////
132 static int process_cb(jack_nframes_t nframes
, void *arg
)
134 struct cbox_jack_io_impl
*jii
= arg
;
135 struct cbox_io
*io
= jii
->ioi
.pio
;
136 struct cbox_io_callbacks
*cb
= io
->cb
;
138 io
->io_env
.buffer_size
= nframes
;
139 for (int i
= 0; i
< io
->io_env
.input_count
; i
++)
140 io
->input_buffers
[i
] = jack_port_get_buffer(jii
->inputs
[i
], nframes
);
141 for (int i
= 0; i
< io
->io_env
.output_count
; i
++)
143 io
->output_buffers
[i
] = jack_port_get_buffer(jii
->outputs
[i
], nframes
);
144 for (int j
= 0; j
< nframes
; j
++)
145 io
->output_buffers
[i
][j
] = 0.f
;
147 for (GSList
*p
= io
->midi_inputs
; p
; p
= p
->next
)
149 struct cbox_jack_midi_input
*input
= p
->data
;
150 if (input
->hdr
.output_set
|| input
->hdr
.enable_appsink
)
152 copy_midi_data_to_buffer(input
->port
, io
->io_env
.buffer_size
, &input
->hdr
.buffer
);
153 if (input
->hdr
.enable_appsink
)
154 cbox_midi_appsink_supply(&input
->hdr
.appsink
, &input
->hdr
.buffer
);
157 cbox_midi_buffer_clear(&input
->hdr
.buffer
);
159 if (cb
->on_transport_sync
)
161 jack_transport_state_t state
= jack_transport_query(jii
->client
, NULL
);
162 if (state
!= jii
->last_transport_state
)
165 jack_transport_query(jii
->client
, &pos
);
166 if (jii
->debug_transport
)
167 g_message("JACK transport: incoming state change, state = %d, last state = %d, pos = %d\n", (int)state
, (int)jii
->last_transport_state
, (int)pos
.frame
);
168 if (state
== JackTransportStopped
)
170 if (cb
->on_transport_sync(cb
->user_data
, ts_stopping
, pos
.frame
))
171 jii
->last_transport_state
= state
;
174 if (state
== JackTransportRolling
&& jii
->last_transport_state
== JackTransportStarting
)
176 if (cb
->on_transport_sync(cb
->user_data
, ts_rolling
, pos
.frame
))
177 jii
->last_transport_state
= state
;
180 jii
->last_transport_state
= state
;
183 cb
->process(cb
->user_data
, io
, nframes
);
184 for (int i
= 0; i
< io
->io_env
.input_count
; i
++)
185 io
->input_buffers
[i
] = NULL
;
186 for (int i
= 0; i
< io
->io_env
.output_count
; i
++)
187 io
->output_buffers
[i
] = NULL
;
188 for (GSList
*p
= io
->midi_outputs
; p
; p
= g_slist_next(p
))
190 struct cbox_jack_midi_output
*midiout
= p
->data
;
192 void *pbuf
= jack_port_get_buffer(midiout
->port
, nframes
);
193 jack_midi_clear_buffer(pbuf
);
195 cbox_midi_merger_render(&midiout
->hdr
.merger
);
196 if (midiout
->hdr
.buffer
.count
)
199 for (int i
= 0; i
< midiout
->hdr
.buffer
.count
; i
++)
201 const struct cbox_midi_event
*event
= cbox_midi_buffer_get_event(&midiout
->hdr
.buffer
, i
);
202 const uint8_t *pdata
= cbox_midi_event_get_data(event
);
203 if ((pdata
[0] & 0xF0) == 0x90 && !pdata
[2] && event
->size
== 3)
205 tmp_data
[0] = pdata
[0] & ~0x10;
206 tmp_data
[1] = pdata
[1];
207 tmp_data
[2] = pdata
[2];
210 if (jack_midi_event_write(pbuf
, event
->time
, pdata
, event
->size
))
212 g_warning("MIDI buffer overflow on JACK output port '%s'", midiout
->hdr
.name
);
221 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
)
224 if (only_connect_port
)
227 right
= jack_port_by_name(client
, use_name
);
228 if (only_connect_port
!= right
)
232 const char *pfrom
= is_cbox_input
? use_name
: port
;
233 const char *pto
= !is_cbox_input
? use_name
: port
;
235 res
= jack_connect(client
, pfrom
, pto
);
238 gboolean suppressed
= FALSE
;
242 suppressed
= cbox_execute_on(fb
, NULL
, "/io/jack/connected", "ss", NULL
, pfrom
, pto
);
244 suppressed
= cbox_execute_on(fb
, NULL
, "/io/jack/connect_failed", "sss", NULL
, pfrom
, pto
, (res
== EEXIST
? "already connected" : "failed"));
247 g_message("Connect: %s %s %s (%s)", port
, is_cbox_input
? "<-" : "->", use_name
, res
== 0 ? "success" : (res
== EEXIST
? "already connected" : "failed"));
250 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
)
252 char *name
, *copy_spec
, *dpos
;
253 const char *use_name
;
255 copy_spec
= g_strdup(orig_spec
);
258 dpos
= strchr(name
, ';');
263 if (use_name
[0] == '#')
266 long portidx
= strtol(use_name
+ 1, &endptr
, 10) - 1;
267 if (endptr
== use_name
+ strlen(use_name
))
269 const char **names
= jack_get_ports(client
, ".*", is_midi
? JACK_DEFAULT_MIDI_TYPE
: JACK_DEFAULT_AUDIO_TYPE
, is_cbox_input
? JackPortIsOutput
: JackPortIsInput
);
271 for (i
= 0; i
< portidx
&& names
[i
]; i
++)
275 autoconnect_port(client
, port
, names
[i
], is_cbox_input
, only_connect_port
, fb
);
277 g_message("Connect: unmatched port index %d", (int)portidx
);
282 else if (use_name
[0] == '~' || use_name
[0] == '*')
284 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
);
286 if (names
&& names
[0])
288 if (use_name
[0] == '*')
291 for (i
= 0; names
[i
]; i
++)
292 autoconnect_port(client
, port
, names
[i
], is_cbox_input
, only_connect_port
, fb
);
295 autoconnect_port(client
, port
, names
[0], is_cbox_input
, only_connect_port
, fb
);
298 g_message("Connect: unmatched port regexp %s", use_name
);
302 autoconnect_port(client
, port
, use_name
, is_cbox_input
, only_connect_port
, fb
);
310 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
)
312 const char *orig_spec
= cbox_config_get_string(cbox_io_section
, config_var
);
314 autoconnect_by_spec(client
, port
, orig_spec
, is_cbox_input
, is_midi
, only_connect_port
, fb
);
317 static void port_connect_cb(jack_port_id_t port
, int registered
, void *arg
)
319 struct cbox_jack_io_impl
*jii
= arg
;
322 jack_port_t
*portobj
= jack_port_by_id(jii
->client
, port
);
324 jack_ringbuffer_write(jii
->rb_autoconnect
, (char *)&portobj
, sizeof(portobj
));
328 static void port_autoconnect(struct cbox_jack_io_impl
*jii
, jack_port_t
*portobj
, struct cbox_command_target
*fb
)
330 struct cbox_io
*io
= jii
->ioi
.pio
;
332 for (int i
= 0; i
< io
->io_env
.output_count
; i
++)
334 gchar
*cbox_port
= g_strdup_printf("%s:out_%d", jii
->client_name
, 1 + i
);
335 gchar
*config_key
= g_strdup_printf("out_%d", 1 + i
);
336 autoconnect_by_var(jii
->client
, cbox_port
, config_key
, 0, 0, portobj
, fb
);
340 for (int i
= 0; i
< io
->io_env
.input_count
; i
++)
342 gchar
*cbox_port
= g_strdup_printf("%s:in_%d", jii
->client_name
, 1 + i
);
343 gchar
*config_key
= g_strdup_printf("in_%d", 1 + i
);
344 autoconnect_by_var(jii
->client
, cbox_port
, config_key
, 1, 0, portobj
, fb
);
348 for (GSList
*p
= io
->midi_outputs
; p
; p
= g_slist_next(p
))
350 struct cbox_jack_midi_output
*midiout
= p
->data
;
351 if (midiout
->autoconnect_spec
)
353 gchar
*cbox_port
= g_strdup_printf("%s:%s", jii
->client_name
, midiout
->hdr
.name
);
354 autoconnect_by_spec(jii
->client
, cbox_port
, midiout
->autoconnect_spec
, 0, 1, portobj
, fb
);
358 for (GSList
*p
= io
->midi_inputs
; p
; p
= g_slist_next(p
))
360 struct cbox_jack_midi_input
*midiin
= p
->data
;
361 if (midiin
->autoconnect_spec
)
363 gchar
*cbox_port
= g_strdup_printf("%s:%s", jii
->client_name
, midiin
->hdr
.name
);
364 autoconnect_by_spec(jii
->client
, cbox_port
, midiin
->autoconnect_spec
, 1, 1, portobj
, fb
);
368 gchar
*cbox_port
= g_strdup_printf("%s:midi", jii
->client_name
);
369 autoconnect_by_var(jii
->client
, cbox_port
, "midi", 1, 1, portobj
, fb
);
373 int cbox_jackio_get_sample_rate(struct cbox_io_impl
*impl
)
375 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
377 return jack_get_sample_rate(jii
->client
);
380 gboolean
cbox_jackio_get_status(struct cbox_io_impl
*impl
, GError
**error
)
382 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
385 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "%s", jii
->error_str
);
389 static void client_shutdown_cb(jack_status_t code
, const char *reason
, void *arg
)
391 struct cbox_jack_io_impl
*jii
= arg
;
392 struct cbox_io
*io
= jii
->ioi
.pio
;
393 jii
->error_str
= g_strdup(reason
);
394 if (io
->cb
&& io
->cb
->on_disconnected
)
395 (io
->cb
->on_disconnected
)(io
->cb
->user_data
);
398 static int sync_cb(jack_transport_state_t state
, jack_position_t
*pos
, void *arg
)
400 struct cbox_jack_io_impl
*jii
= arg
;
401 struct cbox_io
*io
= jii
->ioi
.pio
;
402 gboolean result
= TRUE
;
405 case JackTransportStopped
:
406 result
= io
->cb
->on_transport_sync(io
->cb
->user_data
, ts_stopped
, pos
->frame
);
408 case JackTransportStarting
:
409 jii
->last_transport_state
= JackTransportStarting
;
410 result
= io
->cb
->on_transport_sync(io
->cb
->user_data
, ts_starting
, pos
->frame
);
412 case JackTransportRolling
:
413 result
= io
->cb
->on_transport_sync(io
->cb
->user_data
, ts_rolling
, pos
->frame
);
416 // assume the client is ready
419 if (jii
->debug_transport
)
420 g_message("JACK transport: incoming sync callback, state = %d, last state = %d, pos = %d, result = %d\n", (int)state
, (int)jii
->last_transport_state
, (int)pos
->frame
, result
);
424 gboolean
cbox_jackio_start(struct cbox_io_impl
*impl
, struct cbox_command_target
*fb
, GError
**error
)
426 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
427 struct cbox_io
*io
= jii
->ioi
.pio
;
429 if (io
->cb
->on_transport_sync
)
430 jack_set_sync_callback(jii
->client
, sync_cb
, jii
);
431 jack_set_process_callback(jii
->client
, process_cb
, jii
);
432 jack_set_port_registration_callback(jii
->client
, port_connect_cb
, jii
);
433 jack_on_info_shutdown(jii
->client
, client_shutdown_cb
, jii
);
435 if (io
->cb
->on_started
)
436 io
->cb
->on_started(io
->cb
->user_data
);
438 jack_activate(jii
->client
);
440 if (cbox_config_has_section(cbox_io_section
))
441 port_autoconnect(jii
, NULL
, fb
);
446 gboolean
cbox_jackio_stop(struct cbox_io_impl
*impl
, GError
**error
)
448 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
452 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "%s", jii
->error_str
);
455 jack_deactivate(jii
->client
);
459 void cbox_jackio_poll_ports(struct cbox_io_impl
*impl
, struct cbox_command_target
*fb
)
461 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
463 while (jack_ringbuffer_read_space(jii
->rb_autoconnect
) >= sizeof(jack_port_t
*))
465 jack_port_t
*portobj
;
466 jack_ringbuffer_read(jii
->rb_autoconnect
, (char *)&portobj
, sizeof(portobj
));
467 port_autoconnect(jii
, portobj
, fb
);
471 int cbox_jackio_get_midi_data(struct cbox_io_impl
*impl
, struct cbox_midi_buffer
*destination
)
473 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
474 if (!jii
->enable_common_midi_input
)
476 cbox_midi_buffer_clear(destination
);
480 return copy_midi_data_to_buffer(jii
->midi
, jii
->ioi
.pio
->io_env
.buffer_size
, destination
);
483 void cbox_jackio_destroy(struct cbox_io_impl
*impl
)
485 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
486 struct cbox_io
*io
= impl
->pio
;
491 g_free(jii
->error_str
);
492 jii
->error_str
= NULL
;
496 for (int i
= 0; i
< io
->io_env
.input_count
; i
++)
497 jack_port_unregister(jii
->client
, jii
->inputs
[i
]);
499 for (int i
= 0; i
< io
->io_env
.output_count
; i
++)
500 jack_port_unregister(jii
->client
, jii
->outputs
[i
]);
503 jack_port_unregister(jii
->client
, jii
->midi
);
505 if (jii
->client_name
)
507 free(jii
->client_name
);
508 jii
->client_name
= NULL
;
510 cbox_io_destroy_all_midi_ports(io
);
512 jack_ringbuffer_free(jii
->rb_autoconnect
);
513 jack_client_close(jii
->client
);
518 gboolean
cbox_jackio_cycle(struct cbox_io_impl
*impl
, struct cbox_command_target
*fb
, GError
**error
)
520 struct cbox_io
*io
= impl
->pio
;
521 struct cbox_io_callbacks
*cb
= io
->cb
;
524 // XXXKF use params structure some day
525 if (!cbox_io_init_jack(io
, NULL
, fb
, error
))
528 cbox_io_start(io
, cb
, fb
);
529 if (cb
->on_reconnected
)
530 (cb
->on_reconnected
)(cb
->user_data
);
536 ///////////////////////////////////////////////////////////////////////////////
538 struct cbox_midi_input
*cbox_jackio_create_midi_in(struct cbox_io_impl
*impl
, const char *name
, GError
**error
)
540 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
541 jack_port_t
*port
= jack_port_register(jii
->client
, name
, JACK_DEFAULT_MIDI_TYPE
, JackPortIsInput
, 0);
544 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create input MIDI port '%s'", name
);
547 struct cbox_jack_midi_input
*input
= calloc(1, sizeof(struct cbox_jack_midi_input
));
548 input
->hdr
.name
= g_strdup(name
);
549 input
->hdr
.removing
= FALSE
;
552 cbox_uuid_generate(&input
->hdr
.uuid
);
553 cbox_midi_buffer_init(&input
->hdr
.buffer
);
555 return (struct cbox_midi_input
*)input
;
558 struct cbox_midi_output
*cbox_jackio_create_midi_out(struct cbox_io_impl
*impl
, const char *name
, GError
**error
)
560 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
561 jack_port_t
*port
= jack_port_register(jii
->client
, name
, JACK_DEFAULT_MIDI_TYPE
, JackPortIsOutput
, 0);
564 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create output MIDI port '%s'", name
);
567 struct cbox_jack_midi_output
*output
= calloc(1, sizeof(struct cbox_jack_midi_output
));
568 output
->hdr
.name
= g_strdup(name
);
569 output
->hdr
.removing
= FALSE
;
572 cbox_uuid_generate(&output
->hdr
.uuid
);
573 cbox_midi_buffer_init(&output
->hdr
.buffer
);
574 cbox_midi_merger_init(&output
->hdr
.merger
, &output
->hdr
.buffer
);
576 return (struct cbox_midi_output
*)output
;
579 void cbox_jack_midi_input_set_autoconnect(struct cbox_jack_midi_input
*jmi
, const gchar
*autoconnect_spec
)
581 if (jmi
->autoconnect_spec
)
582 g_free(jmi
->autoconnect_spec
);
583 jmi
->autoconnect_spec
= autoconnect_spec
&& *autoconnect_spec
? g_strdup(autoconnect_spec
) : NULL
;
584 if (jmi
->autoconnect_spec
)
586 gchar
*cbox_port
= g_strdup_printf("%s:%s", jmi
->jii
->client_name
, jmi
->hdr
.name
);
587 autoconnect_by_spec(jmi
->jii
->client
, cbox_port
, jmi
->autoconnect_spec
, 1, 1, NULL
, NULL
);
592 void cbox_jack_midi_output_set_autoconnect(struct cbox_jack_midi_output
*jmo
, const gchar
*autoconnect_spec
)
594 if (jmo
->autoconnect_spec
)
595 g_free(jmo
->autoconnect_spec
);
596 jmo
->autoconnect_spec
= autoconnect_spec
&& *autoconnect_spec
? g_strdup(autoconnect_spec
) : NULL
;
597 if (jmo
->autoconnect_spec
)
599 gchar
*cbox_port
= g_strdup_printf("%s:%s", jmo
->jii
->client_name
, jmo
->hdr
.name
);
600 autoconnect_by_spec(jmo
->jii
->client
, cbox_port
, jmo
->autoconnect_spec
, 0, 1, NULL
, NULL
);
605 void cbox_jackio_destroy_midi_in(struct cbox_io_impl
*ioi
, struct cbox_midi_input
*midiin
)
607 cbox_jack_midi_input_destroy((struct cbox_jack_midi_input
*)midiin
);
610 void cbox_jackio_destroy_midi_out(struct cbox_io_impl
*ioi
, struct cbox_midi_output
*midiout
)
612 cbox_jack_midi_output_destroy((struct cbox_jack_midi_output
*)midiout
);
615 static gboolean
cbox_jack_io_process_cmd(struct cbox_command_target
*ct
, struct cbox_command_target
*fb
, struct cbox_osc_command
*cmd
, GError
**error
)
617 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)ct
->user_data
;
618 struct cbox_io
*io
= jii
->ioi
.pio
;
619 gboolean handled
= FALSE
;
620 if (!strcmp(cmd
->command
, "/status") && !strcmp(cmd
->arg_types
, ""))
622 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
624 return cbox_execute_on(fb
, NULL
, "/client_type", "s", error
, "JACK") &&
625 cbox_execute_on(fb
, NULL
, "/client_name", "s", error
, jii
->client_name
) &&
626 cbox_io_process_cmd(io
, fb
, cmd
, error
, &handled
);
628 else if (!strcmp(cmd
->command
, "/rename_midi_port") && !strcmp(cmd
->arg_types
, "ss"))
630 const char *uuidstr
= CBOX_ARG_S(cmd
, 0);
631 const char *new_name
= CBOX_ARG_S(cmd
, 1);
632 struct cbox_uuid uuid
;
633 if (!cbox_uuid_fromstring(&uuid
, uuidstr
, error
))
635 struct cbox_midi_input
*midiin
= cbox_io_get_midi_input(io
, NULL
, &uuid
);
636 struct cbox_midi_output
*midiout
= cbox_io_get_midi_output(io
, NULL
, &uuid
);
637 if (!midiout
&& !midiin
)
639 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Port '%s' not found", uuidstr
);
642 jack_port_t
*port
= midiout
? ((struct cbox_jack_midi_output
*)midiout
)->port
643 : ((struct cbox_jack_midi_input
*)midiin
)->port
;
644 char **pname
= midiout
? &midiout
->name
: &midiin
->name
;
645 if (0 != jack_port_set_name(port
, new_name
))
647 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot set port name to '%s'", new_name
);
651 *pname
= g_strdup(new_name
);
654 else if (!strcmp(cmd
->command
, "/autoconnect") && !strcmp(cmd
->arg_types
, "ss"))
656 const char *uuidstr
= CBOX_ARG_S(cmd
, 0);
657 const char *spec
= CBOX_ARG_S(cmd
, 1);
658 struct cbox_uuid uuid
;
659 if (!cbox_uuid_fromstring(&uuid
, uuidstr
, error
))
661 struct cbox_midi_output
*midiout
= cbox_io_get_midi_output(io
, NULL
, &uuid
);
664 cbox_jack_midi_output_set_autoconnect((struct cbox_jack_midi_output
*)midiout
, spec
);
667 struct cbox_midi_input
*midiin
= cbox_io_get_midi_input(io
, NULL
, &uuid
);
670 cbox_jack_midi_input_set_autoconnect((struct cbox_jack_midi_input
*)midiin
, spec
);
673 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Port '%s' not found", uuidstr
);
676 else if (!strcmp(cmd
->command
, "/disconnect_midi_port") && !strcmp(cmd
->arg_types
, "s"))
678 const char *uuidstr
= CBOX_ARG_S(cmd
, 0);
679 struct cbox_uuid uuid
;
680 if (!cbox_uuid_fromstring(&uuid
, uuidstr
, error
))
682 struct cbox_midi_input
*midiin
= cbox_io_get_midi_input(io
, NULL
, &uuid
);
683 struct cbox_midi_output
*midiout
= cbox_io_get_midi_output(io
, NULL
, &uuid
);
684 if (!midiout
&& !midiin
)
686 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Port '%s' not found", uuidstr
);
689 jack_port_t
*port
= midiout
? ((struct cbox_jack_midi_output
*)midiout
)->port
690 : ((struct cbox_jack_midi_input
*)midiin
)->port
;
691 jack_port_disconnect(jii
->client
, port
);
694 else if (!strcmp(cmd
->command
, "/port_connect") && !strcmp(cmd
->arg_types
, "ss"))
696 const char *port_from
= CBOX_ARG_S(cmd
, 0);
697 const char *port_to
= CBOX_ARG_S(cmd
, 1);
698 int res
= jack_connect(jii
->client
, port_from
, port_to
);
702 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot connect port '%s' to '%s'", port_from
, port_to
);
705 else if (!strcmp(cmd
->command
, "/port_disconnect") && !strcmp(cmd
->arg_types
, "ss"))
707 const char *port_from
= CBOX_ARG_S(cmd
, 0);
708 const char *port_to
= CBOX_ARG_S(cmd
, 1);
709 int res
= jack_disconnect(jii
->client
, port_from
, port_to
);
711 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot disconnect port '%s' from '%s'", port_from
, port_to
);
714 else if (!strcmp(cmd
->command
, "/get_ports") && !strcmp(cmd
->arg_types
, "ssi"))
716 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
718 const char *mask
= CBOX_ARG_S(cmd
, 0);
719 const char *type
= CBOX_ARG_S(cmd
, 1);
720 uint32_t flags
= CBOX_ARG_I(cmd
, 2);
721 const char** ports
= jack_get_ports(jii
->client
, mask
, type
, flags
);
722 for (int i
= 0; ports
&& ports
[i
]; i
++)
724 if (!cbox_execute_on(fb
, NULL
, "/port", "s", error
, ports
[i
]))
732 gboolean result
= cbox_io_process_cmd(io
, fb
, cmd
, error
, &handled
);
734 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
);
739 ///////////////////////////////////////////////////////////////////////////////
741 static void cbox_jackio_control_transport(struct cbox_io_impl
*impl
, gboolean roll
, uint32_t pos
)
743 struct cbox_jack_io_impl
*jii
= (struct cbox_jack_io_impl
*)impl
;
745 jack_transport_state_t state
= jack_transport_query(jii
->client
, NULL
);
746 if (roll
&& state
== JackTransportStopped
)
747 jack_transport_start(jii
->client
);
748 if (!roll
&& state
!= JackTransportStopped
)
749 jack_transport_stop(jii
->client
);
751 if (pos
!= (uint32_t)-1)
752 jack_transport_locate(jii
->client
, pos
);
755 ///////////////////////////////////////////////////////////////////////////////
757 gboolean
cbox_io_init_jack(struct cbox_io
*io
, struct cbox_open_params
*const params
, struct cbox_command_target
*fb
, GError
**error
)
759 const char *client_name
= cbox_config_get_string_with_default("io", "client_name", "cbox");
761 jack_client_t
*client
= NULL
;
762 jack_status_t status
= 0;
763 client
= jack_client_open(client_name
, JackNoStartServer
, &status
);
766 if (!cbox_hwcfg_setup_jack())
768 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot set up JACK server configuration based on current hardware");
773 client
= jack_client_open(client_name
, 0, &status
);
777 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create JACK instance");
781 // XXXKF would use a callback instead
782 io
->io_env
.buffer_size
= jack_get_buffer_size(client
);
784 io
->io_env
.input_count
= cbox_config_get_int("io", "inputs", 0);
785 io
->input_buffers
= malloc(sizeof(float *) * io
->io_env
.input_count
);
786 io
->io_env
.output_count
= cbox_config_get_int("io", "outputs", 2);
787 io
->output_buffers
= malloc(sizeof(float *) * io
->io_env
.output_count
);
789 struct cbox_jack_io_impl
*jii
= malloc(sizeof(struct cbox_jack_io_impl
));
790 io
->impl
= &jii
->ioi
;
791 jii
->enable_common_midi_input
= cbox_config_get_int("io", "enable_common_midi_input", 1);
792 jii
->debug_transport
= cbox_config_get_int("debug", "jack_transport", 0);
793 jii
->last_transport_state
= -1;
795 cbox_command_target_init(&io
->cmd_target
, cbox_jack_io_process_cmd
, jii
);
797 jii
->ioi
.getsampleratefunc
= cbox_jackio_get_sample_rate
;
798 jii
->ioi
.startfunc
= cbox_jackio_start
;
799 jii
->ioi
.stopfunc
= cbox_jackio_stop
;
800 jii
->ioi
.getstatusfunc
= cbox_jackio_get_status
;
801 jii
->ioi
.pollfunc
= cbox_jackio_poll_ports
;
802 jii
->ioi
.cyclefunc
= cbox_jackio_cycle
;
803 jii
->ioi
.getmidifunc
= cbox_jackio_get_midi_data
;
804 jii
->ioi
.createmidiinfunc
= cbox_jackio_create_midi_in
;
805 jii
->ioi
.destroymidiinfunc
= cbox_jackio_destroy_midi_in
;
806 jii
->ioi
.createmidioutfunc
= cbox_jackio_create_midi_out
;
807 jii
->ioi
.destroymidioutfunc
= cbox_jackio_destroy_midi_out
;
808 jii
->ioi
.updatemidiinroutingfunc
= NULL
;
809 jii
->ioi
.controltransportfunc
= cbox_jackio_control_transport
;
810 jii
->ioi
.destroyfunc
= cbox_jackio_destroy
;
812 jii
->client_name
= g_strdup(jack_get_client_name(client
));
813 jii
->client
= client
;
814 jii
->rb_autoconnect
= jack_ringbuffer_create(sizeof(jack_port_t
*) * 128);
815 jii
->error_str
= NULL
;
816 io
->io_env
.srate
= jack_get_sample_rate(client
);
818 jii
->inputs
= malloc(sizeof(jack_port_t
*) * io
->io_env
.input_count
);
819 jii
->outputs
= malloc(sizeof(jack_port_t
*) * io
->io_env
.output_count
);
820 for (int i
= 0; i
< io
->io_env
.input_count
; i
++)
821 jii
->inputs
[i
] = NULL
;
822 for (int i
= 0; i
< io
->io_env
.output_count
; i
++)
823 jii
->outputs
[i
] = NULL
;
824 for (int i
= 0; i
< io
->io_env
.input_count
; i
++)
826 gchar
*name
= g_strdup_printf("in_%d", 1 + i
);
827 jii
->inputs
[i
] = jack_port_register(jii
->client
, name
, JACK_DEFAULT_AUDIO_TYPE
, JackPortIsInput
, 0);
830 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create input port %d (%s)", i
, name
);
836 for (int i
= 0; i
< io
->io_env
.output_count
; i
++)
838 gchar
*name
= g_strdup_printf("out_%d", 1 + i
);
839 jii
->outputs
[i
] = jack_port_register(jii
->client
, name
, JACK_DEFAULT_AUDIO_TYPE
, JackPortIsOutput
, 0);
840 if (!jii
->outputs
[i
])
842 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create output port %d (%s)", i
, name
);
848 if (jii
->enable_common_midi_input
)
850 jii
->midi
= jack_port_register(jii
->client
, "midi", JACK_DEFAULT_MIDI_TYPE
, JackPortIsInput
, 0);
853 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot create MIDI port");
861 cbox_execute_on(fb
, NULL
, "/io/jack_client_name", "s", NULL
, jii
->client_name
);
863 cbox_io_poll_ports(io
, fb
);
870 for (int i
= 0; i
< io
->io_env
.input_count
; i
++)
871 free(jii
->inputs
[i
]);
876 for (int i
= 0; i
< io
->io_env
.output_count
; i
++)
877 free(jii
->outputs
[i
]);
880 cbox_io_destroy_all_midi_ports(io
);
881 if (jii
->client_name
)
882 free(jii
->client_name
);
883 jack_client_close(jii
->client
);