I2S—音訊播放與錄音輸入
本章參考資料:《STM32F4xx 中文參考手冊》、《STM32F4xx規格書》、庫幫助文件《stm32f4xx_dsp_stdperiph_lib_um.chm》及《I2S BUS》。
若對I2S通訊協議不瞭解,可先閱讀《I2S BUS》文件的內容學習。
關於音訊編譯碼器WM8978,請參考其規格書《WM8978_v4.5》來了解。
38.1 I2S簡介
Inter-IC Sount Bus(I2S)是飛利浦半導體公司(現為恩智浦半導體公司)針對數字音訊裝置之間的音訊資料傳輸而制定的一種匯流排標準。在飛利浦公司的I2S標準中,既規定了硬體介面規範,也規定了數字音訊資料的格式。
38.1.1 數字音訊技術
現實生活中的聲音是通過一定介質傳播的連續的波,它可以由週期和振幅兩個重要指標描述。正常人可以聽到的聲音訊率範圍為20Hz~20KHz。現實存在的聲音是模擬量,這對聲音儲存和長距離傳輸造成很大的困難,一般的做法是把模擬量轉成對應的數字量儲存,在需要還原聲音的地方再把數字量的轉成模擬量輸出,參考圖 381。
圖 381 音訊轉換過程
模擬量轉成數字量過程,一般可以分為三個過程,分別為取樣、量化、編碼,參考圖 382。用一個比源聲音訊率高的取樣訊號去量化源聲音,記錄每個取樣點的值,最後如果把所有采樣點數值連線起來與源聲音曲線是互相吻合的,只是它不是連續的。在圖中兩條藍色虛線距離就是取樣訊號的週期,即對應一個取樣頻率(FS),可以想象得到取樣頻率越高最後得到的結果就與源聲音越吻合,但此時取樣資料量越越大,一般使用44.1KHz取樣頻率即可得到高保真的聲音。每條藍色虛線長度決定著該時刻源聲音的量化值,該量化值有另外一個概念與之掛鉤,就是量化位數。量化位數表示每個取樣點用多少位表示資料範圍,常用有16bit、24bit或32bit,位數越高最後還原得到的音質越好,資料量也會越大。
圖 382 聲音數字化過程
WM8978是一個低功耗、高質量的立體聲多媒體數字訊號編譯碼器,整合DAC和ADC,可以實現聲音訊號量化成數字量輸出,也可以實現數字量音訊資料轉換為模擬量聲音驅動揚聲器。這樣使用WM8978晶片解決了聲音與數字量音訊資料轉換問題,並且通過配置WM8978晶片相關暫存器可以控制轉換過程的引數,比如取樣頻率,量化位數,增益、濾波等等。
WM8978晶片是一個音訊編譯碼器,但本身沒有儲存音訊資料功能,它只能接收其它裝置傳輸過來的音訊資料進行轉換輸出到揚聲器,或者把取樣到的音訊資料輸出到其它具有儲存功能的裝置儲存下來。該晶片與其他裝置進行音訊資料傳輸介面就是I2S協議的音訊介面。
38.1.2 I2S匯流排介面
I2S匯流排介面有3個主要訊號,但只能實現資料半雙工傳輸,後來為實現全雙工傳輸有些裝置增加了擴充套件資料引腳。STM32f42x系列控制器支援擴充套件的I2S匯流排介面。
(1) SD(Serial Data):序列資料線,用於傳送或接收兩個時分複用的資料通道上的資料(僅半雙工模式),如果是全雙工模式,該訊號僅用於傳送資料。
(2) WS(Word Select):欄位選擇線,也稱幀時鐘(LRC)線,表明當前傳輸資料的聲道,不同標準有不同的定義。WS線的頻率等於取樣頻率(FS)。
(3) CK(Serial Clock):序列時鐘線,也稱位時鐘(BCLK),數字音訊的每一位資料都對應有一個CK脈衝,它的頻率為:2*取樣頻率*量化位數,2代表左右兩個通道資料。
(4) ext_SD(extend Serial Data):擴充套件序列資料線,用於全雙工傳輸的資料接收。
另外,有時為使系統間更好地同步,還要傳輸一個主時鐘(MCK),STM32F42x系列控制器固定輸出為256* FS。
38.1.3 音訊資料傳輸協議標準
隨著技術的發展,在統一的I2S硬體介面下,出現了多種不同的資料格式,可分為左對齊(MSB)標準、右對齊(LSB)標準、I2S Philips標準。另外,STM32F42x系列控制器還支援PCM(脈衝編碼調)音訊傳輸協議。下面以STM32F42x系列控制器資源解釋這四個傳輸協議。
STM32f42x系列控制器I2S的資料暫存器只有16bit,並且左右聲道資料一般是緊鄰傳輸,為正確得到左右兩個聲道資料,需要軟體控制資料對應通道資料寫入或讀取。另外,音訊資料的量化位數可能不同,控制器支援16bit、24bit和32bit三種資料長度,因為資料暫存器是16bit的,所以對於24bit和32bit資料長度需要傳送兩個。為此,可以產生四種資料和幀格式組合:
將16位資料封裝在16位幀中
將16位資料封裝在32位幀中
將24位資料封裝在32位幀中
將32位資料封裝在32位幀中
當使用32位資料包中的16位資料時,前16位(MSB)為有效位,16位LSB被強制清零,無需任何軟體操作或DMA請求(只需一個讀/寫操作)。如果程式使用DMA傳輸(一般都會用),則24位和32位資料幀需要對資料暫存器執行兩次DMA操作。24位的資料幀,硬體會將8位非有效位擴充套件到帶有0位的32位。對於所有資料格式和通訊標準而言,始終會先發送最高有效位(MSB優先)。
1. I2S Philips標準
使用WS訊號來指示當前正在傳送的資料所屬的通道,為0時表示左通道資料。該訊號從當前通道資料的第一個位(MSB)之前的一個時鐘開始有效。傳送方在時鐘訊號(CK)的下降沿改變資料,接收方在上升沿讀取資料。WS訊號也在SCK的下降沿變化。參考圖 383,為24bit資料封裝在32bit幀傳輸波形。正如之前所說,WS線頻率對於取樣頻率FS,一個WS線週期包括髮送左聲道和右聲道資料,在圖中實際需要64個CK週期來完成一次傳輸。
圖 383 I2S Philips標準24bit傳輸
2. 左對齊標準
在WS發生翻轉同時開始傳輸資料,參考圖 384,為24bit資料封裝在32bit幀傳輸波形。該標準較少使用。注意此時WS為1時,傳輸的是左聲道資料,這剛好與I2S Philips標準相反。
圖 384 左對齊標準24bit傳輸
3. 右對齊標準
與左對齊標準類似,參考圖 385,為24bit資料封裝在32bit幀傳輸波形。
圖 385 右對齊標準24bit傳輸
4. PCM標準
PCM即脈衝編碼調製,模擬語音訊號經過取樣量化以及一定資料排列就是PCM了。WS不再作為聲道資料選擇。它有兩種模式,短幀模式和長幀模式,以WS訊號高電平保持時間為判別依據,長幀模式保持13個CK週期,短幀模式只保持1個CK週期,可以通過相關暫存器位選擇。如果有多通道資料是在一個WS週期內傳輸完成的,傳完左聲道資料就緊跟傳送右聲道資料。圖 386為單聲道資料16bit擴充套件到32bit資料幀傳送波形。
圖 386 PCM標準16bit傳輸
38.2 I2S功能框圖
STM32f42x系列控制器有兩個I2S,I2S2和I2S3,兩個的資源是相互獨立的,但分別與SPI2和SPI3共用大部分資源。這樣I2S2和SPI2只能選擇一個功能使用,I2S3和SPI3相同道理。資源共用包括引腳共用和部分暫存器共用,當然也有部分是專用的。SPI已經在之前相關章節做了詳細講解,建議先看懂SPI相關內容再學習I2S。
控制器的I2S支援兩種工作模式,主模式和從模式;主模式下使用自身時鐘發生器生成通訊時鐘。I2S功能框圖參考圖 387。
圖 387 I2S功能框圖
1. 功能引腳
I2S的SD對映到SPI的MOSI引腳,ext_SD對映到SPI的MISO引腳,WS對映到SPI的NSS引腳,CK對映到SPI的SCK引腳。MCK是I2S專用引腳,用於主模式下輸出時鐘或在從模式下輸入時鐘。I2S時鐘發生器可以由控制器內部時鐘源分頻產生,亦可採用CKIN引腳輸入時鐘分頻得到,一般使用內部時鐘源即可。控制器I2S引腳分佈參考表 381。
表 381 STM32f42x系列控制器I2S引腳分佈
引腳 |
I2S2 |
I2S3 |
SD |
PC3/PB15/PI3 |
PC12/PD6/PB5 |
ext_SD |
PC2/PB14/PI2 |
PC11/PB4 |
WS |
PB12/PI0/PB9 |
PA4/PA15 |
CK |
PB10/PB13/PI1/PD3 |
PC10/PB3 |
MCK |
PC6 |
PC7 |
CKIN |
PC9 |
其中,PI0和PI1不能用於I2S的全雙工模式。
2. 資料暫存器
I2S有一個與SPI共用的SPI資料暫存器(SPI_DR),有效長度為16bit,用於I2S資料傳送和接收,它實際由三個部分組成,一個移位暫存器、一個傳送緩衝區和一個接收緩衝區,當處於傳送模式時,向SPI_DR寫入資料先儲存在傳送緩衝區,匯流排自動把傳送緩衝區內容轉入到移位暫存器中進行傳輸;在接收模式下,實際接收到的資料先填充移位暫存器,然後自動轉入接收緩衝區,軟體讀取SPI_DR時自動從接收緩衝區內讀取。I2S是掛載在APB1總線上的。
3. 邏輯控制
I2S的邏輯控制通過設定相關暫存器位實現,比如通過配置SPI_I2S配置暫存器(SPI_I2SCFGR)的相關位可以實現選擇I2S和SPI模式切換、選擇I2S工作在主模式還是從模式並且選擇是傳送還是接收、選擇I2S標準、傳輸資料長度等等。SPI控制暫存器2(SPI_CR2)可用於設定相關中斷和DMA請求使能,I2S有5箇中斷事件,分別為傳送緩衝區為空、接收緩衝區非空、上溢錯誤、下溢錯誤和幀錯誤。SPI狀態暫存器(SPI_SR)用於指示當前I2S狀態。
4. 時鐘發生器
I2S位元率用來確定I2S資料線上的資料流和I2S時鐘訊號頻率。I2S位元率=每個通道的位數×通道數×音訊取樣頻率。
圖 388為I2S時鐘發生器內部結構圖。I2SxCLK(x可選2或3)可以通過RCC_CFGR暫存器的I2SSRC位選擇使用PLLI2S時鐘作為I2S時鐘源或I2S_CKIN引腳輸入時鐘作為I2S時鐘源。一般選擇內部PLLI2S(通過R分頻係數)作為時鐘源。例程程式設定PLLI2S時鐘為258MHz,R分頻係數為3,此時I2SxCLK時鐘為86MHz。
圖 388 I2S時鐘發生器內部結構
SPI_I2S預分頻器暫存器(SPI_I2SPR)的MCKOE位用於設定MCK引腳時鐘輸出使能;ODD位設定預分頻器的奇數因子,實際分頻值=I2SDIV*2+ODD;I2SDIV為8位線性分頻器,不可設定為0或1。
當使能MCK時鐘輸出,即MCKOE=1時,取樣頻率計算如下:
FS = I2SxCLK/[(16*2)*((2*I2SDIV)+ODD)*8)](通道幀寬度為16bit時)
FS = I2SxCLK/[(32*2)*((2*I2SDIV)+ODD)*4)](通道幀寬度為32bit時)
當禁止MCK時鐘輸出,即MCKOE=0時,取樣頻率計算如下:
FS = I2SxCLK/[(16*2)*((2*I2SDIV)+ODD))](通道幀寬度為16bit時)
FS = I2SxCLK/[(32*2)*((2*I2SDIV)+ODD))](通道幀寬度為32bit時)
38.3 WM8978音訊編譯碼器
WM8978是一個低功耗、高質量的立體聲多媒體數字訊號編譯碼器。它主要應用於行動式應用。它結合了立體聲差分麥克風的前置放大與揚聲器、耳機和差分、立體聲線輸出的驅動,減少了應用時必需的外部元件,比如不需要單獨的麥克風或者耳機的放大器。
高階的片上數字訊號處理功能,包含一個5路均衡功能,一個用於ADC和麥克風或者線路輸入之間的混合訊號的電平自動控制功能,一個純粹的錄音或者重放的數字限幅功能。另外在ADC的線路上提供了一個數字濾波的功能,可以更好的應用濾波,比如"減少風噪聲"。
WM8978可以被應用為一個主機或者一個從機。基於共同的參考時鐘頻率,比如 12MHz和13MHz,內部的PLL可以為編譯碼器提供所有需要的音訊時鐘。與STM32控制器連線使用,STM32一般作為主機,WM8978作為從機。
圖 389為WM8978晶片內部結構示意圖,參考來自《WM8978_v4.5》。該圖給人的第一印象感覺就是很複雜,密密麻麻很多內容,特別有很多"開關"。實際上,每個開關對應著WM8978內部暫存器的一個位,通過控制暫存器的就可以控制開關的狀態。
圖 389 WM8978內部結構
1. 輸入部分
WM8978結構圖的左邊部分是輸入部分,可用於模擬聲音輸入,即用於錄音輸入。有三個輸入介面,一個是由LIN和LIP、RIN和RIP組合而成的偽差分立體聲麥克風輸入,一個是由L2和R2組合的立體聲麥克風輸入,還有一個是由AUXL和AUXR組合的線輸入或用來傳輸告警聲的輸入。
2. 輸出部分
WM8978結構圖的右邊部分是聲音放大輸出部分,LOUT1和ROUT1用於耳機驅動,LOUT2和ROUT2用於揚聲器驅動,OUT3和OUT4也可以配置成立體聲線輸出,OUT4也可以用於提供一個左右聲道的單聲道混合。
3. ADC和DAC
WM8978結構圖的中邊部分是晶片核心內容,處理聲音的AD和DA轉換。ADC部分對聲音輸入進行處理,包括ADC濾波處理、音量控制、輸入限幅器/電平自動控制等等。DAC部分控制聲音輸出效果,包括DAC5路均衡器、DAC 3D放大、DAC輸出限幅以及音量控制等等處理。
4. 通訊介面
WM8978有兩個通訊介面,一個是數字音訊通訊介面,另外一個是控制介面。音訊介面是採用I2S介面,支援左對齊、右對齊和I2S標準模式,以及DSP模式A和模擬B。控制介面用於控制器傳送控制命令配置WM8978執行狀態,它提供2線或3線控制介面,對於STM32控制器,我們選擇2線介面方式,它實際就是I2C匯流排方式,其晶片地址固定為0011010。通過控制介面可以訪問WM8978內部暫存器,實現晶片工作環境配置,總共有58個暫存器,標示為R0至R57,限於篇幅問題這裡不再深入探究,每個暫存器意義參考《WM8978_v4.5》瞭解。
WM8978暫存器是16bit長度,高7位([15:9]bit)用於標示暫存器地址,低9為有實際意義,比如對於圖 389中的某個開關。所以在控制器向晶片傳送控制命令時,必須傳輸長度為16bit的指令,晶片會根據接收命令高7位值定址。
5. 其他部分
WM8978作為主從機都必須對時鐘進行管理,由內部PLL單元控制。另外還有電源管理單元。
38.4 WAV格式檔案
WAV是微軟公司開發的一種音訊格式檔案,用於儲存Windows平臺的音訊資訊資源,它符合資源互換檔案格式(Resource Interchange File Format,RIFF)檔案規範。標準格式化的WAV檔案和CD格式一樣,也是44.1K的取樣頻率,16位量化數字,因此在聲音檔案質量和CD相差無幾!WAVE是錄音時用的標準的WINDOWS檔案格式,檔案的副檔名為"WAV",資料本身的格式為PCM或壓縮型,屬於無損音樂格式的一種。
38.4.1 RIFF檔案規範
RIFF有不同數量的chunk(區塊)組成,每個chunk由"識別符號"、"資料大小"和"資料"三個部分組成,"識別符號"和"資料大小"都是佔用4個位元組空間。簡單RIFF格式檔案結構參考圖 3810。最開始是ID為"RIFF"的chunk,Size為"RIFF"chunk資料位元組長度,所以總檔案大小為Size+8。一般來說,chunk不允許內部再包含chunk,但有兩個例外,ID為"RIFF"和"LIST"的chunk卻是允許。對此"RIFF"在其"資料"首4個位元組用來存放"格式標識碼(Form Type)","LIST"則對應"LIST Type"。
圖 3810 RIFF檔案格式結構
38.4.2 WAVE檔案
WAVE檔案是非常簡單的一種RIFF檔案,其"格式標識碼"定義為WAVE。RIFF chunk包括兩個子chunk,ID分別為fmt和data,還有一個可選的fact chunk。Fmt chunk用於標示音訊資料的屬性,包括編碼方式、聲道數目、取樣頻率、每個取樣需要的bit數等等資訊。fact chunk是一個可選chunk,一般當WAVE檔案由某些軟體轉化而成就包含fact chunk。data chunk包含WAVE檔案的數字化波形聲音資料。WAVE整體結構如表 382。
表 382 WAVE檔案結構
標識碼("RIFF") |
資料大小 |
格式標識碼("WAVE") |
"fmt" |
"fmt"塊資料大小 |
"fmt"資料 |
"fact"(可選) |
"fact"塊資料大小 |
"fact"資料 |
"data" |
聲音資料大小 |
聲音資料 |
data chunk是WAVE檔案主體部分,包含聲音資料,一般有兩個編碼格式:PCM和ADPCM,ADPCM(自適應差分脈衝編碼調製)屬於有失真壓縮,現在幾乎不用,絕大部分WAVE檔案是PCM編碼。PCM編碼聲音資料可以說是在"數字音訊技術"介紹的源資料,主要引數是取樣頻率和量化位數。
表 383為量化位數為16bit時不同聲道資料在data chunk資料排列格式。
表 383 16bit聲音資料格式
單聲道 |
取樣一 |
取樣二 |
…… |
||
低位元組 |
高位元組 |
低位元組 |
高位元組 |
…… |
|
雙聲道 |
取樣一 |
…… |
|||
左聲道 |
右聲道 |
…… |
|||
低位元組 |
高位元組 |
低位元組 |
高位元組 |
…… |
38.4.3 WAVE檔案例項分析
利用winhex工具軟體可以非常方便以十六進位制檢視檔案,圖 3811為名為"張國榮-一盞小明燈.wav"檔案使用winhex工具開啟的部分介面截圖。這部分截圖是WAVE檔案頭部分,聲音資料部分資料量非常大,有興趣可以使用winhex檢視。
圖 3811 WAV檔案頭例項
下面對檔案頭進行解讀,參考表 384。
表 384 WAVE檔案格式說明
|
偏移地址 |
位元組數 |
資料型別 |
十六進位制原始碼 |
內容 |
檔案頭 |
00H |
4 |
char |
52 49 46 46 |
"RIFF"識別符號 |
04H |
4 |
long int |
F4 FE 83 01 |
檔案長度:0x0183FEF4(注意順序) |
|
08H |
4 |
char |
57 41 56 45 |
"WAVE"識別符號 |
|
0CH |
4 |
char |
66 6D 74 20 |
"fmt ",最後一位為空格 |
|
10H |
4 |
long int |
10 00 00 00 |
fmt chunk大小:0x10 |
|
14H |
2 |
int |
01 00 |
編碼格式:0x01為PCM。 |
|
16H |
2 |
int |
02 00 |
聲道數目:0x01為單聲道,0x02為雙聲道 |
|
18H |
4 |
int |
44 AC 00 00 |
取樣頻率(每秒樣本數):0xAC44(44100) |
|
1CH |
4 |
long int |
10 B1 02 00 |
每秒位元組數:0x02B110,等於聲道數*取樣頻率*量化位數/8 |
|
20H |
2 |
int |
04 00 |
每個取樣點位元組數:0x04,等於聲道數*量化位數/8 |
|
22H |
2 |
int |
10 00 |
量化位數:0x10 |
|
24H |
4 |
char |
64 61 74 61 |
"data"資料識別符號 |
|
28H |
4 |
long int |
48 FE 83 01 |
聲音資料量:0x0183FE48 |