418 | | switch (descriptor->descriptor_type) { |
419 | | case USB_AUDIO_CS_INTERFACE: |
420 | | DumpAudioCSInterfaceDescriptor(descriptor); |
| 419 | printf(" Type .............. %u (CS_INTERFACE)\n", |
| 420 | descriptor->descriptor_type); |
| 421 | printf(" Subtype ........... %u (AS_GENERAL)\n", |
| 422 | descriptor->descriptor_subtype); |
| 423 | printf(" Terminal link ..... %u\n", |
| 424 | descriptor->terminal_link); |
| 425 | printf(" Delay ............. %u\n", |
| 426 | descriptor->r1.delay); |
| 427 | printf(" Format tag ........ %u\n", |
| 428 | descriptor->r1.format_tag); |
| 429 | } |
| 430 | |
| 431 | |
| 432 | void |
| 433 | DumpASFormatTypeI(const usb_audio_format_descriptor* descriptor) |
| 434 | { |
| 435 | printf(" Type .............. %u (CS_INTERFACE)\n", |
| 436 | descriptor->descriptor_type); |
| 437 | printf(" Subtype ........... %u (FORMAT_TYPE)\n", |
| 438 | descriptor->descriptor_subtype); |
| 439 | printf(" Format Type ....... %u (FORMAT_TYPE_I)\n", |
| 440 | descriptor->format_type); |
| 441 | printf(" Channels .......... %u\n", |
| 442 | descriptor->typeI.nr_channels); |
| 443 | printf(" Subframe size ..... %u\n", |
| 444 | descriptor->typeI.subframe_size); |
| 445 | printf(" Bit resoultion .... %u\n", |
| 446 | descriptor->typeI.bit_resolution); |
| 447 | |
| 448 | uint8 samFreqType = descriptor->typeI.sam_freq_type; |
| 449 | printf(" Sample Freq Type .. %u\n", |
| 450 | samFreqType); |
| 451 | |
| 452 | if (samFreqType == 0) { |
| 453 | printf(" Lower Sample Freq . %u\n", |
| 454 | descriptor->typeI.sam_freqs[0].bytes[0] |
| 455 | | (descriptor->typeI.sam_freqs[0].bytes[1] << 8) |
| 456 | | (descriptor->typeI.sam_freqs[0].bytes[2] << 16)); |
| 457 | printf(" Upper Sample Freq . %u\n", |
| 458 | descriptor->typeI.sam_freqs[1].bytes[0] |
| 459 | | (descriptor->typeI.sam_freqs[1].bytes[1] << 8) |
| 460 | | (descriptor->typeI.sam_freqs[1].bytes[2] << 16)); |
| 461 | } else { |
| 462 | for (uint8 i = 0; i < samFreqType; i++) |
| 463 | printf(" Sample Freq %u .... %u\n", |
| 464 | i + 1, descriptor->typeI.sam_freqs[i].bytes[0] |
| 465 | | (descriptor->typeI.sam_freqs[i].bytes[1] << 8) |
| 466 | | (descriptor->typeI.sam_freqs[i].bytes[2] << 16)); |
| 467 | } |
| 468 | } |
| 469 | |
| 470 | |
| 471 | void |
| 472 | DumpASFormatTypeIII(const usb_audio_format_descriptor* descriptor) |
| 473 | { |
| 474 | printf(" Type .............. %u (CS_INTERFACE)\n", |
| 475 | descriptor->descriptor_type); |
| 476 | printf(" Subtype ........... %u (FORMAT_TYPE)\n", |
| 477 | descriptor->descriptor_subtype); |
| 478 | printf(" Format Type ....... %u (FORMAT_TYPE_III)\n", |
| 479 | descriptor->format_type); |
| 480 | printf(" Channels .......... %u\n", |
| 481 | descriptor->typeIII.nr_channels); |
| 482 | printf(" Subframe size ..... %u\n", |
| 483 | descriptor->typeIII.subframe_size); |
| 484 | printf(" Bit resoultion .... %u\n", |
| 485 | descriptor->typeIII.bit_resolution); |
| 486 | |
| 487 | uint8 samFreqType = descriptor->typeIII.sam_freq_type; |
| 488 | printf(" Sample Freq Type .. %u\n", |
| 489 | samFreqType); |
| 490 | |
| 491 | if (samFreqType == 0) { |
| 492 | printf(" Lower Sample Freq . %u\n", |
| 493 | descriptor->typeIII.sam_freqs[0].bytes[0] |
| 494 | | (descriptor->typeIII.sam_freqs[0].bytes[1] << 8) |
| 495 | | (descriptor->typeIII.sam_freqs[0].bytes[2] << 16)); |
| 496 | printf(" Upper Sample Freq . %u\n", |
| 497 | descriptor->typeIII.sam_freqs[1].bytes[0] |
| 498 | | (descriptor->typeIII.sam_freqs[1].bytes[1] << 8) |
| 499 | | (descriptor->typeIII.sam_freqs[1].bytes[2] << 16)); |
| 500 | } else { |
| 501 | for (uint8 i = 0; i < samFreqType; i++) |
| 502 | printf(" Sample Freq %u .... %u\n", |
| 503 | i + 1, descriptor->typeIII.sam_freqs[i].bytes[0] |
| 504 | | (descriptor->typeIII.sam_freqs[i].bytes[1] << 8) |
| 505 | | (descriptor->typeIII.sam_freqs[i].bytes[2] << 16)); |
| 506 | } |
| 507 | } |
| 508 | |
| 509 | |
| 510 | void |
| 511 | DumpASFormatTypeII(const usb_audio_format_descriptor* descriptor) |
| 512 | { |
| 513 | printf(" Type .............. %u (CS_INTERFACE)\n", |
| 514 | descriptor->descriptor_type); |
| 515 | printf(" Subtype ........... %u (FORMAT_TYPE)\n", |
| 516 | descriptor->descriptor_subtype); |
| 517 | printf(" Format Type ....... %u (FORMAT_TYPE_II)\n", |
| 518 | descriptor->format_type); |
| 519 | printf(" Max Bitrate ....... %u\n", |
| 520 | descriptor->typeII.max_bit_rate); |
| 521 | printf(" Samples per Frame . %u\n", |
| 522 | descriptor->typeII.samples_per_frame); |
| 523 | |
| 524 | uint8 samFreqType = descriptor->typeII.sam_freq_type; |
| 525 | printf(" Sample Freq type .. %u\n", |
| 526 | samFreqType); |
| 527 | |
| 528 | if (samFreqType == 0) { |
| 529 | printf(" Lower Sample Freq . %u\n", |
| 530 | descriptor->typeII.sam_freqs[0].bytes[0] |
| 531 | | (descriptor->typeII.sam_freqs[0].bytes[1] << 8) |
| 532 | | (descriptor->typeII.sam_freqs[0].bytes[2] << 16)); |
| 533 | printf(" Upper Sample Freq . %u\n", |
| 534 | descriptor->typeII.sam_freqs[1].bytes[0] |
| 535 | | (descriptor->typeII.sam_freqs[1].bytes[1] << 8) |
| 536 | | (descriptor->typeII.sam_freqs[1].bytes[2] << 16)); |
| 537 | } else { |
| 538 | for (uint8 i = 0; i < samFreqType; i++) |
| 539 | printf(" Sample Freq %u .... %u\n", |
| 540 | i + 1, descriptor->typeII.sam_freqs[i].bytes[0] |
| 541 | | (descriptor->typeII.sam_freqs[i].bytes[1] << 8) |
| 542 | | (descriptor->typeII.sam_freqs[i].bytes[2] << 16)); |
| 543 | } |
| 544 | } |
| 545 | |
| 546 | |
| 547 | void |
| 548 | DumpASFmtType(const usb_audio_format_descriptor* descriptor) |
| 549 | { |
| 550 | uint8 format = descriptor->format_type; |
| 551 | switch (format) { |
| 552 | case USB_AUDIO_FORMAT_TYPE_I: |
| 553 | DumpASFormatTypeI(descriptor); |
| 554 | break; |
| 555 | case USB_AUDIO_FORMAT_TYPE_II: |
| 556 | DumpASFormatTypeII(descriptor); |
| 557 | break; |
| 558 | case USB_AUDIO_FORMAT_TYPE_III: |
| 559 | DumpASFormatTypeIII(descriptor); |
| 560 | break; |
| 561 | default: |
| 562 | DumpDescriptorData((usb_generic_descriptor*)descriptor); |
| 563 | } |
| 564 | } |
| 565 | |
| 566 | |
| 567 | void |
| 568 | DumpMPEGCapabilities(uint16 capabilities) |
| 569 | { |
| 570 | const char* MPEGCapabilities[] = { |
| 571 | "Layer I", |
| 572 | "Layer II", |
| 573 | "Layer III", |
| 574 | |
| 575 | "MPEG-1 only", |
| 576 | "MPEG-1 dual-channel", |
| 577 | "MPEG-2 second stereo", |
| 578 | "MPEG-2 7.1 channel augumentation", |
| 579 | "Adaptive multi-channel predicion" |
| 580 | }; |
| 581 | |
| 582 | uint16 mask = 1; |
| 583 | for (uint8 i = 0; i < sizeof(MPEGCapabilities) / sizeof(char*); i++) { |
| 584 | if (capabilities & mask) |
| 585 | printf(" %s\n", MPEGCapabilities[i]); |
| 586 | mask <<= 1; |
| 587 | } |
| 588 | |
| 589 | mask = 0x300; // bits 8 and 9 |
| 590 | uint16 multilingualSupport = (capabilities & mask) >> 8; |
| 591 | switch (multilingualSupport) { |
| 592 | case 0: |
| 593 | printf(" No Multilingual support\n"); |
| 594 | break; |
| 595 | case 1: |
| 596 | printf(" Supported at Fs\n"); |
| 597 | break; |
| 598 | case 3: |
| 599 | printf(" Supported at Fs and 1/2Fs\n"); |
| 600 | |
| 601 | } |
| 602 | } |
| 603 | |
| 604 | |
| 605 | void |
| 606 | DumpMPEGFeatures(uint8 features) |
| 607 | { |
| 608 | uint8 mask = 0x30; // bits 4 and 5 |
| 609 | uint8 dynRangeControl = (features & mask) >> 4; |
| 610 | switch (dynRangeControl) { |
| 611 | case 0: |
| 612 | printf(" Not supported\n"); |
| 613 | break; |
| 614 | case 1: |
| 615 | printf(" Supported, not scaleable\n"); |
| 616 | break; |
| 617 | case 2: |
| 618 | printf(" Scaleable, common boost, " |
| 619 | "cut scaling value\n"); |
| 620 | break; |
| 621 | case 3: |
| 622 | printf(" Scaleable, separate boost, " |
| 623 | "cut scaling value\n"); |
| 624 | |
| 625 | } |
| 626 | } |
| 627 | |
| 628 | |
| 629 | void |
| 630 | DumpASFmtSpecificMPEG(const usb_generic_descriptor* descriptor) |
| 631 | { |
| 632 | printf(" Type .............. %u (CS_INTERFACE)\n", |
| 633 | descriptor->descriptor_type); |
| 634 | printf(" Subtype ........... %u (FORMAT_SPECIFIC)\n", |
| 635 | descriptor->data[0]); |
| 636 | printf(" Format Tag ........ %u\n", |
| 637 | *(uint16*)&descriptor->data[1]); |
| 638 | printf(" MPEG Capabilities . %u\n", |
| 639 | *(uint16*)&descriptor->data[3]); |
| 640 | DumpMPEGCapabilities(*(uint16*)&descriptor->data[3]); |
| 641 | printf(" MPEG Features ..... %u\n", |
| 642 | descriptor->data[5]); |
| 643 | DumpMPEGFeatures(descriptor->data[5]); |
| 644 | } |
| 645 | |
| 646 | |
| 647 | void |
| 648 | DumpAC_3Features(uint8 features) |
| 649 | { |
| 650 | const char* featuresStr[] = { |
| 651 | "RF mode", |
| 652 | "Line mode", |
| 653 | "Custom0 mode", |
| 654 | "Custom1 mode", |
| 655 | }; |
| 656 | |
| 657 | uint8 mask = 1; |
| 658 | for (uint8 i = 0; i < sizeof(featuresStr) / sizeof(const char*); i++) { |
| 659 | if (features & mask) |
| 660 | printf(" %s\n", featuresStr[i]); |
| 661 | mask <<= 1; |
| 662 | } |
| 663 | |
| 664 | mask = 0x30; // bits 4 and 5 |
| 665 | uint8 dynRangeControl = (features & mask) >> 4; |
| 666 | switch (dynRangeControl) { |
| 667 | case 0: |
| 668 | printf(" Not supported\n"); |
| 669 | break; |
| 670 | case 1: |
| 671 | printf(" Supported, not scaleable\n"); |
| 672 | break; |
| 673 | case 2: |
| 674 | printf(" Scaleable, common boost, " |
| 675 | "cut scaling value\n"); |
| 676 | case 3: |
| 677 | printf(" Scaleable, separate boost, " |
| 678 | "cut scaling value\n"); |
| 679 | |
| 680 | } |
| 681 | } |
| 682 | |
| 683 | |
| 684 | void |
| 685 | DumpASFmtSpecificAC_3(const usb_generic_descriptor* descriptor) |
| 686 | { |
| 687 | printf(" Type .............. %u (CS_INTERFACE)\n", |
| 688 | descriptor->descriptor_type); |
| 689 | printf(" Subtype ........... %u (FORMAT_TYPE)\n", |
| 690 | descriptor->data[0]); |
| 691 | printf(" Format Tag ........ %u\n", |
| 692 | *(uint16*)&descriptor->data[1]); |
| 693 | printf(" BSID .............. %lx\n", |
| 694 | *(uint32*)&descriptor->data[2]); |
| 695 | printf(" AC3 Features ...... %u\n", |
| 696 | descriptor->data[6]); |
| 697 | DumpAC_3Features(descriptor->data[6]); |
| 698 | } |
| 699 | |
| 700 | |
| 701 | void |
| 702 | DumpASFmtSpecific(const usb_generic_descriptor* descriptor) |
| 703 | { |
| 704 | enum { |
| 705 | TYPE_II_UNDEFINED = 0x1000, |
| 706 | MPEG = 0x1001, |
| 707 | AC_3 = 0x1002 |
| 708 | }; |
| 709 | |
| 710 | uint16 formatTag = *(uint16*)&descriptor->data[1]; |
| 711 | switch (formatTag) { |
| 712 | case MPEG: |
| 713 | DumpASFmtSpecificMPEG(descriptor); |
| 714 | break; |
| 715 | case AC_3: |
| 716 | DumpASFmtSpecificAC_3(descriptor); |
429 | | DumpDescriptor(const usb_generic_descriptor* descriptor, int classNum) |
| 725 | DumpAudioStreamCSInterfaceDescriptor(const usb_generic_descriptor* descriptor) |
| 726 | { |
| 727 | uint8 subtype = descriptor->data[0]; |
| 728 | switch (subtype) { |
| 729 | case USB_AUDIO_AS_GENERAL: |
| 730 | DumpGeneralASInterfaceDescriptor( |
| 731 | (usb_audio_streaming_interface_descriptor*)descriptor); |
| 732 | break; |
| 733 | case USB_AUDIO_AS_FORMAT_TYPE: |
| 734 | DumpASFmtType( |
| 735 | (usb_audio_format_descriptor*)descriptor); |
| 736 | break; |
| 737 | case USB_AUDIO_AS_FORMAT_SPECIFIC: |
| 738 | DumpASFmtSpecific(descriptor); |
| 739 | break; |
| 740 | default: |
| 741 | DumpDescriptorData(descriptor); |
| 742 | } |
| 743 | } |
| 744 | |
| 745 | |
| 746 | void |
| 747 | DumpAudioStreamInterfaceDescriptor(const usb_generic_descriptor* descriptor) |
| 748 | { |
| 749 | printf(" Type .............. %u (INTERFACE)\n", |
| 750 | descriptor->descriptor_type); |
| 751 | printf(" Interface ........... %u\n", |
| 752 | descriptor->data[0]); |
| 753 | printf(" Alternate setting ... %u\n", |
| 754 | descriptor->data[1]); |
| 755 | printf(" Endpoints ........... %u\n", |
| 756 | descriptor->data[2]); |
| 757 | printf(" Interface class ..... %u (AUDIO)\n", |
| 758 | descriptor->data[3]); |
| 759 | printf(" Interface subclass .. %u (AUDIO_STREAMING)\n", |
| 760 | descriptor->data[4]); |
| 761 | printf(" Interface ........... %u\n", |
| 762 | descriptor->data[6]); |
| 763 | } |
| 764 | |
| 765 | |
| 766 | void |
| 767 | DumpAudioDescriptor(const usb_generic_descriptor* descriptor, int subclass) |
| 768 | { |
| 769 | const uint8 USB_AUDIO_INTERFACE = 0x04; |
| 770 | |
| 771 | switch (subclass) { |
| 772 | case USB_AUDIO_INTERFACE_AUDIOCONTROL_SUBCLASS: |
| 773 | switch (descriptor->descriptor_type) { |
| 774 | case USB_AUDIO_CS_INTERFACE: |
| 775 | DumpAudioControlCSInterfaceDescriptor(descriptor); |
| 776 | break; |
| 777 | default: |
| 778 | DumpDescriptorData(descriptor); |
| 779 | } |
| 780 | break; |
| 781 | case USB_AUDIO_INTERFACE_AUDIOSTREAMING_SUBCLASS: |
| 782 | switch (descriptor->descriptor_type) { |
| 783 | case USB_AUDIO_INTERFACE: |
| 784 | DumpAudioStreamInterfaceDescriptor(descriptor); |
| 785 | break; |
| 786 | case USB_AUDIO_CS_INTERFACE: |
| 787 | DumpAudioStreamCSInterfaceDescriptor(descriptor); |
| 788 | break; |
| 789 | default: |
| 790 | DumpDescriptorData(descriptor); |
| 791 | } |
| 792 | break; |
| 793 | } |
| 794 | } |
| 795 | |
| 796 | |
| 797 | void |
| 798 | DumpDescriptor(const usb_generic_descriptor* descriptor, |
| 799 | int classNum, int subclass) |