Sample Code

Windows Driver Samples/ USBView sample application/ C++/ dispaud.c/

/*++

Copyright (c) 1997-2008 Microsoft Corporation

Module Name:

DISPAUD.C

Abstract:

This source file contains routines which update the edit control
to display information about USB Audio descriptors.

Environment:

user mode

Revision History:

03-07-1998 : created

--*/

/*****************************************************************************
 I N C L U D E S
*****************************************************************************/

#include "uvcview.h"

/*****************************************************************************
 G L O B A L S    P R I V A T E    T O    T H I S    F I L E
*****************************************************************************/

//
// USB Device Class Definition for Terminal Types  0.9 Draft Revision
//
STRINGLIST slAudioTerminalTypes [] =
{
    //
    // 2.1 USB Terminal Types
    //
    {0x0100, "USB Undefined",       ""},
    {0x0101, "USB streaming",       ""},
    {0x01FF, "USB vendor specific", ""},
    //
    // 2.2 Input Terminal Types
    //
    {0x0200, "Input Undefined",             ""},
    {0x0201, "Microphone",                  ""},
    {0x0202, "Desktop microphone",          ""},
    {0x0203, "Personal microphone",         ""},
    {0x0204, "Omni-directional microphone", ""},
    {0x0205, "Microphone array",            ""},
    {0x0206, "Processing microphone array", ""},
    //
    // 2.3 Output Terminal Types
    //
    {0x0300, "Output Undefined",              ""},
    {0x0301, "Speaker",                       ""},
    {0x0302, "Headphones",                    ""},
    {0x0303, "Head Mounted Display Audio",    ""},
    {0x0304, "Desktop speaker",               ""},
    {0x0305, "Room speaker",                  ""},
    {0x0306, "Communication speaker",         ""},
    {0x0307, "Low frequency effects speaker", ""},
    //
    // 2.4 Bi-directional Terminal Types
    //
    {0x0400, "Bi-directional Undefined",        ""},
    {0x0401, "Handset",                         ""},
    {0x0402, "Headset",                         ""},
    {0x0403, "Speakerphone, no echo reduction", ""},
    {0x0404, "Echo-suppressing speakerphone",   ""},
    {0x0405, "Echo-canceling speakerphone",     ""},
    //
    // 2.5 Telephony Terminal Types
    //
    {0x0500, "Telephony Undefined", ""},
    {0x0501, "Phone line",          ""},
    {0x0502, "Telephone",           ""},
    {0x0503, "Down Line Phone",     ""},
    //
    // 2.6 External Terminal Types
    //
    {0x0600, "External Undefined",        ""},
    {0x0601, "Analog connector",          ""},
    {0x0602, "Digital audio interface",   ""},
    {0x0603, "Line connector",            ""},
    {0x0604, "Legacy audio connector",    ""},
    {0x0605, "S/PDIF interface",          ""},
    {0x0606, "1394 DA stream",            ""},
    {0x0607, "1394 DV stream soundtrack", ""},
    //
    // Embedded Function Terminal Types
    //
    {0x0700, "Embedded Undefined",             ""},
    {0x0701, "Level Calibration Noise Source", ""},
    {0x0702, "Equalization Noise",             ""},
    {0x0703, "CD player",                      ""},
    {0x0704, "DAT",                            ""},
    {0x0705, "DCC",                            ""},
    {0x0706, "MiniDisk",                       ""},
    {0x0707, "Analog Tape",                    ""},
    {0x0708, "Phonograph",                     ""},
    {0x0709, "VCR Audio",                      ""},
    {0x070A, "Video Disc Audio",               ""},
    {0x070B, "DVD Audio",                      ""},
    {0x070C, "TV Tuner Audio",                 ""},
    {0x070D, "Satellite Receiver Audio",       ""},
    {0x070E, "Cable Tuner Audio",              ""},
    {0x070F, "DSS Audio",                      ""},
    {0x0710, "Radio Receiver",                 ""},
    {0x0711, "Radio Transmitter",              ""},
    {0x0712, "Multi-track Recorder",           ""},
    {0x0713, "Synthesizer",                    ""},
};
STRINGLIST slAudioFormatTypes [] =
{
    //
    // A.1.1 Audio Data Format Type I Codes
    //
    {0x0000, "TYPE_I_UNDEFINED", ""},
    {0x0001, "PCM",              ""},
    {0x0002, "PCM8",             ""},
    {0x0003, "IEEE_FLOAT",       ""},
    {0x0004, "ALAW",             ""},
    {0x0005, "MULAW",            ""},
    //
    // A.1.2 Audio Data Format Type II Codes
    //
    {0x1000, "TYPE_II_UNDEFINED", ""},
    {0x1001, "MPEG",              ""},
    {0x1002, "AC-3",              ""},
    //
    // A.1.3 Audio Data Format Type III Codes
    //
    {0x2000, "TYPE_III_UNDEFINED",                              ""},
    {0x2001, "IEC1937_AC-3",                                    ""},
    {0x2002, "IEC1937_MPEG-1_Layer1",                           ""},
    {0x2003, "IEC1937_MPEG-1_Layer2/3 or IEC1937_MPEG-2_NOEXT", ""},
    {0x2004, "IEC1937_MPEG-2_EXT",                              ""},
    {0x2005, "IEC1937_MPEG-2_Layer1_LS",                        ""},
    {0x2006, "IEC1937_MPEG-2_Layer2/3_LS",                      ""},
};



