先给出完整的usb描述符供参考:

const unsigned char Demo_DeviceDescriptor[] =

{

//Device:USB1.10,Vid=0x0435,Pid=0x2430,bNumConfigurations= 0x01,

0x12,//Length

0x01,//DescriptorType

0x10,

0x01,//bcdUSB

0x00,//DeviceClass

0x00,//DeviceSubClass

0x00,//DeviceProtocol

0x08,//bMaxPacketSize8

0x35,

0x04,//idVendor........

0x30,

0x24,//idProduct........

0x01,

0x00,//bcdDevice

1,//iManufacturer

2,//iProduct

3,//iSerialNumber

0x01//bNumConfigurations

};


/* USB Configuration Descriptor */

/*All Descriptors (Configuration,Interface, Endpoint, Class, Vendor */

const unsigned char Demo_ConfigDescriptor[] =

{

//Configuration:wTotalLength =0x00be,NumInterfaces = 0x03,

0x09,//Length

0x02,//DescriptorType: ConfigDescriptor

0xbe,

0x00,//TotalLength:0x00be

0x03,//NumInterfaces:3

0x01,//ConfigurationValue

0x00,//ConfigurationString

0x80,//Attributes:BusPower

0xfa,//MaxPower =0xfa*2ma

//standard interface ACdescriptor(Interface 0, Alternate Setting 0):

//bNumEndpoints =0x00,bInterFaceClass = 0x01(audio),bInterfaceSubClass = 0x01(audio ctl),

0x09,//Length

0x04,//DescriptorType:Inerface

0x00,//InterfaceNum:0

0x00, //AlternateSetting:0

0x00,//NumEndpoint:0

0x01,//InterfaceClass:audio

0x01,//InterfaceSubClass:audioctl

0x00,//InterfaceProtocol

0x00,//InterfaceString

//class-specific AC interfacedescriptor,audio interface(0x24),audio control header(0x01),

//Total Length 0x0048,Number ofstreaming interface 2,interfaceNr 2,1

0x0a,//Length

0x24,//DescriptorType:audiointerface descriptor

0x01,//DescriptorSubType:audiocontrol header

0x00,

0x01,//bcdADC:audio Device Class v1.00

0x48,

0x00,//TotalLength:0x0048

0x02,//InCollection:2AudioStreaming interface

0x02,//InterfaceNr(2)- AS #1 id AudioStreaming interface 2 belongs to this AudioControlinterface

0x01,//InterfaceNr(1)- AS #2 id AudioStreaming interface 1 belongs to this AudioControlinterface

//USB Microphone IT:audiointerface descriptor,audio control input terminal(0x02),terminal id 0x01,

//Microphone(0x0201),InputTerminal(0x02),2 channel:Left Front,Right Front

0x0c,//Length

0x24,//DescriptorType:audiointerface descriptor

0x02,//DescriptorSubType:InputTerminal

0x01,//TerminalID:0x01

0x01,

0x02,//TerminalType:USB Microphone

0x00,//AssocTerminal

0x02,//NrChannels:2channel

0x03,

0x00,//ChannelConfig:Left Front,Right Front,

0x00,//ChannelNameString

0x00,//TerminalString

//Audio Feature UnitDescriptor:audio interface descriptor,feature_unit(0x06),terminal id 0x02,

//SourceId 0x01,ControlSize0x01,Mute,Volume,

0x0a,//Length

0x24,//DescriptorType:audiointerface descriptor

0x06,//DescriptorSubType:AudioFeature Unit

0x02,//UnitID:0x02

0x01,//SourceID:1#Microphone IT

0x01,//ControlSize:1byte

0x01,//Controls:Mute

0x02,//Controls(0):Volume

0x02,//Controls(1):Volume

0x00,//Feature String

//USB Streaming OT:audiointerface descriptor,audio control output terminal(0x03),terminal id 0x03,

//USB Streaming(0x0101),OutputTerminal(0x03),SourceId 0x02,

0x09,//Length

0x24,//DescriptorType:audiointerface descriptor

0x03,//DescriptorSubTYpe:OutputTerminal

0x03,//TerminalID:0x03

0x01,

0x01,//TerminalType:USB Streaming

0x00,//AssocTerminal:ID0

0x02,//SourceID:2#Feature UNIT

0x00,//TerminalString

//USB USB Streaming IT:audiointerface descriptor,audio control input terminal(0x02),terminal id 0x04,

//USB Streaming(0x0101),InputTerminal(0x02),2 channel:Left Front,Right Front

0x0c,//Length

0x24,//DescriptorType:audiointerface descriptor

0x02,//DescriptorSubType:InputTerminal

0x04,//TerminalID:0x04

0x01,

0x01,//TerminalType:USB Streaming

0x00,//AssocTerminal

0x02,//NrChannels:2channel

0x03,

0x00,//ChannelConfig:Left Front,Right Front,

0x00,//ChannelNameString

0x00,//TerminalString

//Audio Feature UnitDescriptor:audio interface descriptor,feature_unit(0x06),terminal id 0x05,

//SourceId 0x04,ControlSize0x01,Mute,Volume,

0x0a,//Length

0x24,//DescriptorType:audiointerface descriptor

0x06,//DescriptorSubType:AudioFeature Unit

0x05,//UnitID:0x05

0x04,//SourceID:4 #USBStreaming IT

0x01,//ControlSize:1byte

0x01,//Controls:Mute,

0x02,//Controls(0):Volume

0x02,//Controls(1):Volume

0x00,//FeatureString

//USB Speaker OT:audio interfacedescriptor,audio control output terminal(0x03),terminal id 0x06,

//USB Speaker(0x0301),OutputTerminal(0x03),SourceId 0x05,

0x09,//Length

0x24,//DescriptorType:audiointerface descriptor

0x03,//DescriptorSubTYpe:OutputTerminal

0x06,//TerminalID:0x06

0x01,

0x03,//TerminalType:Speaker

0x00,//AssocTerminal:

0x05,//SourceID:5#Feature UNIT

0x00,//Terminal String

//-------------------Microphoneinterface---------------------//

//standardinterface AS descriptor(Interface 1, Alternate Setting 0):

//bNumEndpoints =0x00,bInterFaceClass = 0x01(audio),bInterfaceSubClass = 0x02(audiostream),

0x09,//Length

0x04,//DescriptorType:Interface

0x01,//InterfaceNum:1

0x00,//AlternateSetting:0

0x00,//NumEndpoint:0

0x01,//InterfaceClass:audio

0x02,//InterfaceSubClass:audiostreaming

0x00,//InterfaceProtocol

0x00,//InterfaceString

//standard interface ASdescriptor(Interface 1, Alternate Setting 1):

//bNumEndpoints = 0x01,bInterFaceClass = 0x01(audio),bInterfaceSubClass= 0x02(audio stream),

0x09,//Length

0x04,//DescriptorType:Interface

0x01,//InterfaceNum:1

0x01,//AlternateSetting:1

0x01,//NumEndpoint:1

0x01,//InterfaceClass:audio

0x02,//InterfaceSubClass:audiostreaming

0x00,//InterfaceProtocol

0x00,//Interface String

//Audio Streaming InterfaceDescriptor:AS_GENERAL(0x01),

//TerminalLink 0x03,PCM(0x0001)

0x07,//Length

0x24,//DescriptorType:audiointerface descriptor

0x01,//DescriptorSubType:AS_GENERAL

0x03,//TerminalLink:#3USBUSB Streaming OT

0x01,//Delay:1

0x01,

0x00,//FormatTag:PCM

//Type 1 Format typedescriptor:FORMAT_TYPE(0x02),FORMAT_TYPE_I(0x01),

//physical channels 0x02,twobyte per audio subframe(0x02),16bit,

//32K(0x007d00)

0x0b,//Length

0x24,//DescriptorType:audiointerface descriptor

0x02,//DescriptorSubType:Format_type

0x01,//FormatType:Formattype 1

0x02,//NumberOfChanne:2

0x02,//SubframeSize:2byte

0x10,//BitsResolution:16bit

0x01,//SampleFreqType:Onesampling frequency.

0x00,

0x7d,

0x00,//32K(0x007d00)

//Endpoint 1 - StandardDescriptor:Input Endpoint1

//Isochronous,SynchronizationType(Asynchronous),MaxPacketSize 0x0084,

0x07,//Length

0x05,//DescriptorType:endpointdescriptor

0x81,//EndpointAddress:Inputendpoint 1

0x05,//Attributes:0x05,Isochronous,SynchronizationType(Asynchronous).........

0x84,

0x00,//MaxPacketSize:0x0084=........

0x01,//Interval

//Endpoint - Audio StreamingDescriptor:

//Audio Endpointdescriptor,General,

0x07,//Length

0x25,//DescriptorType:audioendpoint descriptor

0x01,//DescriptorSubType:audioendpiont general

0x00,//Attributes:0x00........

0x00,//LockDelayUnits

0x00,

0x00,//LockDelay

//-------------------Speakerinterface---------------------//

//standard interfaceAS descriptor(Interface 2, Alternate Setting 0):

//bNumEndpoints =0x00,bInterFaceClass = 0x01(audio),bInterfaceSubClass = 0x02(audio stream),

0x09,//Length

0x04,//DescriptorType:Interface

0x02,//InterfaceNum:2

0x00,//AlternateSetting:0

0x00,//NumEndpoint:0

0x01,//InterfaceClass:audio

0x02,//InterfaceSubClass:audiostreaming

0x00,//InterfaceProtocol

0x00,//InterfaceString

//standard interface ASdescriptor(Interface 2, Alternate Setting 1):

//bNumEndpoints =0x01,bInterFaceClass = 0x01(audio),bInterfaceSubClass = 0x02(audio stream),

0x09,//Length

0x04,//DescriptorType:Interface

0x02,//InterfaceNum:2

0x01,//AlternateSetting:1

0x01,//NumEndpoint:1

0x01,//InterfaceClass:audio

0x02,//InterfaceSubClass:audiostreaming

0x00,//InterfaceProtocol

0x00,//InterfaceString

//Audio Streaming InterfaceDescriptor:AS_GENERAL(0x01),

//TerminalLink 0x04,PCM(0x0001)

0x07,//Length

0x24,//DescriptorType:audiointerface descriptor

0x01,//DescriptorSubType:AS_GENERAL

0x04,//TerminalLink:#4USB Streaming IT

0x01,//Delay:1

0x01,

0x00,//FormatTag:PCM

//Type 1 Format typedescriptor:FORMAT_TYPE(0x02),FORMAT_TYPE_I(0x01),

//physical channels 0x02,twobyte per audio subframe(0x02),16bit,

//32K(0x007d00)

0x0b,//Length

0x24,//DescriptorType:audiointerface descriptor

0x02,//DescriptorSubType:Format_type

0x01,//FormatType:Formattype 1

0x02,//NumberOfChanne:2

0x02,//SubframeSize:2byte

0x10,//BitsResolution:16bit

0x01,//SampleFreqType:Onesampling frequency.

0x00,

0x7d,

0x00,//32K(0x007d00)

//Endpoint 2 - StandardDescriptor:Output Endpoint2

//Isochronous,SynchronizationType(Asynchronous),MaxPacketSize 0x0084,

0x07,//Length

0x05,//DescriptorType:endpoint descriptor

0x02,//EndpointAddress:Outputendpoint 2

0x05,//Attributes:0x05,Isochronous,SynchronizationType(Asynchronous).........

0x84,

0x00,//MaxPacketSize:0x0084=.....

0x01,//Interval

//Endpoint - Audio StreamingDescriptor:

//Audio Endpointdescriptor,General,

0x07,//Length

0x25,//DescriptorType:audioendpoint descriptor

0x01,//DescriptorSubType:audioendpiont general

0x00,//Attributes:0x00.............

0x00,//LockDelayUnits

0x00,

0x00,//LockDelay

};


