UAC规范(USB音频)
+ -

UAC音频控制接口头描述符bInCollection及baInterfaceNr字段分析

2023-01-13 9 0
欢迎加入官方QQ群:952873936或联系站长进行技术交流。

UAC1.0规范音频控制接口头描述符的定义如下:

typedef struct _USB_AC_HEADER
{
    UINT8  bLength;
    UINT8  bDescriptorType;
    UINT8  bDescriptorSubType;
    UINT16 bcdADC;
    UINT16 wTotalLength;
    UINT8  bInCollection;
    UINT8  baInterfaceNr[bInCollection];
} USB_AC_HEADER;

其各字段的解释可详见:https://www.usbzh.com/article/detail-222.html

从这个结构来看,这是一个可变长的结构体,其变体主要是baInterfaceNr,是一个不定长的数组,其数组的大小由bInCollection。
这里我们先列出2个不同bInCollection的两种示例:

bInCollection为1时的示例:

        ------ Audio Control Interface Header Descriptor ------
bLength                  : 0x09 (9 bytes)
bDescriptorType          : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype       : 0x01 (Header)
bcdADC                   : 0x0100
wTotalLength             : 0x0028 (40 bytes)
bInCollection            : 0x01
baInterfaceNr[1]         : 0x01
Data (HexDump)           : 09 24 01 00 01 28 00 01 01                        .$...(...

baInterfaceNr为2时的示例:

        ------ Audio Control Interface Header Descriptor ------
bLength                  : 0x0A (10 bytes)
bDescriptorType          : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype       : 0x01 (Header)
bcdADC                   : 0x0100
wTotalLength             : 0x0041 (65 bytes)
bInCollection            : 0x02
baInterfaceNr[1]         : 0x01
baInterfaceNr[2]         : 0x02
Data (HexDump)           : 0A 24 01 00 01 41 00 02 01 02                     .$...A....

bInCollection从规范上来讲,代表数据流的个数。
当为1时,代表只有1个数据流,只为2时代表有2个数据流。
所以我们上面为1时,是一个USB小音响的内容,由于其只有一个输出音频流,故为1。
当为2时,是我们的华为耳机的内容,由于我们既是一个麦克风同时也有一个耳机,故数据流为2。

baInterfaceNr数组中的内容代表的是音频流接口的索引。如为2时我们的华为耳机全部的配置描述符可参考:https://www.usbzh.com/article/detail-717.html

通过分析,其接口ID=1是的内容如下:

-------- Audio Streaming Interface Descriptor ---------
bLength                  : 0x07 (7 bytes)
bDescriptorType          : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype       : 0x01 (AS_GENERAL)
bTerminalLink            : 0x05 (Terminal ID 5)
bDelay                   : 0x00 (0 frames)
wFormatTag               : 0x0001 (PCM)
Data (HexDump)           : 07 24 01 05 00 01 00                              .$.....

        ------- Audio Streaming Format Type Descriptor --------
bLength                  : 0x0B (11 bytes)
bDescriptorType          : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype       : 0x02 (Format Type)
bFormatType              : 0x01 (FORMAT_TYPE_I)
bNrChannels              : 0x02 (2 channels)
bSubframeSize            : 0x02 (2 bytes per subframe)
bBitResolution           : 0x10 (16 bits per sample)
bSamFreqType             : 0x01 (supports 1 sample frequence)
tSamFreq[1]              : 0x0BB80 (48000 Hz)
Data (HexDump)           : 0B 24 02 01 02 02 10 01 80 BB 00                  .$.........

        ----------------- Endpoint Descriptor -----------------
bLength                  : 0x09 (9 bytes)
bDescriptorType          : 0x05 (Endpoint Descriptor)
bEndpointAddress         : 0x83 (Direction=IN EndpointID=3)
bmAttributes             : 0x0D (TransferType=Isochronous  SyncType=Synchronous  EndpointType=Data)
wMaxPacketSize           : 0x00C0 (192 bytes)
bInterval                : 0x01 (1 ms)
bRefresh                 : 0x00
bSynchAddress            : 0x00
Data (HexDump)           : 09 05 83 0D C0 00 01 00 00                        .........

        ----------- Audio Data Endpoint Descriptor ------------
bLength                  : 0x07 (7 bytes)
bDescriptorType          : 0x25 (Audio Endpoint Descriptor)
bDescriptorSubtype       : 0x01 (General)
bmAttributes             : 0x01
 D0   : Sampling Freq    : 0x01 (supported)
 D1   : Pitch            : 0x00 (not supported)
 D6..2: Reserved         : 0x00
 D7   : MaxPacketsOnly   : 0x00 (no)
bLockDelayUnits          : 0x00 (Undefined)
wLockDelay               : 0x0000
Data (HexDump)           : 07 25 01 01 00 00 00                              .%.....

这是一个输入设备即麦克风音频流接描述符。

其接口为2时的:

 ---------------- Interface Descriptor -----------------
bLength                  : 0x09 (9 bytes)
bDescriptorType          : 0x04 (Interface Descriptor)
bInterfaceNumber         : 0x02 (Interface 2)
bAlternateSetting        : 0x00
bNumEndpoints            : 0x00 (Default Control Pipe only)
bInterfaceClass          : 0x01 (Audio)
bInterfaceSubClass       : 0x02 (Audio Streaming)
bInterfaceProtocol       : 0x00
iInterface               : 0x00 (No String Descriptor)
Data (HexDump)           : 09 04 02 00 00 01 02 00 00                        .........

        ---------------- Interface Descriptor -----------------
bLength                  : 0x09 (9 bytes)
bDescriptorType          : 0x04 (Interface Descriptor)
bInterfaceNumber         : 0x02 (Interface 2)
bAlternateSetting        : 0x01
bNumEndpoints            : 0x01 (1 Endpoint)
bInterfaceClass          : 0x01 (Audio)
bInterfaceSubClass       : 0x02 (Audio Streaming)
bInterfaceProtocol       : 0x00
iInterface               : 0x00 (No String Descriptor)
Data (HexDump)           : 09 04 02 01 01 01 02 00 00                        .........

        -------- Audio Streaming Interface Descriptor ---------
bLength                  : 0x07 (7 bytes)
bDescriptorType          : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype       : 0x01 (AS_GENERAL)
bTerminalLink            : 0x01 (Terminal ID 1)
bDelay                   : 0x00 (0 frames)
wFormatTag               : 0x0001 (PCM)
Data (HexDump)           : 07 24 01 01 00 01 00                              .$.....

        ------- Audio Streaming Format Type Descriptor --------
bLength                  : 0x11 (17 bytes)
bDescriptorType          : 0x24 (Audio Interface Descriptor)
bDescriptorSubtype       : 0x02 (Format Type)
bFormatType              : 0x01 (FORMAT_TYPE_I)
bNrChannels              : 0x02 (2 channels)
bSubframeSize            : 0x02 (2 bytes per subframe)
bBitResolution           : 0x10 (16 bits per sample)
bSamFreqType             : 0x03 (supports 3 sample frequencies)
tSamFreq[1]              : 0x0AC44 (44100 Hz)
tSamFreq[2]              : 0x0BB80 (48000 Hz)
tSamFreq[3]              : 0x17700 (96000 Hz)
Data (HexDump)           : 11 24 02 01 02 02 10 03 44 AC 00 80 BB 00 00 77   .$......D......w
                           01                                                .

        ----------------- Endpoint Descriptor -----------------
bLength                  : 0x09 (9 bytes)
bDescriptorType          : 0x05 (Endpoint Descriptor)
bEndpointAddress         : 0x03 (Direction=OUT EndpointID=3)
bmAttributes             : 0x0D (TransferType=Isochronous  SyncType=Synchronous  EndpointType=Data)
wMaxPacketSize           : 0x0180 (384 bytes)
bInterval                : 0x01 (1 ms)
bRefresh                 : 0x00
bSynchAddress            : 0x00
Data (HexDump)           : 09 05 03 0D 80 01 01 00 00                        .........

        ----------- Audio Data Endpoint Descriptor ------------
bLength                  : 0x07 (7 bytes)
bDescriptorType          : 0x25 (Audio Endpoint Descriptor)
bDescriptorSubtype       : 0x01 (General)
bmAttributes             : 0x01
 D0   : Sampling Freq    : 0x01 (supported)
 D1   : Pitch            : 0x00 (not supported)
 D6..2: Reserved         : 0x00
 D7   : MaxPacketsOnly   : 0x00 (no)
bLockDelayUnits          : 0x00 (Undefined)
wLockDelay               : 0x0000
Data (HexDump)           : 07 25 01 01 00 00 00                              .%.....

这是一个输出设备的,即USB耳机音频流接描述符。

我们再通过代码来更深层的理解一下音频流。
我们知道USB需要选择配置,选择配置之前需要解析各个USB接口述符的位置,所以对于UAC设备,可以采样如下的方式来解析音频流接口。即先获取到AC音频控制接口头描述符bInCollection,然后再循环解析配置描述符中各个音频流接口。

//首先获取UAC音频控制接口头描述符接针
pHeader = (PAUDIO_HEADER_UNIT)GetAudioSpecificInterface(pConfigurationDescriptor, pAudioInterface, HEADER_UNIT);
if (!pHeader)
{
    FreeMem(pHwDevExt->pInterfaceList);
    return STATUS_INVALID_PARAMETER;
}

//根据其接口描述符ID从配置描述符中获取对应的接口描述符指针
for (i = 0; i < pHeader->bInCollection; i++) 
{
    pAudioStreamingInterface = USBD_ParseConfigurationDescriptorEx(
        pConfigurationDescriptor,
        (PVOID)pConfigurationDescriptor,
        (LONG)pHeader->baInterfaceNr[i],  // Interface number
        -1,                               // Alternate Setting
        USB_DEVICE_CLASS_AUDIO,           // Audio Class (Interface Class)
        AUDIO_SUBCLASS_STREAMING,         // Audio Streaming (Interface Sub-Class)
        -1);                            // protocol don't care    (InterfaceProtocol)

    if (pAudioStreamingInterface)
    {
        pHwDevExt->pInterfaceList[j++].InterfaceDescriptor = pAudioStreamingInterface;
    }

}

0 篇笔记 写笔记

UAC 类特定音频控制接口头描述符
UAC类特定音频控制头接口描述符这个名字有点绕,其实这个描述符是前接标准的音频控制接口描述符,后续关于音频控制的所有相关描述符,起着承上起下的作用。当然也可以认为是音频控制相关描述符的前导。这是因为UAC类特定音频控制接口描述符含有一个关键的字段wTotalLength,用于包含音频控制所有接口描述......
UAC麦克风类特定音频控制接口描述符
UAC的类特定音频控制接口描述符又叫类特定音频控制接口头描述符,包含了UAC音频控制各终端,单元的描述符信息。在UAC规范中,其包含的描述符有:关于类特定音频控制接口描述符可详见本站:http://www.usbzh.com/article/detail-222.html由于该UAC麦克风是基于......
UAC音频控制接口头描述符bInCollectionbaInterfaceNr字段分析
UAC1.0规范音频控制接口头描述符的定义如下:typedef struct _USB_AC_HEADER{ UINT8 bLength; UINT8 bDescriptorType; UINT8 bDescriptorSubType; UINT16 bcd......
作者信息
USB中文网
B站搜索 站长漫谈 看视频。
pnpon内核开发网,USB中文网,
busrom硬核技术网站长
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!