USB声卡驱动(二)USB音频设备描述符
本篇笔记,分两部分,第一部分,是基本知识的记录。第二部分是一个实际的例子。
一.基本知识
一个音频设备(Audio Device)含有多个音频功能(Audio Function),而音频功能(Audio Function)内部还有各种各样的模块(Unit)和输入输出终端(Terminal)。这些模块(Unit)提供各种各样的功能,比如静音控制,音量调整等等。输入输出终端(Terminal)用于传输数据流,比如原始的PCM数据,或者经过AC-3编码的数据,或者MIDI数据
那么操作音频功能(Audio Function)就分为两部分:一个是操作Unit,一个是操作Terminal
操作Unit通常是出于控制要求,把这部分操作归类为Audio Control.操作Terminal是处于数据传输的要求,把这部分操作归类为Audio Stream.那么前者的接口被称为Audio Control Interface.后者的接口被称为Audio Stream Interface.这里提到了接口,而本笔记,又是USB相关的,所以,这两个接口都是指的USB接口。所有的这些接口统称为Audio Interface Collection.即操作音频功能(Audio Function)是通过Audio Interfacae Collection.
Audio Interface Collection在USB规范中即为Audio Interface Class.上面提到,Audio Interface Collection有两部分组成,一部分为Audio Control Interface.另外一部分为Audio Stream Interface.而后者还包括MIDI Stream Interface.所以Audio Interface SubClass即有三种,分别为:Audio Control Interface SubClass,Audio Streaming Interface SubClass,Midi Streaming Interface SubClass.
在USB的世界中,除了,Class,SubClass以外,还有Protocol.在USB音频世界中,Protocl没有被使用,因此该值为0x00.
- Audio Interface Class的值为:0x01,表示AUDIO
- Audio Interface SubClass的值为:
SUBCLASS_UNDEFINED:0x00;
AUDIOCONTROL:0x01;
AUDIOSTREAMING:0x02;
MIDISTREAMING:0x03 - Audio Interface Protocol的值:0x00
在USB的世界中,真正做沟通的是EndPoint,因此,Audio Function也需要和EndPoint相关联.
AudioControl中的EndPoint
Audio Control可以有下面的端点:
- 一个用于操作Unit或者Terminal的控制端点,这个端点是强制要求的,且默认为端点0
- 一个可选的中断端点,该端点可以报告Audio Function状态等
AudioStream中的EndPoint
Audio Streaming 接口用于数据传输,它是可选的端口。注意,每个Audio Streaming 接口最多只有一个等时数据端点。在某些情况下,等时数据端点还伴有一个对应的等时同步端点。
另外,对于等时数据端点,没必要直接映射到逻辑通道上。比如一个Audio Function它有左右两个声道,但是可以只有一个等时数据端点。在这个端点上面传输左右两个声道的数据。
来一个实际的例子
在上面了解了基本的Audio Function,以及一些相应的术语之后,来看一个实际的例子,在这个例子中,将会有对应的描述符的详细笔记。
USB 电话
产品描述
这是一个USB电话,这个电话含有16bit-8KHz的输入输出。它有手持电话筒和电话线的输入输出连接器。这个电话还含有USB接口,插入主机之后,可以使用主机直接和电话进行通话。手持电话筒和电话线上面的数据是模拟信号,而USB接口传输的是数字信号,因此里面USB接口对应的输入输出Terminal需要有模数转换模块。
整个USB电话的拓扑图如下:
描述符的层级
这个电话设备,包含一个Audio Control interface(0),和两个Audio Streaming interface(1和2)(因为有输入和输出)。
Audio Streaming interface都有两个可选的设置。第一个可选设置(可选设置0)占用0带宽,用于释放USB资源。第二个可选设置(可选设置1)是对应接口的操作部分,它有一个等时数据端点。下图展示了整个层级关系。
描述符详解
设备描述符
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x12 | 描述符大小 |
1 | bDescriptorType | 1 | 0x01 | DEVICE描述符 |
2 | bcdUSB | 2 | 0x0100 | USB spc当前版本 |
4 | bDeviceClass | 1 | 0x00 | 在Interface层定义 |
5 | bDeviceSubClass | 1 | 0x00 | 未使用 |
6 | bDeviceProtocol | 1 | 0x00 | 未使用 |
7 | bMaxPacketSize0 | 1 | 0x08 | 8字节 |
8 | idVendor | 2 | 0xxxxx | Vendor ID |
10 | idProduct | 2 | 0xxxxx | Product ID |
12 | bcdDevice | 2 | 0xxxxx | Device Release |
14 | iManufacturer | 1 | 0x01 | 字符串描述符索引号 |
15 | iProduct | 1 | 0x02 | 字符串描述符索引号 |
16 | iSerialNumber | 1 | 0x00 | 未使用 |
17 | bNumConfiguration | 1 | 0x01 | 一个配置 |
配置描述符
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x09 | 描述符大小 |
1 | bDescriptorType | 1 | 0x02 | CONFIGURATION描述符 |
2 | wTotalLength | 2 | 0x00xx | 整个配置块长度 |
4 | bNumInterfaces | 1 | 0x03 | 三个接口 |
5 | bConfigurationValue | 1 | 0x01 | 本配置的ID |
6 | iConfiguration | 1 | 0x00 | 未使用 |
7 | bmAttributes | 1 | 0x06 | 自给电,远程唤醒 |
8 | MaxPower | 1 | 0x00 | Not applicable |
Audio Control Interface 描述符
标准的Audio Control Interface 描述符
Audio Control Interface没有使用专用的端点,而是使用了默认的端点0来操作。并且该接口,没有中断端点。
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x09 | 描述符大小 |
1 | bDescriptorType | 1 | 0x04 | INTERFACE描述符 |
2 | bInterfaceNumber | 1 | 0x00 | 本接口索引 |
3 | bAlternateSetting | 1 | 0x00 | 本设置索引 |
4 | bNumEndpoints | 1 | 0x00 | 0端点 |
5 | bInterfaceClass | 1 | 0x01 | AUDIO |
6 | bInterfaceSubclass | 1 | 0x01 | AUDIO_CONTROL |
7 | bInterfaceProtocol | 1 | 0x00 | 未使用 |
8 | iInterface | 1 | 0x00 | 未使用 |
音频相关的描述符
音频相关的描述符,需要有一个header作为一些统一的描述,如下
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x0A | 描述符大小 |
1 | bDescriptorType | 1 | 0x24 | CS_INTERFACE描述符 |
2 | bDescriptorSubtype | 1 | 0x01 | HEADER子类型 |
3 | bcdADC | 2 | 0x0100 | Audio Class 规范1.0 |
5 | wTotalLength | 2 | 0x0064 | Audio Class相关描述总大小 |
7 | bInCollection | 1 | 0x02 | streaming接口数 |
8 | baInterfaceNr(1) | 1 | 0x01 | AudioStreaming接口1属于这个控制接口 |
8 | baInterfaceNr(2) | 1 | 0x02 | AudioStreaming接口2属于这个控制接口 |
7 | bInterfaceProtocol | 1 | 0x00 | 未使用 |
8 | iInterface | 1 | 0x00 | 未使用 |
输入Terminal描述符(ID1)
这个描述符代表了模拟电话线的输入。它只有一个声道,且没有位置信息。
这是双向Terminal的输入部分,因此有一个相关的输出Terminal(ID4)
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x0C | 描述符大小 |
1 | bDescriptorType | 1 | 0x24 | CS_INTERFACE描述符 |
2 | bDescriptorSubtype | 1 | 0x02 | INPUT_TERMINAL |
3 | bTerminalID | 1 | 0x01 | 本Termianl ID |
4 | wTerminalType | 2 | 0x0501 | 电话线In |
6 | bAssocTerminal | 1 | 0x04 | 对应电话线OUT terminal |
7 | bNrChannels | 1 | 0x01 | 1通道 |
8 | wChannelConfig | 2 | 0x0000 | 单声道没有位需要被设置 |
10 | iChannelNames | 1 | 0x00 | 未使用 |
11 | iTerminal | 1 | 0x00 | 未使用 |
输入Terminal描述符(ID2)
这个描述符是手持电话筒的输入麦克风。它只有单声道,且无位置信息。同样的它还有一个关联的输出Terminal(ID5)
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x0C | 描述符大小 |
1 | bDescriptorType | 1 | 0x24 | CS_INTERFACE描述符 |
2 | bDescriptorSubtype | 1 | 0x02 | INPUT_TERMINAL |
3 | bTerminalID | 1 | 0x02 | 本Termianl ID |
4 | wTerminalType | 2 | 0x0401 | 手持电话IN |
6 | bAssocTerminal | 1 | 0x05 | 对应手持电话的OUT terminal |
7 | bNrChannels | 1 | 0x01 | 1通道 |
8 | wChannelConfig | 2 | 0x0000 | 单声道没有位需要被设置 |
10 | iChannelNames | 1 | 0x00 | 未使用 |
11 | iTerminal | 1 | 0x04 | 未使用 |
输入Terminal描述符(ID3)
这个描述符,代表了从主机到电话的USB流。同样的只有单声道,且无位置信息。它也有一个关联的输出Terminal (ID6)
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x0C | 描述符大小 |
1 | bDescriptorType | 1 | 0x24 | CS_INTERFACE描述符 |
2 | bDescriptorSubtype | 1 | 0x02 | INPUT_TERMINAL |
3 | bTerminalID | 1 | 0x03 | 本Termianl ID |
4 | wTerminalType | 2 | 0x0101 | USB流IN |
6 | bAssocTerminal | 1 | 0x06 | 对USB接口的OUT terminal |
7 | bNrChannels | 1 | 0x01 | 1通道 |
8 | wChannelConfig | 2 | 0x0000 | 单声道没有位需要被设置 |
10 | iChannelNames | 1 | 0x00 | 未使用 |
11 | iTerminal | 1 | 0x05 | 未使用 |
输入Terminal描述符(ID4)
这个描述符,代表了模拟电话线的输出端。
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x09 | 描述符大小 |
1 | bDescriptorType | 1 | 0x24 | CS_INTERFACE描述符 |
2 | bDescriptorSubtype | 1 | 0x03 | OUTPUT_TERMINAL |
3 | bTerminalID | 1 | 0x04 | 本Termianl ID |
4 | wTerminalType | 2 | 0x0501 | 电话线OUT |
6 | bAssocTerminal | 1 | 0x01 | 与连电话线IN相关 |
7 | bSourceID | 1 | 0x07 | 源自电话线选择器单元 |
8 | iTerminal | 1 | 0x06 | 未使用 |
输入Terminal描述符(ID5)
这个描述符,代表了手持电话筒的听筒
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x09 | 描述符大小 |
1 | bDescriptorType | 1 | 0x24 | CS_INTERFACE描述符 |
2 | bDescriptorSubtype | 1 | 0x03 | OUTPUT_TERMINAL |
3 | bTerminalID | 1 | 0x05 | 本Termianl ID |
4 | wTerminalType | 2 | 0x0401 | 手持电话OUT |
6 | bAssocTerminal | 1 | 0x01 | 与手持电话IN相关 |
7 | bSourceID | 1 | 0x08 | 源自手持电话选择器单元 |
8 | iTerminal | 1 | 0x00 | 未使用 |
输入Terminal描述符(ID6)
这个描述符,代表了到主机的USB流。
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x09 | 描述符大小 |
1 | bDescriptorType | 1 | 0x24 | CS_INTERFACE描述符 |
2 | bDescriptorSubtype | 1 | 0x03 | OUTPUT_TERMINAL |
3 | bTerminalID | 1 | 0x06 | 本Termianl ID |
4 | wTerminalType | 2 | 0x0101 | USB 流OUT |
6 | bAssocTerminal | 1 | 0x03 | 与USB流IN相关 |
7 | bSourceID | 1 | 0x09 | 源自USB选择器单元 |
8 | iTerminal | 1 | 0x00 | 未使用 |
选择器单元描述符(ID7)
这个描述符,表示连接到电话线OUT终端的选择器单元,他也可以选中手持电话IN或者USB IN
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x09 | 描述符大小 |
1 | bDescriptorType | 1 | 0x24 | CS_INTERFACE描述符 |
2 | bDescriptorSubtype | 1 | 0x05 | SELECTOR_UNIT |
3 | bTerminalID | 1 | 0x07 | 本Unit ID |
4 | bNrInPins | 2 | 0x02 | 输入引脚数 |
6 | baSourceID(1) | 1 | 0x02 | 源自手持电话IN |
6 | baSourceID(2) | 1 | 0x03 | 源自USB 流IN |
8 | iSelector | 1 | 0x00 | 未使用 |
选择器单元描述符(ID8)
这个描述符,表示连接到手持电话OUT终端的选择器单元,他也可以选中电话线IN或者USB IN
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x09 | 描述符大小 |
1 | bDescriptorType | 1 | 0x24 | CS_INTERFACE描述符 |
2 | bDescriptorSubtype | 1 | 0x05 | SELECTOR_UNIT |
3 | bTerminalID | 1 | 0x08 | 本Unit ID |
4 | bNrInPins | 2 | 0x02 | 输入引脚数 |
6 | baSourceID(1) | 1 | 0x01 | 源自电话线IN |
6 | baSourceID(2) | 1 | 0x03 | 源自USB 流IN |
8 | iSelector | 1 | 0x00 | 未使用 |
选择器单元描述符(ID9)
这个描述符,表示连接到USB流OUT终端的选择器单元,他也可以选中手持电话IN或者电话线IN
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x09 | 描述符大小 |
1 | bDescriptorType | 1 | 0x24 | CS_INTERFACE描述符 |
2 | bDescriptorSubtype | 1 | 0x05 | SELECTOR_UNIT |
3 | bTerminalID | 1 | 0x09 | 本Unit ID |
4 | bNrInPins | 2 | 0x02 | 输入引脚数 |
6 | baSourceID(1) | 1 | 0x01 | 源电话线IN |
7 | baSourceID(2) | 1 | 0x02 | 源自手持电话IN |
8 | iSelector | 1 | 0x00 | 未使用 |
Audio Streaming 接口1描述符
该接口用于将主机数据,传输到usb电话中。该接口有两个可选设置(可选设置0),第一个为0带宽设置,用于释放USB资源;第二个(可选设置1)用于正常的操作。
可选设置0
标准接口描述符
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x09 | 描述符大小 |
1 | bDescriptorType | 1 | 0x04 | INTERFACE描述符 |
2 | bInterfaceNumber | 1 | 0x01 | 本接口索引 |
3 | bAlternateSetting | 1 | 0x00 | 本设置索引 |
4 | bNumEndpoints | 1 | 0x00 | 0端点 |
5 | bInterfaceClass | 1 | 0x01 | AUDIO |
6 | bInterfaceSubclass | 1 | 0x02 | AUDIO_STREAMING |
7 | bInterfaceProtocol | 1 | 0x00 | 未使用 |
7 | iInterface | 1 | 0x00 | 未使用 |
可选设置1
标准AS接口描述符
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x09 | 描述符大小 |
1 | bDescriptorType | 1 | 0x04 | INTERFACE描述符 |
2 | bInterfaceNumber | 1 | 0x01 | 本接口索引 |
3 | bAlternateSetting | 1 | 0x01 | 本设置索引 |
4 | bNumEndpoints | 1 | 0x01 | 1个端点 |
5 | bInterfaceClass | 1 | 0x01 | AUDIO |
6 | bInterfaceSubclass | 1 | 0x02 | AUDIO_STREAMING |
7 | bInterfaceProtocol | 1 | 0x00 | 未使用 |
8 | iInterface | 1 | 0x00 | 未使用 |
音频相关描述符
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x07 | 描述符大小 |
1 | bDescriptorType | 1 | 0x24 | CS_INTERFACE 描述符 |
2 | bDescriptorSubtype | 1 | 0x01 | GENERAL |
3 | bTerminalLink | 1 | 0x03 | 链接到USB流IN |
4 | bDelay | 1 | 0x01 | 接口延迟 |
5 | wFormatTag | 2 | 0x0001 | PCM格式 |
Type I Format Type Descriptor
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x0B | 描述符大小 |
1 | bDescriptorType | 1 | 0x24 | CS_INTERFACE描述符 |
2 | bDescriptorSubtype | 1 | 0x02 | FORMAT_TYPE |
3 | bFormatType | 1 | 0x01 | FORMAT_TYPE_I |
4 | bNrChannels | 1 | 0x01 | 1个通道 |
5 | bSubFrameSize | 1 | 0x02 | 两个字节 |
6 | bBitResolution | 1 | 0x010 | 16位 |
7 | bSamFreqType | 1 | 0x01 | 一个采样频率 |
8 | tSamFreq | 3 | 0x01F40 | 8000Hz |
标准端点描述符
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x09 | 描述符大小 |
1 | bDescriptorType | 1 | 0x05 | ENDPOINT描述符 |
2 | bEndpointAddress | 1 | 0x01 | OUT 端点1 |
3 | bmAttributes | 1 | 0x0B | 同步,等时传输 |
4 | wMaxPacketSize | 2 | 0x0010 | 16 bytes 每包 |
6 | bInterval | 1 | 0x01 | 每帧一包 |
7 | bRefresh | 1 | 0x00 | 未使用 |
8 | bSynchAddress | 1 | 0x00 | 未使用 |
音频相关等时数据端点描述符
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x07 | 描述符大小 |
1 | bDescriptorType | 1 | 0x25 | CS_ENDPOINT描述符 |
2 | bDescriptorSubtype | 1 | 0x01 | GENERAL |
3 | bmAttributes | 1 | 0x00 | 无频率控制,无pitch控制 |
4 | bLockDelayUnits | 1 | 0x00 | 未使用 |
5 | wLockDelay | 2 | 0x0000 | 未使用 |
Audio Streaming 接口2描述符
该接口用于将数据传输到主机上。同样有两个可选设置,第一个是0带宽设置,第二个是正常使用设置。
0带宽可选设置
标准接口描述符
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x09 | 描述符大小 |
1 | bDescriptorType | 1 | 0x04 | INTERFACE描述符 |
2 | bInterfaceNumber | 1 | 0x01 | 本接口索引 |
3 | bAlternateSetting | 1 | 0x00 | 本设置索引 |
4 | bNumEndpoints | 1 | 0x00 | 0端点 |
5 | bInterfaceClass | 1 | 0x01 | AUDIO |
6 | bInterfaceSubclass | 1 | 0x02 | AUDIO_STREAMING |
7 | bInterfaceProtocol | 1 | 0x00 | 未使用 |
7 | iInterface | 1 | 0x00 | 未使用 |
可选设置1
标准AS接口描述符
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x09 | 描述符大小 |
1 | bDescriptorType | 1 | 0x04 | INTERFACE描述符 |
2 | bInterfaceNumber | 1 | 0x01 | 本接口索引 |
3 | bAlternateSetting | 1 | 0x01 | 本设置索引 |
4 | bNumEndpoints | 1 | 0x01 | 1个端点 |
5 | bInterfaceClass | 1 | 0x01 | AUDIO |
6 | bInterfaceSubclass | 1 | 0x02 | AUDIO_STREAMING |
7 | bInterfaceProtocol | 1 | 0x00 | 未使用 |
8 | iInterface | 1 | 0x00 | 未使用 |
音频相关AS接口描述符
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x07 | 描述符大小 |
1 | bDescriptorType | 1 | 0x24 | CS_INTERFACE 描述符 |
2 | bDescriptorSubtype | 1 | 0x01 | GENERAL |
3 | bTerminalLink | 1 | 0x06 | 链接到USB流OUT |
4 | bDelay | 1 | 0x01 | 接口延迟 |
5 | wFormatTag | 2 | 0x0001 | PCM格式 |
Type I format type descriptor
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x0B | 描述符大小 |
1 | bDescriptorType | 1 | 0x24 | CS_INTERFACE描述符 |
2 | bDescriptorSubtype | 1 | 0x02 | FORMAT_TYPE |
3 | bFormatType | 1 | 0x01 | FORMAT_TYPE_I |
4 | bNrChannels | 1 | 0x01 | 1个通道 |
5 | bSubFrameSize | 1 | 0x02 | 两个字节 |
6 | bBitResolution | 1 | 0x010 | 16位 |
7 | bSamFreqType | 1 | 0x01 | 一个采样频率 |
8 | tSamFreq | 3 | 0x01F40 | 8000Hz |
标准端点描述符
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x09 | 描述符大小 |
1 | bDescriptorType | 1 | 0x05 | ENDPOINT描述符 |
2 | bEndpointAddress | 1 | 0x81 | IN 端点1 |
3 | bmAttributes | 1 | 0x0B | 同步,等时传输 |
4 | wMaxPacketSize | 2 | 0x0010 | 16 bytes 每包 |
6 | bInterval | 1 | 0x01 | 每帧一包 |
7 | bRefresh | 1 | 0x00 | 未使用 |
8 | bSynchAddress | 1 | 0x00 | 未使用 |
音频相关等时数据端点描述符
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x07 | 描述符大小 |
1 | bDescriptorType | 1 | 0x25 | CS_ENDPOINT描述符 |
2 | bDescriptorSubtype | 1 | 0x01 | GENERAL |
3 | bmAttributes | 1 | 0x00 | 无频率控制,无pitch控制 |
4 | bLockDelayUnits | 1 | 0x00 | 未使用 |
5 | wLockDelay | 2 | 0x0000 | 未使用 |
字符串描述符
Manufacturer String Descriptor
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x18 | 描述符大小 |
1 | bDescriptorType | 1 | 0x03 | STRING描述符 |
2 | bString | 1 | 0x0054 0x0048 0x0045 0x0020 0x0043 0x004F 0x004D 0x0050 0x0041 0x004E 0x0059 | “THE COMPANY” |
Product String Descriptor
offset | 字段 | 大小 | 值 | 说明 |
0 | bLength | 1 | 0x16 | 描述符大小 |
1 | bDescriptorType | 1 | 0x03 | STRING描述符 |
2 | bString | 1 | 0x0054 0x0065 0x006C 0x0065 0x0070 0x0068 0x006F 0x006E 0x0065 | “THE COMPANY” |
上面是关于,这个USB电话产品的完整的描述符介绍。
现在已经知道了,标准的USB,和标准的USB AUDIO的数据组织形式。接下来就是看看,Linux内核中,怎么操作,USB以及怎么操作USB Audio了。