蘇仕強(qiáng)
(中國(guó)衛(wèi)星海上測(cè)控部,江蘇 江陰 214431)
新測(cè)量船指揮調(diào)度系統(tǒng)可對(duì)指揮語(yǔ)音進(jìn)行全過(guò)程錄音,但在回放錄音文件時(shí)發(fā)現(xiàn)播放出來(lái)的語(yǔ)音聲音小、噪音多,從而效果并不理想。雖然采取了升級(jí)錄音線、提高話音音量等措施,但仍不能達(dá)到預(yù)期效果。技術(shù)人員在處理錄音過(guò)程中,發(fā)現(xiàn)錄音文件為wave語(yǔ)音文件,希望通過(guò)對(duì)WAVE文件進(jìn)行提取研究,能找到解決語(yǔ)音效果不理想的問(wèn)題。
WAVE文件是語(yǔ)音文件中的一種,它被廣泛地使用在語(yǔ)音技術(shù)研究中,當(dāng)用其進(jìn)行語(yǔ)音技術(shù)研究時(shí),必須正確提取語(yǔ)音文件中的實(shí)際數(shù)據(jù),在MATLAB中有一個(gè)自帶函數(shù)可以返回實(shí)際語(yǔ)音數(shù)據(jù)。若使用其它語(yǔ)言進(jìn)行程序開發(fā)時(shí),就必須清楚WAVE語(yǔ)音文件的格式及其在計(jì)算機(jī)中的存儲(chǔ)結(jié)構(gòu),才能正確地讀取實(shí)際數(shù)據(jù),本文先分析討論了WAVE文件的存儲(chǔ)結(jié)構(gòu),然后說(shuō)明如何使用Visual C++6.0實(shí)現(xiàn)WAVE文件讀取及濾波等操作。
WAVE文件作為多媒體中使用的聲波文件格式之一,它是以RIFF格式為標(biāo)準(zhǔn)的。RIFF是英文Resource Interchange File Format的縮寫,WAVE文件由文件頭和數(shù)據(jù)體兩大部分組成。其中文件頭又分為RIFF/WAV文件標(biāo)識(shí)段和聲音數(shù)據(jù)格式說(shuō)明段兩部分。
表1 1 8KHz采樣16比特量化的線性PCM語(yǔ)音信號(hào)的WAVE文件頭格式
常見的聲音文件主要有兩種,分別對(duì)應(yīng)于單聲道(11.025kHz采樣率、8Bit的采樣值)和雙聲道(44.1kHz采樣率、16Bit的采樣值)。采樣率是指:聲音信號(hào)在“?!鷶?shù)”轉(zhuǎn)換過(guò)程中單位時(shí)間內(nèi)采樣的次數(shù)。采樣值是指每一次采樣周期內(nèi)聲音模擬信號(hào)的積分值。對(duì)于單聲道聲音文件,采樣數(shù)據(jù)為8位的短整數(shù)(short int 00H-FFH);而對(duì)于雙聲道立體聲聲音文件,每次采樣數(shù)據(jù)為一個(gè)16位的整數(shù)(int),高8位和低8位分別代表左右兩個(gè)聲道。WAVE文件數(shù)據(jù)塊包含以脈沖編碼調(diào)制(PCM)格式表示的樣本。WAVE文件是由樣本組織而成的。在單聲道WAVE文件中,聲道0代表左聲道,聲道1代表右聲道。在多聲道WAVE文件中,樣本是交替出現(xiàn)的。
表1為其中一種WAVE文件格式。
typedef struct
{WORD wFormatag;//編碼格式;
WORD nChannls;//聲道數(shù),單聲道為1,雙聲道為2;
DWORD nSamplesPerSec;//采樣頻率;
DWORD nAvgBytesperSec;//每秒的數(shù)據(jù)量;
WORD nBlockAlign;//塊對(duì)齊;
}WAVEFORMAT;
BYTE*GetData (Cstring*pString)//獲取聲音文件數(shù)據(jù)的函數(shù),pString參數(shù)指向要打開的聲音文件;
{if(pString==NULL)
return NULL;
HMMIO file1;//定義HMMIO文件句柄;
file1=mmioOpen((LPSTR)pString,NULL,MMIO_READWRITE);//以讀寫模式打開;
if(file1==NULL)
{MessageBox("WAVE文件打開失??!");
return NULL;}
char style[4];//定義一個(gè)四字節(jié)的數(shù)據(jù),用來(lái)存放文件的類型;
mmioSeek(file1,8,SEEK_SET);//定位到WAVE文件的類型位置;
mmioRead(file1,style,4);
if(style[0]!='W'||style[1]!='A'||style[2]!='V'||style[3]!='E')
//判斷該文件是否為"WAVE"文件格式;
{MessageBox("該文件不是WAVE格式的文件!");
return NULL;}
PCMWAVEFORMAT format;//定義 PCMWAVEFORMAT結(jié)構(gòu)對(duì)象,用來(lái)判斷WAVE文件格式;
mmioSeek(file1,20,SEEK_SET);
//對(duì)打開的文件進(jìn)行定位, 指向 WAVE文件的PCMWAVEFORMAT結(jié)構(gòu)的數(shù)據(jù);
mmioRead(file1,(char*)&format,sizeof(PCMWAVEFORMAT));//獲取該結(jié)構(gòu)的數(shù)據(jù);
if(format.wf.nChannels!=2)//判斷是否是立體聲聲音;
{MessageBox("該聲音文件不是雙通道立體聲文件");
return NULL;}
mmioSeek(file1,24+sizeof(PCMWAVEFORMAT),SEEK_SET);
//獲取WAVE文件的聲音數(shù)據(jù)的大小;
long size;
mmioRead(file1,(char*)&size,4);
BYTE*pData;
pData=(BYTE*)new char[size];//根據(jù)數(shù)據(jù)的大小申請(qǐng)緩沖區(qū);
mmioSeek(file1,28+sizeof(PCMWAVEFORMAT),SEEK_SET);//對(duì)文件重新定位;
mmioRead(file1,(char*)pData,size);//讀取聲音數(shù)據(jù);
mmioClose(file1,MMIO_FHOPEN);//關(guān)閉WAVE文件;
return pData;}
語(yǔ)音濾波的最終效果度量是人耳的主觀感覺,所以在語(yǔ)音濾波中可以利用人耳感覺特性來(lái)減少運(yùn)算的代價(jià),利用自適應(yīng)濾波器可以獲得令人滿意的解。
自適應(yīng)橫向?yàn)V波器具有以下功能:
1)按照某種自適應(yīng)算法自動(dòng)調(diào)節(jié)濾波系數(shù)的橫向?yàn)V波器:分別以W1(n)…Wn(n)表示各個(gè)濾波器所在時(shí)刻的權(quán)系數(shù)。
2)調(diào)節(jié)這些系數(shù)的過(guò)程:首先自動(dòng)調(diào)節(jié)濾波器系數(shù)的自適應(yīng)訓(xùn)練步驟,然后利用濾波系數(shù)加權(quán)延遲線抽頭上的信號(hào)來(lái)產(chǎn)生輸出信號(hào),將輸出信號(hào)與期望信號(hào)進(jìn)行對(duì)比,所得誤差值通過(guò)一定的自適應(yīng)控制算法再來(lái)調(diào)整權(quán)值,以保證濾波器處在最佳狀態(tài),達(dá)到實(shí)現(xiàn)濾波目的。
圖1 自適應(yīng)橫向?yàn)V波器結(jié)構(gòu)圖
令 W(n)=[W1(n),W2(n),…,Wm(n)],x(n)=[x(n),x(n-1),…,x(n-m+1)]T
則輸出信號(hào):
誤差序列:
其中d(n)為期望信號(hào)。顯然,自適應(yīng)濾波器控制機(jī)理是用誤差序列e(n)按照某種準(zhǔn)則和自適應(yīng)算法對(duì)其系數(shù){Wi(n)},=1,2,3,…m進(jìn)行調(diào)節(jié),最終使自適應(yīng)濾波器的目標(biāo)函數(shù)最小化達(dá)到最佳濾波狀態(tài)。按照均方誤差(MSE)準(zhǔn)則定義:
將e(n)=d(n)-y(n)帶入上式,均方誤差函數(shù)重寫為:
當(dāng)濾波器系數(shù)固定時(shí),均方誤差函數(shù)又可寫成:
其中:R=E[X(n)XT(n)]是輸入信號(hào)的自相關(guān)矩陣;P=E[d(n)X(n)]是期望信號(hào)與輸入信號(hào)的互相關(guān)矢量;將上式對(duì)W求導(dǎo),并令其等于零,同時(shí)假設(shè)R是非奇異的,由此可得最佳濾波系數(shù)W0為:
由式可見,均方誤差 ξ(n)是權(quán)矢量{Wj(n)},i=1,2,…,M 的二次函數(shù)它代表以{w,(n)},i=1,2,…,M 為自變量的一個(gè)“超拋物面”,均方誤差ξ(n)達(dá)到最小值ξmin。幾何上這相當(dāng)于超拋物面的最小點(diǎn)。在一般情況下,濾波器在迭代過(guò)程中或當(dāng)輸入過(guò)程統(tǒng)計(jì)特性發(fā)生變化時(shí),權(quán)矢量W并不正好等于W,而是處于某一最佳值W(n)上。為了減小誤差,一個(gè)顯然的方法是找出該工作點(diǎn)處使均方誤差ξ(n)減小速率最大的方向,亦即梯度的負(fù)方向,然后令權(quán)矢量w(n)沿著梯度的負(fù)方向修正。令▽(n)代表n時(shí)刻的M×I維梯度矢量,則權(quán)矢量W(n+1)可用下列簡(jiǎn)單遞歸關(guān)系計(jì)算:
式中,u是一個(gè)正實(shí)數(shù),通常稱它為自適應(yīng)收斂系數(shù)或步長(zhǎng)因子。根據(jù)梯度矢量定義,▽(n)可寫成:
可計(jì)算出濾波系數(shù)更新值:
上式是最陡下降法的數(shù)學(xué)公式,由此公式信號(hào)流程圖圖2。
圖2 最陡下降算法的信號(hào)流圖
算法計(jì)算步驟如下:
1)根據(jù)所處理信號(hào)的特征,選取濾波器的階數(shù)M及收斂因子u。
2)令W(0)=0,W(0)表示一維數(shù)為M,各分量為0的向量。
3)for(k=M;k<=N;k++)
X=[x(k),…,x(k-M+1)]T
y(k)=W(k)*X
e(k)=x(k)-y(k)
W(k+1)=W(k)+2*u*e(k)*X
本文分析討論WAVE文件的存儲(chǔ)結(jié)構(gòu)以及其樣本數(shù)據(jù)的存儲(chǔ)結(jié)構(gòu),用VC++6.0語(yǔ)言實(shí)現(xiàn)PCM編碼的WAVE文件的讀取,濾波以及存儲(chǔ),得到了正確的結(jié)果。
[1]WAV波形文件的結(jié)構(gòu)及其應(yīng)用實(shí)踐[J].微計(jì)算機(jī)信息,2005,21(8):114-119.
[2]張賢達(dá),保錚.通信信號(hào)處理[M].北京:國(guó)防工業(yè)出版社,2002:258-270.