/* USB String Descriptor (optional) */

const unsigned char Demo_StringLangID[] =

{

0x04,

0x03,

0x09,

0x04

};


const unsigned char Demo_StringVendor[] =

{

0x26, //Length

0x03, //DescriptorType

'D', 0, 'e', 0, 'm', 0, 'o', 0, '-', 0, 's', 0, 'p', 0, 'e', 0,

'r', 0, 'k', 0, 'e', 0, 'r', 0, 'p', 0, 'h', 0, 'o', 0, 'n', 0,

'e', 0, '1', 0

};


const unsigned char Demo_StringProduct[] =

{

0x1c,//Length

0x03,//DescriptorType

'S', 0, 'p', 0, 'e', 0, 'a', 0, 'k', 0, 'e', 0,

'r', 0, 'p', 0, 'h', 0, 'o', 0, 'n', 0, 'e', 0, '2', 0

};


const unsigned char Demo_StringSerial[] =

{

0x1c,//Length

0x03,//DescriptorType

'S', 0, 'p', 0, 'e', 0, 'a', 0, 'k', 0, 'e', 0,

'r', 0, 'p', 0, 'h', 0, 'o', 0, 'n', 0, 'e', 0, '2', 0

};


  相关说明:
这里就不针对整个描述符去作具体的分析,其实注释已经写的很详细了。这里只是对一些细节性的进行说明

