USBAudio技术.docx
《USBAudio技术.docx》由会员分享,可在线阅读,更多相关《USBAudio技术.docx(16页珍藏版)》请在冰豆网上搜索。
USBAudio技术
USBAudio技術解析與應用
1、相關技術與說明
USB傳輸協定
USB1.1通信協定的規範是以1毫秒產生一個USB訊框(frame),USB裝置可以在每一個訊框中傳送和接收一串交易(transactions)。
交易是由數個封包(packets)組成,由一或數個交易來完成傳遞一筆有意義的數據稱之為傳輸(transfer)。
傳輸方式有四種:
(1)控制型傳輸(ControlTransfers):
為雙向傳輸,主要用來溝通主機和裝置之間的配置、命令或狀態。
控制型傳輸包含三種控制傳輸型態:
控制讀取、控制寫入與無資料控制。
USB運用CRC(CyclicRedundancyCheck)來檢查資料之正確性,若此錯誤無法恢復,則要求重新傳送。
(2)中斷型傳輸(InterruptTransfers):
在USB1.0定義為單向傳輸,於USB1.1及USB2.0定義為雙向傳輸。
由於USB不支援硬體的中斷方式運行,所以必須靠主機以週期性的方式來輪詢(Polling),故於USB的中斷傳輸意即是一種輪詢的過程。
對於USB1.1的裝置而言,可以訂定1ms至255ms之間的輪詢週期,所以最快的輪詢速度為1kHz。
(3)巨量型傳輸(BulkTransfers):
可為單向或雙向的傳輸,適用於傳送大量的資料,且沒有固定的傳輸速率。
(4)同時型傳輸(IsochronousTransfers):
可為單向或雙向的傳輸,此種傳輸需要維持一定的傳輸速度,且允許一定錯誤率下的錯誤。
它事先與主機協議好固定的頻寬,以確保發送端及接收端的傳送速度。
在USBAudioMCU中,通常會支援控制型、中斷型與同時型等傳輸,其中同時型是專門用來傳送喇叭與麥克風的語音資料。
同時型(Isochronous)傳輸
USBAudio使用Isochronous傳輸模式,每個frame為1ms(USB規範
1ms±500ns),根據不同的頻率會傳送不同大小的語音資料量,例如48KHz/16-bit/2-CH時,1ms的資料量為192byte,以此為例,USBAudioMCU內部有兩塊Ping-Pong結構的Buffer,各為192Bytes,總共為384Bytes,以SOF(StartOfFrame)做為切換兩個Buffer的控制信號。
由IsochronousIn/Out傳輸的圖可以發現USB的Isochronous傳輸不需要ACK信號,與USB的其他三種傳輸Control/Interrupt/Bulk是不同,也就是說,就算是資料有錯,也不會重傳。
圖(三)IsochronousIn/Out傳輸
在USBAudioMCU必須包含兩個Isochronous端點(Endpoint),一個是IsochronousOut,另一個是IsochronousIn。
IsochronousOut是用來將PC的撥放媒體的語音資料經由USBPort傳給裝置,語音資料設定為PCM格式,假設是在48KHz/16-bit/2-CH情況下,一個Frame傳192Bytes資料,在描述元(Descriptor)關於撥放語音格式的定義如下文字描述所示,在此描述元定義了撥放頻率、一個Frame的資料量、端點號碼與端點的方向等;在USBAudioIC,Isochronousout的EndpointNumber設定為2,圖(四)的USB封包圖是用CATCUSBAnalyzer在撥放音樂時所擷取下來的,可以觀察出每個frame主機(PC)傳192Bytes語音資料給裝置。
format_type_descriptor:
;;11bytes
DW0240BH;descriptortype(CS_INTERFACE),sizeofdescriptor
DW00102H;FormatType(FORMAT_TYPE_I),descriptorSubType(FORMAT_TYPE)
DW00202H;SubFrameSize(2byteperslot),numberofchannel(2channels)
DW00110H;SamFreqType(support1type),BitSolution(16bits)
DW03F80H;SampleFrequency(48000Hz)
DW000BBH;BB80H=48000
end_point_descriptor:
;;9bytes
DW00509H;descriptortype(END_POINT),sizeofdescriptor
DW00902H;endpointattributes(adaptive,isochronous),endpoint2(outdirection)
DW000C0H;maxPacketSize(192bytes)
DW00001H;Refresh(0),Interval(1ms)
DW03F00H;indexstringofthisdescriptor
圖(四)IsochronousOutUSB傳輸封包
接下來介紹的是IsochronousIn端點,這個端點是用來將Microphone的語音資料經由此端點傳給PC,語音資料為PCM格式,一般是8KHz/16-bit/1-CH,在此情況下,一個Frame傳16Bytes資料,在描述元關於語音格式的定義如下文字描述所示,與IsochronousOut的定義方式類似:
圖(五)是用CATCUSBAnalyzer,在麥克風錄音時所擷取下來的USB封包圖。
ad_typeI_format_type:
;;11bytes
DW0240BH;CS_INTERFACE,Sizeofthisdescriptor
DW00102H;FORMAT_TYPE_I,FORMAT_TYPE
DW00201H;twobytesperslot,onechannel
DW00110H;1frequency,16bits
DW03F40H;8000Hz
DW0001FH;1F40H=8000
ad_standard_endpoint_descriptor:
;;9bytes
DW00509H;ENFPOINTdescriptor,Sizeofthisdescriptor
DW00183H;(bmAttributes)Isochronous,asynchronous,notshare,INendpoint3
DW00010H;2bytes*8sample*1CH=16bytes/frame
DW00001H;Unused,1packeteveryframe(mustbesetto1)
DW03F00H;Unused
圖(五)IsochronousInUSB傳輸封包
音量控制
(一)喇叭與麥克風的音量控制:
在微軟作業系統有一個音量控制的視窗,當使用者拉動此控制鍵時,USB會透過端點0(ControlEndpoint)下一個SET_CUR的咨求函數來調整(SET_CUR咨求函數內容如下表格所示)音量,PC下過來的音量設定值會反應到IC的DigitalVolumeControl暫存器,因此就能改變音樂時的聲音大小。
在使用麥克風時,也能由視窗作業系統控制台的聲音及音訊裝置改變麥克風的音量。
下表為喇叭與麥克風的音量控制咨求函數,由SET_CUR的wIndex欄位來決定是要對喇叭還是麥克風做音量控制,wIndex=0x0200表示要對喇叭做音量控制,要對麥克風做音量控制時wIndex=0x0600。
Offset
Field
Size
Value
Description
0
bmRequestType
1
0x21
1
bRequest
1
0x01
SET_CUR
2
wValue
2
0x0200
DAC:
VOLUME_CONTROL|MasterChannel
ADC:
VOLUMECONTROL|MasterChannel
4
wIndex
2
0x0200
0x0600
D/AFeatureUnitID:
0x02(LineoutLchandRchVolume)
A/DFeatureUnitID:
0x06(MICRECMasterCH)
LowerByte:
AudioControlInterface(0x00)
6
wLength
2
0x0002
VolumeControl
表
(一)SET_CUR咨求函數內容
Offset
Field
Size
Value
Description
0
bMute
2
0xYYYY
Thevalueissetbyhost
表
(二)SET_CUR咨求函數送出2-Bytes的資料
在對喇叭或麥克風進行音量控制時,咨求函數後會跟隨2-Bytes的資料,這兩個Bytes資料就是音量大小的值,表(三)的喇叭音量控制的高位元組,是根據IC的音量控制暫存器所定義的設定範圍,表(四)是麥克風音量控制的高位元組值。
此外,在匯流排列舉(BusEnumeration)過程中,作業系統會以SET_CUR的咨求函數來設定喇叭與麥克風的初始音量值,一般而言會設在中間值。
VolumeValue
USBAudioClassFormat
+6.0dB
0x0C00
+5.5dB
0x0B00
+0.5dB
0x0100
+0.0dB
0x0000
-0.5dB
0xFF00
-1.0dB
0xFE00
-12.0dB
0xE800
-13.0dB
0xE700
-14.0dB
0xE600
-32.0dB
0xC800
表(三)喇叭音量控制的高位元組(低位元組皆為00H)
VolumeValue
USBAudioClassFormat
6.0dB
001100
5.5dB
001011
5.0dB
001010
4.5dB
001001
4.0dB
001000
3.5dB
000111
3.0dB
000110
2.5dB
000101
2.0dB
000100
1.5dB
000011
1.0dB
000010
0.5dB
000001
0.0dB
000000
表(四)麥克風音量控制的高位元組(低位元組皆為00H)
圖(七)喇叭音量設定USB封包圖
圖(八)麥克風音量設定之USB封包圖
下表為喇叭與麥克風的靜音控制咨求函數,由wIndex欄位來決定是要對喇叭還是麥克風做音量控制,wIndex=0x0200表示要對喇叭做靜音控制,要對麥克風做靜音控制時wIndex=0x0600,接下來主機會送1-byte資料,如果值是0x01代表要靜音。
Offset
Field
Size
Value
Description
0
bmRequestType
1
0x21
1
bRequest
1
0x01
SET_CUR
2
wValue
2
0x0100
MUTE_CONTROL|CHANNEL_0
4
wIndex
2
0x0200
0x0600
MuteforLineoutVolume|interface0
MuteforMICRecordingVolume|interface0
6
wLength
2
0x0001
表(五)靜音控制的咨求函數
Offset
Field
Size
Value
Description
0
bMute
1
0x01
0x00
TRUE(靜音)
FALSE
表(六)靜音控制咨求函數送出1-Byte的資料
圖(九)麥克風靜音控制之USB封包圖
在匯流排列舉過程中,作業系統會先來讀取AudioDevice音量的參數(最大音量、最小音量、變化單位),當作業系統從裝置讀取這些參數後,才能對裝置做正確音量控制,讀取關於音量咨求函數與裝置的回傳值說明如表(七)與表(八);在表(八)可以得知,喇叭的音量最大為+6dB,喇叭音量最小為-32dB,而麥克風的音量最大為+6dB,麥克風音量最小為0dB,解析度1代表裝置的音量控制變化單位為1,以上所談到的這些值,可以依不同音效裝置的需求而改變。
Offset
Field
Size
Value
Description
0
bmRequestType
1
0xA1
1
bRequest
1
0x81
0x82
0x83
0x84
GET_CUR
GET_MIN
GET_MAX
GET_RES
2
wValue
2
0x0200
VOLUME_CONTROL|MasterCH
4
wIndex
2
0x0200
0x0600
LineoutVolume|interface0
MICRecordingVolume|interface0
LowerByte:
AudioControlInterface(0x00)
6
wLength
2
0x0002
VolumeControl
表(七)讀取音量參數的咨求函數
bRequest
wValue
wIndex
wVolume
說明
0x81
0x0200
0x0200
0xYYYY
讀取裝置目前的喇叭音量
0x82
0x0200
0x0200
0xE000
讀取裝置目前的喇叭音量的最小音量(-32dB).
0x83
0x0200
0x0200
0x0C00
讀取裝置目前的喇叭音量的最大音量(+6dB).
0x84
0x0200
0x0200
0x0100
讀取裝置的喇叭音量變化單位
(1)
0x81
0x0200
0x0600
0xYYYY
讀取裝置目前的麥克風音量
0x82
0x0200
0x0600
0x0000
讀取裝置目前的麥克風音量的最小音量(0dB)
0x83
0x0200
0x0600
0x0C00
讀取裝置目前的麥克風音量的最大音量(6dB)
0x84
0x0200
0x0600
0x0100
讀取裝置的麥克風音量變化單位
(1)
表(八)讀取喇叭/麥克風音量參數咨求函數的回傳值範例
除了直接用Windows上的音量控制改變音量外,另外一種方式也可以用USB規範中的HID(HumanInterfaceDevice),直接在使用者的裝置端以按鍵的方式,直接改變音量,要用此方法在裝置端改變音量,必須撰寫正確的HID報告描述語言。
如下的hid_report_desc_table是MediaKey的完整報告描述元。
在USBHIDUsageTables規範中可以查詢,VolumeIncrement的UsageID是E9、VolumeDecrement的UsageID是EA及Mute的UsageID是E2,而前面的09代表後面的UsageID是一個Byte,如果後面的UsageID是2個Bytes,則UsageID前面的Byte為0A。
值DW00175H所表示的意思是所輸入的MediaKey佔多少位元,以00175H為例子,它表示一個Key佔用一個位元。
第二個值為DW00295H表示的意思是上面使用到幾個Bit,由於上面使用到VolumeIncrement/Decrement二種功能,所以在這裏為00295H,佔用二個Bit。
由上說明我們使用MediaKey,目前使用了三個鍵,而這三個鍵分別為VolumeIncrement/Decrement/Mute,這三個鍵在一個Byte裏佔了三個Bit,其功能與位元對應關係如下表所示。
Bit7
Bit6
Bit5
Bit4
Bit3
Bit2
Bit1
Bit0
Unused
Unused
Unused
Unused
Unused
Mute
VolumeDecrement
VolumeIncrement
而且先宣告的功能是先佔用低的位元。
以我們例子來看,上面先宣告VolumeIncrement,所以它在位元0,而VolumeIncrement則在位元1,以此類推。
此時,有五個位元未使用到(Unused)也必須將報告描述元完整描述,構成一完整位元組。
舉例來說,若為靜音時,則送出04H,若要增加音量增則為01H,音量減少則是02H。
hid_report_desc_table:
DW00C05H;//UsagePage(Consumer)
DW00109H;//UsagePage(ConsumerControl)
DW001A1H;//Collection(Application)
DW00015H;//LogicMinimum(0)
DW00125H;//LogicMaximum
(1)
DW03F09H;//Usage(VolumeIncrement)
DW03FE9H
DW03F09H;//Usage(VolumeDecrement)
DW03FEAH
DW00175H;//ReportSize
(1):
DataLength
(1)bit
DW00295H;//ReportCount
(2):
NumberofData(INC,DEC)
DW02A81H;//Input(Data,Variable,Absolute,No_Wrap,No_Preferred)
DW03F09H;//Usage(Mute)
DW03FE2H
DW00195H;//ReportCount
(1)
DW02E81H;//Input(Data,Variable,Relative,No_Wrap,No_preferred)
DW00595H;//ReportCount(5)
DW00181H;//Input(Constant)
DW03FC0H;//EndCollection
end_hid_report_desc_table:
將介面宣告成HID介面,一方面裝置可用微軟提供的內建HID驅動程式,不用自行開發驅動程式,另一方面,在應用程式方面才可以直接呼叫微軟現成提供的API去讀寫裝置,如以下4個函式原型。
此4個函式目前都是呼叫微軟所提供的API,從主機寫資料至裝置去或將裝置的資料讀取進來。
boolReadDeviceFirst(constDWORDvendorID,constDWORDproductID,constDWORDUsagePageNum,constWORDUsageNum);
voidNewReadDevice();
boolWriteDeviceFirst(constDWORDvendorID,constDWORDproductID,constDWORDUsagePageNum,constWORDUsageNum);
voidNewWriteevice(stringpszBig5,constWORDUpPageAddress,constWORDDownPageAddress,intbFlagXOR);
舉例來說,一個讀取函式的例子,如下所示:
DWORDvendorID=0x04D9;
DWORDproductID=0x2832;
DWORDversionNumber=0x0100;
PUSBDevicemydevice;
mydevice.ReadDeviceFirst(vendorID,productID,0xFF00,0x00A5);
第一個參數vendorID=0x04D9以及第二個參數productID=0x2832,這2個數值是在裝置描述元中宣告(如下),而第三個及第四個分別為0xff00(UsagePageNum)以及0x00A5(UsageNum)是在HID報告描述元裏宣告。
device_desc_table:
;;18bytes
DW00112H;descriptortype(devicedescriptor),sizeofdescriptor(18bytes)
DW00110H;USBspecrelease(ver1.1)
DW00000H;devicesub-class,deviceclass
DW00800H;maximumpacketsize,devicesub-sub-class
DW004D9H;vendorID=004D9H
DW02832H;productversionID(HT82A832R)
DW00100H;productversionID
DW00201H;productstringindex,manufacturerstringindex
DW00103H;numberofconfigurations,serialnumberstringindex
end_device_desc_table:
再舉一個寫入裝置函式的例子,如下所示:
mydevice.WriteDeviceFirst(vendorID,productID,0xFF00,0x01);
而第三個及第四個參數分別為0xff00(UsagePageNum)以及0x0001(UsageNum);中斷輸入端點的報告描述語言如下所示:
hid_report_desc_table2:
DW03F06H;//UsagePage(Global)
DW03F00H
DW03FFFH;//UsagePage
DW03F09H;//Usage(Local1bytes)
DW03F01H
DW001A1H;//collection(Main)
;output
DW03F19H