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 "usbio_impl.h"
22 ////////////////////////////////////////////////////////////////////////////////
24 static const struct libusb_endpoint_descriptor
*get_midi_endpoint(const struct libusb_interface_descriptor
*asdescr
, gboolean is_output
)
26 for (int epi
= 0; epi
< asdescr
->bNumEndpoints
; epi
++)
28 const struct libusb_endpoint_descriptor
*ep
= &asdescr
->endpoint
[epi
];
29 if ((ep
->bEndpointAddress
>= 0x80) == !is_output
)
35 static const struct libusb_endpoint_descriptor
*get_audio_output_endpoint(const struct libusb_interface_descriptor
*asdescr
, const struct libusb_endpoint_descriptor
**sync_endpoint
)
37 for (int epi
= 0; epi
< asdescr
->bNumEndpoints
; epi
++)
39 const struct libusb_endpoint_descriptor
*ep
= &asdescr
->endpoint
[epi
];
40 uint8_t ep_type
= (ep
->bmAttributes
& 0xF);
41 if (ep
->bEndpointAddress
< 0x80 && (ep_type
== 9 || ep_type
== 13)) // output, isochronous, adaptive or synchronous
44 *sync_endpoint
= NULL
;
47 if (ep
->bEndpointAddress
< 0x80 && ep_type
== 5) // output, isochronous, asynchronous
49 // Look for corresponding synch endpoint. It must be placed after the original output endpoint.
50 if (sync_endpoint
&& ep
->bSynchAddress
>= 0x81)
52 *sync_endpoint
= NULL
;
53 for(int epi2
= epi
+ 1; epi2
< asdescr
->bNumEndpoints
; epi2
++)
55 const struct libusb_endpoint_descriptor
*ep2
= &asdescr
->endpoint
[epi2
];
56 if (ep2
->bEndpointAddress
== ep
->bSynchAddress
&& (ep2
->bmAttributes
& 0xF) == 1) // input, isochronous, no sync
69 static void fill_endpoint_desc(struct usbio_endpoint_descriptor
*epdesc
, const struct libusb_endpoint_descriptor
*ep
)
72 epdesc
->interrupt
= FALSE
;
73 epdesc
->bEndpointAddress
= ep
->bEndpointAddress
;
74 epdesc
->wMaxPacketSize
= ep
->wMaxPacketSize
;
77 static gboolean
fill_endpoint_by_address(const struct libusb_interface_descriptor
*asdescr
, uint8_t addr
, struct usbio_endpoint_descriptor
*epdesc
)
79 epdesc
->found
= FALSE
;
80 epdesc
->interrupt
= FALSE
;
81 for (int epi
= 0; epi
< asdescr
->bNumEndpoints
; epi
++)
83 const struct libusb_endpoint_descriptor
*ep
= &asdescr
->endpoint
[epi
];
84 if (ep
->bEndpointAddress
== addr
)
86 fill_endpoint_desc(epdesc
, ep
);
93 ////////////////////////////////////////////////////////////////////////////////
95 struct usb_ut_descriptor_header
98 uint8_t bDescriptorType
;
99 uint8_t bDescriptorSubtype
;
102 struct usb_class_specific_header
104 struct usb_ut_descriptor_header hdr
;
106 uint8_t wTotalLengthLo
, wTotalLengthHi
;
107 uint8_t bInCollection
;
108 uint8_t baInterfaceNr
[0];
111 struct usbaudio_input_terminal_descriptor
114 uint8_t wTerminalTypeLo
, wTerminalTypeHi
;
115 uint8_t bAssocTerminal
;
117 uint8_t wChannelConfigLo
, wChannelConfigHi
;
118 uint8_t iChannelNames
;
122 struct usbaudio_output_terminal_descriptor
125 uint8_t wTerminalTypeLo
, wTerminalTypeHi
;
126 uint8_t bAssocTerminal
;
131 struct usbaudio_mixer_unit_descriptor1
135 uint8_t baSourceID
[0];
138 struct usbaudio_mixer_unit_descriptor2
141 uint8_t wChannelConfigLo
, wChannelConfigHi
;
142 uint8_t bmControls
[0];
143 // after the last index, 8-bit iMixer
146 struct usbaudio_selector_unit_descriptor1
150 uint8_t baSourceID
[0];
151 // after the last index, 8-bit iSelector
154 struct usbaudio_feature_unit_descriptor1
158 uint8_t bControlSize
;
159 uint8_t bmaControls
[0];
160 // after the last index, 8-bit iFeature
163 // Unit/Terminal Descriptor header from the spec
168 static const char *get_terminal_type_name(int type
)
172 case 0x101: return "USB Streaming";
173 case 0x1FF: return "USB vendor specific";
174 case 0x201: return "Microphone";
175 case 0x202: return "Desktop microphone";
176 case 0x203: return "Personal microphone";
177 case 0x204: return "Omni-directional microphone";
178 case 0x205: return "Microphone array";
179 case 0x206: return "Processing microphone array";
180 case 0x301: return "Speaker";
181 case 0x302: return "Headphones";
182 case 0x303: return "Head-mounted display audio";
183 case 0x304: return "Desktop speaker";
184 case 0x305: return "Room speaker";
185 case 0x306: return "Communication speaker";
186 case 0x307: return "Low-frequency effects speaker";
187 case 0x400: return "Bi-directional Undefined";
188 case 0x401: return "Handset (handheld)";
189 case 0x402: return "Handset (head-mounted)";
190 case 0x403: return "Speakerphone";
191 case 0x404: return "Echo-suppressing speakerphone";
192 case 0x405: return "Echo-cancelling speakerphone";
193 case 0x501: return "Phone line";
194 case 0x502: return "Telephone";
195 case 0x503: return "Down line phone";
196 case 0x600: return "External Undefined";
197 case 0x601: return "Analog connector";
198 case 0x602: return "Digital audio interface";
199 case 0x603: return "Line connector";
200 case 0x604: return "Legacy audio";
201 case 0x605: return "S/PDIF";
202 case 0x606: return "1394 D/A Stream";
203 case 0x607: return "1394 D/V Stream Sountrack";
204 case 0x700: return "Embedded undefined";
205 case 0x701: return "Level calibration noise source";
206 case 0x702: return "Equalization noise";
207 case 0x703: return "CD player";
208 case 0x704: return "DAT";
209 case 0x705: return "DCC";
210 case 0x706: return "MiniDisc";
211 case 0x707: return "Analog tape";
212 case 0x708: return "Phono";
213 case 0x709: return "VCR Audio";
214 case 0x70A: return "VideoDisc Audio";
215 case 0x70B: return "DVD Audio";
216 case 0x70C: return "TV Tuner Audio";
217 case 0x70D: return "Satellite Receiver Audio";
218 case 0x70E: return "Cable Tuner Audio";
219 case 0x70F: return "DSS Audio";
220 case 0x710: return "Radio Receiver";
221 case 0x711: return "Radio Transmitter";
222 case 0x712: return "Multitrack Recorder";
223 case 0x713: return "Synthesizer";
230 static gboolean
parse_audio_control_class(struct cbox_usb_audio_info
*uai
, const struct libusb_interface_descriptor
*asdescr
, gboolean other_config
)
233 if (asdescr
->extra_length
< 8)
235 g_warning("AudioControl interface descriptor length is %d, should be at least 8", (int)asdescr
->extra_length
);
238 const struct usb_class_specific_header
*extra
= (const struct usb_class_specific_header
*)asdescr
->extra
;
239 uint16_t wTotalLength
= extra
->wTotalLengthLo
+ 256 * extra
->wTotalLengthHi
;
240 if (wTotalLength
> asdescr
->extra_length
)
242 g_warning("AudioControl interface descriptor total length is %d, but libusb value is %d", (int)wTotalLength
, (int)asdescr
->extra_length
);
245 if (extra
->hdr
.bDescriptorType
!= 36)
247 g_warning("AudioControl interface descriptor type is %d, but expected 36 (CS_INTERFACE)", (int)extra
->hdr
.bDescriptorType
);
250 if (extra
->hdr
.bDescriptorSubtype
!= 1)
252 g_warning("AudioControl interface descriptor type is %d, but expected 1 (HEADER)", (int)extra
->hdr
.bDescriptorSubtype
);
256 printf("Device %04x:%04x\n", uai
->udi
->vid
, uai
->udi
->pid
);
257 printf("hdrlen=%d dt=%d dst=%d ver=%02x%02x total len=%d\n", extra
->hdr
.bLength
, extra
->hdr
.bDescriptorType
, extra
->hdr
.bDescriptorSubtype
, extra
->bcdADC
[0], extra
->bcdADC
[1], wTotalLength
);
258 for(int i
= 0; i
< extra
->bInCollection
; i
++)
260 printf("interface nr %d = %d\n", i
, extra
->baInterfaceNr
[i
]);
263 for(uint32_t pos
= extra
->hdr
.bLength
; pos
< wTotalLength
; pos
+= asdescr
->extra
[pos
])
265 const struct usb_ut_descriptor_header
*hdr
= (const struct usb_ut_descriptor_header
*)(asdescr
->extra
+ pos
);
266 if (hdr
->bDescriptorType
!= 36)
268 g_warning("Skipping unit/terminal descriptor type %d,%d", (int)hdr
->bDescriptorType
, (int)hdr
->bDescriptorSubtype
);
271 printf("hdr %d,%d len %d\n", hdr
->bDescriptorType
, hdr
->bDescriptorSubtype
, hdr
->bLength
);
272 switch(hdr
->bDescriptorSubtype
)
274 case 2: // INPUT_TERMINAL
276 const struct usbaudio_input_terminal_descriptor
*itd
= (const struct usbaudio_input_terminal_descriptor
*)(hdr
+ 1);
277 int wTerminalType
= itd
->wTerminalTypeHi
* 256 + itd
->wTerminalTypeLo
;
278 printf("INPUT TERMINAL %d: type %04x (%s)\n", (int)itd
->bTerminalID
, wTerminalType
, get_terminal_type_name(wTerminalType
));
281 case 3: // OUTPUT_TERMINAL
283 const struct usbaudio_output_terminal_descriptor
*otd
= (const struct usbaudio_output_terminal_descriptor
*)(hdr
+ 1);
284 int wTerminalType
= otd
->wTerminalTypeHi
* 256 + otd
->wTerminalTypeLo
;
285 printf("OUTPUT TERMINAL %d: type %04x (%s) source %d\n", (int)otd
->bTerminalID
, wTerminalType
, get_terminal_type_name(wTerminalType
), otd
->bSourceID
);
288 case 4: // MIXER_UNIT
290 const struct usbaudio_mixer_unit_descriptor1
*mud
= (const struct usbaudio_mixer_unit_descriptor1
*)(hdr
+ 1);
291 printf("MIXER UNIT %d\n", (int)mud
->bUnitID
);
292 for (int i
= 0; i
< mud
->bNrInPins
; i
++)
294 printf("Input[%d] = %d\n", i
, mud
->baSourceID
[i
]);
298 case 5: // SELECTOR_UNIT
300 const struct usbaudio_selector_unit_descriptor1
*sud
= (const struct usbaudio_selector_unit_descriptor1
*)(hdr
+ 1);
301 printf("SELECTOR UNIT %d (%d pins)\n", (int)sud
->bUnitID
, sud
->bNrInPins
);
302 for (int i
= 0; i
< sud
->bNrInPins
; i
++)
304 printf("Input[%d] = %d\n", i
, sud
->baSourceID
[i
]);
308 case 6: // FEATURE_UNIT
310 static const char *features
[] = {"Mute", "Volume", "Bass", "Mid", "Treble", "EQ", "AGC", "Delay", "Bass Boost", "Loudness" };
311 const struct usbaudio_feature_unit_descriptor1
*fud
= (const struct usbaudio_feature_unit_descriptor1
*)(hdr
+ 1);
312 printf("FEATURE UNIT %d (source = %d, control size %d)\n", (int)fud
->bUnitID
, fud
->bSourceID
, fud
->bControlSize
);
313 for (int i
= 0; i
< fud
->bControlSize
* 8; i
++)
315 if (i
>= sizeof(features
) / sizeof(features
[0]))
317 if (fud
->bmaControls
[i
>> 3] & (1 << (i
& 7)))
318 printf("Master %s\n", features
[i
]);
320 for (int ch
= 1; ch
< (hdr
->bLength
- 7) / fud
->bControlSize
; ch
++)
322 int chofs
= ch
* fud
->bControlSize
;
323 for (int i
= 0; i
< fud
->bControlSize
* 8; i
++)
325 if (i
>= sizeof(features
) / sizeof(features
[0]))
327 if (fud
->bmaControls
[(i
>> 3) + chofs
] & (1 << (i
& 7)))
328 printf("Channel %d %s\n", ch
, features
[i
]);
334 printf("Unsupported unit type %d\n", hdr
->bDescriptorSubtype
);
342 struct usbaudio_streaming_interface_descriptor_general
344 struct usb_ut_descriptor_header hdr
; // 7, 36, 1
345 uint8_t bTerminalLink
;
347 uint8_t wFormatTagLo
, wFormatTagHi
;
350 struct usbaudio_streaming_interface_descriptor_format_type_pcm
352 struct usb_ut_descriptor_header hdr
; // 7, 36, 2
355 uint8_t bSubframeSize
;
356 uint8_t bBitResolution
;
357 uint8_t bSamFreqType
;
358 uint8_t taSamFreq
[0][3];
361 static gboolean
parse_audio_class(struct cbox_usb_io_impl
*uii
, struct cbox_usb_audio_info
*uai
, const struct libusb_interface_descriptor
*asdescr
, gboolean other_config
)
363 // omit alternate setting 0, as it's used to describe a 'standby' setting of the interface (no bandwidth)
364 if (asdescr
->bAlternateSetting
== 0)
366 if (asdescr
->extra_length
< 7)
368 g_warning("AudioStreaming interface descriptor length is %d, should be at least 7", (int)asdescr
->extra_length
);
371 const struct usbaudio_streaming_interface_descriptor_general
*extra
= (struct usbaudio_streaming_interface_descriptor_general
*)asdescr
->extra
;
372 if (extra
->hdr
.bLength
!= 7 || extra
->hdr
.bDescriptorType
!= 36 || extra
->hdr
.bDescriptorSubtype
!= 1)
374 g_warning("The AudioStreaming descriptor does not start with the general descriptor (len %d, type %d, subtype %d)", (int)extra
->hdr
.bLength
, (int)extra
->hdr
.bDescriptorType
, (int)extra
->hdr
.bDescriptorSubtype
);
377 if (extra
->wFormatTagLo
!= 1 || extra
->wFormatTagHi
!= 0)
379 g_warning("The AudioStreaming descriptor does not describe a PCM device");
382 const struct usbaudio_streaming_interface_descriptor_format_type_pcm
*fmt
= (struct usbaudio_streaming_interface_descriptor_format_type_pcm
*)(asdescr
->extra
+ extra
->hdr
.bLength
);
383 if (fmt
->hdr
.bLength
< 11 || ((fmt
->hdr
.bLength
- 11) % 3) || fmt
->hdr
.bDescriptorType
!= 36 || fmt
->hdr
.bDescriptorSubtype
!= 2)
385 g_warning("The AudioStreaming descriptor does not have a format type descriptor after general descriptor (len %d, type %d, subtype %d)", (int)fmt
->hdr
.bLength
, (int)fmt
->hdr
.bDescriptorType
, (int)fmt
->hdr
.bDescriptorSubtype
);
389 // We need this to tell inputs from outputs - until I implement reasonable
390 // Audio Control support
391 const struct libusb_endpoint_descriptor
*sync_ep
= NULL
;
392 const struct libusb_endpoint_descriptor
*ep
= get_audio_output_endpoint(asdescr
, &sync_ep
);
395 if (fmt
->bBitResolution
!= uii
->output_resolution
* 8)
397 g_warning("Interface %d alternate setting %d does not support %d bit resolution, only %d", asdescr
->bInterfaceNumber
, asdescr
->bAlternateSetting
, uii
->output_resolution
* 8, fmt
->bBitResolution
);
400 if (fmt
->bSamFreqType
)
402 gboolean found
= FALSE
;
403 for (int i
= 0; i
< fmt
->bSamFreqType
; i
++)
405 int sf
= fmt
->taSamFreq
[i
][0] + 256 * fmt
->taSamFreq
[i
][1] + 65536 * fmt
->taSamFreq
[i
][2];
406 if (sf
== uii
->sample_rate
)
414 g_warning("Interface %d alternate setting %d does not support sample rate of %d Hz", asdescr
->bInterfaceNumber
, asdescr
->bAlternateSetting
, uii
->sample_rate
);
415 for (int i
= 0; i
< fmt
->bSamFreqType
; i
++)
417 int sf
= fmt
->taSamFreq
[i
][0] + 256 * fmt
->taSamFreq
[i
][1] + 65536 * fmt
->taSamFreq
[i
][2];
418 g_warning("Sample rate[%d] = %d Hz", i
, sf
);
423 // XXXKF in case of continuous sample rate, check the limits... assuming
424 // that there are any devices with continuous sample rate, that is.
427 if (uai
->epdesc
.found
)
430 g_warning("Interface %d alt-setting %d endpoint %02x (synched via %02x) looks promising", asdescr
->bInterfaceNumber
, asdescr
->bAlternateSetting
, ep
->bEndpointAddress
, sync_ep
->bEndpointAddress
);
432 g_warning("Interface %d alt-setting %d endpoint %02x looks promising", asdescr
->bInterfaceNumber
, asdescr
->bAlternateSetting
, ep
->bEndpointAddress
);
433 uai
->intf
= asdescr
->bInterfaceNumber
;
434 uai
->alt_setting
= asdescr
->bAlternateSetting
;
435 fill_endpoint_desc(&uai
->epdesc
, ep
);
436 uai
->sync_protocol
= (sync_ep
!= NULL
) ? USBAUDIOSYNC_PROTOCOL_CLASS
: USBAUDIOSYNC_PROTOCOL_NONE
;
438 fill_endpoint_desc(&uai
->sync_epdesc
, sync_ep
);
440 uai
->sync_epdesc
.found
= FALSE
;
446 static gboolean
parse_midi_class(struct cbox_usb_midi_info
*umi
, const struct libusb_interface_descriptor
*asdescr
, gboolean other_config
, gboolean is_output
)
448 const struct libusb_endpoint_descriptor
*ep
= get_midi_endpoint(asdescr
, is_output
);
455 struct usbio_endpoint_descriptor
*epd
= is_output
? &umi
->epdesc_out
: &umi
->epdesc_in
;
459 umi
->intf
= asdescr
->bInterfaceNumber
;
460 umi
->alt_setting
= asdescr
->bAlternateSetting
;
461 fill_endpoint_desc(epd
, ep
);
465 static gboolean
inspect_device(struct cbox_usb_io_impl
*uii
, struct libusb_device
*dev
, uint16_t busdevadr
, gboolean probe_only
)
467 struct libusb_device_descriptor dev_descr
;
468 int bus
= busdevadr
>> 8;
469 int devadr
= busdevadr
& 255;
471 if (0 != libusb_get_device_descriptor(dev
, &dev_descr
))
473 g_warning("USB device %03d:%03d - cannot get device descriptor (will retry)", bus
, devadr
);
477 struct cbox_usb_device_info
*udi
= g_hash_table_lookup(uii
->device_table
, GINT_TO_POINTER(busdevadr
));
480 struct libusb_config_descriptor
*cfg_descr
= NULL
;
481 if (0 != libusb_get_active_config_descriptor(dev
, &cfg_descr
))
483 udi
= malloc(sizeof(struct cbox_usb_device_info
));
486 udi
->status
= CBOX_DEVICE_STATUS_PROBING
;
487 udi
->active_config
= cfg_descr
->bConfigurationValue
;
489 udi
->devadr
= devadr
;
490 udi
->busdevadr
= busdevadr
;
491 udi
->vid
= dev_descr
.idVendor
;
492 udi
->pid
= dev_descr
.idProduct
;
493 udi
->configs_with_midi
= 0;
494 udi
->configs_with_audio
= 0;
495 udi
->is_midi
= FALSE
;
496 udi
->is_audio
= FALSE
;
497 udi
->last_probe_time
= time(NULL
);
499 g_hash_table_insert(uii
->device_table
, GINT_TO_POINTER(busdevadr
), udi
);
500 libusb_free_config_descriptor(cfg_descr
);
503 if (udi
->vid
== dev_descr
.idVendor
&& udi
->pid
== dev_descr
.idProduct
)
505 // device already open or determined to be
506 if (udi
->status
== CBOX_DEVICE_STATUS_OPENED
||
507 udi
->status
== CBOX_DEVICE_STATUS_UNSUPPORTED
)
509 // give up after 10 attempts to query or open the device
510 if (udi
->failures
> 10)
512 // only do ~1 attempt per second
513 if (probe_only
&& time(NULL
) == udi
->last_probe_time
)
515 udi
->last_probe_time
= time(NULL
);
518 struct cbox_usb_audio_info uainf
;
519 cbox_usb_audio_info_init(&uainf
, udi
);
521 struct cbox_usb_midi_info uminf
;
522 cbox_usb_midi_info_init(&uminf
, udi
);
524 gboolean is_audio
= FALSE
;
526 // printf("%03d:%03d Device %04X:%04X\n", bus, devadr, dev_descr.idVendor, dev_descr.idProduct);
527 for (int ci
= 0; ci
< (int)dev_descr
.bNumConfigurations
; ci
++)
529 struct libusb_config_descriptor
*cfg_descr
= NULL
;
530 // if this is not the current config, and another config with MIDI input
531 // has already been found, do not look any further
532 if (0 != libusb_get_config_descriptor(dev
, ci
, &cfg_descr
))
535 g_warning("%03d:%03d - cannot get configuration descriptor (try %d)", bus
, devadr
, udi
->failures
);
539 int cur_config
= cfg_descr
->bConfigurationValue
;
540 gboolean other_config
= cur_config
!= udi
->active_config
;
541 uint32_t config_mask
= 0;
542 // XXXKF not sure about legal range for bConfigurationValue
543 if(cfg_descr
->bConfigurationValue
>= 0 && cfg_descr
->bConfigurationValue
< 32)
544 config_mask
= 1 << cfg_descr
->bConfigurationValue
;
546 g_warning("Unexpected configuration value %d", cfg_descr
->bConfigurationValue
);
548 for (int ii
= 0; ii
< cfg_descr
->bNumInterfaces
; ii
++)
550 const struct libusb_interface
*idescr
= &cfg_descr
->interface
[ii
];
551 for (int as
= 0; as
< idescr
->num_altsetting
; as
++)
553 const struct libusb_interface_descriptor
*asdescr
= &idescr
->altsetting
[as
];
554 if (asdescr
->bInterfaceClass
== LIBUSB_CLASS_AUDIO
&& asdescr
->bInterfaceSubClass
== 1) // Audio control
556 if (parse_audio_control_class(&uainf
, asdescr
, other_config
) && other_config
)
557 udi
->configs_with_audio
|= config_mask
;
559 else if (asdescr
->bInterfaceClass
== LIBUSB_CLASS_AUDIO
&& asdescr
->bInterfaceSubClass
== 2) // Audio streaming
561 if (parse_audio_class(uii
, &uainf
, asdescr
, other_config
) && other_config
)
562 udi
->configs_with_audio
|= config_mask
;
564 else if (asdescr
->bInterfaceClass
== LIBUSB_CLASS_AUDIO
&& asdescr
->bInterfaceSubClass
== 3) // MIDI streaming
566 if (parse_midi_class(&uminf
, asdescr
, other_config
, FALSE
) && other_config
)
567 udi
->configs_with_midi
|= config_mask
;
568 if (parse_midi_class(&uminf
, asdescr
, other_config
, TRUE
) && other_config
)
569 udi
->configs_with_midi
|= config_mask
;
570 uminf
.protocol
= USBMIDI_PROTOCOL_CLASS
;
572 else if (udi
->vid
== 0x09e8 && udi
->pid
== 0x0062) // Akai MPD16
574 uminf
.intf
= asdescr
->bInterfaceNumber
;
575 uminf
.alt_setting
= asdescr
->bAlternateSetting
;
576 uminf
.protocol
= USBMIDI_PROTOCOL_MPD16
;
577 fill_endpoint_by_address(asdescr
, 0x82, &uminf
.epdesc_in
);
579 else if (udi
->vid
== 0x1235 && udi
->pid
== 0x000a) // Novation Nocturn
581 uminf
.intf
= asdescr
->bInterfaceNumber
;
582 uminf
.alt_setting
= asdescr
->bAlternateSetting
;
583 fill_endpoint_by_address(asdescr
, 0x81, &uminf
.epdesc_in
);
584 fill_endpoint_by_address(asdescr
, 0x02, &uminf
.epdesc_out
);
585 uminf
.epdesc_in
.interrupt
= TRUE
;
586 uminf
.epdesc_out
.interrupt
= TRUE
;
587 uminf
.protocol
= USBMIDI_PROTOCOL_NOCTURN
;
591 libusb_free_config_descriptor(cfg_descr
);
593 if (!uminf
.epdesc_in
.found
&& !uminf
.epdesc_out
.found
&& udi
->configs_with_midi
)
594 g_warning("%03d:%03d - MIDI port available on different configs: mask=0x%x", bus
, devadr
, udi
->configs_with_midi
);
596 if (uainf
.epdesc
.found
) // Class-compliant USB audio device
598 if (udi
->vid
== 0x13b2 && udi
->pid
== 0x0030) // Alesis Multimix 8
600 uainf
.sync_protocol
= USBAUDIOSYNC_PROTOCOL_MULTIMIX8
; // not used later
604 // All configs/interfaces/alts scanned, nothing interesting found -> mark as unsupported
605 udi
->is_midi
= uminf
.epdesc_in
.found
|| uminf
.epdesc_out
.found
;
606 udi
->is_audio
= is_audio
;
607 if (!udi
->is_midi
&& !udi
->is_audio
)
609 udi
->status
= CBOX_DEVICE_STATUS_UNSUPPORTED
;
613 gboolean opened
= FALSE
;
614 struct libusb_device_handle
*handle
= NULL
;
615 int err
= libusb_open(dev
, &handle
);
618 g_warning("Cannot open device %03d:%03d: %s; errno = %s", bus
, devadr
, libusb_error_name(err
), strerror(errno
));
625 libusb_close(handle
);
626 // Make sure that the reconnection code doesn't bail out due to
627 // last_probe_time == now.
628 udi
->last_probe_time
= 0;
629 return udi
->is_midi
|| udi
->is_audio
;
632 if (uminf
.epdesc_in
.found
|| uminf
.epdesc_out
.found
)
634 g_debug("Found MIDI device %03d:%03d, trying to open", bus
, devadr
);
635 if (0 != usbio_open_midi_interface(uii
, &uminf
, handle
))
638 if (uainf
.epdesc
.found
)
640 GError
*error
= NULL
;
641 if (usbio_open_audio_interface(uii
, &uainf
, handle
, &error
))
643 // should have already been marked as opened by the MIDI code, but
644 // I might add the ability to disable some MIDI interfaces at some point
645 udi
->status
= CBOX_DEVICE_STATUS_OPENED
;
650 g_warning("Cannot open class-compliant USB audio output: %s", error
->message
);
654 else if (udi
->vid
== 0x13b2 && udi
->pid
== 0x0030)
656 GError
*error
= NULL
;
657 if (usbio_open_audio_interface_multimix(uii
, bus
, devadr
, handle
, &error
))
659 // should have already been marked as opened by the MIDI code, but
660 // I might add the ability to disable some MIDI interfaces at some point
661 udi
->status
= CBOX_DEVICE_STATUS_OPENED
;
666 g_warning("Cannot open Alesis Multimix audio output: %s", error
->message
);
674 libusb_close(handle
);
677 udi
->handle
= handle
;
682 gboolean
usbio_scan_devices(struct cbox_usb_io_impl
*uii
, gboolean probe_only
)
684 struct libusb_device
**dev_list
;
685 size_t i
, num_devices
;
686 gboolean added
= FALSE
;
687 gboolean removed
= FALSE
;
689 num_devices
= libusb_get_device_list(probe_only
? uii
->usbctx_probe
: uii
->usbctx
, &dev_list
);
691 uint16_t *busdevadrs
= malloc(sizeof(uint16_t) * num_devices
);
692 for (i
= 0; i
< num_devices
; i
++)
694 struct libusb_device
*dev
= dev_list
[i
];
695 int bus
= libusb_get_bus_number(dev
);
696 int devadr
= libusb_get_device_address(dev
);
697 busdevadrs
[i
] = (bus
<< 8) | devadr
;
700 GList
*prev_keys
= g_hash_table_get_values(uii
->device_table
);
701 for (GList
*p
= prev_keys
; p
; p
= p
->next
)
703 gboolean found
= FALSE
;
704 struct cbox_usb_device_info
*udi
= p
->data
;
705 for (i
= 0; !found
&& i
< num_devices
; i
++)
706 found
= busdevadrs
[i
] == udi
->busdevadr
;
709 // Only specifically trigger removal if the device is ours
710 if (udi
->status
== CBOX_DEVICE_STATUS_OPENED
)
712 g_message("Disconnected: %03d:%03d (%s)", udi
->bus
, udi
->devadr
, probe_only
? "probe" : "reconfigure");
716 usbio_forget_device(uii
, udi
);
719 g_list_free(prev_keys
);
721 for (i
= 0; i
< num_devices
; i
++)
722 added
= inspect_device(uii
, dev_list
[i
], busdevadrs
[i
], probe_only
) || added
;
725 libusb_free_device_list(dev_list
, 0);
726 return added
|| removed
;
729 void usbio_forget_device(struct cbox_usb_io_impl
*uii
, struct cbox_usb_device_info
*devinfo
)
731 g_hash_table_remove(uii
->device_table
, GINT_TO_POINTER(devinfo
->busdevadr
));
732 for (GList
*p
= uii
->midi_ports
, *pNext
= NULL
; p
; p
= pNext
)
735 struct cbox_usb_midi_interface
*umi
= p
->data
;
736 if (umi
->busdevadr
== devinfo
->busdevadr
)
738 uii
->midi_ports
= g_list_delete_link(uii
->midi_ports
, p
);
742 if (uii
->handle_audiodev
== devinfo
->handle
)
743 uii
->handle_audiodev
= NULL
;
744 libusb_close(devinfo
->handle
);