usb 音频类描述符及其说明(usb audio descriptor)

写在前面:

前两天拿到一个产品,也就是一speakerphone;以前自己也参加过音频类USB设备的研发,当然只是单独的speaker或microphone,也曾经想过怎么让同一USB设备即作speaker输出又作microphone输入,只不过没有具体去实现。当拿到这个speakerphone后就有一种去实现这样一个USB设备的冲动,于是就有了这篇文章.......

 

先给出完整的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,    //bMaxPacketSize 8
 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,    //Configuration String             
 0x80,    //Attributes:Bus Power             
 0xfa,     //MaxPower = 0xfa*2ma  

            

 //standard interface AC descriptor(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:audio ctl
 0x00,       //InterfaceProtocol         
 0x00,      //Interface String       

   

 //class-specific AC interface descriptor,audio interface(0x24),audio control header(0x01),
 //Total Length 0x0048,Number of streaming interface 2,interfaceNr 2,1
 0x0a,    //Length                                                                                       
 0x24,      //DescriptorType:audio interface descriptor                                                    
 0x01,     //DescriptorSubType:audio control header                                                       
 0x00,0x01,  //bcdADC:audio Device Class v1.00                                                              
 0x48,0x00,  //TotalLength:0x0048                                                                           
 0x02,      //InCollection:2 AudioStreaming interface                                                      
 0x02,      //InterfaceNr(2) - AS #1 id AudioStreaming interface 2 belongs to this AudioControl interface  
 0x01,     //InterfaceNr(1) - AS #2 id AudioStreaming interface 1 belongs to this AudioControl interface  

 

 //USB Microphone IT:audio interface descriptor,audio control input terminal(0x02),terminal id 0x01,
 //Microphone(0x0201),Input Terminal(0x02),2 channel:Left Front,Right Front
 0x0c,    //Length                                                                                                   
 0x24,    //DescriptorType:audio interface descriptor                                                                
 0x02,     //DescriptorSubType:Input Terminal                                                                         
 0x01,     //TerminalID:0x01                                                                                          
 0x01,0x02,  //TerminalType:USB Microphone                                                                               
 0x00,      //AssocTerminal                                                                                            
 0x02,      //NrChannels:2 channel                                                                                            
 0x03,0x00,  //ChannelConfig:Left Front,Right Front, 
 0x00,       //ChannelName String                                                                                       
 0x00,       //Terminal String               

                                                                           

 //Audio Feature Unit Descriptor:audio interface descriptor,feature_unit(0x06),terminal id 0x02,
 //SourceId 0x01,ControlSize 0x01,Mute,Volume,                                          
 0x0a,    //Length                                  
 0x24,      //DescriptorType:audio interface descriptor
 0x06,      //DescriptorSubType:Audio Feature Unit    
 0x02,       //UnitID:0x02                             
 0x01,      //SourceID:1 #Microphone IT               
 0x01,      //ControlSize:1 byte                      
 0x01,     //Controls:Mute                          
 0x02,      //Controls(0):Volume                      
 0x02,       //Controls(1):Volume                      
 0x00,       //Feature String            

              

 //USB Streaming OT:audio interface descriptor,audio control output terminal(0x03),terminal id 0x03,
 //USB Streaming(0x0101),Output Terminal(0x03),SourceId 0x02,     
 0x09,    //Length                                    
 0x24,       //DescriptorType:audio interface descriptor 
 0x03,      //DescriptorSubTYpe:Output Terminal         
 0x03,      //TerminalID:0x03                          
 0x01,0x01,  //TerminalType:USB Streaming                
 0x00,       //AssocTerminal:ID 0                        
 0x02,      //SourceID:2 #Feature UNIT                          
 0x00,       //Terminal String          

                 

 //USB USB Streaming IT:audio interface descriptor,audio control input terminal(0x02),terminal id 0x04,
 //USB Streaming(0x0101),Input Terminal(0x02),2 channel:Left Front,Right Front
 0x0c,       //Length                                   
 0x24,       //DescriptorType:audio interface descriptor
 0x02,       //DescriptorSubType:Input Terminal         
 0x04,       //TerminalID:0x04                          
 0x01,0x01,  //TerminalType:USB Streaming              
 0x00,       //AssocTerminal                            
 0x02,       //NrChannels:2 channel                             
 0x03,0x00,  //ChannelConfig:Left Front,Right Front,    
 0x00,       //ChannelName String                       
 0x00,       //Terminal String                          


 //Audio Feature Unit Descriptor:audio interface descriptor,feature_unit(0x06),terminal id 0x05,
 //SourceId 0x04,ControlSize 0x01,Mute,Volume, 
 0x0a,    //Length                                  
 0x24,      //DescriptorType:audio interface descriptor
 0x06,       //DescriptorSubType:Audio Feature Unit    
 0x05,       //UnitID:0x05                            
 0x04,      //SourceID:4 #USB Streaming IT               
 0x01,      //ControlSize:1 byte                      
 0x01,      //Controls:Mute,                    
 0x02,       //Controls(0):Volume                            
 0x02,      //Controls(1):Volume                            
 0x00,       //Feature String              

            

 //USB Speaker OT:audio interface descriptor,audio control output terminal(0x03),terminal id 0x06,
 //USB Speaker(0x0301),Output Terminal(0x03),SourceId 0x05,
 0x09,      //Length                                   
 0x24,      //DescriptorType:audio interface descriptor
 0x03,      //DescriptorSubTYpe:Output Terminal        
 0x06,      //TerminalID:0x06                          
 0x01,0x03,  //TerminalType:Speaker               
 0x00,       //AssocTerminal:                      
 0x05,      //SourceID:5 #Feature UNIT                   
 0x00,      //Terminal String
                       
 //-------------------Microphone  interface---------------------//
 //standard interface AS descriptor(Interface 1, Alternate Setting 0):
 //bNumEndpoints = 0x00,bInterFaceClass = 0x01(audio),bInterfaceSubClass = 0x02(audio stream),                 
 0x09,    //Length                          
 0x04,       //DescriptorType:Interface        
 0x01,      //InterfaceNum:1                  
 0x00,      //AlternateSetting:0              
 0x00,       //NumEndpoint:0                   
 0x01,      //InterfaceClass:audio            
 0x02,      //InterfaceSubClass:audio streaming
 0x00,       //InterfaceProtocol               
 0x00,       //Interface String            

    

 //standard interface AS descriptor(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:audio streaming
 0x00,      //InterfaceProtocol               
 0x00,       //Interface String        

        

 //Audio Streaming Interface Descriptor:AS_GENERAL(0x01),
 //TerminalLink 0x03,PCM(0x0001)
 0x07,    //Length                                     
 0x24,       //DescriptorType:audio interface descriptor  
 0x01,      //DescriptorSubType:AS_GENERAL               
 0x03,       //TerminalLink:#3USB USB Streaming OT          
 0x01,       //Delay:1                                    
 0x01,0x00,  //FormatTag:PCM        

                      

 //Type 1 Format type descriptor:FORMAT_TYPE(0x02),FORMAT_TYPE_I(0x01),
 //physical channels 0x02,two byte per audio subframe(0x02),16bit,
 //32K(0x007d00)
 0x0b,    //Length                                  
 0x24,      //DescriptorType:audio interface descriptor
 0x02,      //DescriptorSubType:Format_type           
 0x01,       //FormatType:Format type 1                
 0x02,      //NumberOfChanne:2                        
 0x02,       //SubframeSize:2byte                      
 0x10,      //BitsResolution:16bit                    
 0x01,       //SampleFreqType:One sampling frequency.   
 0x00,0x7d,0x00,   //32K(0x007d00)                     

    

 //Endpoint 1 - Standard Descriptor:Input Endpoint1                  
 //Isochronous,Synchronization Type(Asynchronous),MaxPacketSize 0x0084,
 0x07,     //Length                                                            
 0x05,      //DescriptorType:endpoint descriptor                                
 0x81,       //EndpointAddress:Input endpoint 1                                 
 0x05,       //Attributes:0x05,Isochronous,Synchronization Type(Asynchronous).........
 0x84,0x00,  //MaxPacketSize:0x0084=........                                       
 0x01,      //Interval                                        

                  

 //Endpoint - Audio Streaming Descriptor:
 //Audio Endpoint descriptor,General, 
 0x07,    //Length                                   
 0x25,      //DescriptorType:audio endpoint descriptor 
 0x01,      //DescriptorSubType:audio endpiont general 
 0x00,       //Attributes:0x00........             
 0x00,      //LockDelayUnits                           
 0x00,0x00,  //LockDelay                 

               

 //-------------------Speaker  interface---------------------//
 //standard interface AS 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:audio streaming
 0x00,      //InterfaceProtocol               
 0x00,       //Interface String                

 

 //standard interface AS descriptor(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:audio streaming
 0x00,       //InterfaceProtocol               
 0x00,      //Interface String                

 

 //Audio Streaming Interface Descriptor:AS_GENERAL(0x01),
 //TerminalLink 0x04,PCM(0x0001)
 0x07,      //Length                                  
 0x24,       //DescriptorType:audio interface descriptor
 0x01,       //DescriptorSubType:AS_GENERAL            
 0x04,      //TerminalLink:#4 USB Streaming IT    
 0x01,      //Delay:1                                 
 0x01,0x00,  //FormatTag:PCM     

                      

 //Type 1 Format type descriptor:FORMAT_TYPE(0x02),FORMAT_TYPE_I(0x01),
 //physical channels 0x02,two byte per audio subframe(0x02),16bit,
 //32K(0x007d00)
 0x0b,     //Length                                  
 0x24,       //DescriptorType:audio interface descriptor
 0x02,      //DescriptorSubType:Format_type           
 0x01,       //FormatType:Format type 1                
 0x02,       //NumberOfChanne:2                        
 0x02,       //SubframeSize:2byte                      
 0x10,      //BitsResolution:16bit                    
 0x01,      //SampleFreqType:One sampling frequency.  
 0x00,0x7d,0x00,   //32K(0x007d00)         

                  

 //Endpoint 2 - Standard Descriptor:Output Endpoint2                  
 //Isochronous,Synchronization Type(Asynchronous),MaxPacketSize 0x0084,
 0x07,      //Length                                                               
 0x05,       //DescriptorType:endpoint descriptor                                   
 0x02,       //EndpointAddress:Output endpoint 2                                     
 0x05,      //Attributes:0x05,Isochronous,Synchronization Type(Asynchronous).........
 0x84,0x00,  //MaxPacketSize:0x0084=.....                                           
 0x01,      //Interval                               

                              

 //Endpoint - Audio Streaming Descriptor:
 //Audio Endpoint descriptor,General, 
 0x07,       //Length                                    
 0x25,       //DescriptorType:audio endpoint descriptor  
 0x01,       //DescriptorSubType:audio endpiont 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描述符可以得到其拓扑图:

 

 

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

 

 

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

 

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

 

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

 

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

 

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

 

8. IF1和IF2中都定义了2个setting,其中setting 0都不包含传输endpoint,setting 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.在IF1和IF2中定义了音频流格式为PCM格式(更多关于格式的信息参考USB audio相关文档)。支持一个采样频点:32K,如果需要更多的采样频点的支持,可以通过修改相应字段得到(注意修改相应同步端点支持的包大小)。

 

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

 

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

 

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

 

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

你可能感兴趣的:(杂七杂八)