Remove module from future :)
[calfbox.git] / usbmidi.c
blobb635ed7431236c59df43be80c26565669372f6e0
1 /*
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/>.
19 #include "app.h"
20 #include "config.h"
21 #include "config-api.h"
22 #include "errors.h"
23 #include "hwcfg.h"
24 #include "io.h"
25 #include "meter.h"
26 #include "midi.h"
27 #include "recsrc.h"
28 #include "usbio_impl.h"
30 #include <unistd.h>
32 static void decode_events_mpd16(struct cbox_usb_midi_interface *umi, struct libusb_transfer *transfer)
34 for (int i = 0; i < transfer->actual_length;)
36 uint8_t *data = &transfer->buffer[i];
37 uint8_t len = data[0] & 15;
38 if (!len || i + len >= transfer->actual_length)
39 break;
40 cbox_midi_buffer_write_inline(&umi->input_port->hdr.buffer, 0, data[1], len > 1 ? data[2] : 0, len > 2 ? data[3] : 0);
41 i += len + 1;
45 static void decode_events_nocturn(struct cbox_usb_midi_interface *umi, struct libusb_transfer *transfer)
47 uint8_t control = 0;
48 for (int i = 0; i < transfer->actual_length;)
50 uint8_t *data = &transfer->buffer[i];
51 if (*data >= 128)
53 control = *data;
54 i++;
55 continue;
57 if (control != 176 || i + 2 > transfer->actual_length)
59 g_warning("Unrecognized combination of control, data and length: %02x %02x %02x", control, data[0], transfer->actual_length - i);
60 break;
62 cbox_midi_buffer_write_inline(&umi->input_port->hdr.buffer, 0, control, data[0], data[1]);
63 i += 2;
67 static void decode_events_class(struct cbox_usb_midi_interface *umi, struct libusb_transfer *transfer)
69 for (int i = 0; i + 3 < transfer->actual_length; i += 4)
71 uint8_t *data = &transfer->buffer[i];
72 uint8_t etype = data[0] & 15;
73 if (etype >= 8)
75 // normalise: note on with vel 0 -> note off
76 if ((data[1] & 0xF0) == 0x90 && data[3] == 0)
77 cbox_midi_buffer_write_inline(&umi->input_port->hdr.buffer, 0, data[1] - 0x10, data[2], data[3]);
78 else
79 cbox_midi_buffer_write_event(&umi->input_port->hdr.buffer, 0, data + 1, midi_cmd_size(data[1]));
81 else
82 if (etype == 2 || etype == 3)
84 cbox_midi_buffer_write_event(&umi->input_port->hdr.buffer, 0, data + 1, etype);
86 else
87 if (etype == 4)
89 if (umi->current_sysex_length + 3 <= MAX_SYSEX_SIZE)
90 memcpy(&umi->sysex_data[umi->current_sysex_length], data + 1, 3);
91 umi->current_sysex_length += 3;
93 else
94 if (etype >= 5 && etype <= 7)
96 int len = etype - 4;
97 if (umi->current_sysex_length + len <= MAX_SYSEX_SIZE)
98 memcpy(&umi->sysex_data[umi->current_sysex_length], data + 1, len);
99 umi->current_sysex_length += len;
100 if (umi->current_sysex_length <= MAX_SYSEX_SIZE)
101 cbox_midi_buffer_write_event(&umi->input_port->hdr.buffer, 0, umi->sysex_data, umi->current_sysex_length);
102 else
103 g_warning("Dropping oversized SysEx: length %d", umi->current_sysex_length);
104 umi->current_sysex_length = 0;
107 else
108 g_warning("Unrecognized USB MIDI initiating byte %02x\n", data[0]);
112 static void midi_transfer_cb(struct libusb_transfer *transfer)
114 struct usbio_transfer *xf = transfer->user_data;
115 struct cbox_usb_midi_interface *umi = xf->user_data;
116 xf->pending = FALSE;
118 if (transfer->status == LIBUSB_TRANSFER_CANCELLED)
120 xf->cancel_confirm = 1;
121 return;
123 if (transfer->status == LIBUSB_TRANSFER_TIMED_OUT || transfer->status == LIBUSB_TRANSFER_ERROR || transfer->status == LIBUSB_TRANSFER_STALL)
125 if (transfer->status != LIBUSB_TRANSFER_TIMED_OUT)
126 g_warning("USB error on device %03d:%03d: transfer status %d", umi->busdevadr >> 8, umi->busdevadr & 255, transfer->status);
127 if (umi->uii->no_resubmit)
128 return;
129 int res = usbio_transfer_submit(xf);
130 if (res != 0)
131 g_warning("Error submitting URB to MIDI endpoint: error code %d", res);
132 return;
134 if (transfer->status == LIBUSB_TRANSFER_NO_DEVICE)
136 g_debug("No device %03d:%03d, unlinking", umi->busdevadr >> 8, umi->busdevadr & 255);
137 umi->uii->rt_midi_ports = g_list_remove(umi->uii->rt_midi_ports, umi);
138 return;
141 if (umi->protocol == USBMIDI_PROTOCOL_MPD16) // MPD16
142 decode_events_mpd16(umi, transfer);
143 else
144 if (umi->protocol == USBMIDI_PROTOCOL_NOCTURN) // Nocturn
145 decode_events_nocturn(umi, transfer);
146 else
147 decode_events_class(umi, transfer);
149 if (umi->uii->no_resubmit)
150 return;
151 usbio_transfer_submit(xf);
154 static gboolean push_data_to_umo(struct cbox_usb_midi_output *umo, const uint8_t *pdata, uint32_t size, uint8_t first_byte)
156 if (umo->endpoint_buffer_pos + 4 <= USB_MIDI_OUTPUT_QUEUE)
158 umo->endpoint_buffer[umo->endpoint_buffer_pos] = first_byte;
159 memcpy(&umo->endpoint_buffer[umo->endpoint_buffer_pos + 1], pdata, size);
160 umo->endpoint_buffer_pos += 4;
162 else
164 g_warning("Class MIDI buffer overflow.");
165 return FALSE;
167 return TRUE;
170 static void encode_events_class(struct cbox_usb_midi_output *umo)
172 for (int i = 0; i < umo->hdr.buffer.count; i++)
174 const struct cbox_midi_event *event = cbox_midi_buffer_get_event(&umo->hdr.buffer, i);
175 const uint8_t *pdata = cbox_midi_event_get_data(event);
176 if (event->size <= 3)
178 if (!push_data_to_umo(umo, pdata, event->size, pdata[0] >> 4))
179 return;
181 else
183 int i = 0;
184 while(i + 3 < event->size)
186 push_data_to_umo(umo, pdata + i, 3, 4);
187 i += 3;
189 push_data_to_umo(umo, pdata + i, 3, 4 + event->size - i);
194 static void encode_events_nocturn(struct cbox_usb_midi_output *umo)
196 for (int i = 0; i < umo->hdr.buffer.count; i++)
198 const struct cbox_midi_event *event = cbox_midi_buffer_get_event(&umo->hdr.buffer, i);
199 const uint8_t *pdata = cbox_midi_event_get_data(event);
200 // Only encode control change events on channel 1 - it's the only
201 // recognized type of events
202 if (event->size == 3 && pdata[0] == 0xB0)
204 if (umo->endpoint_buffer_pos + 2 <= 8)
206 umo->endpoint_buffer[umo->endpoint_buffer_pos] = pdata[1];
207 umo->endpoint_buffer[umo->endpoint_buffer_pos + 1] = pdata[2];
208 umo->endpoint_buffer_pos += 2;
210 else
211 g_warning("Nocturn MIDI buffer overflow.");
216 void usbio_fill_midi_output_buffer(struct cbox_usb_midi_output *umo)
218 cbox_midi_merger_render(&umo->hdr.merger);
219 if (!umo->hdr.buffer.count)
220 return;
222 if (umo->ifptr->protocol == USBMIDI_PROTOCOL_CLASS)
223 encode_events_class(umo);
224 else
225 if (umo->ifptr->protocol == USBMIDI_PROTOCOL_NOCTURN)
226 encode_events_nocturn(umo);
229 void usbio_send_midi_to_output(struct cbox_usb_midi_output *umo)
231 if (!umo->endpoint_buffer_pos)
232 return;
234 int transferred = 0;
235 int res = 0;
236 if (umo->ifptr->epdesc_out.interrupt)
237 res = libusb_interrupt_transfer(umo->ifptr->handle, umo->ifptr->epdesc_out.bEndpointAddress, umo->endpoint_buffer, umo->endpoint_buffer_pos, &transferred, 10);
238 else
239 res = libusb_bulk_transfer(umo->ifptr->handle, umo->ifptr->epdesc_out.bEndpointAddress, umo->endpoint_buffer, umo->endpoint_buffer_pos, &transferred, 10);
240 if (res == 0 && transferred == umo->endpoint_buffer_pos)
241 umo->endpoint_buffer_pos = 0;
242 else
243 g_warning("Failed to send MIDI events, transferred = %d out of %d, result = %d", (int)transferred, (int)umo->endpoint_buffer_pos, res);
246 void usbio_update_port_routing(struct cbox_io_impl *ioi)
248 struct cbox_usb_io_impl *uii = (struct cbox_usb_io_impl *)ioi;
249 for(GList *p = uii->rt_midi_ports; p; p = p->next)
251 struct cbox_usb_midi_interface *umi = p->data;
252 if (umi->input_port)
254 if (!umi->input_port->hdr.output_set)
255 cbox_midi_merger_connect(&uii->midi_input_merger, &umi->input_port->hdr.buffer, app.rt);
256 else
257 cbox_midi_merger_disconnect(&uii->midi_input_merger, &umi->input_port->hdr.buffer, app.rt);
262 void usbio_start_midi_capture(struct cbox_usb_io_impl *uii)
264 uii->rt_midi_ports = g_list_copy(uii->midi_ports);
266 for(GList *p = uii->rt_midi_ports; p; p = p->next)
268 struct cbox_usb_midi_interface *umi = p->data;
269 cbox_midi_buffer_clear(&umi->input_port->hdr.buffer);
270 if (umi->epdesc_in.found)
272 umi->current_sysex_length = 0;
273 umi->transfer_in = usbio_transfer_new(uii->usbctx, "MIDI In", 0, 0, umi);
274 int pktsize = umi->epdesc_in.wMaxPacketSize;
275 if (pktsize > MAX_MIDI_PACKET_SIZE)
276 pktsize = MAX_MIDI_PACKET_SIZE;
277 if (umi->epdesc_in.interrupt)
278 libusb_fill_interrupt_transfer(umi->transfer_in->transfer, umi->handle, umi->epdesc_in.bEndpointAddress, umi->midi_recv_data, pktsize, midi_transfer_cb, umi->transfer_in, 0);
279 else
280 libusb_fill_bulk_transfer(umi->transfer_in->transfer, umi->handle, umi->epdesc_in.bEndpointAddress, umi->midi_recv_data, pktsize, midi_transfer_cb, umi->transfer_in, 0);
282 else
283 umi->transfer_in = NULL;
284 if (umi->epdesc_out.found)
285 umi->transfer_out = usbio_transfer_new(uii->usbctx, "MIDI Out", 0, 0, umi);
286 else
287 umi->transfer_out = NULL;
289 for(GList *p = uii->rt_midi_ports; p; p = p->next)
291 struct cbox_usb_midi_interface *umi = p->data;
292 int res = usbio_transfer_submit(umi->transfer_in);
293 if (res != 0)
295 usbio_transfer_destroy(umi->transfer_in);
296 umi->transfer_in = NULL;
301 void usbio_stop_midi_capture(struct cbox_usb_io_impl *uii)
303 for(GList *p = uii->rt_midi_ports; p; p = p->next)
305 struct cbox_usb_midi_interface *umi = p->data;
307 if (umi->transfer_in)
309 usbio_transfer_shutdown(umi->transfer_in);
310 usbio_transfer_destroy(umi->transfer_in);
311 umi->transfer_in = NULL;
312 cbox_midi_buffer_clear(&umi->input_port->hdr.buffer);
314 if (umi->transfer_out)
316 usbio_transfer_shutdown(umi->transfer_out);
317 usbio_transfer_destroy(umi->transfer_out);
318 umi->transfer_out = NULL;
321 for(GList *p = uii->rt_midi_ports; p; p = p->next)
323 struct cbox_usb_midi_interface *umi = p->data;
324 if (umi->epdesc_in.found)
325 cbox_midi_merger_disconnect(&uii->midi_input_merger, &umi->input_port->hdr.buffer, NULL);
327 g_list_free(uii->rt_midi_ports);
330 void cbox_usb_midi_info_init(struct cbox_usb_midi_info *umi, struct cbox_usb_device_info *udi)
332 umi->udi = udi;
333 umi->intf = -1;
334 umi->alt_setting = -1;
335 umi->epdesc_in.found = FALSE;
336 umi->epdesc_out.found = FALSE;
339 struct cbox_usb_midi_interface *usbio_open_midi_interface(struct cbox_usb_io_impl *uii, const struct cbox_usb_midi_info *uminf, struct libusb_device_handle *handle)
341 struct cbox_usb_device_info *devinfo = uminf->udi;
342 int bus = devinfo->bus;
343 int devadr = devinfo->devadr;
344 GError *error = NULL;
345 // printf("Has MIDI port\n");
346 // printf("Output endpoint address = %02x\n", ep->bEndpointAddress);
347 if (!configure_usb_interface(handle, bus, devadr, uminf->intf, uminf->alt_setting, "MIDI (class driver)", &error))
349 g_warning("%s", error->message);
350 g_error_free(error);
351 return NULL;
354 struct cbox_usb_midi_interface *umi = calloc(sizeof(struct cbox_usb_midi_interface), 1);
355 umi->uii = uii;
356 umi->devinfo = devinfo;
357 umi->handle = handle;
358 umi->busdevadr = devinfo->busdevadr;
359 uii->midi_ports = g_list_prepend(uii->midi_ports, umi);
360 umi->protocol = uminf->protocol;
361 memcpy(&umi->epdesc_in, &uminf->epdesc_in, sizeof(umi->epdesc_in));
362 memcpy(&umi->epdesc_out, &uminf->epdesc_out, sizeof(umi->epdesc_out));
364 // Drain the output buffer of the device - otherwise playing a few notes and running the program will cause
365 // those notes to play.
366 unsigned char flushbuf[256];
367 int transferred = 0;
368 int len = umi->epdesc_in.wMaxPacketSize;
369 if (len > MAX_MIDI_PACKET_SIZE)
370 len = MAX_MIDI_PACKET_SIZE;
371 if (umi->epdesc_in.interrupt)
373 while(0 == libusb_interrupt_transfer(handle, umi->epdesc_in.bEndpointAddress, flushbuf, len, &transferred, 10) && transferred > 0)
374 usleep(1000);
376 else
378 while(0 == libusb_bulk_transfer(handle, umi->epdesc_in.bEndpointAddress, flushbuf, len, &transferred, 10) && transferred > 0)
379 usleep(1000);
381 devinfo->status = CBOX_DEVICE_STATUS_OPENED;
383 // Initialise device - only used for Novation Nocturn, and it performs a
384 // device reset. Perhaps not the best implementation of hot swap - it
385 // will reset the device even when some other device was connected.
386 if (umi->protocol == USBMIDI_PROTOCOL_NOCTURN)
388 static uint8_t data1[] = { 0xB0, 0, 0 };
389 libusb_interrupt_transfer(handle, umi->epdesc_out.bEndpointAddress, data1, sizeof(data1), &transferred, 10);
392 return umi;