音頻類定義
USB非常適合作為以PC為平台的音頻(包括語音和音樂等)傳輸協定,而基於PC的電話系統從一開始就是USB接口發展的重要考量和推動力。從另一方面來說,USB接口擁有遠遠高於音頻需求的頻寬,可以傳輸極高品質(高採樣率,高編碼率,多聲道)的音頻數據。因此,例如電話,音樂回放,錄音等音頻功能都可以很容易在USB接口實現。
理論上,一個像USB這樣的通用數據接口,可以有很多種實現數字音頻數據傳輸的方式。不同的開發者可以根據自己的喜好和需求,定義任意的控制方式,傳輸模式,音頻格式等等參數。但是,從市場和工業開發考慮,定義一個被不同開發者認可,高質量的,並且被標準化的音頻傳輸機制是非常必要的。只有這樣,才有可能使可能在USB上連線的不同音頻設備保持最大的兼容性。標準化的傳輸機制,同樣可以使軟體驅動儘可能保持通用和簡潔。而USB音頻類( Audio Device Class)就是為了滿足以上要求而定義。USB音頻類包括了所有和USB接口兼容的音頻流和音頻控制功能,甚至包括使用模擬音源,利用USB接口作為控制接口的設備也被歸入USB音頻類設備。
下面將介紹開發USB音頻類中設計USB語音設備所有必須的信息。
任何USB設備在連線到USB接口後,主機檢測到有新設備接入,會利用不同的請求命令(Request)查詢該設備的屬性,設備通過不同的描述符向主機報告自己的情況。包括設備的種類,設備的功能,設備具有的端點數量以及其他工作屬性等等。在了解這些信息之後,主機就可以根據需要分配USB工作頻寬。USB定義了描述符層級如下:
/*Device Descriptors設備描述符*/
struct _DEVICE_DESCRIPTOR_STRUCT
{
BYTE bLength; //設備描述符的位元組數大小,為0x12
BYTE bDescriptorType; //描述符類型編號,為0x01
WORD bcdUSB; //USB版本號
BYTE bDeviceClass; //USB分配的設備類代碼,0x01~0xfe為標準設備類,0xff為廠商自定義類型
//0x00不是在設備描述符中定義的,如HID
BYTE bDeviceSubClass; //usb分配的子類代碼,同上,值由USB規定和分配的
BYTE bDeviceProtocl; //USB分配的設備協定代碼,同上
BYTE bMaxPacketSize0; //端點0的最大包的大小
WORD idVendor; //廠商編號
WORD idProduct; //產品編號
WORD bcdDevice; //設備出廠編號
BYTE iManufacturer; //描述廠商字元串的索引
BYTE iProduct; //描述產品字元串的索引
BYTE iSerialNumber; //描述設備序列號字元串的索引
BYTE bNumConfiguration; //可能的配置數量
}
/*Configuration Descriptor 配置描述符*/
struct _CONFIGURATION_DESCRIPTOR_STRUCT
{
BYTE bLength; //配置描述符的位元組數大小,為0x09
BYTE bDescriptorType; //描述符類型編號,為0x02
WORD wTotalLength; //配置所返回的所有數量的大小
BYTE bNumInterface; //此配置所支持的接口數量
BYTE bConfigurationVale; //Set_Configuration命令需要的參數值
BYTE iConfiguration; //描述該配置的字元串的索引值
BYTE bmAttribute; //供電模式的選擇
BYTE MaxPower; //設備從匯流排提取的最大電流
}
/*Interface Descriptor 接口描述符*/
struct _INTERFACE_DEscriptOR_STRUCT
{
BYTE bLength; //接口描述符的位元組數大小,為0x09
BYTE bDescriptorType; //描述符類型編號,為0x04
BYTE bInterfaceNunber; //接口的編號
BYTE bAlternateSetting;//備用的接口描述符編號
BYTE bNumEndpoints; //該接口使用端點數,不包括端點0
BYTE bInterfaceClass; //接口類型
BYTE bInterfaceSubClass;//接口子類型
BYTE bInterfaceProtocol;//接口所遵循的協定
BYTE iInterface; //描述該接口的字元串索引值
}
/*Endpoint Descriptor 端點描述符*/
struct _ENDPOIN_DESCRIPTOR_STRUCT
{
BYTE bLength; //端點描述符的位元組數大小,為0x07
BYTE bDescriptorType; //描述符類型編號,為0x05
BYTE bEndpointAddress; //端點地址及輸入輸出屬性
BYTE bmAttribute; //端點的傳輸類型屬性
WORD wMaxPacketSize; //端點收、發的最大包的大小
BYTE bInterval; //主機查詢端點的時間間隔
}
表1- 1音頻類接口描述符碼
Audio Interface Class Code | Value |
Audio | 0x01 |
子類和協定
USB音頻類定義在接口層,而USB音頻類又分為不同的子類(SubClass)以便於進一步的細節枚舉和設定。所有的USB音頻功能都被包括在USB音頻類的子類中。目前,USB定義了3種不同的音頻子類:
[01] AudioControl Interface Subclass 音頻控制接口子類
[02] AudioStreaming Interface Subclass 音頻流接口子類
[03] MIDIStreaming Interface Subclass MIDI流接口子類
USB不同音頻子類描述符碼:
表1-2音頻子類描述符碼
Audio Subclass Code | Value |
SUBCLASS_UNDEFINED | 0x00 |
AUDIOCONTROL | 0x01 |
AUDIOSTREAMING | 0x02 |
MIDISTREMING | 0x03 |
數據格式
USB音頻類可以被分為3種不同的類別,分別稱為TYPE I,TYPE II,以及TYPE III。
TYPE I
TYPE I主要針對於音頻數據流是按照物理時序以採樣為單位的數據格式,每一個採樣點由一個數據表示,而最終的音頻信號是將這些連續傳送的採樣數據進行DA轉換後得到的波形。在此類型中,使用某些壓縮算法並不改變其格式類型,只要該壓縮算法不影響數據以樣本為單位的基本格式,例如G.711語音編碼算法。在TYPE I格式下如果需要傳送多個聲道的數據,不同聲道的數據是交叉傳送的。因此,要從TYPE I中恢復多聲道數據,只需要將每個簇(Cluster)中依次提取出各個聲道的採樣值並分別恢復即可,因此,TYPE I在傳送過程中,保存了每個聲道的獨立性,恢復非常方便。
典型的TYPE I信號就是標準的PCM碼。
TYPE II
TYPE II針對語音編碼在傳輸中不保存每個物理信道獨立標誌的語音格式。總的來說,所有的非PCM語音編碼都屬於這個類型,通常,來自不同物理聲道的一定數量的音頻採樣點被編碼到一個比特流。只有在經過傳輸並解碼以後,才能以一定精度恢復出不同物理聲道的聲音。這種編碼模式相對於標準的PCM碼而言通常需要更少的數據量來傳送同樣的聲音數據,可以有效的降低傳送中對頻寬的需求。
TYPE III
TYPE III包括那些不屬於以上兩類的特殊的音頻數據格式。事實上,通常TYPE III套用在同時具有TYPE I和TYPE II兩種特點的數據流中。在這類音頻格式中,一個或多個非PCM編碼的音頻數據流被打包成偽立體聲採樣(Pseudo-stereo sample),在傳輸中,把這種信號假設成PCM信號進行傳輸。由於TYPE III通過偽採樣保存了原始的採樣率信息,比起TYPE II格式,更容易在輸出端準確恢復出時鐘信號。不過缺點在於除非把不同的非PCM編碼流打包成一個偽立體聲數據流,比起TYPE II需要更多的頻寬。當然,比起TYPE I對頻寬的需求更低。
USB音頻終端使用PCM碼,數據格式採用TYPE I,因此主要介紹TYPE I。
為了讓主機了解語音外設使用的音頻格式,同其他USB外設一樣,在設備列舉階段,需要利用描述符進行配置。
表1-3 TYPE I描述符格式如下
Offset | Field | Size | SizeValue |
0 | bLength | 1 | Number |
1 | bDescriptorType | 1 | Constant |
2 | bDescriptorSubtype | 1 | Constant |
3 | bFormatType | 1 | Constant |
4 | bNrChannels | 1 | Number |
5 | bSubframeSize | 1 | Number |
6 | bBitResolution | 1 | Number |
7 | bSamFreqType | 1 | Number |
8 | n |
其中,Size表示該欄位長度,以位元組為單位。BLength表示該描述符長度,計算公式為:
bLength=8+(ns*3)
公式中,8為固定欄位長度,ns代表該接口的端點支持的不同採樣率數量。例如,當該端點同時支持針對語音8KHz和針對音樂回放的44.1KHz時,ns取值2。
bDescriptorType 表示該描述符種類為音頻類特有的接口
bDescriptorSubtype 表示該描述符為數據格式描述符
bFormatType 指定該接口具體數據格式
bNrChannels 表示該接口支持的物理聲道數
bSubframeSize 音頻子幀大小
bBitResolution 指定採樣量化比特數
bSamFreqType 指定該接口支持頻率類型,可選為連續和固定兩種
最後一個欄位由bSamFreqType決定,目前,採用單一採樣率,只需要填入以24位二進制數表示的具體採樣率值即可,可選範圍為0到16777215Hz。
TYPE II和TYPE III的具體描述符這裡不再介紹。
數據流定義
USB音頻子幀是在USB匯流排上傳輸音頻數據最基本的單位,每個音頻子幀裝載一個採樣點。而每個子幀只能包含整數個位元組(Byte)的數據。USB協定限制了音頻子幀的數據大小,由bSubframeSize定義,可選範圍包括1,2,3,4位元組數據。一個音頻採樣是以一定位數的二進制數表示,由bBitResolution定義,其包含的二進制位數必須小於或等於一個音頻子幀的位數。例如,可以把一個12bit量化的音頻採樣放入一個2Byte的音頻子幀中。只要正確的配置了描述符,主機就會自動將12bit有效數據裝載到2Byte子幀中或從子幀中取出有效數據。
USB音頻幀是由一組音頻子幀組成的在物理時間上同時採樣得到的數據。他是不同物理聲道的子幀的組合,一個音頻幀中的子幀數量等同於在該音頻流中的邏輯聲道數,同一個音頻幀中的不同子幀定義的數據大小必須一致。在單聲道系統中,音頻幀和子幀數量是一致的。
數據流是一個連續的,由大量的音頻幀組成並按照採樣時間連續傳送的數據。音頻流被打包成USB數據包(USB packets)在USB匯流排上傳送。每個數據包只能包含整數個音頻流數據。
模組拓撲結構
為了能對應聲音的各種物理特性進行控制,例如簡單的音量增減,左右聲道平衡,較複雜的3D聲效,回聲等等功能。需要將聲音設備分割成不同的可獨立控制的實體(Entity)。在USB音頻類中,這些實體被分為兩大類,分別稱為單元和連線埠(Units and Terminals)。
單元(Unit)提供基本的音頻設備拓撲結構的構築“磚塊”,他們通過合理的邏輯連線能夠完成各種音頻功能,不同的音頻設備和功能都是利用將不同的單元通過不同的結構連線起來實現的。一個單元包括一個或多個擁有各自編號的輸入端以及唯一輸出端。
每一個設備中的單元都完全由它的單元描述符(Unit Descriptpr UD)描述。單元描述符包括了所有單元需要的描述信息。
連線埠(Terminal)只有輸入連線埠與輸出連線埠兩種。輸入連線埠(IT)代表音頻設備內一個聲道進入的起始端。相應的,輸出連線埠(OT)代表音頻設備內一個聲道的結束端。考慮整個語音設備和PC機形成的音頻功能中,USB端點就是一個典型的音頻輸出或輸入端。例如,對電腦而言麥克風捕捉的音頻信號經過設備處理髮送USB輸入端點,該端點同時也是語音設備的輸出連線埠。與單元類似,連線埠也完全由連線埠描述符(Terminal Descriptor TD)描述。
USB音頻類主要定義了以下單元和接口實體:
Input Terminal
Output Terminal
Mixer Unit
Selector Unit
Feature Unit
Processing Unit
Extension Unit
每一個單元內部通常還包含不同的功能,例如Feature Unit就包括聲道平衡,音量控制,EQ調整等等功能,通過利用Extension Unit不同的開發者還可以根據自己的需求自己定製功能模組。
USB音頻設備必須將其具有的,以一定的拓撲結構連線的單元和連線埠的拓撲結構和所支持的所有功能完全地通過描述符提交給主機端。主機端的通用驅動程式將利用這些信息來正確控制和配置USB音頻設備。目前,以我們採用的USB音頻終端的拓撲結構為例:
USB OUT Input Terminal Feature Unit Output Terminal
Endpoint ---> ID:1 ---> ID:9 ---> ID:6 ---> Speaker
Input Terminal Feature Unit Output Terminal USB IN
MicroPhone---> ID:2 ---> ID:a ---> ID:7 ---> Endpoint
圖1- 2USB語音終端拓撲結構
由上圖可知,該設備主要由輸出連線埠,輸入連線埠,特徵單元三種實體組成。其中一個輸入連線埠對應於一個USB輸出連線埠,另一個輸出對應於一個USB輸入連線埠。對這兩個連線埠,在向主機列舉設備的描述符時,還必須同時列舉其對應的USB端點的描述符,才能讓主機驅動程式完全了解設備的功能結構,以便正確的配置設備。其中,音頻流相關的參數信息由USB端點描述符描述,聲音控制(Audio Control)信息則由設備連線埠描述符描述。
以ID為1的輸入連線埠和ID為6的輸出連線埠為例,他們的描述符格式如下:
表1 - 4輸出端描述符
Offset | Field | Size | Value | description |
0 | bLength | 1 | 0x0c | 本描述符長度,以位元組為單位 |
1 | bDescriptorType | 1 | 0x24 | 本描述符種類為音頻專屬類別 |
2 | bDescriptorSubType | 1 | 0x02 | 本描述符子類為輸入連線埠 |
3 | bTerminalID | 1 | 0x01 | 本描述符對應實體ID號為1 |
4 | wTerminalType | 2 | 0x0101 | 輸入連線埠種類為USB數據流 |
6 | bAssocTerminal | 1 | 0x00 | 綁定連線埠,無 |
7 | bNrChannels | 1 | 0x02 | 本連線埠對應聲道數為2 |
8 | wChannelConfig | 2 | 0x0003 | 本連線埠對應聲道空間位置為左右聲道 |
10 | iChannelNames | 1 | 0x00 | Unused |
11 | iTerminal | 1 | 0x00 | unused |
表1 - 5 輸出連線埠描述符
Offset | Field | Size | Value | description |
0 | bLength | 1 | 0x09 | 本描述符長度,以位元組為單位 |
1 | bDescriptorType | 1 | 0x24 | 本描述符種類為音頻專屬類別 |
2 | bDescriptorSubType | 1 | 0x03 | 本描述符子類為輸出連線埠 |
3 | bTerminalID | 1 | 0x06 | 本描述符對應實體ID號為6 |
4 | wTerminalType | 2 | 0x0301 | 輸入連線埠種類為喇叭 |
6 | bAssocTerminal | 1 | 0x00 | 無綁定連線埠 |
7 | bSourceID | 1 | 0x09 | 本實體輸入信號來自於ID號為9的實體 |
8 | iTerminal | 1 | 0x00 | unused |
特徵單元負責聲音信號的一些常規處理工作,例如經常使用到的音量控制,靜音開關,音調調整,可視化均衡器,延遲,重低音加強等等。它幾乎包括了所有常用的控制功能,針對語音套用而言,特徵單元足以滿足對聲音的控制需求。在Windows作業系統中,作業系統在得到設備的特徵單元參數後,將利用這些參數調整Windows的音頻控制對畫框。以便於用戶使用可視化的界面對設備進行操作。以ID號為9的特徵單元為例,其描述符如下:
表2 - 6特徵單元描述符表
Offset | Field | Size | Value | descriotion |
0 | bLength | 1 | 0x0a | Descriptor length |
1 | bDescriptorType | 1 | 0x24 | CS_INTERFACE |
2 | bDescriptorSubType | 1 | 0x06 | FEATURE_UNIT |
3 | bUnitID | 1 | 0x09 | ID of this Output Terminal. |
4 | bSourceID | 1 | 0x01 | ID of input terminal |
5 | bControlSize | 1 | 0x01 | Size of an element of bmaControls |
6 | bmaControls(0) | 1 | 0x01 | A bit set to 1 indicates that the mentioned Control is supported for master channel 0: D0: Mute D1: Volume D2: Bass D3: Mid D4: Treble D5: Graphic Equalizer D6: Automatic Gain D7: Delay D8: Bass Boost D9: Loudness D10..(n*8-1): Reserved |