1 /* 2 * Originally released under the Be Sample Code License. 3 * Copyright 2000, Be Incorporated. All rights reserved. 4 * 5 * Modified for Haiku by François Revol and Michael Lotz. 6 * Copyright 2007-2016, Haiku Inc. All rights reserved. 7 */ 8 9 #include <MediaDefs.h> 10 #include <USBKit.h> 11 #include <stdio.h> 12 13 #include <usb/USB_audio.h> 14 #include <usb/USB_midi.h> 15 16 #include "listusb.h" 17 18 void 19 DumpAudioCSInterfaceDescriptorHeader( 20 const usb_audiocontrol_header_descriptor* descriptor) 21 { 22 printf(" Type .............. 0x%02x\n", 23 descriptor->descriptor_type); 24 printf(" Subtype ........... 0x%02x (Header)\n", 25 descriptor->descriptor_subtype); 26 printf(" ADC Release ....... %d.%d\n", 27 descriptor->bcd_release_no >> 8, descriptor->bcd_release_no & 0xFF); 28 printf(" Total Length ...... %u\n", 29 descriptor->r1.total_length); 30 printf(" Interfaces ........ "); 31 32 for (uint8 i = 0; i < descriptor->r1.in_collection; i++) 33 printf("%u, ", descriptor->r1.interface_numbers[i]); 34 printf("\n"); 35 } 36 37 38 void 39 DumpChannelConfig(uint32 wChannelConfig) 40 { 41 struct _Entry { 42 const char* name; 43 uint32 mask; 44 } aClusters[] = { 45 { "Front .......... ", B_CHANNEL_LEFT | B_CHANNEL_RIGHT 46 | B_CHANNEL_CENTER }, 47 { "L.F.E .......... ", B_CHANNEL_SUB }, 48 { "Back ........... ", B_CHANNEL_REARLEFT | B_CHANNEL_REARRIGHT 49 | B_CHANNEL_BACK_CENTER }, 50 { "Center ......... ", B_CHANNEL_FRONT_LEFT_CENTER 51 | B_CHANNEL_FRONT_RIGHT_CENTER }, 52 { "Side ........... ", B_CHANNEL_SIDE_LEFT | B_CHANNEL_SIDE_RIGHT }, 53 { "Top ............ ", B_CHANNEL_TOP_CENTER }, 54 { "Top Front ...... ", B_CHANNEL_TOP_FRONT_LEFT 55 | B_CHANNEL_TOP_FRONT_CENTER | B_CHANNEL_TOP_FRONT_RIGHT }, 56 { "Top Back ....... ", B_CHANNEL_TOP_BACK_LEFT 57 | B_CHANNEL_TOP_BACK_CENTER | B_CHANNEL_TOP_BACK_RIGHT } 58 }; 59 60 struct _Entry aChannels[] = { 61 { "Left", B_CHANNEL_LEFT | B_CHANNEL_FRONT_LEFT_CENTER 62 | B_CHANNEL_REARLEFT | B_CHANNEL_SIDE_LEFT | B_CHANNEL_TOP_BACK_LEFT 63 | B_CHANNEL_TOP_FRONT_LEFT }, 64 { "Right", B_CHANNEL_FRONT_RIGHT_CENTER | B_CHANNEL_TOP_FRONT_RIGHT 65 | B_CHANNEL_REARRIGHT | B_CHANNEL_RIGHT | B_CHANNEL_SIDE_RIGHT 66 | B_CHANNEL_TOP_BACK_RIGHT }, 67 { "Center", B_CHANNEL_BACK_CENTER | B_CHANNEL_CENTER 68 | B_CHANNEL_TOP_BACK_CENTER | B_CHANNEL_TOP_CENTER 69 | B_CHANNEL_TOP_FRONT_CENTER }, 70 { "L.F.E.", B_CHANNEL_SUB } 71 }; 72 73 for (size_t i = 0; i < sizeof(aClusters) / sizeof(aClusters[0]); i++) { 74 uint32 mask = aClusters[i].mask & wChannelConfig; 75 if (mask != 0) { 76 printf(" %s", aClusters[i].name); 77 for (size_t j = 0; j < sizeof(aChannels) / sizeof(aChannels[0]); j++) 78 if ((aChannels[j].mask & mask) != 0) 79 printf("%s ", aChannels[j].name); 80 printf("\n"); 81 } 82 } 83 } 84 85 86 static const char* 87 TerminalTypeName(uint16 terminalType) 88 { 89 switch (terminalType) { 90 case USB_AUDIO_UNDEFINED_USB_IO: 91 return "USB Undefined"; 92 case USB_AUDIO_STREAMING_USB_IO: 93 return "USB Streaming"; 94 case USB_AUDIO_VENDOR_USB_IO: 95 return "USB vendor specific"; 96 97 case USB_AUDIO_UNDEFINED_IN: 98 return "Undefined"; 99 case USB_AUDIO_MICROPHONE_IN: 100 return "Microphone"; 101 case USB_AUDIO_DESKTOPMIC_IN: 102 return "Desktop microphone"; 103 case USB_AUDIO_PERSONALMIC_IN: 104 return "Personal microphone"; 105 case USB_AUDIO_OMNI_MIC_IN: 106 return "Omni-directional microphone"; 107 case USB_AUDIO_MICS_ARRAY_IN: 108 return "Microphone array"; 109 case USB_AUDIO_PROC_MICS_ARRAY_IN: 110 return "Processing microphone array"; 111 case USB_AUDIO_LINE_CONNECTOR_IO: 112 return "Line I/O"; 113 case USB_AUDIO_SPDIF_INTERFACE_IO: 114 return "S/PDIF"; 115 116 case USB_AUDIO_UNDEFINED_OUT: 117 return "Undefined"; 118 case USB_AUDIO_SPEAKER_OUT: 119 return "Speaker"; 120 case USB_AUDIO_HEAD_PHONES_OUT: 121 return "Headphones"; 122 case USB_AUDIO_HMD_AUDIO_OUT: 123 return "Head Mounted Display Audio"; 124 case USB_AUDIO_DESKTOP_SPEAKER: 125 return "Desktop speaker"; 126 case USB_AUDIO_ROOM_SPEAKER: 127 return "Room speaker"; 128 case USB_AUDIO_COMM_SPEAKER: 129 return "Communication speaker"; 130 case USB_AUDIO_LFE_SPEAKER: 131 return "Low frequency effects speaker"; 132 133 default: 134 return "Unknown"; 135 } 136 } 137 138 139 void 140 DumpAudioCSInterfaceDescriptorInputTerminal( 141 const usb_audio_input_terminal_descriptor* descriptor) 142 { 143 printf(" Type .............. 0x%02x\n", 144 descriptor->descriptor_type); 145 printf(" Subtype ........... 0x%02x (Input Terminal)\n", 146 descriptor->descriptor_subtype); 147 printf(" Terminal ID ....... %u\n", 148 descriptor->terminal_id); 149 printf(" Terminal Type ..... 0x%04x (%s)\n", 150 descriptor->terminal_type, 151 TerminalTypeName(descriptor->terminal_type)); 152 printf(" Associated Terminal %u\n", 153 descriptor->assoc_terminal); 154 printf(" Nr Channels ....... %u\n", 155 descriptor->r1.num_channels); 156 printf(" Channel Config .... 0x%x\n", 157 descriptor->r1.channel_config); 158 DumpChannelConfig(descriptor->r1.channel_config); 159 160 printf(" Channel Names ..... %u\n", 161 descriptor->r1.channel_names); 162 printf(" Terminal .......... %u\n", 163 descriptor->r1.terminal); 164 } 165 166 167 void 168 DumpAudioCSInterfaceDescriptorOutputTerminal( 169 const usb_audio_output_terminal_descriptor* descriptor) 170 { 171 printf(" Type .............. 0x%02x\n", 172 descriptor->descriptor_type); 173 printf(" Subtype ........... 0x%02x (Output Terminal)\n", 174 descriptor->descriptor_subtype); 175 printf(" Terminal ID ....... %u\n", 176 descriptor->terminal_id); 177 printf(" Terminal Type ..... 0x%04x (%s)\n", 178 descriptor->terminal_type, 179 TerminalTypeName(descriptor->terminal_type)); 180 printf(" Associated Terminal %u\n", 181 descriptor->assoc_terminal); 182 printf(" Source ID ......... %u\n", 183 descriptor->source_id); 184 printf(" Terminal .......... %u\n", 185 descriptor->r1.terminal); 186 } 187 188 189 void 190 DumpAudioCSInterfaceDescriptorMixerUnit( 191 const usb_audio_mixer_unit_descriptor* descriptor) 192 { 193 printf(" Type .............. 0x%02x\n", 194 descriptor->descriptor_type); 195 printf(" Subtype ........... 0x%02x (Mixer Unit)\n", 196 descriptor->descriptor_subtype); 197 printf(" Unit ID ........... %u\n", 198 descriptor->unit_id); 199 200 printf(" Source IDs ........ "); 201 for (uint8 i = 0; i < descriptor->num_input_pins; i++) 202 printf("%u, ", descriptor->input_pins[i]); 203 printf("\n"); 204 205 usb_audio_output_channels_descriptor_r1* channels 206 = (usb_audio_output_channels_descriptor_r1*) 207 &descriptor->input_pins[descriptor->num_input_pins]; 208 209 printf(" Channels .......... %u\n", 210 channels->num_output_pins); 211 printf(" Channel Config .... 0x%x\n", 212 channels->channel_config); 213 DumpChannelConfig(channels->channel_config); 214 printf(" Channel Names ..... %u\n", 215 channels->channel_names); 216 217 usb_generic_descriptor* generic = (usb_generic_descriptor*)descriptor; 218 uint8 idx = 7 + descriptor->num_input_pins; 219 printf(" Bitmap Control .... 0x"); 220 for (uint i = 1; idx < descriptor->length - 3; idx++, i++) 221 printf("%02x ", (uint8)generic->data[idx]); 222 printf("\n"); 223 224 printf(" Mixer ............. %u\n", 225 generic->data[generic->length - 3]); 226 } 227 228 229 void 230 DumpAudioCSInterfaceDescriptorSelectorUnit( 231 const usb_audio_selector_unit_descriptor* descriptor) 232 { 233 printf(" Type .............. 0x%02x\n", 234 descriptor->descriptor_type); 235 printf(" Subtype ........... 0x%02x (Selector Unit)\n", 236 descriptor->descriptor_subtype); 237 printf(" Unit ID ........... %u\n", 238 descriptor->unit_id); 239 240 printf(" Source IDs ........ "); 241 for (uint8 i = 0; i < descriptor->num_input_pins; i++) 242 printf("%u, ", descriptor->input_pins[i]); 243 printf("\n"); 244 245 usb_generic_descriptor* generic = (usb_generic_descriptor*)descriptor; 246 printf(" Selector .......... %u\n", 247 (uint8)generic->data[descriptor->num_input_pins + 2]); 248 } 249 250 251 void 252 DumpBMAControl(uint8 channel, uint32 bma) 253 { 254 const char* BMAControls[] = { 255 "Mute", 256 "Volume", 257 "Bass", 258 "Mid", 259 "Treble", 260 "Graphic Equalizer", 261 "Automatic Gain", 262 "Delay", 263 "Bass Boost", 264 "Loudness" 265 }; 266 267 if (bma == 0) 268 return; 269 270 if (channel == 0) 271 printf(" Master Channel . "); 272 else 273 printf(" Channel %u ...... ", channel); 274 275 int mask = 1; 276 for (uint8 i = 0; 277 i < sizeof(BMAControls) / sizeof(BMAControls[0]); i++, mask <<= 1) 278 if (bma & mask) 279 printf("%s ", BMAControls[i]); 280 printf("\n"); 281 } 282 283 284 void 285 DumpAudioCSInterfaceDescriptorFeatureUnit( 286 const usb_audio_feature_unit_descriptor* descriptor) 287 { 288 printf(" Type .............. 0x%02x\n", 289 descriptor->descriptor_type); 290 printf(" Subtype ........... 0x%02x (Feature Unit)\n", 291 descriptor->descriptor_subtype); 292 printf(" Unit ID ........... %u\n", 293 descriptor->unit_id); 294 printf(" Source ID ......... %u\n", 295 descriptor->source_id); 296 297 printf(" Control Size ...... %u\n", 298 descriptor->r1.control_size); 299 300 uint8 channels = 0; 301 if (descriptor->r1.control_size > 0) 302 channels = (descriptor->length - 6) / descriptor->r1.control_size; 303 for (uint8 i = 0; i < channels; i++) { 304 switch (descriptor->r1.control_size) { 305 case 1: 306 DumpBMAControl(i, descriptor->r1.bma_controls[i]); 307 break; 308 case 2: 309 DumpBMAControl(i, *(uint16*)&descriptor->r1.bma_controls[i * 2]); 310 break; 311 case 4: 312 DumpBMAControl(i, *(uint32*)&descriptor->r1.bma_controls[i * 4]); 313 break; 314 default: 315 printf(" BMA Channel %u ... ", i); 316 for (uint8 j = 0; j < descriptor->r1.control_size; j++) 317 printf("%02x ", descriptor->r1.bma_controls[i + j]); 318 printf("\n"); 319 break; 320 } 321 } 322 323 usb_generic_descriptor* generic = (usb_generic_descriptor*)descriptor; 324 printf(" Feature ........... %u\n", 325 (uint8)generic->data[descriptor->length - 3]); 326 } 327 328 329 void 330 DumpAudioCSInterfaceDescriptorAssociated( 331 const usb_generic_descriptor* descriptor) 332 { 333 printf(" Type .............. 0x%02x\n", 334 descriptor->descriptor_type); 335 printf(" Subtype ........... 0x%02x (Associate Interface)\n", 336 (uint8)descriptor->data[0]); 337 printf(" Interface ......... %u\n", 338 (uint8)descriptor->data[1]); 339 340 printf(" Data .............. "); 341 for (uint8 i = 0; i < descriptor->length - 2; i++) 342 printf("%02x ", descriptor->data[i]); 343 printf("\n"); 344 } 345 346 347 void 348 DumpAudioControlCSInterfaceDescriptor(const usb_generic_descriptor* descriptor) 349 { 350 uint8 descriptorSubtype = descriptor->data[0]; 351 switch (descriptorSubtype) { 352 case USB_AUDIO_AC_HEADER: 353 DumpAudioCSInterfaceDescriptorHeader( 354 (usb_audiocontrol_header_descriptor*)descriptor); 355 break; 356 case USB_AUDIO_AC_INPUT_TERMINAL: 357 DumpAudioCSInterfaceDescriptorInputTerminal( 358 (usb_audio_input_terminal_descriptor*)descriptor); 359 break; 360 case USB_AUDIO_AC_OUTPUT_TERMINAL: 361 DumpAudioCSInterfaceDescriptorOutputTerminal( 362 (usb_audio_output_terminal_descriptor*)descriptor); 363 break; 364 case USB_AUDIO_AC_MIXER_UNIT: 365 DumpAudioCSInterfaceDescriptorMixerUnit( 366 (usb_audio_mixer_unit_descriptor*)descriptor); 367 break; 368 case USB_AUDIO_AC_SELECTOR_UNIT: 369 DumpAudioCSInterfaceDescriptorSelectorUnit( 370 (usb_audio_selector_unit_descriptor*)descriptor); 371 break; 372 case USB_AUDIO_AC_FEATURE_UNIT: 373 DumpAudioCSInterfaceDescriptorFeatureUnit( 374 (usb_audio_feature_unit_descriptor*)descriptor); 375 break; 376 case USB_AUDIO_AC_EXTENSION_UNIT: 377 DumpAudioCSInterfaceDescriptorAssociated(descriptor); 378 break; 379 default: 380 DumpDescriptorData(descriptor); 381 } 382 } 383 384 385 void 386 DumpGeneralASInterfaceDescriptor( 387 const usb_audio_streaming_interface_descriptor* descriptor) 388 { 389 printf(" Subtype ........... %u (AS_GENERAL)\n", 390 descriptor->descriptor_subtype); 391 printf(" Terminal link ..... %u\n", 392 descriptor->terminal_link); 393 printf(" Delay ............. %u\n", 394 descriptor->r1.delay); 395 printf(" Format tag ........ %u\n", 396 descriptor->r1.format_tag); 397 } 398 399 400 uint32 401 GetSamplingFrequency(const usb_audio_sampling_freq& freq) 402 { 403 return freq.bytes[0] | freq.bytes[1] << 8 | freq.bytes[2] << 16; 404 } 405 406 407 void 408 DumpSamplingFrequencies(uint8 type, const usb_audio_sampling_freq* freqs) 409 { 410 if (type > 0) { 411 printf(" Sampling Freq ..... "); 412 for (uint8 i = 0; i < type; i++) 413 printf("%" B_PRIu32 ", ", GetSamplingFrequency(freqs[i])); 414 printf("\n"); 415 } else { 416 printf(" Sampling Freq ..... %" B_PRIu32 " to %" 417 B_PRIu32 "\n", GetSamplingFrequency(freqs[0]), 418 GetSamplingFrequency(freqs[1])); 419 } 420 } 421 422 423 void 424 DumpASFormatTypeI(const usb_audio_format_descriptor* descriptor) 425 { 426 printf(" Subtype ........... %u (FORMAT_TYPE)\n", 427 descriptor->descriptor_subtype); 428 printf(" Format Type ....... %u (FORMAT_TYPE_I)\n", 429 descriptor->format_type); 430 printf(" Channels .......... %u\n", 431 descriptor->typeI.nr_channels); 432 printf(" Subframe size ..... %u\n", 433 descriptor->typeI.subframe_size); 434 printf(" Bit resolution .... %u\n", 435 descriptor->typeI.bit_resolution); 436 437 DumpSamplingFrequencies(descriptor->typeI.sam_freq_type, 438 descriptor->typeI.sam_freqs); 439 } 440 441 442 void 443 DumpASFormatTypeIII(const usb_audio_format_descriptor* descriptor) 444 { 445 printf(" Subtype ........... %u (FORMAT_TYPE)\n", 446 descriptor->descriptor_subtype); 447 printf(" Format Type ....... %u (FORMAT_TYPE_III)\n", 448 descriptor->format_type); 449 printf(" Channels .......... %u\n", 450 descriptor->typeIII.nr_channels); 451 printf(" Subframe size ..... %u\n", 452 descriptor->typeIII.subframe_size); 453 printf(" Bit resolution .... %u\n", 454 descriptor->typeIII.bit_resolution); 455 456 DumpSamplingFrequencies(descriptor->typeIII.sam_freq_type, 457 descriptor->typeIII.sam_freqs); 458 } 459 460 461 void 462 DumpASFormatTypeII(const usb_audio_format_descriptor* descriptor) 463 { 464 printf(" Subtype ........... %u (FORMAT_TYPE)\n", 465 descriptor->descriptor_subtype); 466 printf(" Format Type ....... %u (FORMAT_TYPE_II)\n", 467 descriptor->format_type); 468 printf(" Max Bitrate ....... %u\n", 469 descriptor->typeII.max_bit_rate); 470 printf(" Samples per Frame . %u\n", 471 descriptor->typeII.samples_per_frame); 472 473 DumpSamplingFrequencies(descriptor->typeII.sam_freq_type, 474 descriptor->typeII.sam_freqs); 475 } 476 477 478 void 479 DumpASFmtType(const usb_audio_format_descriptor* descriptor) 480 { 481 uint8 format = descriptor->format_type; 482 switch (format) { 483 case USB_AUDIO_FORMAT_TYPE_I: 484 DumpASFormatTypeI(descriptor); 485 break; 486 case USB_AUDIO_FORMAT_TYPE_II: 487 DumpASFormatTypeII(descriptor); 488 break; 489 case USB_AUDIO_FORMAT_TYPE_III: 490 DumpASFormatTypeIII(descriptor); 491 break; 492 default: 493 DumpDescriptorData((usb_generic_descriptor*)descriptor); 494 break; 495 } 496 } 497 498 499 void 500 DumpMPEGCapabilities(uint16 capabilities) 501 { 502 const char* MPEGCapabilities[] = { 503 "Layer I", 504 "Layer II", 505 "Layer III", 506 507 "MPEG-1 only", 508 "MPEG-1 dual-channel", 509 "MPEG-2 second stereo", 510 "MPEG-2 7.1 channel augumentation", 511 "Adaptive multi-channel predicion" 512 }; 513 514 uint16 mask = 1; 515 for (uint8 i = 0; 516 i < sizeof(MPEGCapabilities) / sizeof(MPEGCapabilities[0]); i++) { 517 if (capabilities & mask) 518 printf(" %s\n", MPEGCapabilities[i]); 519 mask <<= 1; 520 } 521 522 mask = 0x300; // bits 8 and 9 523 uint16 multilingualSupport = (capabilities & mask) >> 8; 524 switch (multilingualSupport) { 525 case 0: 526 printf(" No Multilingual support\n"); 527 break; 528 case 1: 529 printf(" Supported at Fs\n"); 530 break; 531 case 3: 532 printf(" Supported at Fs and 1/2Fs\n"); 533 break; 534 default: 535 break; 536 } 537 } 538 539 540 void 541 DumpMPEGFeatures(uint8 features) 542 { 543 uint8 mask = 0x30; // bits 4 and 5 544 uint8 dynRangeControl = (features & mask) >> 4; 545 switch (dynRangeControl) { 546 case 0: 547 printf(" Not supported\n"); 548 break; 549 case 1: 550 printf(" Supported, not scalable\n"); 551 break; 552 case 2: 553 printf(" Scalable, common boost, " 554 "cut scaling value\n"); 555 break; 556 case 3: 557 printf(" Scalable, separate boost, " 558 "cut scaling value\n"); 559 default: 560 break; 561 } 562 } 563 564 565 void 566 DumpASFmtSpecificMPEG(const usb_generic_descriptor* descriptor) 567 { 568 printf(" Subtype ........... %u (FORMAT_SPECIFIC)\n", 569 descriptor->data[0]); 570 printf(" Format Tag ........ %u\n", 571 *(uint16*)&descriptor->data[1]); 572 printf(" MPEG Capabilities . %u\n", 573 *(uint16*)&descriptor->data[3]); 574 DumpMPEGCapabilities(*(uint16*)&descriptor->data[3]); 575 printf(" MPEG Features ..... %u\n", 576 descriptor->data[5]); 577 DumpMPEGFeatures(descriptor->data[5]); 578 } 579 580 581 void 582 DumpAC_3Features(uint8 features) 583 { 584 const char* featuresStr[] = { 585 "RF mode", 586 "Line mode", 587 "Custom0 mode", 588 "Custom1 mode" 589 }; 590 591 uint8 mask = 1; 592 for (uint8 i = 0; i < sizeof(featuresStr) / sizeof(const char*); i++) { 593 if (features & mask) 594 printf(" %s\n", featuresStr[i]); 595 mask <<= 1; 596 } 597 598 mask = 0x30; // bits 4 and 5 599 uint8 dynRangeControl = (features & mask) >> 4; 600 switch (dynRangeControl) { 601 case 0: 602 printf(" Not supported\n"); 603 break; 604 case 1: 605 printf(" Supported, not scalable\n"); 606 break; 607 case 2: 608 printf(" Scalable, common boost, " 609 "cut scaling value\n"); 610 break; 611 case 3: 612 printf(" Scalable, separate boost, " 613 "cut scaling value\n"); 614 default: 615 break; 616 } 617 } 618 619 620 void 621 DumpASFmtSpecificAC_3(const usb_generic_descriptor* descriptor) 622 { 623 printf(" Subtype ........... %u (FORMAT_TYPE)\n", 624 descriptor->data[0]); 625 printf(" Format Tag ........ %u\n", 626 *(uint16*)&descriptor->data[1]); 627 printf(" BSID .............. %" B_PRIx32 "\n", 628 *(uint32*)&descriptor->data[2]); 629 printf(" AC3 Features ...... %u\n", 630 descriptor->data[6]); 631 DumpAC_3Features(descriptor->data[6]); 632 } 633 634 635 void 636 DumpASFmtSpecific(const usb_generic_descriptor* descriptor) 637 { 638 enum { 639 TYPE_II_UNDEFINED = 0x1000, 640 MPEG = 0x1001, 641 AC_3 = 0x1002 642 }; 643 644 uint16 formatTag = *(uint16*)&descriptor->data[1]; 645 switch (formatTag) { 646 case MPEG: 647 DumpASFmtSpecificMPEG(descriptor); 648 break; 649 case AC_3: 650 DumpASFmtSpecificAC_3(descriptor); 651 break; 652 default: 653 DumpDescriptorData(descriptor); 654 break; 655 } 656 } 657 658 659 void 660 DumpAudioStreamCSInterfaceDescriptor(const usb_generic_descriptor* descriptor) 661 { 662 uint8 subtype = descriptor->data[0]; 663 switch (subtype) { 664 case USB_AUDIO_AS_GENERAL: 665 DumpGeneralASInterfaceDescriptor( 666 (usb_audio_streaming_interface_descriptor*)descriptor); 667 break; 668 case USB_AUDIO_AS_FORMAT_TYPE: 669 DumpASFmtType( 670 (usb_audio_format_descriptor*)descriptor); 671 break; 672 case USB_AUDIO_AS_FORMAT_SPECIFIC: 673 DumpASFmtSpecific(descriptor); 674 break; 675 default: 676 DumpDescriptorData(descriptor); 677 break; 678 } 679 } 680 681 682 void 683 DumpAudioStreamCSEndpointDescriptor( 684 const usb_audio_streaming_endpoint_descriptor* descriptor) 685 { 686 printf(" Type .............. 0x%02x (CS_ENDPOINT)\n", 687 descriptor->descriptor_type); 688 printf(" Subtype ........... 0x%02x (EP_GENERAL)\n", 689 descriptor->descriptor_subtype); 690 printf(" Attributes ........ 0x%02x ", 691 descriptor->attributes); 692 693 const char* attributes[] = { 694 "Sampling Frequency", 695 "Pitch", 696 "", "", "", "", "", 697 "Max Packet Only" 698 }; 699 700 uint8 mask = 1; 701 for (uint8 i = 0; i < sizeof(attributes) / sizeof(attributes[0]); i++) { 702 if ((descriptor->attributes & mask) != 0) 703 printf("%s ", attributes[i]); 704 mask <<= 1; 705 } 706 printf("\n"); 707 708 const char* aUnits[] = { 709 "Undefined", 710 "Milliseconds", 711 "Decoded PCM samples", 712 "Unknown (%u)" 713 }; 714 715 const char* units = descriptor->lock_delay_units >= 4 716 ? aUnits[3] : aUnits[descriptor->lock_delay_units]; 717 718 printf(" Lock Delay Units .. %u (%s)\n", 719 descriptor->lock_delay_units, units); 720 printf(" Lock Delay ........ %u\n", 721 descriptor->lock_delay); 722 } 723 724 725 void 726 DumpMidiInterfaceHeaderDescriptor( 727 const usb_midi_interface_header_descriptor* descriptor) 728 { 729 printf(" Type .............. 0x%02x (CS_ENDPOINT)\n", 730 descriptor->descriptor_type); 731 printf(" Subtype ........... 0x%02x (MS_HEADER)\n", 732 descriptor->descriptor_subtype); 733 printf(" MSC Version ....... 0x%04x\n", 734 descriptor->ms_version); 735 printf(" Length ............ 0x%04x\n", 736 descriptor->total_length); 737 } 738 739 740 void 741 DumpMidiInJackDescriptor( 742 const usb_midi_in_jack_descriptor* descriptor) 743 { 744 printf(" Type .............. 0x%02x (CS_INTERFACE)\n", 745 descriptor->descriptor_type); 746 printf(" Subtype ........... 0x%02x (MIDI_IN_JACK)\n", 747 descriptor->descriptor_subtype); 748 printf(" Jack ID ........... 0x%02x\n", 749 descriptor->id); 750 // TODO can we get the string? 751 printf(" String ............ 0x%02x\n", 752 descriptor->string_descriptor); 753 754 switch (descriptor->type) { 755 case USB_MIDI_EMBEDDED_JACK: 756 printf(" Jack Type ......... Embedded\n"); 757 break; 758 case USB_MIDI_EXTERNAL_JACK: 759 printf(" Jack Type ......... External\n"); 760 break; 761 default: 762 printf(" Jack Type ......... 0x%02x (unknown)\n", 763 descriptor->type); 764 break; 765 } 766 } 767 768 769 void 770 DumpMidiOutJackDescriptor( 771 const usb_midi_out_jack_descriptor* descriptor) 772 { 773 printf(" Type .............. 0x%02x (CS_INTERFACE)\n", 774 descriptor->descriptor_type); 775 printf(" Subtype ........... 0x%02x (MIDI_OUT_JACK)\n", 776 descriptor->descriptor_subtype); 777 printf(" Jack ID ........... 0x%02x\n", 778 descriptor->id); 779 780 switch (descriptor->type) { 781 case USB_MIDI_EMBEDDED_JACK: 782 printf(" Jack Type ......... Embedded\n"); 783 break; 784 case USB_MIDI_EXTERNAL_JACK: 785 printf(" Jack Type ......... External\n"); 786 break; 787 default: 788 printf(" Jack Type ......... 0x%02x (unknown)\n", 789 descriptor->type); 790 break; 791 } 792 793 for (int i = 0; i < descriptor->inputs_count; i++) { 794 printf(" Pin %02d ............ (%d,%d)\n", i, 795 descriptor->input_source[i].source_id, 796 descriptor->input_source[i].source_pin); 797 } 798 } 799 800 801 void 802 DumpMidiStreamCSInterfaceDescriptor(const usb_generic_descriptor* descriptor) 803 { 804 uint8 subtype = descriptor->data[0]; 805 switch (subtype) { 806 case USB_MS_HEADER_DESCRIPTOR: 807 DumpMidiInterfaceHeaderDescriptor( 808 (usb_midi_interface_header_descriptor*)descriptor); 809 break; 810 case USB_MS_MIDI_IN_JACK_DESCRIPTOR: 811 DumpMidiInJackDescriptor( 812 (usb_midi_in_jack_descriptor*)descriptor); 813 break; 814 case USB_MS_MIDI_OUT_JACK_DESCRIPTOR: 815 DumpMidiOutJackDescriptor( 816 (usb_midi_out_jack_descriptor*)descriptor); 817 break; 818 case USB_MS_ELEMENT_DESCRIPTOR: 819 // TODO 820 DumpDescriptorData(descriptor); 821 break; 822 default: 823 DumpDescriptorData(descriptor); 824 break; 825 } 826 } 827 828 829 void 830 DumpMidiStreamCSEndpointDescriptor( 831 const usb_midi_endpoint_descriptor* descriptor) 832 { 833 printf(" Type .............. 0x%02x (CS_ENDPOINT)\n", 834 descriptor->descriptor_type); 835 printf(" Subtype ........... 0x%02x (MS_GENERAL)\n", 836 descriptor->descriptor_subtype); 837 printf(" Jacks ............. "); 838 839 for (int i = 0; i < descriptor->jacks_count; i++) 840 printf("%d, ", descriptor->jacks_id[i]); 841 842 printf("\n"); 843 } 844 845 846 void 847 DumpAudioStreamInterfaceDescriptor(const usb_interface_descriptor* descriptor) 848 { 849 printf(" Type .............. %u (INTERFACE)\n", 850 descriptor->descriptor_type); 851 printf(" Interface ........... %u\n", 852 descriptor->interface_number); 853 printf(" Alternate setting ... %u\n", 854 descriptor->alternate_setting); 855 printf(" Endpoints ........... %u\n", 856 descriptor->num_endpoints); 857 printf(" Interface class ..... %u (AUDIO)\n", 858 descriptor->interface_class); 859 printf(" Interface subclass .. %u (AUDIO_STREAMING)\n", 860 descriptor->interface_subclass); 861 printf(" Interface ........... %u\n", 862 descriptor->interface); 863 } 864 865 866 void 867 DumpAudioDescriptor(const usb_generic_descriptor* descriptor, int subclass) 868 { 869 const uint8 USB_AUDIO_INTERFACE = 0x04; 870 871 switch (subclass) { 872 case USB_AUDIO_INTERFACE_AUDIOCONTROL_SUBCLASS: 873 switch (descriptor->descriptor_type) { 874 case USB_AUDIO_CS_INTERFACE: 875 DumpAudioControlCSInterfaceDescriptor(descriptor); 876 break; 877 default: 878 DumpDescriptorData(descriptor); 879 break; 880 } 881 break; 882 case USB_AUDIO_INTERFACE_AUDIOSTREAMING_SUBCLASS: 883 switch (descriptor->descriptor_type) { 884 case USB_AUDIO_INTERFACE: 885 DumpAudioStreamInterfaceDescriptor( 886 (const usb_interface_descriptor*)descriptor); 887 break; 888 case USB_AUDIO_CS_INTERFACE: 889 DumpAudioStreamCSInterfaceDescriptor(descriptor); 890 break; 891 case USB_AUDIO_CS_ENDPOINT: 892 DumpAudioStreamCSEndpointDescriptor( 893 (const usb_audio_streaming_endpoint_descriptor*)descriptor); 894 break; 895 default: 896 DumpDescriptorData(descriptor); 897 break; 898 } 899 break; 900 case USB_AUDIO_INTERFACE_MIDISTREAMING_SUBCLASS: 901 switch (descriptor->descriptor_type) { 902 case USB_AUDIO_CS_INTERFACE: 903 DumpMidiStreamCSInterfaceDescriptor(descriptor); 904 break; 905 case USB_AUDIO_CS_ENDPOINT: 906 DumpMidiStreamCSEndpointDescriptor( 907 (const usb_midi_endpoint_descriptor*)descriptor); 908 break; 909 default: 910 DumpDescriptorData(descriptor); 911 break; 912 } 913 break; 914 default: 915 DumpDescriptorData(descriptor); 916 break; 917 } 918 } 919