/*****************************************************************************
 L O C A L    F U N C T I O N    P R O T O T Y P E S
*****************************************************************************/

BOOL
DisplayACHeader (
    PUSB_AUDIO_AC_INTERFACE_HEADER_DESCRIPTOR HeaderDesc
);

BOOL
DisplayACInputTerminal (
    PUSB_AUDIO_INPUT_TERMINAL_DESCRIPTOR ITDesc
);

BOOL
DisplayACOutputTerminal (
    PUSB_AUDIO_OUTPUT_TERMINAL_DESCRIPTOR OTDesc
);

BOOL
DisplayACMixerUnit (
    PUSB_AUDIO_MIXER_UNIT_DESCRIPTOR MixerDesc
);

BOOL
DisplayACSelectorUnit (
    PUSB_AUDIO_SELECTOR_UNIT_DESCRIPTOR SelectorDesc
);

BOOL
DisplayACFeatureUnit (
    PUSB_AUDIO_FEATURE_UNIT_DESCRIPTOR FeatureDesc
);

BOOL
DisplayACProcessingUnit (
    PUSB_AUDIO_PROCESSING_UNIT_DESCRIPTOR ProcessingDesc
);

BOOL
DisplayACExtensionUnit (
    PUSB_AUDIO_EXTENSION_UNIT_DESCRIPTOR ExtensionDesc
);

BOOL
DisplayASGeneral (
    PUSB_AUDIO_GENERAL_DESCRIPTOR GeneralDesc
);

BOOL
DisplayCSEndpoint (
    PUSB_AUDIO_ENDPOINT_DESCRIPTOR EndpointDesc
);

BOOL
DisplayASFormatType (
    PUSB_AUDIO_COMMON_FORMAT_DESCRIPTOR FormatDesc
);

BOOL
DisplayASFormatSpecific (
    PUSB_AUDIO_COMMON_DESCRIPTOR CommonDesc
);

VOID
DisplayBytes (
    PUCHAR Data,
    USHORT Len
);

/*****************************************************************************
 L O C A L    F U N C T I O N S
*****************************************************************************/

/*****************************************************************************

 DisplayAudioDescriptor()

 CommonDesc - An Audio Class Descriptor

 bInterfaceSubClass - The SubClass of the Interface containing the descriptor

*****************************************************************************/

BOOL
DisplayAudioDescriptor (
    PUSB_AUDIO_COMMON_DESCRIPTOR CommonDesc,
    UCHAR                        bInterfaceSubClass
)
{
    switch (CommonDesc->bDescriptorType)
    {
        case USB_AUDIO_CS_INTERFACE:
            switch (bInterfaceSubClass)
            {
                case USB_AUDIO_SUBCLASS_AUDIOCONTROL:
                    switch (CommonDesc->bDescriptorSubtype)
                    {
                        case USB_AUDIO_AC_HEADER:
                            return DisplayACHeader((PUSB_AUDIO_AC_INTERFACE_HEADER_DESCRIPTOR)CommonDesc);

                        case USB_AUDIO_AC_INPUT_TERMINAL:
                            return DisplayACInputTerminal((PUSB_AUDIO_INPUT_TERMINAL_DESCRIPTOR)CommonDesc);

                        case USB_AUDIO_AC_OUTPUT_TERMINAL:
                            return DisplayACOutputTerminal((PUSB_AUDIO_OUTPUT_TERMINAL_DESCRIPTOR)CommonDesc);

                        case USB_AUDIO_AC_MIXER_UNIT:
                            return DisplayACMixerUnit((PUSB_AUDIO_MIXER_UNIT_DESCRIPTOR)CommonDesc);

                        case USB_AUDIO_AC_SELECTOR_UNIT:
                            return DisplayACSelectorUnit((PUSB_AUDIO_SELECTOR_UNIT_DESCRIPTOR)CommonDesc);

                        case USB_AUDIO_AC_FEATURE_UNIT:
                            return DisplayACFeatureUnit((PUSB_AUDIO_FEATURE_UNIT_DESCRIPTOR)CommonDesc);

                        case USB_AUDIO_AC_PROCESSING_UNIT:
                            return DisplayACProcessingUnit((PUSB_AUDIO_PROCESSING_UNIT_DESCRIPTOR)CommonDesc);

                        case USB_AUDIO_AC_EXTENSION_UNIT:
                            return DisplayACExtensionUnit((PUSB_AUDIO_EXTENSION_UNIT_DESCRIPTOR)CommonDesc);

                        default:
                            break;
                    }
                    break;

                case USB_AUDIO_SUBCLASS_AUDIOSTREAMING:
                    switch (CommonDesc->bDescriptorSubtype)
                    {
                        case USB_AUDIO_AS_GENERAL:
                            return DisplayASGeneral((PUSB_AUDIO_GENERAL_DESCRIPTOR)CommonDesc);

                        case USB_AUDIO_AS_FORMAT_TYPE:
                            return DisplayASFormatType((PUSB_AUDIO_COMMON_FORMAT_DESCRIPTOR)CommonDesc);
                            break;

                        case USB_AUDIO_AS_FORMAT_SPECIFIC:
                            return DisplayASFormatSpecific(CommonDesc);

                        default:
                            break;
                    }
                    break;

                default:
                    break;
            }
            break;

        case USB_AUDIO_CS_ENDPOINT:
            return DisplayCSEndpoint((PUSB_AUDIO_ENDPOINT_DESCRIPTOR)CommonDesc);

        default:
            break;
    }

    return FALSE;
}


