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 301 uint8 channels = (descriptor->length - 6) / descriptor->r1.control_size; 302 for (uint8 i = 0; i < channels; i++) { 303 switch (descriptor->r1.control_size) { 304 case 1: 305 DumpBMAControl(i, descriptor->r1.bma_controls[i]); 306 break; 307 case 2: 308 DumpBMAControl(i, *(uint16*)&descriptor->r1.bma_controls[i * 2]); 309 break; 310 case 4: 311 DumpBMAControl(i, *(uint32*)&descriptor->r1.bma_controls[i * 4]); 312 break; 313 default: 314 printf(" BMA Channel %u ... ", i); 315 for (uint8 j = 0; j < descriptor->r1.control_size; j++) 316 printf("%02x ", descriptor->r1.bma_controls[i + j]); 317 break; 318 } 319 } 320 321 usb_generic_descriptor* generic = (usb_generic_descriptor*)descriptor; 322 printf(" Feature ........... %u\n", 323 (uint8)generic->data[descriptor->length - 3]); 324 } 325 326 327 void 328 DumpAudioCSInterfaceDescriptorAssociated( 329 const usb_generic_descriptor* descriptor) 330 { 331 printf(" Type .............. 0x%02x\n", 332 descriptor->descriptor_type); 333 printf(" Subtype ........... 0x%02x (Associate Interface)\n", 334 (uint8)descriptor->data[0]); 335 printf(" Interface ......... %u\n", 336 (uint8)descriptor->data[1]); 337 338 printf(" Data .............. "); 339 for (uint8 i = 0; i < descriptor->length - 2; i++) 340 printf("%02x ", descriptor->data[i]); 341 printf("\n"); 342 } 343 344 345 void 346 DumpAudioControlCSInterfaceDescriptor(const usb_generic_descriptor* descriptor) 347 { 348 uint8 descriptorSubtype = descriptor->data[0]; 349 switch (descriptorSubtype) { 350 case USB_AUDIO_AC_HEADER: 351 DumpAudioCSInterfaceDescriptorHeader( 352 (usb_audiocontrol_header_descriptor*)descriptor); 353 break; 354 case USB_AUDIO_AC_INPUT_TERMINAL: 355 DumpAudioCSInterfaceDescriptorInputTerminal( 356 (usb_audio_input_terminal_descriptor*)descriptor); 357 break; 358 case USB_AUDIO_AC_OUTPUT_TERMINAL: 359 DumpAudioCSInterfaceDescriptorOutputTerminal( 360 (usb_audio_output_terminal_descriptor*)descriptor); 361 break; 362 case USB_AUDIO_AC_MIXER_UNIT: 363 DumpAudioCSInterfaceDescriptorMixerUnit( 364 (usb_audio_mixer_unit_descriptor*)descriptor); 365 break; 366 case USB_AUDIO_AC_SELECTOR_UNIT: 367 DumpAudioCSInterfaceDescriptorSelectorUnit( 368 (usb_audio_selector_unit_descriptor*)descriptor); 369 break; 370 case USB_AUDIO_AC_FEATURE_UNIT: 371 DumpAudioCSInterfaceDescriptorFeatureUnit( 372 (usb_audio_feature_unit_descriptor*)descriptor); 373 break; 374 case USB_AUDIO_AC_EXTENSION_UNIT: 375 DumpAudioCSInterfaceDescriptorAssociated(descriptor); 376 break; 377 default: 378 DumpDescriptorData(descriptor); 379 } 380 } 381 382 383 void 384 DumpGeneralASInterfaceDescriptor( 385 const usb_audio_streaming_interface_descriptor* descriptor) 386 { 387 printf(" Subtype ........... %u (AS_GENERAL)\n", 388 descriptor->descriptor_subtype); 389 printf(" Terminal link ..... %u\n", 390 descriptor->terminal_link); 391 printf(" Delay ............. %u\n", 392 descriptor->r1.delay); 393 printf(" Format tag ........ %u\n", 394 descriptor->r1.format_tag); 395 } 396 397 398 uint32 399 GetSamplingFrequency(const usb_audio_sampling_freq& freq) 400 { 401 return freq.bytes[0] | freq.bytes[1] << 8 | freq.bytes[2] << 16; 402 } 403 404 405 void 406 DumpSamplingFrequencies(uint8 type, const usb_audio_sampling_freq* freqs) 407 { 408 if (type > 0) { 409 printf(" Sampling Freq ..... "); 410 for (uint8 i = 0; i < type; i++) 411 printf("%" B_PRIu32 ", ", GetSamplingFrequency(freqs[i])); 412 printf("\n"); 413 } else { 414 printf(" Sampling Freq ..... %" B_PRIu32 " to %" 415 B_PRIu32 "\n", GetSamplingFrequency(freqs[0]), 416 GetSamplingFrequency(freqs[1])); 417 } 418 } 419 420 421 void 422 DumpASFormatTypeI(const usb_audio_format_descriptor* descriptor) 423 { 424 printf(" Subtype ........... %u (FORMAT_TYPE)\n", 425 descriptor->descriptor_subtype); 426 printf(" Format Type ....... %u (FORMAT_TYPE_I)\n", 427 descriptor->format_type); 428 printf(" Channels .......... %u\n", 429 descriptor->typeI.nr_channels); 430 printf(" Subframe size ..... %u\n", 431 descriptor->typeI.subframe_size); 432 printf(" Bit resoultion .... %u\n", 433 descriptor->typeI.bit_resolution); 434 435 DumpSamplingFrequencies(descriptor->typeI.sam_freq_type, 436 descriptor->typeI.sam_freqs); 437 } 438 439 440 void 441 DumpASFormatTypeIII(const usb_audio_format_descriptor* descriptor) 442 { 443 printf(" Subtype ........... %u (FORMAT_TYPE)\n", 444 descriptor->descriptor_subtype); 445 printf(" Format Type ....... %u (FORMAT_TYPE_III)\n", 446 descriptor->format_type); 447 printf(" Channels .......... %u\n", 448 descriptor->typeIII.nr_channels); 449 printf(" Subframe size ..... %u\n", 450 descriptor->typeIII.subframe_size); 451 printf(" Bit resoultion .... %u\n", 452 descriptor->typeIII.bit_resolution); 453 454 DumpSamplingFrequencies(descriptor->typeIII.sam_freq_type, 455 descriptor->typeIII.sam_freqs); 456 } 457 458 459 void 460 DumpASFormatTypeII(const usb_audio_format_descriptor* descriptor) 461 { 462 printf(" Subtype ........... %u (FORMAT_TYPE)\n", 463 descriptor->descriptor_subtype); 464 printf(" Format Type ....... %u (FORMAT_TYPE_II)\n", 465 descriptor->format_type); 466 printf(" Max Bitrate ....... %u\n", 467 descriptor->typeII.max_bit_rate); 468 printf(" Samples per Frame . %u\n", 469 descriptor->typeII.samples_per_frame); 470 471 DumpSamplingFrequencies(descriptor->typeII.sam_freq_type, 472 descriptor->typeII.sam_freqs); 473 } 474 475 476 void 477 DumpASFmtType(const usb_audio_format_descriptor* descriptor) 478 { 479 uint8 format = descriptor->format_type; 480 switch (format) { 481 case USB_AUDIO_FORMAT_TYPE_I: 482 DumpASFormatTypeI(descriptor); 483 break; 484 case USB_AUDIO_FORMAT_TYPE_II: 485 DumpASFormatTypeII(descriptor); 486 break; 487 case USB_AUDIO_FORMAT_TYPE_III: 488 DumpASFormatTypeIII(descriptor); 489 break; 490 default: 491 DumpDescriptorData((usb_generic_descriptor*)descriptor); 492 break; 493 } 494 } 495 496 497 void 498 DumpMPEGCapabilities(uint16 capabilities) 499 { 500 const char* MPEGCapabilities[] = { 501 "Layer I", 502 "Layer II", 503 "Layer III", 504 505 "MPEG-1 only", 506 "MPEG-1 dual-channel", 507 "MPEG-2 second stereo", 508 "MPEG-2 7.1 channel augumentation", 509 "Adaptive multi-channel predicion" 510 }; 511 512 uint16 mask = 1; 513 for (uint8 i = 0; 514 i < sizeof(MPEGCapabilities) / sizeof(MPEGCapabilities[0]); i++) { 515 if (capabilities & mask) 516 printf(" %s\n", MPEGCapabilities[i]); 517 mask <<= 1; 518 } 519 520 mask = 0x300; // bits 8 and 9 521 uint16 multilingualSupport = (capabilities & mask) >> 8; 522 switch (multilingualSupport) { 523 case 0: 524 printf(" No Multilingual support\n"); 525 break; 526 case 1: 527 printf(" Supported at Fs\n"); 528 break; 529 case 3: 530 printf(" Supported at Fs and 1/2Fs\n"); 531 break; 532 default: 533 break; 534 } 535 } 536 537 538 void 539 DumpMPEGFeatures(uint8 features) 540 { 541 uint8 mask = 0x30; // bits 4 and 5 542 uint8 dynRangeControl = (features & mask) >> 4; 543 switch (dynRangeControl) { 544 case 0: 545 printf(" Not supported\n"); 546 break; 547 case 1: 548 printf(" Supported, not scalable\n"); 549 break; 550 case 2: 551 printf(" Scalable, common boost, " 552 "cut scaling value\n"); 553 break; 554 case 3: 555 printf(" Scalable, separate boost, " 556 "cut scaling value\n"); 557 default: 558 break; 559 } 560 } 561 562 563 void 564 DumpASFmtSpecificMPEG(const usb_generic_descriptor* descriptor) 565 { 566 printf(" Subtype ........... %u (FORMAT_SPECIFIC)\n", 567 descriptor->data[0]); 568 printf(" Format Tag ........ %u\n", 569 *(uint16*)&descriptor->data[1]); 570 printf(" MPEG Capabilities . %u\n", 571 *(uint16*)&descriptor->data[3]); 572 DumpMPEGCapabilities(*(uint16*)&descriptor->data[3]); 573 printf(" MPEG Features ..... %u\n", 574 descriptor->data[5]); 575 DumpMPEGFeatures(descriptor->data[5]); 576 } 577 578 579 void 580 DumpAC_3Features(uint8 features) 581 { 582 const char* featuresStr[] = { 583 "RF mode", 584 "Line mode", 585 "Custom0 mode", 586 "Custom1 mode" 587 }; 588 589 uint8 mask = 1; 590 for (uint8 i = 0; i < sizeof(featuresStr) / sizeof(const char*); i++) { 591 if (features & mask) 592 printf(" %s\n", featuresStr[i]); 593 mask <<= 1; 594 } 595 596 mask = 0x30; // bits 4 and 5 597 uint8 dynRangeControl = (features & mask) >> 4; 598 switch (dynRangeControl) { 599 case 0: 600 printf(" Not supported\n"); 601 break; 602 case 1: 603 printf(" Supported, not scalable\n"); 604 break; 605 case 2: 606 printf(" Scalable, common boost, " 607 "cut scaling value\n"); 608 break; 609 case 3: 610 printf(" Scalable, separate boost, " 611 "cut scaling value\n"); 612 default: 613 break; 614 } 615 } 616 617 618 void 619 DumpASFmtSpecificAC_3(const usb_generic_descriptor* descriptor) 620 { 621 printf(" Subtype ........... %u (FORMAT_TYPE)\n", 622 descriptor->data[0]); 623 printf(" Format Tag ........ %u\n", 624 *(uint16*)&descriptor->data[1]); 625 printf(" BSID .............. %" B_PRIx32 "\n", 626 *(uint32*)&descriptor->data[2]); 627 printf(" AC3 Features ...... %u\n", 628 descriptor->data[6]); 629 DumpAC_3Features(descriptor->data[6]); 630 } 631 632 633 void 634 DumpASFmtSpecific(const usb_generic_descriptor* descriptor) 635 { 636 enum { 637 TYPE_II_UNDEFINED = 0x1000, 638 MPEG = 0x1001, 639 AC_3 = 0x1002 640 }; 641 642 uint16 formatTag = *(uint16*)&descriptor->data[1]; 643 switch (formatTag) { 644 case MPEG: 645 DumpASFmtSpecificMPEG(descriptor); 646 break; 647 case AC_3: 648 DumpASFmtSpecificAC_3(descriptor); 649 break; 650 default: 651 DumpDescriptorData(descriptor); 652 break; 653 } 654 } 655 656 657 void 658 DumpAudioStreamCSInterfaceDescriptor(const usb_generic_descriptor* descriptor) 659 { 660 uint8 subtype = descriptor->data[0]; 661 switch (subtype) { 662 case USB_AUDIO_AS_GENERAL: 663 DumpGeneralASInterfaceDescriptor( 664 (usb_audio_streaming_interface_descriptor*)descriptor); 665 break; 666 case USB_AUDIO_AS_FORMAT_TYPE: 667 DumpASFmtType( 668 (usb_audio_format_descriptor*)descriptor); 669 break; 670 case USB_AUDIO_AS_FORMAT_SPECIFIC: 671 DumpASFmtSpecific(descriptor); 672 break; 673 default: 674 DumpDescriptorData(descriptor); 675 break; 676 } 677 } 678 679 680 void 681 DumpAudioStreamCSEndpointDescriptor( 682 const usb_audio_streaming_endpoint_descriptor* descriptor) 683 { 684 printf(" Type .............. 0x%02x (CS_ENDPOINT)\n", 685 descriptor->descriptor_type); 686 printf(" Subtype ........... 0x%02x (EP_GENERAL)\n", 687 descriptor->descriptor_subtype); 688 printf(" Attributes ........ 0x%02x ", 689 descriptor->attributes); 690 691 const char* attributes[] = { 692 "Sampling Frequency", 693 "Pitch", 694 "", "", "", "", "", 695 "Max Packet Only" 696 }; 697 698 uint8 mask = 1; 699 for (uint8 i = 0; i < sizeof(attributes) / sizeof(attributes[0]); i++) { 700 if ((descriptor->attributes & mask) != 0) 701 printf("%s ", attributes[i]); 702 mask <<= 1; 703 } 704 printf("\n"); 705 706 const char* aUnits[] = { 707 "Undefined", 708 "Milliseconds", 709 "Decoded PCM samples", 710 "Unknown (%u)" 711 }; 712 713 const char* units = descriptor->lock_delay_units >= 4 714 ? aUnits[3] : aUnits[descriptor->lock_delay_units]; 715 716 printf(" Lock Delay Units .. %u (%s)\n", 717 descriptor->lock_delay_units, units); 718 printf(" Lock Delay ........ %u\n", 719 descriptor->lock_delay); 720 } 721 722 723 void 724 DumpMidiInterfaceHeaderDescriptor( 725 const usb_midi_interface_header_descriptor* descriptor) 726 { 727 printf(" Type .............. 0x%02x (CS_ENDPOINT)\n", 728 descriptor->descriptor_type); 729 printf(" Subtype ........... 0x%02x (MS_HEADER)\n", 730 descriptor->descriptor_subtype); 731 printf(" MSC Version ....... 0x%04x\n", 732 descriptor->ms_version); 733 printf(" Length ............ 0x%04x\n", 734 descriptor->total_length); 735 } 736 737 738 void 739 DumpMidiInJackDescriptor( 740 const usb_midi_in_jack_descriptor* descriptor) 741 { 742 printf(" Type .............. 0x%02x (CS_INTERFACE)\n", 743 descriptor->descriptor_type); 744 printf(" Subtype ........... 0x%02x (MIDI_IN_JACK)\n", 745 descriptor->descriptor_subtype); 746 printf(" Jack ID ........... 0x%02x\n", 747 descriptor->id); 748 // TODO can we get the string? 749 printf(" String ............ 0x%02x\n", 750 descriptor->string_descriptor); 751 752 switch (descriptor->type) { 753 case USB_MIDI_EMBEDDED_JACK: 754 printf(" Jack Type ......... Embedded\n"); 755 break; 756 case USB_MIDI_EXTERNAL_JACK: 757 printf(" Jack Type ......... External\n"); 758 break; 759 default: 760 printf(" Jack Type ......... 0x%02x (unknown)\n", 761 descriptor->type); 762 break; 763 } 764 } 765 766 767 void 768 DumpMidiOutJackDescriptor( 769 const usb_midi_out_jack_descriptor* descriptor) 770 { 771 printf(" Type .............. 0x%02x (CS_INTERFACE)\n", 772 descriptor->descriptor_type); 773 printf(" Subtype ........... 0x%02x (MIDI_OUT_JACK)\n", 774 descriptor->descriptor_subtype); 775 printf(" Jack ID ........... 0x%02x\n", 776 descriptor->id); 777 778 switch (descriptor->type) { 779 case USB_MIDI_EMBEDDED_JACK: 780 printf(" Jack Type ......... Embedded\n"); 781 break; 782 case USB_MIDI_EXTERNAL_JACK: 783 printf(" Jack Type ......... External\n"); 784 break; 785 default: 786 printf(" Jack Type ......... 0x%02x (unknown)\n", 787 descriptor->type); 788 break; 789 } 790 791 for (int i = 0; i < descriptor->inputs_count; i++) { 792 printf(" Pin %02d ............ (%d,%d)\n", i, 793 descriptor->input_source[i].source_id, 794 descriptor->input_source[i].source_pin); 795 } 796 } 797 798 799 void 800 DumpMidiStreamCSInterfaceDescriptor(const usb_generic_descriptor* descriptor) 801 { 802 uint8 subtype = descriptor->data[0]; 803 switch (subtype) { 804 case USB_MS_HEADER_DESCRIPTOR: 805 DumpMidiInterfaceHeaderDescriptor( 806 (usb_midi_interface_header_descriptor*)descriptor); 807 break; 808 case USB_MS_MIDI_IN_JACK_DESCRIPTOR: 809 DumpMidiInJackDescriptor( 810 (usb_midi_in_jack_descriptor*)descriptor); 811 break; 812 case USB_MS_MIDI_OUT_JACK_DESCRIPTOR: 813 DumpMidiOutJackDescriptor( 814 (usb_midi_out_jack_descriptor*)descriptor); 815 break; 816 case USB_MS_ELEMENT_DESCRIPTOR: 817 // TODO 818 DumpDescriptorData(descriptor); 819 break; 820 default: 821 DumpDescriptorData(descriptor); 822 break; 823 } 824 } 825 826 827 void 828 DumpMidiStreamCSEndpointDescriptor( 829 const usb_midi_endpoint_descriptor* descriptor) 830 { 831 printf(" Type .............. 0x%02x (CS_ENDPOINT)\n", 832 descriptor->descriptor_type); 833 printf(" Subtype ........... 0x%02x (MS_GENERAL)\n", 834 descriptor->descriptor_subtype); 835 printf(" Jacks ............. "); 836 837 for (int i = 0; i < descriptor->jacks_count; i++) 838 printf("%d, ", descriptor->jacks_id[i]); 839 840 printf("\n"); 841 } 842 843 844 void 845 DumpAudioStreamInterfaceDescriptor(const usb_interface_descriptor* descriptor) 846 { 847 printf(" Type .............. %u (INTERFACE)\n", 848 descriptor->descriptor_type); 849 printf(" Interface ........... %u\n", 850 descriptor->interface_number); 851 printf(" Alternate setting ... %u\n", 852 descriptor->alternate_setting); 853 printf(" Endpoints ........... %u\n", 854 descriptor->num_endpoints); 855 printf(" Interface class ..... %u (AUDIO)\n", 856 descriptor->interface_class); 857 printf(" Interface subclass .. %u (AUDIO_STREAMING)\n", 858 descriptor->interface_subclass); 859 printf(" Interface ........... %u\n", 860 descriptor->interface); 861 } 862 863 864 void 865 DumpAudioDescriptor(const usb_generic_descriptor* descriptor, int subclass) 866 { 867 const uint8 USB_AUDIO_INTERFACE = 0x04; 868 869 switch (subclass) { 870 case USB_AUDIO_INTERFACE_AUDIOCONTROL_SUBCLASS: 871 switch (descriptor->descriptor_type) { 872 case USB_AUDIO_CS_INTERFACE: 873 DumpAudioControlCSInterfaceDescriptor(descriptor); 874 break; 875 default: 876 DumpDescriptorData(descriptor); 877 break; 878 } 879 break; 880 case USB_AUDIO_INTERFACE_AUDIOSTREAMING_SUBCLASS: 881 switch (descriptor->descriptor_type) { 882 case USB_AUDIO_INTERFACE: 883 DumpAudioStreamInterfaceDescriptor( 884 (const usb_interface_descriptor*)descriptor); 885 break; 886 case USB_AUDIO_CS_INTERFACE: 887 DumpAudioStreamCSInterfaceDescriptor(descriptor); 888 break; 889 case USB_AUDIO_CS_ENDPOINT: 890 DumpAudioStreamCSEndpointDescriptor( 891 (const usb_audio_streaming_endpoint_descriptor*)descriptor); 892 break; 893 default: 894 DumpDescriptorData(descriptor); 895 break; 896 } 897 break; 898 case USB_AUDIO_INTERFACE_MIDISTREAMING_SUBCLASS: 899 switch (descriptor->descriptor_type) { 900 case USB_AUDIO_CS_INTERFACE: 901 DumpMidiStreamCSInterfaceDescriptor(descriptor); 902 break; 903 case USB_AUDIO_CS_ENDPOINT: 904 DumpMidiStreamCSEndpointDescriptor( 905 (const usb_midi_endpoint_descriptor*)descriptor); 906 break; 907 default: 908 DumpDescriptorData(descriptor); 909 break; 910 } 911 break; 912 default: 913 DumpDescriptorData(descriptor); 914 break; 915 } 916 } 917