1.
根据USB描述符可以得到其拓扑图
speakerphone
拓扑图

223136189.jpg

2.描述符的分层组织结构
speakerphone
描述符层次结构

223217372.jpg

3.设备描述符里采用的VendorProduct ID号是随便写的一个用于测试。

4.
设备描述符下包含一个配置描述符,配置描述符下包含了3组接口,IF0作为音频控制接口,IF1作为microphone接口,IF2作为speaker接口

5.
IF0的定义中没有包含任何端点,所以与音频相关的控制信息将通过默认的控制端点0来进行信息的交付。也就是说端点0除了响应默认的控制事务(Setinterfance等等)以外还需要响应音频类相关控制事务(set curget max等等)音量调节就是通过控制端点0来完成的

6.IF0
中的Feature Unit定义了音量调节方式,muteVolume,其中ID号为2Unit控制microphoneID 5控制speaker。具体关系常见其拓扑图。

7.IF0
中两个IT(Input Terminal)定义了音频流逻辑通道数及其具体组成形式,在该示例中包含了2个逻辑通道,分别是LEFT&RIGHT,如果需要更多的通道可以通过修改相应描述符单元得到(同时注意修改相应的Streaming描述符中物理通道数,相应USB endpoint支持的包字节大小)

8. IF1
IF2中都定义了2setting,其中setting 0都不包含传输endpointsetting 1都包含一个同步传输endpoint。这里要说明的是,之所以都要定义一个不含有任何传输endpoint(除了默认端点0)setting,是由usb audio设备特性决定的,该setting不可省略,setting用于在设备没有被使用时作为usb设备的设置。如果没有利用该usb设备进行放音和录音则主机使用的接口是IF(1,0)(接口1的设置0)IF(2,0)(接口2的设置0),如果开始放音则使用的接口是IF(1,0)IF(2,1),如果即用于放音又用于录音则使用IF(1,1)IF(2,1)。这里叙述的有些累赘,其实大家可以利用USB协议相关分析软件得到其具体交互过程。