/*****************************************************************************

 DisplayACHeader()

*****************************************************************************/

BOOL
DisplayACHeader (
    PUSB_AUDIO_AC_INTERFACE_HEADER_DESCRIPTOR HeaderDesc
)
{
    UINT i = 0;

    if (HeaderDesc->bLength < sizeof(USB_AUDIO_AC_INTERFACE_HEADER_DESCRIPTOR))
    {
        OOPS();
        return FALSE;
    }

    AppendTextBuffer("\r\n          ===>Audio Control Interface Header Descriptor<===\r\n");

    AppendTextBuffer("bLength:                           0x%02X\r\n",
                     HeaderDesc->bLength);

    AppendTextBuffer("bDescriptorType:                   0x%02X\r\n",
                     HeaderDesc->bDescriptorType);

    AppendTextBuffer("bDescriptorSubtype:                0x%02X\r\n",
                     HeaderDesc->bDescriptorSubtype);

    AppendTextBuffer("bcdADC:                          0x%04X\r\n",
                     HeaderDesc->bcdADC);

    AppendTextBuffer("wTotalLength:                    0x%04X\r\n",
                     HeaderDesc->wTotalLength);

    AppendTextBuffer("bInCollection:                     0x%02X\r\n",
                     HeaderDesc->bInCollection);

    for (i=0; i<HeaderDesc->bInCollection; i++)
    {
        AppendTextBuffer("baInterfaceNr[%d]:                  0x%02X\r\n",
                         i+1,
                         HeaderDesc->baInterfaceNr[i]);
    }

    return TRUE;
}


/*****************************************************************************

 DisplayACInputTerminal()

*****************************************************************************/

BOOL
DisplayACInputTerminal (
    PUSB_AUDIO_INPUT_TERMINAL_DESCRIPTOR ITDesc
)
{
    PCHAR pStr = NULL;

    if (ITDesc->bLength != sizeof(USB_AUDIO_INPUT_TERMINAL_DESCRIPTOR))
    {
        OOPS();
        return FALSE;
    }

    AppendTextBuffer("\r\n          ===>Audio Control Input Terminal Descriptor<===\r\n");

    AppendTextBuffer("bLength:                           0x%02X\r\n",
                     ITDesc->bLength);

    AppendTextBuffer("bDescriptorType:                   0x%02X\r\n",
                     ITDesc->bDescriptorType);

    AppendTextBuffer("bDescriptorSubtype:                0x%02X\r\n",
                     ITDesc->bDescriptorSubtype);

    AppendTextBuffer("bTerminalID:                       0x%02X\r\n",
                     ITDesc->bTerminalID);

    AppendTextBuffer("wTerminalType:                   0x%04X",
                     ITDesc->wTerminalType);
    pStr = GetStringFromList(slAudioTerminalTypes, 
            sizeof(slAudioTerminalTypes) / sizeof(STRINGLIST),
            ITDesc->wTerminalType, 
            "Invalid AC Input Terminal Type");
    AppendTextBuffer(" (%s)\r\n", pStr);

    AppendTextBuffer("bAssocTerminal:                    0x%02X\r\n",
                     ITDesc->bAssocTerminal);

    AppendTextBuffer("bNrChannels:                       0x%02X\r\n",
                     ITDesc->bNrChannels);

    AppendTextBuffer("wChannelConfig:                  0x%04X\r\n",
                     ITDesc->wChannelConfig);

    AppendTextBuffer("iChannelNames:                     0x%02X\r\n",
                     ITDesc->iChannelNames);

    AppendTextBuffer("iTerminal:                         0x%02X\r\n",
                     ITDesc->iTerminal);


    return TRUE;
}


