蘇仕強
(中國衛星海上測控部,江蘇 江陰 214431)
新測量船指揮調度系統可對指揮語音進行全過程錄音,但在回放錄音文件時發現播放出來的語音聲音小、噪音多,從而效果并不理想。雖然采取了升級錄音線、提高話音音量等措施,但仍不能達到預期效果。技術人員在處理錄音過程中,發現錄音文件為wave語音文件,希望通過對WAVE文件進行提取研究,能找到解決語音效果不理想的問題。
WAVE文件是語音文件中的一種,它被廣泛地使用在語音技術研究中,當用其進行語音技術研究時,必須正確提取語音文件中的實際數據,在MATLAB中有一個自帶函數可以返回實際語音數據。若使用其它語言進行程序開發時,就必須清楚WAVE語音文件的格式及其在計算機中的存儲結構,才能正確地讀取實際數據,本文先分析討論了WAVE文件的存儲結構,然后說明如何使用Visual C++6.0實現WAVE文件讀取及濾波等操作。
WAVE文件作為多媒體中使用的聲波文件格式之一,它是以RIFF格式為標準的。RIFF是英文Resource Interchange File Format的縮寫,WAVE文件由文件頭和數據體兩大部分組成。其中文件頭又分為RIFF/WAV文件標識段和聲音數據格式說明段兩部分。

表1 1 8KHz采樣16比特量化的線性PCM語音信號的WAVE文件頭格式
常見的聲音文件主要有兩種,分別對應于單聲道(11.025kHz采樣率、8Bit的采樣值)和雙聲道(44.1kHz采樣率、16Bit的采樣值)。采樣率是指:聲音信號在“模→數”轉換過程中單位時間內采樣的次數。采樣值是指每一次采樣周期內聲音模擬信號的積分值。對于單聲道聲音文件,采樣數據為8位的短整數(short int 00H-FFH);而對于雙聲道立體聲聲音文件,每次采樣數據為一個16位的整數(int),高8位和低8位分別代表左右兩個聲道。WAVE文件數據塊包含以脈沖編碼調制(PCM)格式表示的樣本。WAVE文件是由樣本組織而成的。在單聲道WAVE文件中,聲道0代表左聲道,聲道1代表右聲道。在多聲道WAVE文件中,樣本是交替出現的。
表1為其中一種WAVE文件格式。
typedef struct
{WORD wFormatag;//編碼格式;
WORD nChannls;//聲道數,單聲道為1,雙聲道為2;
DWORD nSamplesPerSec;//采樣頻率;
DWORD nAvgBytesperSec;//每秒的數據量;
WORD nBlockAlign;//塊對齊;
}WAVEFORMAT;
BYTE*GetData (Cstring*pString)//獲取聲音文件數據的函數,pString參數指向要打開的聲音文件;
{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];//定義一個四字節的數據,用來存放文件的類型;
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結構對象,用來判斷WAVE文件格式;
mmioSeek(file1,20,SEEK_SET);
//對打開的文件進行定位, 指向 WAVE文件的PCMWAVEFORMAT結構的數據;
mmioRead(file1,(char*)&format,sizeof(PCMWAVEFORMAT));//獲取該結構的數據;
if(format.wf.nChannels!=2)//判斷是否是立體聲聲音;
{MessageBox("該聲音文件不是雙通道立體聲文件");
return NULL;}
mmioSeek(file1,24+sizeof(PCMWAVEFORMAT),SEEK_SET);
//獲取WAVE文件的聲音數據的大小;
long size;
mmioRead(file1,(char*)&size,4);
BYTE*pData;
pData=(BYTE*)new char[size];//根據數據的大小申請緩沖區;
mmioSeek(file1,28+sizeof(PCMWAVEFORMAT),SEEK_SET);//對文件重新定位;
mmioRead(file1,(char*)pData,size);//讀取聲音數據;
mmioClose(file1,MMIO_FHOPEN);//關閉WAVE文件;
return pData;}
語音濾波的最終效果度量是人耳的主觀感覺,所以在語音濾波中可以利用人耳感覺特性來減少運算的代價,利用自適應濾波器可以獲得令人滿意的解。
自適應橫向濾波器具有以下功能:
1)按照某種自適應算法自動調節濾波系數的橫向濾波器:分別以W1(n)…Wn(n)表示各個濾波器所在時刻的權系數。
2)調節這些系數的過程:首先自動調節濾波器系數的自適應訓練步驟,然后利用濾波系數加權延遲線抽頭上的信號來產生輸出信號,將輸出信號與期望信號進行對比,所得誤差值通過一定的自適應控制算法再來調整權值,以保證濾波器處在最佳狀態,達到實現濾波目的。

圖1 自適應橫向濾波器結構圖
令 W(n)=[W1(n),W2(n),…,Wm(n)],x(n)=[x(n),x(n-1),…,x(n-m+1)]T
則輸出信號:

誤差序列:

其中d(n)為期望信號。顯然,自適應濾波器控制機理是用誤差序列e(n)按照某種準則和自適應算法對其系數{Wi(n)},=1,2,3,…m進行調節,最終使自適應濾波器的目標函數最小化達到最佳濾波狀態。按照均方誤差(MSE)準則定義:

將e(n)=d(n)-y(n)帶入上式,均方誤差函數重寫為:

當濾波器系數固定時,均方誤差函數又可寫成:

其中:R=E[X(n)XT(n)]是輸入信號的自相關矩陣;P=E[d(n)X(n)]是期望信號與輸入信號的互相關矢量;將上式對W求導,并令其等于零,同時假設R是非奇異的,由此可得最佳濾波系數W0為:

由式可見,均方誤差 ξ(n)是權矢量{Wj(n)},i=1,2,…,M 的二次函數它代表以{w,(n)},i=1,2,…,M 為自變量的一個“超拋物面”,均方誤差ξ(n)達到最小值ξmin。幾何上這相當于超拋物面的最小點。在一般情況下,濾波器在迭代過程中或當輸入過程統計特性發生變化時,權矢量W并不正好等于W,而是處于某一最佳值W(n)上。為了減小誤差,一個顯然的方法是找出該工作點處使均方誤差ξ(n)減小速率最大的方向,亦即梯度的負方向,然后令權矢量w(n)沿著梯度的負方向修正。令▽(n)代表n時刻的M×I維梯度矢量,則權矢量W(n+1)可用下列簡單遞歸關系計算:

式中,u是一個正實數,通常稱它為自適應收斂系數或步長因子。根據梯度矢量定義,▽(n)可寫成:

可計算出濾波系數更新值:

上式是最陡下降法的數學公式,由此公式信號流程圖圖2。

圖2 最陡下降算法的信號流圖
算法計算步驟如下:
1)根據所處理信號的特征,選取濾波器的階數M及收斂因子u。
2)令W(0)=0,W(0)表示一維數為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文件的存儲結構以及其樣本數據的存儲結構,用VC++6.0語言實現PCM編碼的WAVE文件的讀取,濾波以及存儲,得到了正確的結果。
[1]WAV波形文件的結構及其應用實踐[J].微計算機信息,2005,21(8):114-119.
[2]張賢達,保錚.通信信號處理[M].北京:國防工業出版社,2002:258-270.