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/>.
20 #include "config-api.h"
27 #include "usbio_impl.h"
31 static void midi_transfer_cb(struct libusb_transfer
*transfer
)
33 struct usbio_transfer
*xf
= transfer
->user_data
;
34 struct cbox_usb_midi_input
*umi
= xf
->user_data
;
37 if (transfer
->status
== LIBUSB_TRANSFER_CANCELLED
)
39 xf
->cancel_confirm
= 1;
42 if (transfer
->status
== LIBUSB_TRANSFER_TIMED_OUT
|| transfer
->status
== LIBUSB_TRANSFER_ERROR
|| transfer
->status
== LIBUSB_TRANSFER_STALL
)
44 if (transfer
->status
!= LIBUSB_TRANSFER_TIMED_OUT
)
45 g_warning("USB error on device %03d:%03d: transfer status %d", umi
->busdevadr
>> 8, umi
->busdevadr
& 255, transfer
->status
);
46 if (umi
->uii
->no_resubmit
)
48 int res
= usbio_transfer_submit(xf
);
50 g_warning("Error submitting URB to MIDI endpoint: error code %d", res
);
53 if (transfer
->status
== LIBUSB_TRANSFER_NO_DEVICE
)
55 g_debug("No device %03d:%03d, unlinking", umi
->busdevadr
>> 8, umi
->busdevadr
& 255);
56 umi
->uii
->rt_midi_input_ports
= g_list_remove(umi
->uii
->rt_midi_input_ports
, umi
);
60 const struct cbox_usb_device_info
*udi
= umi
->devinfo
;
61 if (udi
->vid
== 0x09e8 && udi
->pid
== 0x0062) // MPD16
63 for (int i
= 0; i
< transfer
->actual_length
;)
65 uint8_t *data
= &transfer
->buffer
[i
];
66 uint8_t len
= data
[0] & 15;
67 if (!len
|| i
+ len
>= transfer
->actual_length
)
69 cbox_midi_buffer_write_inline(&umi
->midi_buffer
, 0, data
[1], len
> 1 ? data
[2] : 0, len
> 2 ? data
[3] : 0);
74 if (udi
->vid
== 0x1235 && udi
->pid
== 0x000a) // Nocturn
77 for (int i
= 0; i
< transfer
->actual_length
;)
79 uint8_t *data
= &transfer
->buffer
[i
];
86 if (control
!= 176 || i
+ 2 > transfer
->actual_length
)
88 g_warning("Unrecognized combination of control, data and length: %02x %02x %02x", control
, data
[0], transfer
->actual_length
- i
);
91 cbox_midi_buffer_write_inline(&umi
->midi_buffer
, 0, control
, data
[0], data
[1]);
97 for (int i
= 0; i
+ 3 < transfer
->actual_length
; i
+= 4)
99 uint8_t *data
= &transfer
->buffer
[i
];
100 uint8_t etype
= data
[0] & 15;
103 // normalise: note on with vel 0 -> note off
104 if ((data
[1] & 0xF0) == 0x90 && data
[3] == 0)
105 cbox_midi_buffer_write_inline(&umi
->midi_buffer
, 0, data
[1] - 0x10, data
[2], data
[3]);
107 cbox_midi_buffer_write_event(&umi
->midi_buffer
, 0, data
+ 1, midi_cmd_size(data
[1]));
110 if (etype
== 2 || etype
== 3)
112 cbox_midi_buffer_write_event(&umi
->midi_buffer
, 0, data
+ 1, etype
);
117 if (umi
->current_sysex_length
+ 3 <= MAX_SYSEX_SIZE
)
118 memcpy(&umi
->sysex_data
[umi
->current_sysex_length
], data
+ 1, 3);
119 umi
->current_sysex_length
+= 3;
122 if (etype
>= 5 && etype
<= 7)
125 if (umi
->current_sysex_length
+ len
<= MAX_SYSEX_SIZE
)
126 memcpy(&umi
->sysex_data
[umi
->current_sysex_length
], data
+ 1, len
);
127 umi
->current_sysex_length
+= len
;
128 if (umi
->current_sysex_length
<= MAX_SYSEX_SIZE
)
129 cbox_midi_buffer_write_event(&umi
->midi_buffer
, 0, umi
->sysex_data
, umi
->current_sysex_length
);
131 g_warning("Dropping oversized SysEx: length %d", umi
->current_sysex_length
);
132 umi
->current_sysex_length
= 0;
136 g_warning("Unrecognized USB MIDI initiating byte %02x\n", data
[0]);
139 if (umi
->uii
->no_resubmit
)
141 usbio_transfer_submit(xf
);
144 void usbio_start_midi_capture(struct cbox_usb_io_impl
*uii
)
146 uii
->rt_midi_input_ports
= g_list_copy(uii
->midi_input_ports
);
148 for(GList
*p
= uii
->rt_midi_input_ports
; p
; p
= p
->next
)
150 struct cbox_usb_midi_input
*umi
= p
->data
;
151 cbox_midi_buffer_clear(&umi
->midi_buffer
);
152 cbox_midi_merger_connect(&uii
->midi_input_merger
, &umi
->midi_buffer
, NULL
);
153 umi
->current_sysex_length
= 0;
154 umi
->transfer
= usbio_transfer_new(uii
->usbctx
, "MIDI In", 0, 0, umi
);
156 libusb_fill_interrupt_transfer(umi
->transfer
->transfer
, umi
->handle
, umi
->endpoint
, umi
->midi_recv_data
, umi
->max_packet_size
, midi_transfer_cb
, umi
->transfer
, 0);
158 libusb_fill_bulk_transfer(umi
->transfer
->transfer
, umi
->handle
, umi
->endpoint
, umi
->midi_recv_data
, umi
->max_packet_size
, midi_transfer_cb
, umi
->transfer
, 0);
160 for(GList
*p
= uii
->rt_midi_input_ports
; p
; p
= p
->next
)
162 struct cbox_usb_midi_input
*umi
= p
->data
;
163 int res
= usbio_transfer_submit(umi
->transfer
);
166 usbio_transfer_destroy(umi
->transfer
);
167 umi
->transfer
= NULL
;
172 void usbio_stop_midi_capture(struct cbox_usb_io_impl
*uii
)
174 for(GList
*p
= uii
->rt_midi_input_ports
; p
; p
= p
->next
)
176 struct cbox_usb_midi_input
*umi
= p
->data
;
181 usbio_transfer_shutdown(umi
->transfer
);
182 usbio_transfer_destroy(umi
->transfer
);
183 umi
->transfer
= NULL
;
184 cbox_midi_buffer_clear(&umi
->midi_buffer
);
186 for(GList
*p
= uii
->rt_midi_input_ports
; p
; p
= p
->next
)
188 struct cbox_usb_midi_input
*umi
= p
->data
;
189 cbox_midi_merger_disconnect(&uii
->midi_input_merger
, &umi
->midi_buffer
, NULL
);
191 g_list_free(uii
->rt_midi_input_ports
);
194 void cbox_usb_midi_info_init(struct cbox_usb_midi_info
*umi
, struct cbox_usb_device_info
*udi
)
198 umi
->alt_setting
= -1;
199 umi
->epdesc
.found
= FALSE
;
202 struct cbox_usb_midi_input
*usbio_open_midi_interface(struct cbox_usb_io_impl
*uii
, const struct cbox_usb_midi_info
*uminf
, struct libusb_device_handle
*handle
)
204 struct cbox_usb_device_info
*devinfo
= uminf
->udi
;
205 int bus
= devinfo
->bus
;
206 int devadr
= devinfo
->devadr
;
207 GError
*error
= NULL
;
208 // printf("Has MIDI port\n");
209 // printf("Output endpoint address = %02x\n", ep->bEndpointAddress);
210 if (!configure_usb_interface(handle
, bus
, devadr
, uminf
->intf
, uminf
->alt_setting
, "MIDI (class driver)", &error
))
212 g_warning("%s", error
->message
);
217 struct cbox_usb_midi_input
*umi
= malloc(sizeof(struct cbox_usb_midi_input
));
219 umi
->devinfo
= devinfo
;
220 umi
->handle
= handle
;
221 umi
->busdevadr
= devinfo
->busdevadr
;
222 umi
->endpoint
= uminf
->epdesc
.bEndpointAddress
;
223 umi
->interrupt
= uminf
->epdesc
.interrupt
;
224 cbox_midi_buffer_init(&umi
->midi_buffer
);
225 uii
->midi_input_ports
= g_list_prepend(uii
->midi_input_ports
, umi
);
226 int len
= uminf
->epdesc
.wMaxPacketSize
;
229 umi
->max_packet_size
= len
;
231 // Drain the output buffer of the device - otherwise playing a few notes and running the program will cause
232 // those notes to play.
233 unsigned char flushbuf
[256];
237 while(0 == libusb_interrupt_transfer(handle
, umi
->endpoint
, flushbuf
, umi
->max_packet_size
, &transferred
, 10) && transferred
> 0)
242 while(0 == libusb_bulk_transfer(handle
, umi
->endpoint
, flushbuf
, umi
->max_packet_size
, &transferred
, 10) && transferred
> 0)
245 devinfo
->status
= CBOX_DEVICE_STATUS_OPENED
;