/*****************************************************************************

 DisplayACOutputTerminal()

*****************************************************************************/

BOOL
DisplayACOutputTerminal (
    PUSB_AUDIO_OUTPUT_TERMINAL_DESCRIPTOR OTDesc
)
{
    PCHAR pStr = NULL;

    if (OTDesc->bLength != sizeof(USB_AUDIO_OUTPUT_TERMINAL_DESCRIPTOR))
    {
        OOPS();
        return FALSE;
    }

    AppendTextBuffer("\r\n          ===>Audio Control Output Terminal Descriptor<===\r\n");

    AppendTextBuffer("bLength:                           0x%02X\r\n",
                     OTDesc->bLength);

    AppendTextBuffer("bDescriptorType:                   0x%02X\r\n",
                     OTDesc->bDescriptorType);

    AppendTextBuffer("bDescriptorSubtype:                0x%02X\r\n",
                     OTDesc->bDescriptorSubtype);

    AppendTextBuffer("bTerminalID:                       0x%02X\r\n",
                     OTDesc->bTerminalID);

    AppendTextBuffer("wTerminalType:                   0x%04X",
                     OTDesc->wTerminalType);

    pStr = GetStringFromList(slAudioTerminalTypes, 
            sizeof(slAudioTerminalTypes) / sizeof(STRINGLIST),
            OTDesc->wTerminalType, 
            "Invalid AC Output Terminal Type");
    AppendTextBuffer(" (%s)\r\n", pStr);

    AppendTextBuffer("bAssocTerminal:                    0x%02X\r\n",
                     OTDesc->bAssocTerminal);

    AppendTextBuffer("bSourceID:                         0x%02X\r\n",
                     OTDesc->bSourceID);

    AppendTextBuffer("iTerminal:                         0x%02X\r\n",
                     OTDesc->iTerminal);


    return TRUE;
}


/*****************************************************************************

 DisplayACMixerUnit()

*****************************************************************************/

BOOL
DisplayACMixerUnit (
    PUSB_AUDIO_MIXER_UNIT_DESCRIPTOR MixerDesc
)
{
    UCHAR  i = 0;
    PUCHAR data = NULL;

    if (MixerDesc->bLength < 10)
    {
        OOPS();
        return FALSE;
    }

    AppendTextBuffer("\r\n          ===>Audio Control Mixer Unit Descriptor<===\r\n");

    AppendTextBuffer("bLength:                           0x%02X\r\n",
                     MixerDesc->bLength);

    AppendTextBuffer("bDescriptorType:                   0x%02X\r\n",
                     MixerDesc->bDescriptorType);

    AppendTextBuffer("bDescriptorSubtype:                0x%02X\r\n",
                     MixerDesc->bDescriptorSubtype);

    AppendTextBuffer("bUnitID:                           0x%02X\r\n",
                     MixerDesc->bUnitID);

    AppendTextBuffer("bNrInPins:                         0x%02X\r\n",
                     MixerDesc->bNrInPins);

    for (i=0; i<MixerDesc->bNrInPins; i++)
    {
        AppendTextBuffer("baSourceID[%d]:                     0x%02X\r\n",
                        i+1,
                        MixerDesc->baSourceID[i]);
    }

    data = &MixerDesc->baSourceID[MixerDesc->bNrInPins];

    AppendTextBuffer("bNrChannels:                       0x%02X\r\n",
                     *data++);

    AppendTextBuffer("wChannelConfig:                  0x%04X\r\n",
                     *(PUSHORT)data);

    data = (PUCHAR) ((PUSHORT) data + 1);

    AppendTextBuffer("iChannelNames:                     0x%02X\r\n",
                     *data++);

    AppendTextBuffer("bmControls:\r\n");

    i = MixerDesc->bLength - 10 - MixerDesc->bNrInPins;

    DisplayBytes(data, i);

    data += i;

    AppendTextBuffer("iMixer:                            0x%02X\r\n",
                     *data);

    return TRUE;
}


/*****************************************************************************

 DisplayACSelectorUnit()

*****************************************************************************/