9.
IF1IF2中定义了音频流格式为PCM格式(更多关于格式的信息参考USB audio相关文档)支持一个采样频点:32K,如果需要更多的采样频点的支持,可以通过修改相应字段得到(注意修改相应同步端点支持的包大小)

10.
IF1(microphone)定义了endpoint 1 作为其同步传输输入端点。端点支持的最大传输字节为0x84(132byte),这里的0x44是由 32*2*2=128=0x80(采样率*通道数*每个样点的字节数)得到的(0x80byte/ms),之所以会多出4字节是因为在之前的应用中如果支持44.1K时的一个考虑,当然这里可以将其定义为0x80

11.
IF1IF2AS endpoint Descriptor中的字段attributes可以用来定义是否支持采样率相关事务处理。也就是说如果在同一个IF的同一setting中支持多个采样率,那么在进行同步传输前,主机可以发起一个告知设备即将使用的采样率的事务处理,而这里的attributes用来定义设备是否支持这类事务处理。

12.
支持多个采样率不仅可以通过在第9点所叙述的方式来实现(同一setting下支持多个采样率),也可以通过增加新的setting来支持(每个setting支持一个单独的采样率)。两种方式各有优缺点,第一种方式比较简洁不过需要由主机告知设备即将使用的采样率。第二种方式会较大幅度的增加整个描述符长度,但是不需要主机告知设备使用的采样率。也就是说在第一种方式下主机先告诉即将使用的接口setting,然后再发起一个采样率的SET CUR事务处理。而第二种方式只需要告诉即将使用的接口就可以了(因为一个setting只支持一个采样率,不同采样率将采用不同setting)

13.
同步问题,因为usb传输都是主机发起的,而设备只是被动的响应来进行数据传输。对于同步传输,usb在每一个 frame中启动一次同步传输,该同步传输的启动是基于主机USB主控制器所使用的时钟来进行的,而设备得到数据是依据自己的时钟源,所以这里就存在两个时钟源差异的问题。我采用的方式是利用设备响应主机的SOF中断来调整自身时钟来与主机同步。