2 Calf Box, an open source musical instrument.
3 Copyright (C) 2010-2013 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/>.
21 Note: this is a silly experimental driver for a number of USB MIDI devices.
23 It only supports audio output and MIDI input, as those are my immediate
24 needs, to be able to use a machine running CalfBox as a standalone MIDI
25 instrument. Plug-and-play is supported, as long as current user running
26 calfbox has write access to the USB devices involved. This can be done by
27 running calfbox as root, or by setting right permissions in udev scripts
28 - this may be considered a safer method.
31 * Class-compliant audio output devices (tested with Lexicon Omega and some
32 cheap no-brand C-Media USB soundcard dongle)
33 * Alesis Multimix 8 USB 2.0 (audio output only)
34 * Class-compliant MIDI input devices (tested with several devices)
36 Yes, code quality is pretty awful, especially in areas involving clock
37 sync. I'm going to clean it up iteratively later.
42 #include "config-api.h"
49 #include "usbio_impl.h"
63 ///////////////////////////////////////////////////////////////////////////////
65 int cbox_usbio_get_sample_rate(struct cbox_io_impl
*impl
)
67 struct cbox_usb_io_impl
*uii
= (struct cbox_usb_io_impl
*)impl
;
69 return uii
->sample_rate
;
72 gboolean
cbox_usbio_get_status(struct cbox_io_impl
*impl
, GError
**error
)
74 // XXXKF: needs a flag that would indicate whether device is present
75 // XXXKF: needs to return that flag with appropriate message
79 static void run_audio_loop(struct cbox_usb_io_impl
*uii
)
81 while(!uii
->stop_engine
&& !uii
->device_removed
) {
82 struct cbox_io
*io
= uii
->ioi
.pio
;
87 libusb_handle_events_timeout(uii
->usbctx
, &tv
);
88 for (GSList
*p
= io
->midi_outputs
; p
; p
= p
->next
)
90 struct cbox_usb_midi_output
*umo
= p
->data
;
91 usbio_send_midi_to_output(umo
);
96 void usbio_run_idle_loop(struct cbox_usb_io_impl
*uii
)
98 while(!uii
->stop_engine
)
100 struct cbox_io
*io
= uii
->ioi
.pio
;
101 for (int b
= 0; b
< uii
->output_channels
; b
++)
102 memset(io
->output_buffers
[b
], 0, io
->io_env
.buffer_size
* sizeof(float));
103 io
->cb
->process(io
->cb
->user_data
, io
, io
->io_env
.buffer_size
);
104 for (GList
*p
= uii
->rt_midi_ports
; p
; p
= p
->next
)
106 struct cbox_usb_midi_interface
*umi
= p
->data
;
107 cbox_midi_buffer_clear(&umi
->input_port
->hdr
.buffer
);
109 for (GSList
*p
= io
->midi_outputs
; p
; p
= p
->next
)
111 struct cbox_usb_midi_output
*umo
= p
->data
;
112 usbio_send_midi_to_output(umo
);
115 struct timeval tv
= {
119 libusb_handle_events_timeout(uii
->usbctx
, &tv
);
120 usleep((int)(io
->io_env
.buffer_size
* 1000000.0 / uii
->sample_rate
));
124 static void *engine_thread(void *user_data
)
126 struct cbox_usb_io_impl
*uii
= user_data
;
128 usbio_start_midi_capture(uii
);
130 if (uii
->handle_audiodev
)
132 uii
->no_resubmit
= FALSE
;
133 struct sched_param p
;
134 memset(&p
, 0, sizeof(p
));
135 p
.sched_priority
= cbox_config_get_int("io", "rtpriority", 10);
136 pid_t tid
= syscall(SYS_gettid
);
137 if (0 != sched_setscheduler(tid
, SCHED_FIFO
, &p
))
138 g_warning("Cannot set realtime priority for the processing thread: %s.", strerror(errno
));
140 usbio_start_audio_playback(uii
);
141 if (!uii
->setup_error
)
145 uii
->no_resubmit
= TRUE
;
146 memset(&p
, 0, sizeof(p
));
147 p
.sched_priority
= 0;
148 if (0 != sched_setscheduler(tid
, SCHED_OTHER
, &p
))
149 g_warning("Cannot unset realtime priority for the processing thread: %s.", strerror(errno
));
150 usbio_stop_audio_playback(uii
);
154 uii
->no_resubmit
= TRUE
;
155 g_message("No audio device found - running idle loop.");
156 // notify the UI thread that the (fake) audio loop is running
157 uii
->playback_counter
= uii
->playback_buffers
;
158 usbio_run_idle_loop(uii
);
161 usbio_stop_midi_capture(uii
);
165 static void cbox_usbio_destroy_midi_out(struct cbox_io_impl
*ioi
, struct cbox_midi_output
*midiout
)
167 g_free(midiout
->name
);
171 static struct cbox_usb_midi_interface
*cur_midi_interface
= NULL
;
173 struct cbox_midi_input
*cbox_usbio_create_midi_in(struct cbox_io_impl
*impl
, const char *name
, GError
**error
)
175 // struct cbox_usb_io_impl *uii = (struct cbox_usb_io_impl *)impl;
176 struct cbox_usb_midi_input
*input
= calloc(1, sizeof(struct cbox_usb_midi_input
));
177 input
->hdr
.name
= g_strdup(name
);
178 input
->hdr
.removing
= FALSE
;
179 cbox_uuid_generate(&input
->hdr
.uuid
);
180 cbox_midi_buffer_init(&input
->hdr
.buffer
);
181 input
->ifptr
= cur_midi_interface
;
182 cbox_midi_appsink_init(&input
->hdr
.appsink
, NULL
);
183 input
->hdr
.enable_appsink
= FALSE
;
185 return (struct cbox_midi_input
*)input
;
188 struct cbox_midi_output
*cbox_usbio_create_midi_out(struct cbox_io_impl
*impl
, const char *name
, GError
**error
)
190 // struct cbox_usb_io_impl *uii = (struct cbox_usb_io_impl *)impl;
191 struct cbox_usb_midi_output
*output
= calloc(1, sizeof(struct cbox_usb_midi_output
));
192 output
->hdr
.name
= g_strdup(name
);
193 output
->hdr
.removing
= FALSE
;
194 cbox_uuid_generate(&output
->hdr
.uuid
);
195 cbox_midi_buffer_init(&output
->hdr
.buffer
);
196 cbox_midi_merger_init(&output
->hdr
.merger
, &output
->hdr
.buffer
);
197 output
->ifptr
= cur_midi_interface
;
199 return (struct cbox_midi_output
*)output
;
202 static void create_midi_ports(struct cbox_usb_io_impl
*uii
)
204 uii
->ioi
.createmidiinfunc
= cbox_usbio_create_midi_in
;
205 uii
->ioi
.createmidioutfunc
= cbox_usbio_create_midi_out
;
206 for (GList
*p
= uii
->midi_ports
; p
; p
= p
->next
)
208 struct cbox_usb_midi_interface
*umi
= p
->data
;
210 sprintf(buf
, "usb:%03d:%03d", umi
->devinfo
->bus
, umi
->devinfo
->devadr
);
211 cur_midi_interface
= umi
;
212 if (umi
->epdesc_in
.found
)
213 umi
->input_port
= (struct cbox_usb_midi_input
*)cbox_io_create_midi_input(uii
->ioi
.pio
, buf
, NULL
);
215 umi
->input_port
= NULL
;
216 if (umi
->epdesc_out
.found
)
217 umi
->output_port
= (struct cbox_usb_midi_output
*)cbox_io_create_midi_output(uii
->ioi
.pio
, buf
, NULL
);
219 umi
->output_port
= NULL
;
221 uii
->ioi
.createmidiinfunc
= NULL
;
222 uii
->ioi
.createmidioutfunc
= NULL
;
223 cur_midi_interface
= NULL
;
226 gboolean
cbox_usbio_start(struct cbox_io_impl
*impl
, struct cbox_command_target
*fb
, GError
**error
)
228 struct cbox_usb_io_impl
*uii
= (struct cbox_usb_io_impl
*)impl
;
230 // XXXKF: needs to queue the playback and capture transfers
232 uii
->stop_engine
= FALSE
;
233 uii
->setup_error
= FALSE
;
234 uii
->playback_counter
= 0;
236 create_midi_ports(uii
);
238 struct cbox_io
*io
= uii
->ioi
.pio
;
239 // XXXKF There is a short period of time when the playback is in 'started' state
240 // but is not really processing the event loop. This is likely harmless, but
241 // should be kept in mind when adding any code between pthread_create
242 // and usbio_update_port_routing.
243 if (io
->cb
->on_started
)
244 io
->cb
->on_started(io
->cb
->user_data
);
246 if (pthread_create(&uii
->thr_engine
, NULL
, engine_thread
, uii
))
248 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "cannot create engine thread: %s", strerror(errno
));
251 while(!uii
->setup_error
&& uii
->playback_counter
< uii
->playback_buffers
)
253 usbio_update_port_routing(&uii
->ioi
);
258 gboolean
cbox_usbio_stop(struct cbox_io_impl
*impl
, GError
**error
)
260 struct cbox_usb_io_impl
*uii
= (struct cbox_usb_io_impl
*)impl
;
262 // XXXKF: needs to kill the playback and capture transfers, and
263 // wait for them to be killed
265 uii
->stop_engine
= TRUE
;
266 pthread_join(uii
->thr_engine
, NULL
);
270 void cbox_usbio_poll_ports(struct cbox_io_impl
*impl
, struct cbox_command_target
*fb
)
272 struct cbox_usb_io_impl
*uii
= (struct cbox_usb_io_impl
*)impl
;
274 // Dry run, just to detect if anything changed
275 if (usbio_scan_devices(uii
, TRUE
))
277 struct cbox_io_callbacks
*cb
= uii
->ioi
.pio
->cb
;
278 g_debug("Restarting I/O due to device being connected or disconnected");
279 cbox_io_stop(uii
->ioi
.pio
);
280 // Re-scan, this time actually create the MIDI inputs
281 usbio_scan_devices(uii
, FALSE
);
282 cbox_io_start(uii
->ioi
.pio
, cb
, fb
);
286 gboolean
cbox_usbio_cycle(struct cbox_io_impl
*impl
, struct cbox_command_target
*fb
, GError
**error
)
288 // struct cbox_usb_io_impl *uii = (struct cbox_usb_io_impl *)impl;
289 // XXXKF: this is for restarting the thing; not implemented for now,
290 // the implementation will be something like in case of JACK - close and
295 int cbox_usbio_get_midi_data(struct cbox_io_impl
*impl
, struct cbox_midi_buffer
*destination
)
297 struct cbox_usb_io_impl
*uii
= (struct cbox_usb_io_impl
*)impl
;
299 cbox_midi_merger_render_to(&uii
->midi_input_merger
, destination
);
303 void cbox_usbio_destroy(struct cbox_io_impl
*impl
)
305 struct cbox_usb_io_impl
*uii
= (struct cbox_usb_io_impl
*)impl
;
307 GList
*prev_keys
= g_hash_table_get_values(uii
->device_table
);
308 for (GList
*p
= prev_keys
; p
; p
= p
->next
)
310 struct cbox_usb_device_info
*udi
= p
->data
;
311 if (udi
->status
== CBOX_DEVICE_STATUS_OPENED
)
312 usbio_forget_device(uii
, udi
);
314 g_list_free(prev_keys
);
315 g_hash_table_destroy(uii
->device_table
);
317 libusb_exit(uii
->usbctx_probe
);
318 libusb_exit(uii
->usbctx
);
319 cbox_midi_merger_close(&uii
->midi_input_merger
);
323 ///////////////////////////////////////////////////////////////////////////////
325 struct usbio_transfer
*usbio_transfer_new(struct libusb_context
*usbctx
, const char *transfer_type
, int index
, int isopackets
, void *user_data
)
327 struct usbio_transfer
*p
= malloc(sizeof(struct usbio_transfer
));
329 p
->transfer
= libusb_alloc_transfer(isopackets
);
331 p
->cancel_confirm
= FALSE
;
333 p
->transfer_type
= transfer_type
;
334 p
->user_data
= user_data
;
338 int usbio_transfer_submit(struct usbio_transfer
*xfer
)
340 int res
= libusb_submit_transfer(xfer
->transfer
);
343 g_warning("usbio_transfer_submit: cannot submit transfer '%s:%d', error = %s", xfer
->transfer_type
, xfer
->index
, libusb_error_name(res
));
346 xfer
->pending
= TRUE
;
350 void usbio_transfer_shutdown(struct usbio_transfer
*xfer
)
354 int res
= libusb_cancel_transfer(xfer
->transfer
);
355 if (res
!= LIBUSB_ERROR_NO_DEVICE
)
358 while(!xfer
->cancel_confirm
&& tries
> 0 && xfer
->pending
)
360 struct timeval tv
= {
364 libusb_handle_events_timeout(xfer
->usbctx
, &tv
);
368 g_warning("Timed out waiting for transfer '%s:%d' to complete; status = %d", xfer
->transfer_type
, xfer
->index
, xfer
->transfer
->status
);
373 void usbio_transfer_destroy(struct usbio_transfer
*xfer
)
375 libusb_free_transfer(xfer
->transfer
);
380 ///////////////////////////////////////////////////////////////////////////////
382 static gboolean
cbox_usb_io_process_cmd(struct cbox_command_target
*ct
, struct cbox_command_target
*fb
, struct cbox_osc_command
*cmd
, GError
**error
)
384 struct cbox_usb_io_impl
*uii
= (struct cbox_usb_io_impl
*)ct
->user_data
;
385 struct cbox_io
*io
= uii
->ioi
.pio
;
386 gboolean handled
= FALSE
;
387 if (!strcmp(cmd
->command
, "/status") && !strcmp(cmd
->arg_types
, ""))
389 if (!cbox_check_fb_channel(fb
, cmd
->command
, error
))
392 for (GList
*p
= uii
->midi_ports
; p
; p
= g_list_next(p
))
394 struct cbox_usb_midi_interface
*midi
= p
->data
;
395 struct cbox_usb_device_info
*di
= midi
->devinfo
;
396 if (midi
->epdesc_in
.found
&& !cbox_execute_on(fb
, NULL
, "/usb_midi_input", "iiiiu", error
, di
->bus
, di
->devadr
, di
->vid
, di
->pid
, &midi
->input_port
->hdr
.uuid
))
398 if (midi
->epdesc_out
.found
&& !cbox_execute_on(fb
, NULL
, "/usb_midi_output", "iiiiu", error
, di
->bus
, di
->devadr
, di
->vid
, di
->pid
, &midi
->output_port
->hdr
.uuid
))
402 return cbox_execute_on(fb
, NULL
, "/output_resolution", "i", error
, 8 * uii
->output_resolution
) &&
403 cbox_io_process_cmd(io
, fb
, cmd
, error
, &handled
);
407 gboolean result
= cbox_io_process_cmd(io
, fb
, cmd
, error
, &handled
);
409 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
);
414 ///////////////////////////////////////////////////////////////////////////////
416 gboolean
cbox_io_init_usb(struct cbox_io
*io
, struct cbox_open_params
*const params
, struct cbox_command_target
*fb
, GError
**error
)
418 struct cbox_usb_io_impl
*uii
= malloc(sizeof(struct cbox_usb_io_impl
));
419 if (libusb_init(&uii
->usbctx
))
421 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot initialise libusb.");
424 if (libusb_init(&uii
->usbctx_probe
))
426 libusb_exit(uii
->usbctx
);
427 g_set_error(error
, CBOX_MODULE_ERROR
, CBOX_MODULE_ERROR_FAILED
, "Cannot initialise libusb.");
430 libusb_set_debug(uii
->usbctx
, 3);
431 libusb_set_debug(uii
->usbctx_probe
, 3);
432 uii
->device_table
= g_hash_table_new(g_direct_hash
, NULL
);
434 uii
->sample_rate
= cbox_config_get_int(cbox_io_section
, "sample_rate", 44100);
435 uii
->sync_buffers
= cbox_config_get_int(cbox_io_section
, "sync_buffers", 2);
436 uii
->debug_sync
= cbox_config_get_int(cbox_io_section
, "debug_sync", 0);
437 uii
->playback_buffers
= cbox_config_get_int(cbox_io_section
, "playback_buffers", 2);
438 // shouldn't be more than 4, otherwise it will crackle due to limitations of
439 // the packet length adjustment. It might work better if adjustment
440 // was per-packet and not per-transfer.
441 uii
->iso_packets
= cbox_config_get_int(cbox_io_section
, "iso_packets", 1);
442 // The USB 2.0 device uses a higher packet rate (125us I think), so the
443 // default number of packets per transfer needs to be different, too -
444 // 1ms is a minimum reasonable value
445 uii
->iso_packets_multimix
= cbox_config_get_int(cbox_io_section
, "iso_packets_multimix", 16);
446 uii
->output_resolution
= cbox_config_get_int(cbox_io_section
, "output_resolution", 16) / 8;
447 uii
->output_channels
= 2;
448 uii
->handle_audiodev
= NULL
;
449 cbox_midi_merger_init(&uii
->midi_input_merger
, NULL
);
451 // fixed processing buffer size, as we have to deal with packetisation anyway
452 io
->io_env
.srate
= uii
->sample_rate
;
453 io
->io_env
.buffer_size
= 64;
455 // input and output count is hardcoded for simplicity - in future, it may be
456 // necessary to add support for the extra inputs (needs to be figured out)
457 io
->io_env
.input_count
= 2; //cbox_config_get_int("io", "inputs", 0);
458 io
->input_buffers
= malloc(sizeof(float *) * io
->io_env
.input_count
);
459 for (int i
= 0; i
< io
->io_env
.input_count
; i
++)
460 io
->input_buffers
[i
] = calloc(io
->io_env
.buffer_size
, sizeof(float));
461 io
->io_env
.output_count
= 2; // cbox_config_get_int("io", "outputs", 2);
462 io
->output_buffers
= malloc(sizeof(float *) * io
->io_env
.output_count
);
463 for (int i
= 0; i
< io
->io_env
.output_count
; i
++)
464 io
->output_buffers
[i
] = calloc(io
->io_env
.buffer_size
, sizeof(float));
465 io
->impl
= &uii
->ioi
;
466 cbox_command_target_init(&io
->cmd_target
, cbox_usb_io_process_cmd
, uii
);
469 uii
->ioi
.getsampleratefunc
= cbox_usbio_get_sample_rate
;
470 uii
->ioi
.startfunc
= cbox_usbio_start
;
471 uii
->ioi
.stopfunc
= cbox_usbio_stop
;
472 uii
->ioi
.getstatusfunc
= cbox_usbio_get_status
;
473 uii
->ioi
.pollfunc
= cbox_usbio_poll_ports
;
474 uii
->ioi
.cyclefunc
= cbox_usbio_cycle
;
475 uii
->ioi
.getmidifunc
= cbox_usbio_get_midi_data
;
476 uii
->ioi
.destroymidioutfunc
= cbox_usbio_destroy_midi_out
;
477 uii
->ioi
.destroyfunc
= cbox_usbio_destroy
;
478 uii
->ioi
.controltransportfunc
= NULL
;
479 uii
->ioi
.getsynccompletedfunc
= NULL
;
480 uii
->ioi
.updatemidiinroutingfunc
= usbio_update_port_routing
;
481 uii
->midi_ports
= NULL
;
483 usbio_scan_devices(uii
, FALSE
);
485 if (cbox_config_get_int("io", "lockall", 0))
486 mlockall(MCL_CURRENT
|MCL_FUTURE
);