BOOL
DisplayACSelectorUnit (
    PUSB_AUDIO_SELECTOR_UNIT_DESCRIPTOR SelectorDesc
)
{
    UCHAR  i = 0;
    PUCHAR data = NULL;

    if (SelectorDesc->bLength < 6)
    {
        OOPS();
        return FALSE;
    }

    AppendTextBuffer("\r\n          ===>Audio Control Selector Unit Descriptor<===\r\n");

    AppendTextBuffer("bLength:                           0x%02X\r\n",
                     SelectorDesc->bLength);

    AppendTextBuffer("bDescriptorType:                   0x%02X\r\n",
                     SelectorDesc->bDescriptorType);

    AppendTextBuffer("bDescriptorSubtype:                0x%02X\r\n",
                     SelectorDesc->bDescriptorSubtype);

    AppendTextBuffer("bUnitID:                           0x%02X\r\n",
                     SelectorDesc->bUnitID);

    AppendTextBuffer("bNrInPins:                         0x%02X\r\n",
                     SelectorDesc->bNrInPins);

    for (i=0; i<SelectorDesc->bNrInPins; i++)
    {
        AppendTextBuffer("baSourceID[%d]:                     0x%02X\r\n",
                        i+1,
                        SelectorDesc->baSourceID[i]);
    }

    data = &SelectorDesc->baSourceID[SelectorDesc->bNrInPins];

    AppendTextBuffer("iSelector:                         0x%02X\r\n",
                     *data);

    return TRUE;
}


/*****************************************************************************

 DisplayACFeatureUnit()

*****************************************************************************/

BOOL
DisplayACFeatureUnit (
    PUSB_AUDIO_FEATURE_UNIT_DESCRIPTOR FeatureDesc
)
{
    UCHAR  i = 0;
    UCHAR  n = 0;
    UCHAR  ch = 0;
    PUCHAR data = NULL;

    AppendTextBuffer("\r\n          ===>Audio Control Feature Unit Descriptor<===\r\n");

    AppendTextBuffer("bLength:                           0x%02X\r\n",
                     FeatureDesc->bLength);

    AppendTextBuffer("bDescriptorType:                   0x%02X\r\n",
                     FeatureDesc->bDescriptorType);

    AppendTextBuffer("bDescriptorSubtype:                0x%02X\r\n",
                     FeatureDesc->bDescriptorSubtype);

    AppendTextBuffer("bUnitID:                           0x%02X\r\n",
                     FeatureDesc->bUnitID);

    AppendTextBuffer("bSourceID:                         0x%02X\r\n",
                     FeatureDesc->bSourceID);

    AppendTextBuffer("bControlSize:                      0x%02X\r\n",
                     FeatureDesc->bControlSize);


    if (FeatureDesc->bLength < 7)
    {
        AppendTextBuffer("*!*WARNING:    bLength is invalid (< 7)\r\n");
        OOPS();
        return FALSE;
    }
    else if(FeatureDesc->bLength == 7)
    {
        AppendTextBuffer("Audio controls are not available (bLength = 7)\r\n");
        return TRUE;
    }

    n = FeatureDesc->bControlSize;

    if(n == 0)
    {
        AppendTextBuffer("Audio controls are not available (bControlSize = 0)\r\n");
        return TRUE;
    }

    ch = ((FeatureDesc->bLength - 7) / n) - 1;

    // Check if there are extra bytes in descriptor based on formula in Spec
    if (FeatureDesc->bLength != (7 + (ch + 1) * n))
    {
        // The descriptor length is greater than number of bmaControls
        AppendTextBuffer("*!*WARNING:    bLength is greater than number of bmaControls (bLength > ( 7 + (ch + 1) * n)\r\n");
    }

    data = &FeatureDesc->bmaControls[0];

    if (ch == (UCHAR) -1)
    {
        // This should not happen, but this check is put in place so we don't loop for a long time below
        AppendTextBuffer("*!*WARNING:    Either bLength or bControlSize are invalid. The calculated logical channel count is -1. ((bLength - 7)/ n) - 1\r\n");
        OOPS();
        return FALSE;
    }

    for (i=0; i<=ch; i++)
    {
        AppendTextBuffer("bmaControls[%d]:                    ", i);
        DisplayBytes(data, n);

        data += n;
    }


    AppendTextBuffer("iFeature:                          0x%02X\r\n",
                     *data);

    return TRUE;
}


/*****************************************************************************

 DisplayACProcessingUnit()

*****************************************************************************/

