《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 可編程邏輯 > 設(shè)計應(yīng)用 > 基于FPGA的FLAC音頻硬解碼的設(shè)計與實現(xiàn)
基于FPGA的FLAC音頻硬解碼的設(shè)計與實現(xiàn)
2016年電子技術(shù)應(yīng)用第2期
劉喬壽,黃國臣,吉福生
重慶郵電大學(xué) 光通信與網(wǎng)絡(luò)重點實驗室,重慶400065
摘要: 針對高保真FLAC音頻播放系統(tǒng)中軟件解碼效率低下、占用系統(tǒng)資源大的問題,提出一種基于FPGA的FLAC音頻硬解碼的設(shè)計方案。分析了FLAC音頻基本編解碼原理,并詳細(xì)介紹了基于現(xiàn)場可編程門陣列(FPGA)器件的FLAC解碼器各模塊的設(shè)計思想和實現(xiàn)。利用Verilog語言在Quartus II 的開發(fā)環(huán)境中進(jìn)行設(shè)計輸入與仿真驗證。實驗測試結(jié)果表明,該FLAC解碼器設(shè)計靈活、工作穩(wěn)定可靠、解碼效率高,可作為IP核應(yīng)用于不同SoC的無損音頻播放系統(tǒng)中。
關(guān)鍵詞: FPGA FLAC 硬解碼 IP核
中圖分類號: TP331.2
文獻(xiàn)標(biāo)識碼: A
DOI:10.16157/j.issn.0258-7998.2016.02.005
中文引用格式: 劉喬壽,黃國臣,吉福生. 基于FPGA的FLAC音頻硬解碼的設(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.
Design and implementation of FLAC hardware decoding based on FPGA
Liu Qiaoshou,Huang Guochen,Ji Fusheng
Optical Communication and Network Key Laboratory,Chongqing University of Posts and Telecommunications, Chongqing 400065,China
Abstract: In Hi-Fi FLAC audio player system,software decoding efficiency is low,and also occupy a large number of system resources. To solve these problems,a design scheme of FLAC audio hard decoding based on FPGA is proposed. This paper analyze the basic principles of audio coding and decoding,and introduced the design idea and implementation of FLAC decoder based on field programmable gate array(FPGA) device in detail. Verylog language be used to design and simulation verification in Quartus II. The experimental results show that the FLAC decoder is flexible, stable and reliable, and can be used as the IP core to be used in the SoC system.
Key words : FPGA;FLAC;hard decoding;IP core

0 引言

    FLAC是音頻的無損壓縮格式,即音頻以FALC編碼解碼后不會丟失任何信息,F(xiàn)LAC音頻文件解碼還原為WAV文件后,與壓縮前的WAV文件內(nèi)容是一樣的[1]。FLAC是專門針對PCM音頻的特點而設(shè)計的壓縮方式?,F(xiàn)今大多數(shù)據(jù)系統(tǒng)采用專用芯片或者軟件實現(xiàn)FLAC音頻的解碼。使用專用芯片靈活性差,不利于FLAC解碼器的特殊應(yīng)用。而軟件實現(xiàn)解碼需要占用大量的系統(tǒng)資源,且解碼效率低。

    FPGA具有運行速度快、可重復(fù)編程、集成度高等優(yōu)點,是進(jìn)行原始設(shè)計最理想的載體[2]。為此,筆者以音頻播放系統(tǒng)中FLAC解碼為應(yīng)用背景,提出了一種采用Verilog 語言設(shè)計的通用FLAC音頻解碼器的FPGA模塊化解決方案。所設(shè)計的解碼器可作為IP核用于專用音頻集成電路設(shè)計或者FPGA設(shè)計中,可以縮短設(shè)計周期,提高系統(tǒng)設(shè)計的成功率。

1 FLAC編碼原理及FALC音頻格式 

    與其他的音頻編碼器類似,F(xiàn)LAC對音頻的編碼需要經(jīng)過四階段:分塊、聲道去相關(guān)、預(yù)測編碼和殘差編碼。首先,把未經(jīng)壓縮的音頻流劃分為塊,并進(jìn)行獨立壓縮,分塊的大小是可變的;然后,對每個分塊進(jìn)行聲道去相關(guān)操作,去除聲道間的冗余信息;之后進(jìn)入預(yù)測器進(jìn)行預(yù)測編碼,分塊越大,壓縮等級越高,就越難以找到高效的壓縮模型;最后使用殘差編碼對預(yù)測編碼殘留下來的殘差進(jìn)行編碼,得到最終的音頻編碼信號。FLAC編碼過程如圖1所示。

wdz1-t1.gif

    圖2為FLAC音頻文件格式示意圖。所有FLAC文件都以四個字節(jié)的“fLaC”標(biāo)志開頭。FLAC文件標(biāo)志之后就是數(shù)個元數(shù)據(jù)塊,每個元數(shù)據(jù)塊用來描述特定的音頻信息。最后就是音頻幀。每個音頻幀主要包括了幀同步字、子幀樣本數(shù)量、采樣率、聲道分配、樣本采樣深度、CRC-8校驗碼以及編碼主數(shù)據(jù)。在FLAC比特流中,所有的數(shù)值都是整數(shù),沒有浮點運算。所有的數(shù)值都采用大端模塊,且如果沒有特殊說明,所有的數(shù)值都是無符號的。

wdz1-t2.gif

2 FLAC音頻解碼器的設(shè)計

2.1 硬件結(jié)構(gòu)設(shè)計

    FLAC音頻解碼器的整體設(shè)計框圖見圖3,其中FLAC音頻解碼器由以下9個模塊組成:FLAC文件緩存模塊、預(yù)處理模塊、主控模塊、元數(shù)據(jù)處理模塊、幀同步模塊、幀解碼模塊、左右聲道緩存、逆去相關(guān)模塊和I2S音頻接口模塊。其中主控模塊控制FLAC解碼器運行以及數(shù)據(jù)的流向。FLAC音頻解碼器除了有時鐘和復(fù)位信號外,與處理器連接的還有數(shù)據(jù)輸入端口、寫請求信號線和寫滿信號線。采用I2S音頻總線與音頻數(shù)模轉(zhuǎn)換芯片連接。FLAC音頻解碼器的各個模塊功能將在下面詳細(xì)介紹。

wdz1-t3.gif

2.2 FLAC文件緩存模塊

    FLAC文件緩存模塊負(fù)責(zé)儲存處理器傳遞進(jìn)來的FLAC數(shù)據(jù)。如圖4所示,F(xiàn)LAC文件緩存模塊由兩部分組成:FIFO模塊和啟動信號發(fā)生器。這里的FIFO輸入輸出寬度為32 bit,深度為1K。FIFO模塊的寫滿標(biāo)志信號線作為輸出外,還作為啟動信號發(fā)生器的輸入信號。為了減少操作的復(fù)雜性,此FLAC解碼器并不向外部提供專用的啟動控制信號線,筆者設(shè)計了如下自啟動方式:在處理器開始往解碼器寫入數(shù)據(jù)時,解碼器并沒有立即啟動相應(yīng)的模塊進(jìn)行解碼。當(dāng)FLAC文件緩存模塊首次緩存滿后,啟動信號發(fā)生器會產(chǎn)生一個有效的啟動信號,主控模塊檢測到啟動信號有效才會跳出空閑狀態(tài),啟動相應(yīng)的模塊開始進(jìn)行解碼。

wdz1-t4.gif

2.3 預(yù)處理模塊

    由于FLAC文件緩存模塊輸出的數(shù)據(jù)是并行數(shù)據(jù),而內(nèi)部各個模塊每次取數(shù)是不定長度的,為了降低取數(shù)操作的復(fù)雜性,本文設(shè)計了預(yù)處理模塊,負(fù)責(zé)將并行的碼流轉(zhuǎn)換成可取任意位碼元的碼流。預(yù)處理模塊為控制模塊提供編碼器輸入FIFO的狀態(tài)信息,當(dāng)其他模塊讀取數(shù)據(jù)前需要對FIFO空狀態(tài)進(jìn)行檢測。同時,預(yù)處理模塊還為幀解碼模塊提供字節(jié)對齊信息。

    圖5給出了預(yù)處理模塊結(jié)構(gòu)框圖,其主要由兩部分組成:邊沿檢測器和任意位移位寄存器。邊沿檢測器將檢測到的讀請求信號電平變化轉(zhuǎn)換為與時鐘同步的單脈沖信號,以此作為任意移位寄存器移位控制信號。任意移位寄存器模塊的工作機(jī)制是根據(jù)輸入的移位比特數(shù)n,在讀請求信號的驅(qū)動下,將高位的n比特移出,更新輸出。

wdz1-t5.gif

2.4 控制模塊

    此模塊是整個FLAC解碼器的核心控制模塊,主要功能是檢測FLAC文件緩存的儲存狀態(tài),控制各個模塊的運行與停止,并響應(yīng)模塊解碼過程中反饋的信息,同時完成將FLAC文件數(shù)據(jù)傳送到相應(yīng)模塊。具體過程如圖6所示。在控制器中采用了狀態(tài)機(jī)的設(shè)計方式。

wdz1-t6.gif

    主控模塊的狀態(tài)機(jī)狀態(tài)有:Idle(空閑)、S1(解析元數(shù)據(jù))、S2(幀同步)、S3(幀解碼)、S4(完成文件解碼)、S5(解碼失敗)。

    FLAC文件緩存模塊首次儲存滿時,向主控模塊發(fā)出Start信號有效,主控模塊檢測到啟動信號有效后會立即從預(yù)處理模塊獲取前4個字節(jié)的碼流,如果檢測到這4個字節(jié)是FLAC文件的標(biāo)志“FlaC”,則會進(jìn)入S1(元數(shù)據(jù)解析)狀態(tài),并啟動元數(shù)據(jù)解析模塊。如果檢測到不是有效和FLAC文件標(biāo)志,則會向外部處理發(fā)出文件錯誤信號。

    在解析元數(shù)據(jù)過程中,如果FLAC元數(shù)據(jù)存在錯誤,元數(shù)據(jù)解析模塊會向主控模塊發(fā)出S1_Error信號有效,主控模塊檢測到此S1_Error信號有效后進(jìn)入S5(解碼失?。顟B(tài),并最終返回到Idle(空閑)狀態(tài),同時FLAC解碼器向外部處理器發(fā)出文件錯誤信號。如果元數(shù)據(jù)解析模塊成功完成所有元數(shù)據(jù)的解析工作,則會向主控模塊發(fā)出S1_Finish信號有效,主控模塊檢測到S1_Finish信號有效后會進(jìn)入S2(幀同步)狀態(tài),啟動幀同步模塊進(jìn)行幀同步。

    幀同步模塊如果同步成功會產(chǎn)生Syn_Frame信號有效,主控模塊檢測到此有效信號會進(jìn)入S3(幀解碼)狀態(tài),并啟動幀解碼模塊開始解碼FLAC數(shù)據(jù)。幀解碼模塊完成一幀數(shù)據(jù)的解碼會向主控模塊發(fā)出有效的Finish信號,主控模塊據(jù)此會再次進(jìn)入S2(幀同步)狀態(tài),如此循環(huán),直到完成整個文件的解碼。

2.5 元數(shù)據(jù)解析模塊

    FLAC最多支持128種元數(shù)據(jù)塊,目前只定義了7種。但并不是所有的元數(shù)據(jù)塊都對FALC解碼有用,因此本文設(shè)計的元數(shù)據(jù)解析模塊只對其中STREAMINFO類型的元數(shù)據(jù)進(jìn)行解析,其他類型的元數(shù)據(jù)塊不作解析。所有的FLAC文件都包含STREAMINFO類型的元數(shù)據(jù)塊,此元數(shù)據(jù)塊提供了關(guān)于整個FLAC音頻流的信息:采樣率、聲道數(shù)量、總采樣數(shù)等。其中的總采樣數(shù)參數(shù)提供給主控模塊,主控模塊將此總采樣數(shù)與當(dāng)前已經(jīng)解碼的采樣數(shù)進(jìn)行比較,以此來判斷是否完成整個FLAC的解碼。

2.6 幀解碼

    解碼是編碼的反過程,解碼器并不關(guān)心FLAC文件的壓縮等級,而只需要根據(jù)FLAC文件中提供的編碼參數(shù)進(jìn)行解碼即可。與編碼過程相對應(yīng),解碼同樣也依次經(jīng)過四個階段:殘差解碼、預(yù)測編碼還原、逆去相關(guān)、重組。

2.6.1 殘差解碼

    信號經(jīng)過預(yù)測編碼時,預(yù)測器不能非常精確的描述整個信號,因此使用預(yù)測模型描述的信號與原始信號是存在差值的。FLAC只采用一種方法(Rice Coding)對殘差進(jìn)行無損編碼,殘差編碼后的數(shù)據(jù)量遠(yuǎn)遠(yuǎn)小于原始數(shù)據(jù)量。對殘差編碼值進(jìn)行解碼很簡單,本文采用下面的算法對之進(jìn)行解碼。

    解碼前需要從FLAC碼流中提取出相應(yīng)的殘差解碼參數(shù):階數(shù)m。假設(shè)S為當(dāng)前FLAC碼流,高位在前。首先對S從高位開始計算停止位“1”前“0”的個數(shù)為n。再從停止位“1”后面取出g比特的二進(jìn)制碼,用k表示此二進(jìn)制碼所代表的十進(jìn)制數(shù),再進(jìn)行如下計算:H=n*(2m)+g。最后根據(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ù)測模型的編碼才會產(chǎn)生殘差,前兩種預(yù)測模型只在預(yù)測編碼還原階段進(jìn)行解碼還原。

2.6.2 預(yù)測編碼還原

    如前文所述,F(xiàn)LAC有四種預(yù)測編碼模型,對使用原樣模塊和常量模型編碼的信號進(jìn)行還原比較簡單。如果是原樣模型,只需要根據(jù)幀頭部的編碼個數(shù)L和原樣模型中編碼長度n從FLAC碼流中直接提取L個長度為n編碼值即可。對于常量模型,需要從FLAC碼流中提取出一常量值,依次輸出L個此常量值即可。

    對使用固定線性預(yù)測模型編碼得到的信號,還原信號等于預(yù)測值加上殘差值。預(yù)測值根據(jù)前n個訓(xùn)練樣本通過固定的預(yù)測算法計算得到。

    對使用FIR線性預(yù)測模型編碼得到信號,計算過程稍微復(fù)雜些。在編碼時為了避免小數(shù)乘法運行,需要將實數(shù)型的預(yù)測因子都擴(kuò)大2n倍,舍去小數(shù),同樣也需要將原始信號擴(kuò)大2n倍。因此解碼時使用擴(kuò)大了的預(yù)測因子和訓(xùn)練樣本還原得到的信號需要縮小2n倍,再與所對應(yīng)的殘差相加得到還原信號。

2.7 逆去相關(guān)模塊

    在立體聲音頻流中,左右聲道之間的相關(guān)性導(dǎo)致存在大量的冗余信息。FLAC有多種去除聲道相關(guān)性的方法。對一幀中,編碼器會選擇效果最優(yōu)的一種方法去除聲道相關(guān)性。

    (1)獨立編碼。左右聲道分別獨立編碼,不做去相關(guān)性處理。

    (2)中邊編碼。通過對左右聲道信號進(jìn)行運算產(chǎn)生中值聲道和邊值聲道。而且規(guī)定中值聲道是左右聲道信號的均值,邊值聲道都是左聲道減右聲道得到的。

    (3)左邊編碼。被編碼成獨立的左聲道和差值聲道。

    (4)右邊編碼。被編碼成獨立的右聲道和差值聲道。

    逆去相關(guān)模塊內(nèi)部結(jié)構(gòu)如圖7所示。

wdz1-t7.gif

    逆去相關(guān)模塊主要由相關(guān)性還原模塊、聲道配置隊列模塊、采樣數(shù)隊列模塊和減法計數(shù)器等組成。由于左右聲道緩存中可能存在數(shù)幀,因此需要聲道配置隊列模塊和采樣數(shù)隊列模塊將左右聲道緩存中各個幀的聲道配置信息和采樣數(shù)緩存起來,采用減法計數(shù)器計算緩存中當(dāng)前剩余采樣數(shù),當(dāng)計數(shù)器計數(shù)到“0”時,會從采樣數(shù)隊列模塊中獲取下一幀的采樣數(shù)并預(yù)裝計數(shù)初值,同時聲道配置隊列模塊的輸出也更新到下一幀的聲道配置信息。相關(guān)性還原模塊根據(jù)新的聲道配置信息對新一幀的左右聲道數(shù)據(jù)進(jìn)行相關(guān)性還原。

2.8 I2S音頻接口

    I2S有3個主要信號:(1)比特時鐘BCLK,即對應(yīng)數(shù)字音頻的每一位數(shù)據(jù),BCLK都有一個脈沖。BCLK的頻率=2×采樣頻率×采樣位數(shù);(2)幀時鐘LRCK,用于切換左右聲道的數(shù)據(jù)。LRCK的頻率等于采樣頻率;(3)串行數(shù)據(jù)SDATA,就是用二進(jìn)制補(bǔ)碼表示的音頻數(shù)據(jù)。有時為了使系統(tǒng)間能更好地同步,還需要另外傳輸一個信號MCLK,稱為主時鐘[3]。

    為了解決音源采樣率的問題,實現(xiàn)對44.1 kHz和48 kHz音頻的精確采樣,本設(shè)計采用了雙晶振方案。22.579 2 MHz晶振用于44.1/88.2 kHz的音源采樣率,24.576 MHz用于48/96/192 kHz的音源采樣率。

    本文設(shè)計的I2S音頻接口模塊由兩部分組成:分頻模塊和并串轉(zhuǎn)換模塊,如圖8所示。分頻模塊根據(jù)外部輸入的采樣率選擇22.579 2 MHz或者24.576 MHz作為輸入時鐘,并分頻出I2S的3個時鐘信號。同時分頻出的BCLK也作為并串轉(zhuǎn)換模塊的時鐘,并串轉(zhuǎn)換模塊將DATA信號總線上的數(shù)據(jù)以串行方式輸出。

wdz1-t8.gif

3 系統(tǒng)仿真及分析

    系統(tǒng)在Quartus II 12.0 中進(jìn)行設(shè)計、綜合仿真,并將設(shè)計下載到DE2-115開發(fā)板的Cyclone IV EP4CE115F29C7N上。為了驗證設(shè)計的正確性,通過modelsim工具對FLAC解碼器的工作狀況進(jìn)行仿真驗證。筆者編寫了test_bench文件讀取計算機(jī)中的音頻文件輸入到FLAC解碼器中。圖9為解碼器解碼輸出時序。從圖中可看出,F(xiàn)LAC解碼器能實現(xiàn)正確解碼,且I2S音頻接口模塊各種信號完全滿足時序要求。

wdz1-t9.gif

4 總結(jié)

    為了解決高保真FLAC音頻播放系統(tǒng)中軟件解碼效率低下、占用系統(tǒng)資源大的問題,本文提出了一種基于FPGA的FLAC音頻硬解碼的設(shè)計方案。本設(shè)計采用Verilog語言,在ALTERA公司的FPGA(Cyclone IV EP4CE115F29C7N)芯片上成功實現(xiàn)了對FLAC音頻文件的解碼。利用FPGA實現(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è)計教程[M].北京:北京航空航天大學(xué)出版社,2003.

[3] 張景璐,周金和,朱恭生,等.IIS接口的FPGA實現(xiàn)[J].電子技術(shù)應(yīng)用,2007(6).

此內(nèi)容為AET網(wǎng)站原創(chuàng),未經(jīng)授權(quán)禁止轉(zhuǎn)載。