文獻(xiàn)標(biāo)識(shí)碼: A
DOI:10.16157/j.issn.0258-7998.2016.02.005
中文引用格式: 劉喬壽,黃國臣,吉福生. 基于FPGA的FLAC音頻硬解碼的設(shè)計(jì)與實(shí)現(xiàn)[J].電子技術(shù)應(yīng)用,2016,42(2):21-24.
英文引用格式: Liu Qiaoshou,Huang Guochen,Ji Fusheng. Design and implementation of FLAC hardware decoding based on FPGA[J].Application of Electronic Technique,2016,42(2):21-24.
0 引言
FLAC是音頻的無損壓縮格式,即音頻以FALC編碼解碼后不會(huì)丟失任何信息,F(xiàn)LAC音頻文件解碼還原為WAV文件后,與壓縮前的WAV文件內(nèi)容是一樣的[1]。FLAC是專門針對(duì)PCM音頻的特點(diǎn)而設(shè)計(jì)的壓縮方式。現(xiàn)今大多數(shù)據(jù)系統(tǒng)采用專用芯片或者軟件實(shí)現(xiàn)FLAC音頻的解碼。使用專用芯片靈活性差,不利于FLAC解碼器的特殊應(yīng)用。而軟件實(shí)現(xiàn)解碼需要占用大量的系統(tǒng)資源,且解碼效率低。
FPGA具有運(yùn)行速度快、可重復(fù)編程、集成度高等優(yōu)點(diǎn),是進(jìn)行原始設(shè)計(jì)最理想的載體[2]。為此,筆者以音頻播放系統(tǒng)中FLAC解碼為應(yīng)用背景,提出了一種采用Verilog 語言設(shè)計(jì)的通用FLAC音頻解碼器的FPGA模塊化解決方案。所設(shè)計(jì)的解碼器可作為IP核用于專用音頻集成電路設(shè)計(jì)或者FPGA設(shè)計(jì)中,可以縮短設(shè)計(jì)周期,提高系統(tǒng)設(shè)計(jì)的成功率。
1 FLAC編碼原理及FALC音頻格式
與其他的音頻編碼器類似,F(xiàn)LAC對(duì)音頻的編碼需要經(jīng)過四階段:分塊、聲道去相關(guān)、預(yù)測編碼和殘差編碼。首先,把未經(jīng)壓縮的音頻流劃分為塊,并進(jìn)行獨(dú)立壓縮,分塊的大小是可變的;然后,對(duì)每個(gè)分塊進(jìn)行聲道去相關(guān)操作,去除聲道間的冗余信息;之后進(jìn)入預(yù)測器進(jìn)行預(yù)測編碼,分塊越大,壓縮等級(jí)越高,就越難以找到高效的壓縮模型;最后使用殘差編碼對(duì)預(yù)測編碼殘留下來的殘差進(jìn)行編碼,得到最終的音頻編碼信號(hào)。FLAC編碼過程如圖1所示。
圖2為FLAC音頻文件格式示意圖。所有FLAC文件都以四個(gè)字節(jié)的“fLaC”標(biāo)志開頭。FLAC文件標(biāo)志之后就是數(shù)個(gè)元數(shù)據(jù)塊,每個(gè)元數(shù)據(jù)塊用來描述特定的音頻信息。最后就是音頻幀。每個(gè)音頻幀主要包括了幀同步字、子幀樣本數(shù)量、采樣率、聲道分配、樣本采樣深度、CRC-8校驗(yàn)碼以及編碼主數(shù)據(jù)。在FLAC比特流中,所有的數(shù)值都是整數(shù),沒有浮點(diǎn)運(yùn)算。所有的數(shù)值都采用大端模塊,且如果沒有特殊說明,所有的數(shù)值都是無符號(hào)的。
2 FLAC音頻解碼器的設(shè)計(jì)
2.1 硬件結(jié)構(gòu)設(shè)計(jì)
FLAC音頻解碼器的整體設(shè)計(jì)框圖見圖3,其中FLAC音頻解碼器由以下9個(gè)模塊組成:FLAC文件緩存模塊、預(yù)處理模塊、主控模塊、元數(shù)據(jù)處理模塊、幀同步模塊、幀解碼模塊、左右聲道緩存、逆去相關(guān)模塊和I2S音頻接口模塊。其中主控模塊控制FLAC解碼器運(yùn)行以及數(shù)據(jù)的流向。FLAC音頻解碼器除了有時(shí)鐘和復(fù)位信號(hào)外,與處理器連接的還有數(shù)據(jù)輸入端口、寫請(qǐng)求信號(hào)線和寫滿信號(hào)線。采用I2S音頻總線與音頻數(shù)模轉(zhuǎn)換芯片連接。FLAC音頻解碼器的各個(gè)模塊功能將在下面詳細(xì)介紹。
2.2 FLAC文件緩存模塊
FLAC文件緩存模塊負(fù)責(zé)儲(chǔ)存處理器傳遞進(jìn)來的FLAC數(shù)據(jù)。如圖4所示,F(xiàn)LAC文件緩存模塊由兩部分組成:FIFO模塊和啟動(dòng)信號(hào)發(fā)生器。這里的FIFO輸入輸出寬度為32 bit,深度為1K。FIFO模塊的寫滿標(biāo)志信號(hào)線作為輸出外,還作為啟動(dòng)信號(hào)發(fā)生器的輸入信號(hào)。為了減少操作的復(fù)雜性,此FLAC解碼器并不向外部提供專用的啟動(dòng)控制信號(hào)線,筆者設(shè)計(jì)了如下自啟動(dòng)方式:在處理器開始往解碼器寫入數(shù)據(jù)時(shí),解碼器并沒有立即啟動(dòng)相應(yīng)的模塊進(jìn)行解碼。當(dāng)FLAC文件緩存模塊首次緩存滿后,啟動(dòng)信號(hào)發(fā)生器會(huì)產(chǎn)生一個(gè)有效的啟動(dòng)信號(hào),主控模塊檢測到啟動(dòng)信號(hào)有效才會(huì)跳出空閑狀態(tài),啟動(dòng)相應(yīng)的模塊開始進(jìn)行解碼。
2.3 預(yù)處理模塊
由于FLAC文件緩存模塊輸出的數(shù)據(jù)是并行數(shù)據(jù),而內(nèi)部各個(gè)模塊每次取數(shù)是不定長度的,為了降低取數(shù)操作的復(fù)雜性,本文設(shè)計(jì)了預(yù)處理模塊,負(fù)責(zé)將并行的碼流轉(zhuǎn)換成可取任意位碼元的碼流。預(yù)處理模塊為控制模塊提供編碼器輸入FIFO的狀態(tài)信息,當(dāng)其他模塊讀取數(shù)據(jù)前需要對(duì)FIFO空狀態(tài)進(jìn)行檢測。同時(shí),預(yù)處理模塊還為幀解碼模塊提供字節(jié)對(duì)齊信息。
圖5給出了預(yù)處理模塊結(jié)構(gòu)框圖,其主要由兩部分組成:邊沿檢測器和任意位移位寄存器。邊沿檢測器將檢測到的讀請(qǐng)求信號(hào)電平變化轉(zhuǎn)換為與時(shí)鐘同步的單脈沖信號(hào),以此作為任意移位寄存器移位控制信號(hào)。任意移位寄存器模塊的工作機(jī)制是根據(jù)輸入的移位比特?cái)?shù)n,在讀請(qǐng)求信號(hào)的驅(qū)動(dòng)下,將高位的n比特移出,更新輸出。
2.4 控制模塊
此模塊是整個(gè)FLAC解碼器的核心控制模塊,主要功能是檢測FLAC文件緩存的儲(chǔ)存狀態(tài),控制各個(gè)模塊的運(yùn)行與停止,并響應(yīng)模塊解碼過程中反饋的信息,同時(shí)完成將FLAC文件數(shù)據(jù)傳送到相應(yīng)模塊。具體過程如圖6所示。在控制器中采用了狀態(tài)機(jī)的設(shè)計(jì)方式。
主控模塊的狀態(tài)機(jī)狀態(tài)有:Idle(空閑)、S1(解析元數(shù)據(jù))、S2(幀同步)、S3(幀解碼)、S4(完成文件解碼)、S5(解碼失敗)。
FLAC文件緩存模塊首次儲(chǔ)存滿時(shí),向主控模塊發(fā)出Start信號(hào)有效,主控模塊檢測到啟動(dòng)信號(hào)有效后會(huì)立即從預(yù)處理模塊獲取前4個(gè)字節(jié)的碼流,如果檢測到這4個(gè)字節(jié)是FLAC文件的標(biāo)志“FlaC”,則會(huì)進(jìn)入S1(元數(shù)據(jù)解析)狀態(tài),并啟動(dòng)元數(shù)據(jù)解析模塊。如果檢測到不是有效和FLAC文件標(biāo)志,則會(huì)向外部處理發(fā)出文件錯(cuò)誤信號(hào)。
在解析元數(shù)據(jù)過程中,如果FLAC元數(shù)據(jù)存在錯(cuò)誤,元數(shù)據(jù)解析模塊會(huì)向主控模塊發(fā)出S1_Error信號(hào)有效,主控模塊檢測到此S1_Error信號(hào)有效后進(jìn)入S5(解碼失?。顟B(tài),并最終返回到Idle(空閑)狀態(tài),同時(shí)FLAC解碼器向外部處理器發(fā)出文件錯(cuò)誤信號(hào)。如果元數(shù)據(jù)解析模塊成功完成所有元數(shù)據(jù)的解析工作,則會(huì)向主控模塊發(fā)出S1_Finish信號(hào)有效,主控模塊檢測到S1_Finish信號(hào)有效后會(huì)進(jìn)入S2(幀同步)狀態(tài),啟動(dòng)幀同步模塊進(jìn)行幀同步。
幀同步模塊如果同步成功會(huì)產(chǎn)生Syn_Frame信號(hào)有效,主控模塊檢測到此有效信號(hào)會(huì)進(jìn)入S3(幀解碼)狀態(tài),并啟動(dòng)幀解碼模塊開始解碼FLAC數(shù)據(jù)。幀解碼模塊完成一幀數(shù)據(jù)的解碼會(huì)向主控模塊發(fā)出有效的Finish信號(hào),主控模塊據(jù)此會(huì)再次進(jìn)入S2(幀同步)狀態(tài),如此循環(huán),直到完成整個(gè)文件的解碼。
2.5 元數(shù)據(jù)解析模塊
FLAC最多支持128種元數(shù)據(jù)塊,目前只定義了7種。但并不是所有的元數(shù)據(jù)塊都對(duì)FALC解碼有用,因此本文設(shè)計(jì)的元數(shù)據(jù)解析模塊只對(duì)其中STREAMINFO類型的元數(shù)據(jù)進(jìn)行解析,其他類型的元數(shù)據(jù)塊不作解析。所有的FLAC文件都包含STREAMINFO類型的元數(shù)據(jù)塊,此元數(shù)據(jù)塊提供了關(guān)于整個(gè)FLAC音頻流的信息:采樣率、聲道數(shù)量、總采樣數(shù)等。其中的總采樣數(shù)參數(shù)提供給主控模塊,主控模塊將此總采樣數(shù)與當(dāng)前已經(jīng)解碼的采樣數(shù)進(jìn)行比較,以此來判斷是否完成整個(gè)FLAC的解碼。
2.6 幀解碼
解碼是編碼的反過程,解碼器并不關(guān)心FLAC文件的壓縮等級(jí),而只需要根據(jù)FLAC文件中提供的編碼參數(shù)進(jìn)行解碼即可。與編碼過程相對(duì)應(yīng),解碼同樣也依次經(jīng)過四個(gè)階段:殘差解碼、預(yù)測編碼還原、逆去相關(guān)、重組。
2.6.1 殘差解碼
信號(hào)經(jīng)過預(yù)測編碼時(shí),預(yù)測器不能非常精確的描述整個(gè)信號(hào),因此使用預(yù)測模型描述的信號(hào)與原始信號(hào)是存在差值的。FLAC只采用一種方法(Rice Coding)對(duì)殘差進(jìn)行無損編碼,殘差編碼后的數(shù)據(jù)量遠(yuǎn)遠(yuǎn)小于原始數(shù)據(jù)量。對(duì)殘差編碼值進(jìn)行解碼很簡單,本文采用下面的算法對(duì)之進(jìn)行解碼。
解碼前需要從FLAC碼流中提取出相應(yīng)的殘差解碼參數(shù):階數(shù)m。假設(shè)S為當(dāng)前FLAC碼流,高位在前。首先對(duì)S從高位開始計(jì)算停止位“1”前“0”的個(gè)數(shù)為n。再從停止位“1”后面取出g比特的二進(jìn)制碼,用k表示此二進(jìn)制碼所代表的十進(jìn)制數(shù),再進(jìn)行如下計(jì)算:H=n*(2m)+g。最后根據(jù)下面的方法計(jì)算最終的解碼值X:
(1)如果H是偶數(shù),X=H/2;
(2)如果H是奇數(shù),X=-((H+1)/2)。
至此,殘差解碼已經(jīng)完成,解碼得到的X需要輸送到預(yù)測編碼還原模塊。需要指出的是,F(xiàn)LAC的殘差解碼采用四種預(yù)測模型:原樣模型、常量模型、固定的線性預(yù)測模型和FIR線性預(yù)測模型。而只有采用后兩種預(yù)測模型的編碼才會(huì)產(chǎn)生殘差,前兩種預(yù)測模型只在預(yù)測編碼還原階段進(jìn)行解碼還原。
2.6.2 預(yù)測編碼還原
如前文所述,F(xiàn)LAC有四種預(yù)測編碼模型,對(duì)使用原樣模塊和常量模型編碼的信號(hào)進(jìn)行還原比較簡單。如果是原樣模型,只需要根據(jù)幀頭部的編碼個(gè)數(shù)L和原樣模型中編碼長度n從FLAC碼流中直接提取L個(gè)長度為n編碼值即可。對(duì)于常量模型,需要從FLAC碼流中提取出一常量值,依次輸出L個(gè)此常量值即可。
對(duì)使用固定線性預(yù)測模型編碼得到的信號(hào),還原信號(hào)等于預(yù)測值加上殘差值。預(yù)測值根據(jù)前n個(gè)訓(xùn)練樣本通過固定的預(yù)測算法計(jì)算得到。
對(duì)使用FIR線性預(yù)測模型編碼得到信號(hào),計(jì)算過程稍微復(fù)雜些。在編碼時(shí)為了避免小數(shù)乘法運(yùn)行,需要將實(shí)數(shù)型的預(yù)測因子都擴(kuò)大2n倍,舍去小數(shù),同樣也需要將原始信號(hào)擴(kuò)大2n倍。因此解碼時(shí)使用擴(kuò)大了的預(yù)測因子和訓(xùn)練樣本還原得到的信號(hào)需要縮小2n倍,再與所對(duì)應(yīng)的殘差相加得到還原信號(hào)。
2.7 逆去相關(guān)模塊
在立體聲音頻流中,左右聲道之間的相關(guān)性導(dǎo)致存在大量的冗余信息。FLAC有多種去除聲道相關(guān)性的方法。對(duì)一幀中,編碼器會(huì)選擇效果最優(yōu)的一種方法去除聲道相關(guān)性。
(1)獨(dú)立編碼。左右聲道分別獨(dú)立編碼,不做去相關(guān)性處理。
(2)中邊編碼。通過對(duì)左右聲道信號(hào)進(jìn)行運(yùn)算產(chǎn)生中值聲道和邊值聲道。而且規(guī)定中值聲道是左右聲道信號(hào)的均值,邊值聲道都是左聲道減右聲道得到的。
(3)左邊編碼。被編碼成獨(dú)立的左聲道和差值聲道。
(4)右邊編碼。被編碼成獨(dú)立的右聲道和差值聲道。
逆去相關(guān)模塊內(nèi)部結(jié)構(gòu)如圖7所示。
逆去相關(guān)模塊主要由相關(guān)性還原模塊、聲道配置隊(duì)列模塊、采樣數(shù)隊(duì)列模塊和減法計(jì)數(shù)器等組成。由于左右聲道緩存中可能存在數(shù)幀,因此需要聲道配置隊(duì)列模塊和采樣數(shù)隊(duì)列模塊將左右聲道緩存中各個(gè)幀的聲道配置信息和采樣數(shù)緩存起來,采用減法計(jì)數(shù)器計(jì)算緩存中當(dāng)前剩余采樣數(shù),當(dāng)計(jì)數(shù)器計(jì)數(shù)到“0”時(shí),會(huì)從采樣數(shù)隊(duì)列模塊中獲取下一幀的采樣數(shù)并預(yù)裝計(jì)數(shù)初值,同時(shí)聲道配置隊(duì)列模塊的輸出也更新到下一幀的聲道配置信息。相關(guān)性還原模塊根據(jù)新的聲道配置信息對(duì)新一幀的左右聲道數(shù)據(jù)進(jìn)行相關(guān)性還原。
2.8 I2S音頻接口
I2S有3個(gè)主要信號(hào):(1)比特時(shí)鐘BCLK,即對(duì)應(yīng)數(shù)字音頻的每一位數(shù)據(jù),BCLK都有一個(gè)脈沖。BCLK的頻率=2×采樣頻率×采樣位數(shù);(2)幀時(shí)鐘LRCK,用于切換左右聲道的數(shù)據(jù)。LRCK的頻率等于采樣頻率;(3)串行數(shù)據(jù)SDATA,就是用二進(jìn)制補(bǔ)碼表示的音頻數(shù)據(jù)。有時(shí)為了使系統(tǒng)間能更好地同步,還需要另外傳輸一個(gè)信號(hào)MCLK,稱為主時(shí)鐘[3]。
為了解決音源采樣率的問題,實(shí)現(xiàn)對(duì)44.1 kHz和48 kHz音頻的精確采樣,本設(shè)計(jì)采用了雙晶振方案。22.579 2 MHz晶振用于44.1/88.2 kHz的音源采樣率,24.576 MHz用于48/96/192 kHz的音源采樣率。
本文設(shè)計(jì)的I2S音頻接口模塊由兩部分組成:分頻模塊和并串轉(zhuǎn)換模塊,如圖8所示。分頻模塊根據(jù)外部輸入的采樣率選擇22.579 2 MHz或者24.576 MHz作為輸入時(shí)鐘,并分頻出I2S的3個(gè)時(shí)鐘信號(hào)。同時(shí)分頻出的BCLK也作為并串轉(zhuǎn)換模塊的時(shí)鐘,并串轉(zhuǎn)換模塊將DATA信號(hào)總線上的數(shù)據(jù)以串行方式輸出。
3 系統(tǒng)仿真及分析
系統(tǒng)在Quartus II 12.0 中進(jìn)行設(shè)計(jì)、綜合仿真,并將設(shè)計(jì)下載到DE2-115開發(fā)板的Cyclone IV EP4CE115F29C7N上。為了驗(yàn)證設(shè)計(jì)的正確性,通過modelsim工具對(duì)FLAC解碼器的工作狀況進(jìn)行仿真驗(yàn)證。筆者編寫了test_bench文件讀取計(jì)算機(jī)中的音頻文件輸入到FLAC解碼器中。圖9為解碼器解碼輸出時(shí)序。從圖中可看出,F(xiàn)LAC解碼器能實(shí)現(xiàn)正確解碼,且I2S音頻接口模塊各種信號(hào)完全滿足時(shí)序要求。
4 總結(jié)
為了解決高保真FLAC音頻播放系統(tǒng)中軟件解碼效率低下、占用系統(tǒng)資源大的問題,本文提出了一種基于FPGA的FLAC音頻硬解碼的設(shè)計(jì)方案。本設(shè)計(jì)采用Verilog語言,在ALTERA公司的FPGA(Cyclone IV EP4CE115F29C7N)芯片上成功實(shí)現(xiàn)了對(duì)FLAC音頻文件的解碼。利用FPGA實(shí)現(xiàn)FLAC音頻的解碼器可以作為IP核應(yīng)用于不同的SoC音頻播放系統(tǒng)中,有助于縮短產(chǎn)品的開發(fā)周期。
參考文獻(xiàn)
[1] COALSON J.Flac-free lossless audio codec[EB/OL].(2014-12-27)[2015-5-2].http://xiph.org/flac/index.html.
[2] 夏宇聞.Verilog數(shù)字系統(tǒng)設(shè)計(jì)教程[M].北京:北京航空航天大學(xué)出版社,2003.
[3] 張景璐,周金和,朱恭生,等.IIS接口的FPGA實(shí)現(xiàn)[J].電子技術(shù)應(yīng)用,2007(6).