BOOL
DisplayACProcessingUnit (
    PUSB_AUDIO_PROCESSING_UNIT_DESCRIPTOR ProcessingDesc
)
{
    UCHAR  i = 0;
    PUCHAR data = NULL;

    if (ProcessingDesc->bLength < sizeof(USB_AUDIO_PROCESSING_UNIT_DESCRIPTOR))
    {
        OOPS();
        return FALSE;
    }

    AppendTextBuffer("\r\n          ===>Audio Control Processing Unit Descriptor<===\r\n");

    AppendTextBuffer("bLength:                          0x%02X\r\n",
                     ProcessingDesc->bLength);

    AppendTextBuffer("bDescriptorType:                   0x%02X\r\n",
                     ProcessingDesc->bDescriptorType);

    AppendTextBuffer("bDescriptorSubtype:                0x%02X\r\n",
                     ProcessingDesc->bDescriptorSubtype);

    AppendTextBuffer("bUnitID:                           0x%02X\r\n",
                     ProcessingDesc->bUnitID);

    AppendTextBuffer("wProcessType:                    0x%04X",
                     ProcessingDesc->wProcessType);

    switch (ProcessingDesc->wProcessType)
    {
        case USB_AUDIO_PROCESS_UNDEFINED:
            AppendTextBuffer("(Undefined Process)\r\n");
            break;

        case USB_AUDIO_PROCESS_UPDOWNMIX:
            AppendTextBuffer("(Up / Down Mix Process)\r\n");
            break;

        case USB_AUDIO_PROCESS_DOLBYPROLOGIC:
            AppendTextBuffer("(Dolby Prologic Process)\r\n");
            break;

        case USB_AUDIO_PROCESS_3DSTEREOEXTENDER:
            AppendTextBuffer("(3D-Stereo Extender Process)\r\n");
            break;

        case USB_AUDIO_PROCESS_REVERBERATION:
            AppendTextBuffer("(Reverberation Process)\r\n");
            break;

        case USB_AUDIO_PROCESS_CHORUS:
            AppendTextBuffer("(Chorus Process)\r\n");
            break;

        case USB_AUDIO_PROCESS_DYNRANGECOMP:
            AppendTextBuffer("(Dynamic Range Compressor Process)\r\n");
            break;

        default:
            AppendTextBuffer("\r\n");
            break;
    }

    AppendTextBuffer("bNrInPins:                         0x%02X\r\n",
                     ProcessingDesc->bNrInPins);

    for (i=0; i<ProcessingDesc->bNrInPins; i++)
    {
        AppendTextBuffer("baSourceID[%d]:                     0x%02X\r\n",
                        i+1,
                        ProcessingDesc->baSourceID[i]);
    }

    data = &ProcessingDesc->baSourceID[ProcessingDesc->bNrInPins];

    AppendTextBuffer("bNrChannels:                       0x%02X\r\n",
                     *data++);

    AppendTextBuffer("wChannelConfig:                  0x%04X\r\n",
                     *(PUSHORT)data);

    data = (PUCHAR) ((PUSHORT) data + 1);

    AppendTextBuffer("iChannelNames:                     0x%02X\r\n",
                     *data++);

    i = *data++;

    AppendTextBuffer("bControlSize:                      0x%02X\r\n",
                     i);

    AppendTextBuffer("bmControls:\r\n");

    DisplayBytes(data, i);

    data += i;

    AppendTextBuffer("iProcessing:                       0x%02X\r\n",
                     *data++);


    i = ProcessingDesc->bLength - 13 - ProcessingDesc->bNrInPins - i;

    if (i)
    {
        AppendTextBuffer("Process Specific:\r\n");

        DisplayBytes(data, i);
    }

    return TRUE;
}


/*****************************************************************************

 DisplayACExtensionUnit()

*****************************************************************************/

BOOL
DisplayACExtensionUnit (
    PUSB_AUDIO_EXTENSION_UNIT_DESCRIPTOR ExtensionDesc
)
{
    UCHAR  i = 0;
    PUCHAR data = NULL;

    if (ExtensionDesc->bLength < 13)
    {
        OOPS();
        return FALSE;
    }

    AppendTextBuffer("\r\n          ===>Audio Control Extension Unit Descriptor<===\r\n");

    AppendTextBuffer("bLength:                           0x%02X\r\n",
                     ExtensionDesc->bLength);

    AppendTextBuffer("bDescriptorType:                   0x%02X\r\n",
                     ExtensionDesc->bDescriptorType);

    AppendTextBuffer("bDescriptorSubtype:                0x%02X\r\n",
                     ExtensionDesc->bDescriptorSubtype);

    AppendTextBuffer("bUnitID:                           0x%02X\r\n",
                     ExtensionDesc->bUnitID);

    AppendTextBuffer("wExtensionCode:                  0x%04X\r\n",
                     ExtensionDesc->wExtensionCode);


    AppendTextBuffer("bNrInPins:                         0x%02X\r\n",
                     ExtensionDesc->bNrInPins);

    for (i=0; i<ExtensionDesc->bNrInPins; i++)
    {
        AppendTextBuffer("baSourceID[%d]:                     0x%02X\r\n",
                        i+1,
                        ExtensionDesc->baSourceID[i]);
    }

    data = &ExtensionDesc->baSourceID[ExtensionDesc->bNrInPins];

    AppendTextBuffer("bNrChannels:                       0x%02X\r\n",
                     *data++);

    AppendTextBuffer("wChannelConfig:                  0x%04X\r\n",
                     *(PUSHORT)data);

    data = (PUCHAR) ((PUSHORT) data + 1);

    AppendTextBuffer("iChannelNames:                     0x%02X\r\n",
                     *data++);

    i = *data++;

    AppendTextBuffer("bControlSize:                      0x%02X\r\n",
                     i);

    AppendTextBuffer("bmControls:\r\n");

    DisplayBytes(data, i);

    data += i;

    AppendTextBuffer("iExtension:                        0x%02X\r\n",
                     *data);
    return TRUE;
}


