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
)
37 for (int epi
= 0; epi
< asdescr
->bNumEndpoints
; epi
++)
39 const struct libusb_endpoint_descriptor
*ep
= &asdescr
->endpoint
[epi
];
40 if (ep
->bEndpointAddress
< 0x80 && (ep
->bmAttributes
& 0xF) == 9) // output, isochronous, adaptive
46 static void fill_endpoint_desc(struct usbio_endpoint_descriptor
*epdesc
, const struct libusb_endpoint_descriptor
*ep
)
49 epdesc
->interrupt
= FALSE
;
50 epdesc
->bEndpointAddress
= ep
->bEndpointAddress
;
51 epdesc
->wMaxPacketSize
= ep
->wMaxPacketSize
;
54 static gboolean
fill_endpoint_by_address(const struct libusb_interface_descriptor
*asdescr
, uint8_t addr
, struct usbio_endpoint_descriptor
*epdesc
)
56 epdesc
->found
= FALSE
;
57 epdesc
->interrupt
= FALSE
;
58 for (int epi
= 0; epi
< asdescr
->bNumEndpoints
; epi
++)
60 const struct libusb_endpoint_descriptor
*ep
= &asdescr
->endpoint
[epi
];
61 if (ep
->bEndpointAddress
== addr
)
63 fill_endpoint_desc(epdesc
, ep
);
70 ////////////////////////////////////////////////////////////////////////////////
72 struct usb_ut_descriptor_header
75 uint8_t bDescriptorType
;
76 uint8_t bDescriptorSubtype
;
79 struct usb_class_specific_header
81 struct usb_ut_descriptor_header hdr
;
83 uint8_t wTotalLengthLo
, wTotalLengthHi
;
84 uint8_t bInCollection
;
85 uint8_t baInterfaceNr
[0];
88 struct usbaudio_input_terminal_descriptor
91 uint8_t wTerminalTypeLo
, wTerminalTypeHi
;
92 uint8_t bAssocTerminal
;
94 uint8_t wChannelConfigLo
, wChannelConfigHi
;
95 uint8_t iChannelNames
;
99 struct usbaudio_output_terminal_descriptor
102 uint8_t wTerminalTypeLo
, wTerminalTypeHi
;
103 uint8_t bAssocTerminal
;
108 struct usbaudio_mixer_unit_descriptor1
112 uint8_t baSourceID
[0];
115 struct usbaudio_mixer_unit_descriptor2
118 uint8_t wChannelConfigLo
, wChannelConfigHi
;
119 uint8_t bmControls
[0];
120 // after the last index, 8-bit iMixer
123 struct usbaudio_selector_unit_descriptor1
127 uint8_t baSourceID
[0];
128 // after the last index, 8-bit iSelector
131 struct usbaudio_feature_unit_descriptor1
135 uint8_t bControlSize
;
136 uint8_t bmaControls
[0];
137 // after the last index, 8-bit iFeature
140 // Unit/Terminal Descriptor header from the spec
145 static const char *get_terminal_type_name(int type
)
149 case 0x101: return "USB Streaming";
150 case 0x1FF: return "USB vendor specific";
151 case 0x201: return "Microphone";
152 case 0x202: return "Desktop microphone";
153 case 0x203: return "Personal microphone";
154 case 0x204: return "Omni-directional microphone";
155 case 0x205: return "Microphone array";
156 case 0x206: return "Processing microphone array";
157 case 0x301: return "Speaker";
158 case 0x302: return "Headphones";
159 case 0x303: return "Head-mounted display audio";
160 case 0x304: return "Desktop speaker";
161 case 0x305: return "Room speaker";
162 case 0x306: return "Communication speaker";
163 case 0x307: return "Low-frequency effects speaker";
164 case 0x400: return "Bi-directional Undefined";
165 case 0x401: return "Handset (handheld)";
166 case 0x402: return "Handset (head-mounted)";
167 case 0x403: return "Speakerphone";
168 case 0x404: return "Echo-suppressing speakerphone";
169 case 0x405: return "Echo-cancelling speakerphone";
170 case 0x501: return "Phone line";
171 case 0x502: return "Telephone";
172 case 0x503: return "Down line phone";
173 case 0x600: return "External Undefined";
174 case 0x601: return "Analog connector";
175 case 0x602: return "Digital audio interface";
176 case 0x603: return "Line connector";
177 case 0x604: return "Legacy audio";
178 case 0x605: return "S/PDIF";
179 case 0x606: return "1394 D/A Stream";
180 case 0x607: return "1394 D/V Stream Sountrack";
181 case 0x700: return "Embedded undefined";
182 case 0x701: return "Level calibration noise source";
183 case 0x702: return "Equalization noise";
184 case 0x703: return "CD player";
185 case 0x704: return "DAT";
186 case 0x705: return "DCC";
187 case 0x706: return "MiniDisc";
188 case 0x707: return "Analog tape";
189 case 0x708: return "Phono";
190 case 0x709: return "VCR Audio";
191 case 0x70A: return "VideoDisc Audio";
192 case 0x70B: return "DVD Audio";
193 case 0x70C: return "TV Tuner Audio";
194 case 0x70D: return "Satellite Receiver Audio";
195 case 0x70E: return "Cable Tuner Audio";
196 case 0x70F: return "DSS Audio";
197 case 0x710: return "Radio Receiver";
198 case 0x711: return "Radio Transmitter";
199 case 0x712: return "Multitrack Recorder";
200 case 0x713: return "Synthesizer";
207 static gboolean
parse_audio_control_class(struct cbox_usb_audio_info
*uai
, const struct libusb_interface_descriptor
*asdescr
, gboolean other_config
)
210 if (asdescr
->extra_length
< 8)
212 g_warning("AudioControl interface descriptor length is %d, should be at least 8", (int)asdescr
->extra_length
);
215 const struct usb_class_specific_header
*extra
= (const struct usb_class_specific_header
*)asdescr
->extra
;
216 uint16_t wTotalLength
= extra
->wTotalLengthLo
+ 256 * extra
->wTotalLengthHi
;
217 if (wTotalLength
> asdescr
->extra_length
)
219 g_warning("AudioControl interface descriptor total length is %d, but libusb value is %d", (int)wTotalLength
, (int)asdescr
->extra_length
);
222 if (extra
->hdr
.bDescriptorType
!= 36)
224 g_warning("AudioControl interface descriptor type is %d, but expected 36 (CS_INTERFACE)", (int)extra
->hdr
.bDescriptorType
);
227 if (extra
->hdr
.bDescriptorSubtype
!= 1)
229 g_warning("AudioControl interface descriptor type is %d, but expected 1 (HEADER)", (int)extra
->hdr
.bDescriptorSubtype
);
233 printf("Device %04x:%04x\n", uai
->udi
->vid
, uai
->udi
->pid
);
234 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
);
235 for(int i
= 0; i
< extra
->bInCollection
; i
++)
237 printf("interface nr %d = %d\n", i
, extra
->baInterfaceNr
[i
]);
240 for(uint32_t pos
= extra
->hdr
.bLength
; pos
< wTotalLength
; pos
+= asdescr
->extra
[pos
])
242 const struct usb_ut_descriptor_header
*hdr
= (const struct usb_ut_descriptor_header
*)(asdescr
->extra
+ pos
);
243 if (hdr
->bDescriptorType
!= 36)
245 g_warning("Skipping unit/terminal descriptor type %d,%d", (int)hdr
->bDescriptorType
, (int)hdr
->bDescriptorSubtype
);
248 printf("hdr %d,%d len %d\n", hdr
->bDescriptorType
, hdr
->bDescriptorSubtype
, hdr
->bLength
);
249 switch(hdr
->bDescriptorSubtype
)
251 case 2: // INPUT_TERMINAL
253 const struct usbaudio_input_terminal_descriptor
*itd
= (const struct usbaudio_input_terminal_descriptor
*)(hdr
+ 1);
254 int wTerminalType
= itd
->wTerminalTypeHi
* 256 + itd
->wTerminalTypeLo
;
255 printf("INPUT TERMINAL %d: type %04x (%s)\n", (int)itd
->bTerminalID
, wTerminalType
, get_terminal_type_name(wTerminalType
));
258 case 3: // OUTPUT_TERMINAL
260 const struct usbaudio_output_terminal_descriptor
*otd
= (const struct usbaudio_output_terminal_descriptor
*)(hdr
+ 1);
261 int wTerminalType
= otd
->wTerminalTypeHi
* 256 + otd
->wTerminalTypeLo
;
262 printf("OUTPUT TERMINAL %d: type %04x (%s) source %d\n", (int)otd
->bTerminalID
, wTerminalType
, get_terminal_type_name(wTerminalType
), otd
->bSourceID
);
265 case 4: // MIXER_UNIT
267 const struct usbaudio_mixer_unit_descriptor1
*mud
= (const struct usbaudio_mixer_unit_descriptor1
*)(hdr
+ 1);
268 printf("MIXER UNIT %d\n", (int)mud
->bUnitID
);
269 for (int i
= 0; i
< mud
->bNrInPins
; i
++)
271 printf("Input[%d] = %d\n", i
, mud
->baSourceID
[i
]);
275 case 5: // SELECTOR_UNIT
277 const struct usbaudio_selector_unit_descriptor1
*sud
= (const struct usbaudio_selector_unit_descriptor1
*)(hdr
+ 1);
278 printf("SELECTOR UNIT %d (%d pins)\n", (int)sud
->bUnitID
, sud
->bNrInPins
);
279 for (int i
= 0; i
< sud
->bNrInPins
; i
++)
281 printf("Input[%d] = %d\n", i
, sud
->baSourceID
[i
]);
285 case 6: // FEATURE_UNIT
287 static const char *features
[] = {"Mute", "Volume", "Bass", "Mid", "Treble", "EQ", "AGC", "Delay", "Bass Boost", "Loudness" };
288 const struct usbaudio_feature_unit_descriptor1
*fud
= (const struct usbaudio_feature_unit_descriptor1
*)(hdr
+ 1);
289 printf("FEATURE UNIT %d (source = %d, control size %d)\n", (int)fud
->bUnitID
, fud
->bSourceID
, fud
->bControlSize
);
290 for (int i
= 0; i
< fud
->bControlSize
* 8; i
++)
292 if (i
>= sizeof(features
) / sizeof(features
[0]))
294 if (fud
->bmaControls
[i
>> 3] & (1 << (i
& 7)))
295 printf("Master %s\n", features
[i
]);
297 for (int ch
= 1; ch
< (hdr
->bLength
- 7) / fud
->bControlSize
; ch
++)
299 int chofs
= ch
* fud
->bControlSize
;
300 for (int i
= 0; i
< fud
->bControlSize
* 8; i
++)
302 if (i
>= sizeof(features
) / sizeof(features
[0]))
304 if (fud
->bmaControls
[(i
>> 3) + chofs
] & (1 << (i
& 7)))
305 printf("Channel %d %s\n", ch
, features
[i
]);
311 printf("Unsupported unit type %d\n", hdr
->bDescriptorSubtype
);
319 struct usbaudio_streaming_interface_descriptor_general
321 struct usb_ut_descriptor_header hdr
; // 7, 36, 1
322 uint8_t bTerminalLink
;
324 uint8_t wFormatTagLo
, wFormatTagHi
;
327 struct usbaudio_streaming_interface_descriptor_format_type_pcm
329 struct usb_ut_descriptor_header hdr
; // 7, 36, 2
332 uint8_t bSubframeSize
;
333 uint8_t bBitResolution
;
334 uint8_t bSamFreqType
;
335 uint8_t taSamFreq
[0][3];
338 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
)
340 // omit alternate setting 0, as it's used to describe a 'standby' setting of the interface (no bandwidth)
341 if (asdescr
->bAlternateSetting
== 0)
343 if (asdescr
->extra_length
< 7)
345 g_warning("AudioStreaming interface descriptor length is %d, should be at least 7", (int)asdescr
->extra_length
);
348 const struct usbaudio_streaming_interface_descriptor_general
*extra
= (struct usbaudio_streaming_interface_descriptor_general
*)asdescr
->extra
;
349 if (extra
->hdr
.bLength
!= 7 || extra
->hdr
.bDescriptorType
!= 36 || extra
->hdr
.bDescriptorSubtype
!= 1)
351 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
);
354 if (extra
->wFormatTagLo
!= 1 || extra
->wFormatTagHi
!= 0)
356 g_warning("The AudioStreaming descriptor does not describe a PCM device");
359 const struct usbaudio_streaming_interface_descriptor_format_type_pcm
*fmt
= (struct usbaudio_streaming_interface_descriptor_format_type_pcm
*)(asdescr
->extra
+ extra
->hdr
.bLength
);
360 if (fmt
->hdr
.bLength
!= 14 || fmt
->hdr
.bDescriptorType
!= 36 || fmt
->hdr
.bDescriptorSubtype
!= 2)
362 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
);
366 // We need this to tell inputs from outputs - until I implement reasonable
367 // Audio Control support
368 const struct libusb_endpoint_descriptor
*ep
= get_audio_output_endpoint(asdescr
);
371 if (fmt
->bBitResolution
!= uii
->output_resolution
* 8)
373 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
);
376 if (fmt
->bSamFreqType
)
378 gboolean found
= FALSE
;
379 for (int i
= 0; i
< fmt
->bSamFreqType
; i
++)
381 int sf
= fmt
->taSamFreq
[i
][0] + 256 * fmt
->taSamFreq
[i
][1] + 65536 * fmt
->taSamFreq
[i
][2];
382 if (sf
== uii
->sample_rate
)
390 g_warning("Interface %d alternate setting %d does not support sample rate of %d Hz", asdescr
->bInterfaceNumber
, asdescr
->bAlternateSetting
, uii
->sample_rate
);
391 for (int i
= 0; i
< fmt
->bSamFreqType
; i
++)
393 int sf
= fmt
->taSamFreq
[i
][0] + 256 * fmt
->taSamFreq
[i
][1] + 65536 * fmt
->taSamFreq
[i
][2];
394 g_warning("Sample rate[%d] = %d Hz", i
, sf
);
399 // XXXKF in case of continuous sample rate, check the limits... assuming
400 // that there are any devices with continuous sample rate, that is.
403 if (uai
->epdesc
.found
)
405 g_warning("Interface %d alt-setting %d endpoint %02x looks promising", asdescr
->bInterfaceNumber
, asdescr
->bAlternateSetting
, ep
->bEndpointAddress
);
406 uai
->intf
= asdescr
->bInterfaceNumber
;
407 uai
->alt_setting
= asdescr
->bAlternateSetting
;
408 fill_endpoint_desc(&uai
->epdesc
, ep
);
414 static gboolean
parse_midi_class(struct cbox_usb_midi_info
*umi
, const struct libusb_interface_descriptor
*asdescr
, gboolean other_config
, gboolean is_output
)
416 const struct libusb_endpoint_descriptor
*ep
= get_midi_endpoint(asdescr
, is_output
);
423 struct usbio_endpoint_descriptor
*epd
= is_output
? &umi
->epdesc_out
: &umi
->epdesc_in
;
427 umi
->intf
= asdescr
->bInterfaceNumber
;
428 umi
->alt_setting
= asdescr
->bAlternateSetting
;
429 fill_endpoint_desc(epd
, ep
);
433 static gboolean
inspect_device(struct cbox_usb_io_impl
*uii
, struct libusb_device
*dev
, uint16_t busdevadr
, gboolean probe_only
)
435 struct libusb_device_descriptor dev_descr
;
436 int bus
= busdevadr
>> 8;
437 int devadr
= busdevadr
& 255;
439 if (0 != libusb_get_device_descriptor(dev
, &dev_descr
))
441 g_warning("USB device %03d:%03d - cannot get device descriptor (will retry)", bus
, devadr
);
445 struct cbox_usb_device_info
*udi
= g_hash_table_lookup(uii
->device_table
, GINT_TO_POINTER(busdevadr
));
448 struct libusb_config_descriptor
*cfg_descr
= NULL
;
449 if (0 != libusb_get_active_config_descriptor(dev
, &cfg_descr
))
451 udi
= malloc(sizeof(struct cbox_usb_device_info
));
454 udi
->status
= CBOX_DEVICE_STATUS_PROBING
;
455 udi
->active_config
= cfg_descr
->bConfigurationValue
;
457 udi
->devadr
= devadr
;
458 udi
->busdevadr
= busdevadr
;
459 udi
->vid
= dev_descr
.idVendor
;
460 udi
->pid
= dev_descr
.idProduct
;
461 udi
->configs_with_midi
= 0;
462 udi
->configs_with_audio
= 0;
463 udi
->is_midi
= FALSE
;
464 udi
->is_audio
= FALSE
;
465 udi
->last_probe_time
= time(NULL
);
467 g_hash_table_insert(uii
->device_table
, GINT_TO_POINTER(busdevadr
), udi
);
468 libusb_free_config_descriptor(cfg_descr
);
471 if (udi
->vid
== dev_descr
.idVendor
&& udi
->pid
== dev_descr
.idProduct
)
473 // device already open or determined to be
474 if (udi
->status
== CBOX_DEVICE_STATUS_OPENED
||
475 udi
->status
== CBOX_DEVICE_STATUS_UNSUPPORTED
)
477 // give up after 10 attempts to query or open the device
478 if (udi
->failures
> 10)
480 // only do ~1 attempt per second
481 if (probe_only
&& time(NULL
) == udi
->last_probe_time
)
483 udi
->last_probe_time
= time(NULL
);
486 struct cbox_usb_audio_info uainf
;
487 cbox_usb_audio_info_init(&uainf
, udi
);
489 struct cbox_usb_midi_info uminf
;
490 cbox_usb_midi_info_init(&uminf
, udi
);
492 gboolean is_audio
= FALSE
;
494 // printf("%03d:%03d Device %04X:%04X\n", bus, devadr, dev_descr.idVendor, dev_descr.idProduct);
495 for (int ci
= 0; ci
< (int)dev_descr
.bNumConfigurations
; ci
++)
497 struct libusb_config_descriptor
*cfg_descr
= NULL
;
498 // if this is not the current config, and another config with MIDI input
499 // has already been found, do not look any further
500 if (0 != libusb_get_config_descriptor(dev
, ci
, &cfg_descr
))
503 g_warning("%03d:%03d - cannot get configuration descriptor (try %d)", bus
, devadr
, udi
->failures
);
507 int cur_config
= cfg_descr
->bConfigurationValue
;
508 gboolean other_config
= cur_config
!= udi
->active_config
;
509 uint32_t config_mask
= 0;
510 // XXXKF not sure about legal range for bConfigurationValue
511 if(cfg_descr
->bConfigurationValue
>= 0 && cfg_descr
->bConfigurationValue
< 32)
512 config_mask
= 1 << cfg_descr
->bConfigurationValue
;
514 g_warning("Unexpected configuration value %d", cfg_descr
->bConfigurationValue
);
516 for (int ii
= 0; ii
< cfg_descr
->bNumInterfaces
; ii
++)
518 const struct libusb_interface
*idescr
= &cfg_descr
->interface
[ii
];
519 for (int as
= 0; as
< idescr
->num_altsetting
; as
++)
521 const struct libusb_interface_descriptor
*asdescr
= &idescr
->altsetting
[as
];
522 if (asdescr
->bInterfaceClass
== LIBUSB_CLASS_AUDIO
&& asdescr
->bInterfaceSubClass
== 1) // Audio control
524 if (parse_audio_control_class(&uainf
, asdescr
, other_config
) && other_config
)
525 udi
->configs_with_audio
|= config_mask
;
527 else if (asdescr
->bInterfaceClass
== LIBUSB_CLASS_AUDIO
&& asdescr
->bInterfaceSubClass
== 2) // Audio streaming
529 if (parse_audio_class(uii
, &uainf
, asdescr
, other_config
) && other_config
)
530 udi
->configs_with_audio
|= config_mask
;
532 else if (asdescr
->bInterfaceClass
== LIBUSB_CLASS_AUDIO
&& asdescr
->bInterfaceSubClass
== 3) // MIDI streaming
534 if (parse_midi_class(&uminf
, asdescr
, other_config
, FALSE
) && other_config
)
535 udi
->configs_with_midi
|= config_mask
;
536 if (parse_midi_class(&uminf
, asdescr
, other_config
, TRUE
) && other_config
)
537 udi
->configs_with_midi
|= config_mask
;
538 uminf
.protocol
= USBMIDI_PROTOCOL_CLASS
;
540 else if (udi
->vid
== 0x09e8 && udi
->pid
== 0x0062) // Akai MPD16
542 uminf
.intf
= asdescr
->bInterfaceNumber
;
543 uminf
.alt_setting
= asdescr
->bAlternateSetting
;
544 uminf
.protocol
= USBMIDI_PROTOCOL_MPD16
;
545 fill_endpoint_by_address(asdescr
, 0x82, &uminf
.epdesc_in
);
547 else if (udi
->vid
== 0x1235 && udi
->pid
== 0x000a) // Novation Nocturn
549 uminf
.intf
= asdescr
->bInterfaceNumber
;
550 uminf
.alt_setting
= asdescr
->bAlternateSetting
;
551 fill_endpoint_by_address(asdescr
, 0x81, &uminf
.epdesc_in
);
552 fill_endpoint_by_address(asdescr
, 0x02, &uminf
.epdesc_out
);
553 uminf
.epdesc_in
.interrupt
= TRUE
;
554 uminf
.epdesc_out
.interrupt
= TRUE
;
555 uminf
.protocol
= USBMIDI_PROTOCOL_NOCTURN
;
559 libusb_free_config_descriptor(cfg_descr
);
561 if (!uminf
.epdesc_in
.found
&& !uminf
.epdesc_out
.found
&& udi
->configs_with_midi
)
562 g_warning("%03d:%03d - MIDI port available on different configs: mask=0x%x", bus
, devadr
, udi
->configs_with_midi
);
564 if (uainf
.epdesc
.found
) // Class-compliant USB audio device
566 if (udi
->vid
== 0x13b2 && udi
->pid
== 0x0030) // Alesis Multimix 8
569 // All configs/interfaces/alts scanned, nothing interesting found -> mark as unsupported
570 udi
->is_midi
= uminf
.epdesc_in
.found
|| uminf
.epdesc_out
.found
;
571 udi
->is_audio
= is_audio
;
572 if (!udi
->is_midi
&& !udi
->is_audio
)
574 udi
->status
= CBOX_DEVICE_STATUS_UNSUPPORTED
;
578 gboolean opened
= FALSE
;
579 struct libusb_device_handle
*handle
= NULL
;
580 int err
= libusb_open(dev
, &handle
);
583 g_warning("Cannot open device %03d:%03d: %s; errno = %s", bus
, devadr
, libusb_error_name(err
), strerror(errno
));
590 libusb_close(handle
);
591 // Make sure that the reconnection code doesn't bail out due to
592 // last_probe_time == now.
593 udi
->last_probe_time
= 0;
594 return udi
->is_midi
|| udi
->is_audio
;
597 if (uminf
.epdesc_in
.found
|| uminf
.epdesc_out
.found
)
599 g_debug("Found MIDI device %03d:%03d, trying to open", bus
, devadr
);
600 if (0 != usbio_open_midi_interface(uii
, &uminf
, handle
))
603 if (uainf
.epdesc
.found
)
605 GError
*error
= NULL
;
606 if (usbio_open_audio_interface(uii
, &uainf
, handle
, &error
))
608 // should have already been marked as opened by the MIDI code, but
609 // I might add the ability to disable some MIDI interfaces at some point
610 udi
->status
= CBOX_DEVICE_STATUS_OPENED
;
615 g_warning("Cannot open class-compliant USB audio output: %s", error
->message
);
619 else if (udi
->vid
== 0x13b2 && udi
->pid
== 0x0030)
621 GError
*error
= NULL
;
622 if (usbio_open_audio_interface_multimix(uii
, bus
, devadr
, handle
, &error
))
624 // should have already been marked as opened by the MIDI code, but
625 // I might add the ability to disable some MIDI interfaces at some point
626 udi
->status
= CBOX_DEVICE_STATUS_OPENED
;
631 g_warning("Cannot open Alesis Multimix audio output: %s", error
->message
);
639 libusb_close(handle
);
642 udi
->handle
= handle
;
647 gboolean
usbio_scan_devices(struct cbox_usb_io_impl
*uii
, gboolean probe_only
)
649 struct libusb_device
**dev_list
;
650 size_t i
, num_devices
;
651 gboolean added
= FALSE
;
652 gboolean removed
= FALSE
;
654 num_devices
= libusb_get_device_list(probe_only
? uii
->usbctx_probe
: uii
->usbctx
, &dev_list
);
656 uint16_t *busdevadrs
= malloc(sizeof(uint16_t) * num_devices
);
657 for (i
= 0; i
< num_devices
; i
++)
659 struct libusb_device
*dev
= dev_list
[i
];
660 int bus
= libusb_get_bus_number(dev
);
661 int devadr
= libusb_get_device_address(dev
);
662 busdevadrs
[i
] = (bus
<< 8) | devadr
;
665 GList
*prev_keys
= g_hash_table_get_values(uii
->device_table
);
666 for (GList
*p
= prev_keys
; p
; p
= p
->next
)
668 gboolean found
= FALSE
;
669 struct cbox_usb_device_info
*udi
= p
->data
;
670 for (i
= 0; !found
&& i
< num_devices
; i
++)
671 found
= busdevadrs
[i
] == udi
->busdevadr
;
674 // Only specifically trigger removal if the device is ours
675 if (udi
->status
== CBOX_DEVICE_STATUS_OPENED
)
677 g_message("Disconnected: %03d:%03d (%s)", udi
->bus
, udi
->devadr
, probe_only
? "probe" : "reconfigure");
681 usbio_forget_device(uii
, udi
);
684 g_list_free(prev_keys
);
686 for (i
= 0; i
< num_devices
; i
++)
687 added
= inspect_device(uii
, dev_list
[i
], busdevadrs
[i
], probe_only
) || added
;
690 libusb_free_device_list(dev_list
, 0);
691 return added
|| removed
;
694 void usbio_forget_device(struct cbox_usb_io_impl
*uii
, struct cbox_usb_device_info
*devinfo
)
696 g_hash_table_remove(uii
->device_table
, GINT_TO_POINTER(devinfo
->busdevadr
));
697 for (GList
*p
= uii
->midi_ports
, *pNext
= NULL
; p
; p
= pNext
)
700 struct cbox_usb_midi_interface
*umi
= p
->data
;
701 if (umi
->busdevadr
== devinfo
->busdevadr
)
703 uii
->midi_ports
= g_list_delete_link(uii
->midi_ports
, p
);
707 if (uii
->handle_audiodev
== devinfo
->handle
)
708 uii
->handle_audiodev
= NULL
;
709 libusb_close(devinfo
->handle
);