MPEG音頻實(shí)時(shí)解碼系統(tǒng)的DSP實(shí)現(xiàn)
來源:視頻網(wǎng)視頻技術(shù)編碼與解碼 編輯:merry 2011-11-08 12:31:20 加入收藏
為了使用單片DSP實(shí)現(xiàn)MPEG音頻實(shí)時(shí)解碼,本文對MPEG音頻解碼算法的運(yùn)算量和存儲量要求進(jìn)行了分析,并根據(jù)編碼質(zhì)量和處理器速度的要求結(jié)合計(jì)算機(jī)仿真結(jié)果,介紹了充分利用ADSP2181為音頻處理優(yōu)化的硬件結(jié)構(gòu),對MPEG解碼算法及DSP設(shè)計(jì)優(yōu)化的方法。
MPEG音頻解碼過程是通過I/O口獲得MPEG音頻碼流數(shù)據(jù),依照MPEG標(biāo)準(zhǔn)進(jìn)行解碼,并以PCM碼流格式存放在數(shù)據(jù)空間的緩沖單元中,供直接存儲器存取(DMA)方式使用。MPEG音頻解碼的主程序流程如下:開始-->輸入比特流查找標(biāo)題-->側(cè)信息解碼-->比例因子解碼-->哈夫曼數(shù)據(jù)解碼-->反量化采樣-->頻譜重排序-->減小混疊-->通過IMDCT綜合并重疊-->通過多相濾波器組綜合-->輸出PCM樣點(diǎn)-->結(jié)束。
可以看出對輸入碼流進(jìn)行解碼先要經(jīng)過幀同步,讀入同步頭的信息,得到該MPEG音頻碼流的采樣頻率、碼流速率等參數(shù),并且記錄所解碼的MPEG碼流的幀數(shù),接著獲取側(cè)信息。從側(cè)信息中根據(jù)同步頭中所得的MPEG碼流的壓縮類型來讀取信息,獲得對應(yīng)于各自顆粒中各自通道的相關(guān)參數(shù)。然后,對一幀中的兩個(gè)顆粒進(jìn)行解碼,首先從碼流中獲取每個(gè)顆粒所對應(yīng)的比例因子,并對每個(gè)顆粒下的數(shù)據(jù)進(jìn)行霍夫曼解碼,這個(gè)霍夫曼解碼過程需要34個(gè)霍夫曼碼表之一進(jìn)行解碼,可以從側(cè)信息中含有的每個(gè)顆粒選擇碼表的信息來進(jìn)行選擇。
經(jīng)過霍夫曼解碼的數(shù)據(jù)接下來要經(jīng)過反量化采樣。在這一步中,各個(gè)子帶的數(shù)據(jù)根據(jù)所使用窗的類型,利用在側(cè)信息中獲得參數(shù)反量化。然后是立體聲處理模塊,這個(gè)模塊根據(jù)MP3碼流所采用的壓縮類型進(jìn)行相應(yīng)的處理。如果MPEG音頻碼流是立體聲或雙聲道壓縮的,那么就要對每一個(gè)通道的音頻數(shù)據(jù)進(jìn)行如下處理:
重新排序處理:根據(jù)窗變換標(biāo)記和所使用窗的類型所決定長窗、短窗和混和窗三種方式進(jìn)行數(shù)據(jù)的重新排列;
抗鋸齒處理:這一步中使用抗鋸齒蝶型對每個(gè)子帶中的數(shù)據(jù)進(jìn)行處理;
IMDCT:對每通道中的32個(gè)子帶的數(shù)據(jù)根據(jù)所使用窗的不同進(jìn)行變換,在這一步中需要兩組144點(diǎn)的表用以存儲窗類型數(shù)據(jù)和正弦數(shù)據(jù);
多相頻率倒置:對于經(jīng)過IMDCT的子帶數(shù)據(jù)按照在偶數(shù)號子帶中偶數(shù)號數(shù)據(jù)符號取反的原則進(jìn)行處理,然后將所得數(shù)據(jù)輸入到子帶合成濾波器的輸入緩沖中;
子帶合成:這一步需要4.5KB的緩沖用來存儲同步濾波器參數(shù)和同步窗數(shù)據(jù)。
這樣,當(dāng)處理完一個(gè)顆粒中所有通道的數(shù)據(jù)后,就可以將這一顆粒已解碼好的數(shù)據(jù)輸出到輸出緩沖區(qū)中。當(dāng)將下一顆粒的數(shù)據(jù)解碼并輸出后,這樣一幀數(shù)據(jù)解碼完成,這幀數(shù)據(jù)就可以輸入到D/A部分進(jìn)行播放,并將輸出緩沖清空,等待下一幀的解碼數(shù)據(jù)輸入。解碼程序直到碼流中再也找不到一幀的同步頭時(shí),就完成這一音頻流的解碼。
MPEG音頻解碼系統(tǒng)設(shè)計(jì)
MPEG音頻解碼器的解碼算法完全由DSP芯片實(shí)現(xiàn),其控制部分用CPLD實(shí)現(xiàn)。電路的整體設(shè)計(jì)與開發(fā)需要綜合考慮前面兩部分程序算法接口內(nèi)容,可以在進(jìn)行詳細(xì)程序設(shè)計(jì)的基礎(chǔ)上進(jìn)行。這樣,可以把MPEG音頻解碼器的開發(fā)工作分為兩大模塊:MPEG音頻解碼程序DSP實(shí)現(xiàn),即軟件設(shè)計(jì),以及CPLD控制程序開發(fā)和電路板設(shè)計(jì)部分,即硬件設(shè)計(jì)。各個(gè)模塊的開發(fā)工作針對該開發(fā)模塊的特點(diǎn)進(jìn)行。MPEG音頻解碼系統(tǒng)開發(fā)從模塊上可以劃分為硬件開發(fā)和軟件開發(fā)兩個(gè)部分。軟件主要實(shí)現(xiàn)MPEG音頻解碼算法,硬件實(shí)現(xiàn)存儲器訪問控制、MPEG音頻文件播放控制以及電源供給等功能。系統(tǒng)總體的功能結(jié)構(gòu)如圖1所示。
軟件系統(tǒng)設(shè)計(jì)方案是用DSP軟件實(shí)現(xiàn)MPEG音頻解碼算法功能,并完成相應(yīng)的接口訪問功能,軟件功能見圖2所示。
通過分析,我們可以看出使用DSP作為MPEG音頻解碼系統(tǒng)的核心芯片,并輔助相應(yīng)的擴(kuò)展功能模塊,就能夠方便地實(shí)現(xiàn)一個(gè)獨(dú)立的解碼系統(tǒng)。這樣的系統(tǒng)還能夠方便地通過修改DSP中的程序進(jìn)行系統(tǒng)升級。
系統(tǒng)實(shí)現(xiàn)的框圖見圖3,該框圖為MPEG音頻解碼系統(tǒng)的基本組成部分,在圖中與計(jì)算機(jī)的接口芯片采用USB接口芯片,通過USB接口將MPEG等格式的音頻流下載到FLASH存儲器中。除了用于存儲音樂的FLASH之外,還應(yīng)有存儲MPEG音頻解碼程序及其所用碼表的FLASH存儲器,這種FLASH的速度要求比較快,容量不必很大,一般256K就可以。如果使用ADSP2181,因?yàn)槠鋬?nèi)部RAM只有16k,那么片外擴(kuò)展RAM是必要的。
在一般情況下,該系統(tǒng)可以通過其USB接口借助計(jì)算機(jī)從因特網(wǎng)上下載音頻文件,并將這些文件存儲到FLASH記憶棒中。當(dāng)聽音樂的時(shí)候,啟動(dòng)該系統(tǒng)的解碼部分,將存于FLASH中的DSP解碼程序加載到DSP中的內(nèi)部RAM中,DSP開始運(yùn)行解碼程序,從存儲音樂的FLASH中讀取要解碼音頻流,在這種情況下,ADSP2181具有的6通道DMA控制器為系統(tǒng)的設(shè)計(jì)帶來了很大的便利。ADSP2181在處理器全速運(yùn)行的情況下可以自動(dòng)完成DMA口的接收和發(fā)送數(shù)據(jù),而不需要處理器的干預(yù)。利用這個(gè)特點(diǎn),可以通過DMA口來實(shí)現(xiàn)ADDSP2181讀入和讀出數(shù)據(jù)。將解碼后的音頻流經(jīng)過D/A后輸出到耳機(jī),就可以聽到MPEG音頻解碼后的音樂了。這個(gè)系統(tǒng)的優(yōu)點(diǎn)在于可以根據(jù)音頻技術(shù)的發(fā)展,加入新的DSP解碼程序就可以滿足升級的需要。
MPEG音頻解碼算法的DSP設(shè)計(jì)和優(yōu)化
1. 程序空間和數(shù)據(jù)空間的安排和優(yōu)化
MP3解碼程序所需的程序區(qū)空間約為24KB,所需存儲變量的空間約為10KB,而其在解碼中所需要的各種碼表和參數(shù)所需要的存儲空間約為10KB,因?yàn)樵贛P3解碼中生成和變換的數(shù)據(jù)量比較大,所以需要比較大的堆棧段,經(jīng)過多次測試和比較,其所需空間的大小至少為10KB。另外,在程序運(yùn)行時(shí)還要考慮其所需要的動(dòng)態(tài)空間的大小。所以根據(jù)以上的要求就可以編寫該程序的CMD文件。
在ADSP2181的軟件仿真器下運(yùn)行該程序,在該仿真器下給出可以利用的資源如下:
a. 可以映射到程序區(qū)地址范圍和存儲器類型
(0x80到0x2000):/雙口RAM/
(0x2000到0x8000):/單口RAM,SARAMl/
(0x8000:到0x10000):/外部擴(kuò)展RAM和ROM/
(0x18000到0x20000):/單口RAM,SARAM2/
b. 可以映射到數(shù)據(jù)區(qū)地址范圍和存儲器類型
(0x0到0x60):/內(nèi)存寄存器/
(0x60到0x2000):/雙口RAM/
(0x2000到0x8000):/單口RAM,SARAMl/
(0x8000到0x10000):/外部擴(kuò)展RAM和ROM/
將DSP設(shè)置于微處理器模式,并使OVLY為1,編寫CMD文件。如下所示:
MEMORY
{
PAGE 0: DRAM (RWI) :0=0x0080, 1=0x0500
PROG (RWXI) :0=0x18000, l=0x8000
PAGE 1: DATAl (RW) :0=0x580, l=0x500
RAMl (RW) :0=0xa80, l=0x580
RAM2 (RW) :0=0xl000, l=0x 1000
DATA2 (RW) :0=0x2000, 1=0x6000
DA'I'A (RW) : 0=0x 8000, 1=0x8000
}
SECTIONS
{
.text :>PROG PAGE 0
.cinit :>DRAM PAGE 0
.cio :>DRAM PAGE 0
.switch :>DRAM PAGE 0
.bss :>DATA PAGE 1
.const : >DATA1 PAGE 1
.sysmem :>DATA PAGE 1
.stack :>DATA2 PAGE 1
.input : fill=0x00,>RAMl PACE 1,align(256)
}
2.解碼程序各個(gè)模塊計(jì)算量的優(yōu)化
在進(jìn)行MPEG音頻解碼之前,有必要做一些準(zhǔn)備工作:
a. 在數(shù)據(jù)空間劃分大約4.5KB的空間,將在霍夫曼解碼中所用的34個(gè)碼表寫入,這部分?jǐn)?shù)據(jù)地址可以映射到片外擴(kuò)展的FLASH ROM中去;
b. 可以將在IMDCT模塊中的正弦表和窗函數(shù)表寫入到片外擴(kuò)展的FLASH ROM中,因?yàn)檫@些數(shù)據(jù)都是浮點(diǎn)的,用DSP實(shí)時(shí)生成比較費(fèi)時(shí);
c. 片外擴(kuò)展FLASH ROM中還應(yīng)該有一個(gè)4KB的碼表用以存儲用于子帶合成濾波器組的參數(shù),這些數(shù)據(jù)都是正弦浮點(diǎn)表示,用查表的方式來得到其值是比較快的一種方法。
做完這些工作后就可以進(jìn)行解碼。在解碼的各個(gè)模塊中計(jì)算量主要集中在反量化采樣、IMDCT和子帶合成濾波模塊,并且以后兩者的計(jì)算量為最大。以下將說明在這三個(gè)模塊中如何簡化計(jì)算量:
反量化采樣模塊
在這個(gè)模塊中涉及較多的是冪指數(shù)運(yùn)算,并且冪指數(shù)一般不是整數(shù)。如果直接使用C語言所帶的POWER函數(shù),那么匯編的代碼太長。對其優(yōu)化的辦法是觀察其計(jì)算公式,因?yàn)楣街兴〉母鱾€(gè)變量的取值個(gè)數(shù)是有限的,所以其計(jì)算結(jié)果也就是可數(shù)的,因此可以預(yù)先計(jì)算出這些結(jié)果,編成一個(gè)表格,根據(jù)實(shí)際的變量的選取來作為查表的索引。
IMDCT模塊
在這個(gè)模塊中主要涉及到兩個(gè)問題,一是找到一種快速方法來實(shí)現(xiàn)求余算法,二是如何快速實(shí)現(xiàn)大量的乘累加計(jì)算。對于前者,可以使用如下語句來代替求余函數(shù):
n1=2*p+19;
n2=2*m+l;
n=_smpy(nl,n2);
j=n/144;
n=n-144*j
這樣做可以較大幅度地提高計(jì)算速度。對于后者,因?yàn)樵贒SP中有專用的匯編指令來實(shí)現(xiàn)乘法累加功能,理論上對定點(diǎn)的乘法累加計(jì)算速度比較快。但是在本程序中參加乘法累加運(yùn)算的都至少是單精度的浮點(diǎn)數(shù),其運(yùn)算速度比較慢。因此,有必要將浮點(diǎn)轉(zhuǎn)定點(diǎn)運(yùn)算,因?yàn)樵贛PEG音頻流中的數(shù)據(jù)都是16位定點(diǎn)數(shù)據(jù),可以確定其值的取值范圍,可以將用于乘法累加運(yùn)算的數(shù)據(jù)乘以一個(gè)比較大的系數(shù),通過舍入運(yùn)算使其值變?yōu)檎?,利用一個(gè)字16位比特可以用32,768到32,767之間的整數(shù)來表示這些數(shù)據(jù)。這樣一來就可以利用在CCS中所提供的INTRISIC函數(shù)庫中的快速運(yùn)算指令。
但是,在以上所說的過程中需要注意防止乘以較大系數(shù)后溢出問題,因?yàn)榧臃ㄆ魇?0位,乘法器是17位乘17位,所以乘法累加的中間結(jié)果是不會出現(xiàn)溢出和誤差,因此經(jīng)過放大后的乘累加結(jié)果最后再除以放大系數(shù)仍然可以用一個(gè)字來表示。這樣的處理使程序結(jié)構(gòu)變復(fù)雜,并且?guī)硪欢ǖ纳崛朐肼?。由于是采用?6位量化,引入的舍入噪聲影響不大。而使用INTRISIC函數(shù)庫中的快速運(yùn)算指令,需要注意DSP的流水線指令操作,以免引起流水線沖突。
子帶合成模塊 該模塊主要涉及到乘法累加運(yùn)算的簡化。
評論comment