/*****************************************************************************

 DisplayASGeneral()

*****************************************************************************/

BOOL
DisplayASGeneral (
    PUSB_AUDIO_GENERAL_DESCRIPTOR GeneralDesc
)
{
    PCHAR pStr = NULL;

    if (GeneralDesc->bLength != sizeof(USB_AUDIO_GENERAL_DESCRIPTOR))
    {
        OOPS();
        return FALSE;
    }

    AppendTextBuffer("\r\n          ===>Audio Streaming Class Specific Interface Descriptor<===\r\n");

    AppendTextBuffer("bLength:                           0x%02X\r\n",
                     GeneralDesc->bLength);

    AppendTextBuffer("bDescriptorType:                   0x%02X\r\n",
                     GeneralDesc->bDescriptorType);

    AppendTextBuffer("bDescriptorSubtype:                0x%02X\r\n",
                     GeneralDesc->bDescriptorSubtype);

    AppendTextBuffer("bTerminalLink:                     0x%02X\r\n",
                     GeneralDesc->bTerminalLink);

    AppendTextBuffer("bDelay:                            0x%02X\r\n",
                     GeneralDesc->bDelay);

    AppendTextBuffer("wFormatTag:                      0x%04X",
                     GeneralDesc->wFormatTag);

    pStr = GetStringFromList(slAudioFormatTypes, 
            sizeof(slAudioFormatTypes) / sizeof(STRINGLIST),
            GeneralDesc->wFormatTag, 
            "Invalid AC Format Type");
    AppendTextBuffer(" (%s)\r\n", pStr);

    return TRUE;
}


/*****************************************************************************

 DisplayCSEndpoint()

*****************************************************************************/

BOOL
DisplayCSEndpoint (
    PUSB_AUDIO_ENDPOINT_DESCRIPTOR EndpointDesc
)
{
    if (EndpointDesc->bLength != sizeof(USB_AUDIO_ENDPOINT_DESCRIPTOR))
    {
        OOPS();
        return FALSE;
    }

    AppendTextBuffer("\r\n          ===>Audio Streaming Class Specific Audio Data Endpoint Descriptor<===\r\n");

    AppendTextBuffer("bLength:                           0x%02X\r\n",
                     EndpointDesc->bLength);

    AppendTextBuffer("bDescriptorType:                   0x%02X\r\n",
                     EndpointDesc->bDescriptorType);

    AppendTextBuffer("bDescriptorSubtype:                0x%02X\r\n",
                     EndpointDesc->bDescriptorSubtype);

    AppendTextBuffer("bmAttributes:                      0x%02X\r\n",
                     EndpointDesc->bmAttributes);

    AppendTextBuffer("bLockDelayUnits:                   0x%02X\r\n",
                     EndpointDesc->bLockDelayUnits);

    AppendTextBuffer("wLockDelay:                      0x%04X\r\n",
                     EndpointDesc->wLockDelay);

    return TRUE;
}


/*****************************************************************************

 DisplayASFormatType()

*****************************************************************************/

BOOL
DisplayASFormatType (
    PUSB_AUDIO_COMMON_FORMAT_DESCRIPTOR FormatDesc
)
{
    UCHAR  i = 0;
    UCHAR  n = 0;
    ULONG  freq = 0;
    PUCHAR data = NULL;

    if (FormatDesc->bLength < sizeof(USB_AUDIO_COMMON_FORMAT_DESCRIPTOR))
    {
        OOPS();
        return FALSE;
    }

    AppendTextBuffer("\r\n          ===>Audio Streaming Format Type Descriptor<===\r\n");

    AppendTextBuffer("bLength:                           0x%02X\r\n",
                     FormatDesc->bLength);

    AppendTextBuffer("bDescriptorType:                   0x%02X\r\n",
                     FormatDesc->bDescriptorType);

    AppendTextBuffer("bDescriptorSubtype:                0x%02X\r\n",
                     FormatDesc->bDescriptorSubtype);

    AppendTextBuffer("bFormatType:                       0x%02X\r\n",
                     FormatDesc->bFormatType);


    if (FormatDesc->bFormatType == 0x01 ||
        FormatDesc->bFormatType == 0x03)
    {
        PUSB_AUDIO_TYPE_I_OR_III_FORMAT_DESCRIPTOR FormatI_IIIDesc;

        FormatI_IIIDesc = (PUSB_AUDIO_TYPE_I_OR_III_FORMAT_DESCRIPTOR)FormatDesc;

        AppendTextBuffer("bNrChannels:                       0x%02X\r\n",
                         FormatI_IIIDesc->bNrChannels);

        AppendTextBuffer("bSubframeSize:                     0x%02X\r\n",
                         FormatI_IIIDesc->bSubframeSize);

        AppendTextBuffer("bBitResolution:                    0x%02X\r\n",
                         FormatI_IIIDesc->bBitResolution);

        AppendTextBuffer("bSamFreqType:                      0x%02X\r\n",
                         FormatI_IIIDesc->bSamFreqType);

        data = (PUCHAR)(FormatI_IIIDesc + 1);

        n = FormatI_IIIDesc->bSamFreqType;

    }
    else if (FormatDesc->bFormatType == 0x02)
    {
        PUSB_AUDIO_TYPE_II_FORMAT_DESCRIPTOR FormatIIDesc;

        FormatIIDesc = (PUSB_AUDIO_TYPE_II_FORMAT_DESCRIPTOR)FormatDesc;

        AppendTextBuffer("wMaxBitRate:                     0x%04X\r\n",
                         FormatIIDesc->wMaxBitRate);

        AppendTextBuffer("wSamplesPerFrame:                0x%04X\r\n",
                         FormatIIDesc->wSamplesPerFrame);

        AppendTextBuffer("bSamFreqType:                      0x%02X\r\n",
                         FormatIIDesc->bSamFreqType);

        data = (PUCHAR)(FormatIIDesc + 1);

        n = FormatIIDesc->bSamFreqType;
    }
    else
    {
        data = NULL;
    }

    if (data != NULL)
    {
        if (n == 0)
        {
            freq = (data[0]) + (data[1] << 8) + (data[2] << 16);
            data += 3;

            AppendTextBuffer("tLowerSamFreq:                 0x%06X (%d Hz)\r\n",
                             freq,
                             freq);

            freq = (data[0]) + (data[1] << 8) + (data[2] << 16);
            data += 3;

            AppendTextBuffer("tUpperSamFreq:                 0x%06X (%d Hz)\r\n",
                             freq,
                             freq);
        }
        else
        {
            for (i=0; i<n; i++)
            {
                freq = (data[0]) + (data[1] << 8) + (data[2] << 16);
                data += 3;

                AppendTextBuffer("tSamFreq[%d]:                   0x%06X (%d Hz)\r\n",
                                 i+1,
                                 freq,
                                 freq);
            }
        }
    }

    return TRUE;
}


/*****************************************************************************

 DisplayASFormatSpecific()

*****************************************************************************/

BOOL
DisplayASFormatSpecific (
    PUSB_AUDIO_COMMON_DESCRIPTOR CommonDesc
)
{
    AppendTextBuffer("\r\n          ===>Audio Streaming Format Specific Descriptor<===\r\n");

    AppendTextBuffer("bLength:                           0x%02X\r\n",
                     CommonDesc->bLength);

    AppendTextBuffer("bDescriptorType:                   0x%02X\r\n",
                     CommonDesc->bDescriptorType);

    AppendTextBuffer("bDescriptorSubtype:                0x%02X\r\n",
                     CommonDesc->bDescriptorSubtype);

    DisplayBytes((PUCHAR)(CommonDesc + 1),
                 CommonDesc->bLength);

    return TRUE;
}

/*****************************************************************************

 DisplayBytes()

*****************************************************************************/

VOID
DisplayBytes (
    PUCHAR Data,
    USHORT Len
)
{
    USHORT i;

    for (i = 0; i < Len; i++)
    {
        AppendTextBuffer("%02X ", Data[i]);

        if (i % 16 == 15)
        {
            AppendTextBuffer("\r\n");
        }
    }

    if (i % 16 != 0)
    {
        AppendTextBuffer("\r\n");
    }
}


Our Services

  • What our customers say about us?

© 2011-2024 All Rights Reserved. Joya Systems. 4425 South Mopac Building II Suite 101 Austin, TX 78735 Tel: 800-DEV-KERNEL

Privacy Policy. Terms of use. Valid XHTML & CSS