資源簡介
我用過了,還可以吧,分享一下,基于譜減法的matlab程序,聲音自己去錄一個就行了

代碼片段和文件信息
clear;
j=sqrt(-1);
%讀取一段語音
%[filenamepathname]=uigetfile(‘*.wav‘‘請選擇語音文件:‘);
[xfsnbits]=wavread(‘abama.wav‘[1?208210]);
[yfsnbits]=wavread(‘ab.wav‘[1?208210]);
wavin=10*x;%+0.3*y;
wbvin=10*x+0.3*y;
sound(wavinfsnbits);
%[wavinfsnbits]=wavread(z);?%提取語音特征信息,wavin保存.wav的抽樣值,fs保存該信號的抽樣頻率
wav_length=length(wavin);
%設置基本信息
%基音周期最大為20ms,為使ifft還原后語音失真盡量小,幀長至少要為基音周期的2倍
%根據fs選擇幀長??%定義幀長fram_len和步長step_len?步長為幀長的一半
switch?fs?
?????case?8000
?????????frame_len=320;step_len=160;
?????case?10000
?????????frame_len=400;step_len=200;
?????case?12000
?????????frame_len=480;step_len=240;
?????case?16000
?????????frame_len=640;step_len=320;
?????case?44100
?????????frame_len=1800;step_len=900;
?????otherwise
?????????frame_len=1800;step_len=900;
end;
n_frame=fix((wav_length-frame_len)/step_len)+1;??%確定幀數
%分幀
for?i=1:n_frame
????n1=(i-1)*step_len+1;
????n2=(i-1)*step_len+frame_len;
??S(i:)=wavin(n1:n2);
end
win_ham=hamming(frame_len);?%定義漢明窗函數
%取前15幀學習噪聲
noise_foward15frame=zeros(15frame_len);%定義一個數組放前15幀的噪音短時傅立葉變換結果
for?nifrm=1:15
????nf=fft(win_ham.*(S(nifrm1:frame_len)‘)frame_len);
????noise_foward15frame(nifrm:)=noise_foward15frame(nifrm:)+(abs(nf)‘);??%noise_foward15frame保存前15幀的噪音短時傅立葉變換幅度結果
end
am_noise=mean(noise_foward15frame(:1:frame_len));%求出每幀的噪聲幅度
%用譜減法進行語音增強
sum_timedomain=zeros(n_frameframe_len);%定義一個數組放時域和的結果
voice_timedomain=zeros(n_frameframe_len);%定義一個數組放去噪后的語音的時域
for?ifrm=1:n_frame??
????sum_timedomain(ifrm1:frame_len)=sum_timedomain(ifrm1:frame_len)+(win_ham‘).*S(ifrm1:frame_len);%sum_timedomain保存整個語音信號的時域和的結果
????sf=fft((win_ham‘).*S(ifrm:)frame_len);?
????phase=angle(sf);%保存這幀語音信號的傅立葉變換的結果的相位
????am_signal=abs(sf);?%保存這幀語音信號的傅立葉變換的結果的幅度
????am_voice=am_signal-am_noise;?%譜減??%用信號的幅度減去噪聲的幅度得到純凈語音的幅度
????for?b=1:frame_len
????????if(am_voice(1b)<0)
????????????am_voice(1b)=0;
????????end
????end
????voice=am_voice.*exp(j*phase);%組合相位與幅度得到去噪后的純凈語音信號
????sif=real(ifft(voiceframe_len));%?求這幀純凈語音信號的傅立葉反變換的實部
????voice_timedomain(ifrm:)=voice_timedomain(ifrm:)+sif;%voice_timedomain保存整個去噪后的語音信號的時域和的結果
end
%求出純凈語音信號的真實幅度
wavout=zeros(1wav_length);
for?d=1:n_frame
????m1=(d-1)*step_len+1;
????m2=(d-1)*step_len+frame_len;
????wavout(m1:m2)=wavout(m1:m2)+voice_timedomain(d1:frame_len);
end
%將處理結果輸出為‘wav‘文件
wavwrite(wavoutfsnbits[‘去噪后的語音‘]);
sound(wavoutfsnbits);
%將處理前后的結果進行作圖比較
subplot(211);
plot(wavin);grid?on;
axis([1?wav_length?-1?1]);
subplot(212);
plot(wbvin);grid?on;
axis([1?wav_length?-4?4]);
?屬性????????????大小?????日期????時間???名稱
-----------?---------??----------?-----??----
?????文件???????2948??2011-08-11?15:09??新建文件夾?(2)\war5.m
?????目錄??????????0??2011-08-12?14:59??新建文件夾?(2)
-----------?---------??----------?-----??----
?????????????????2948????????????????????2
- 上一篇:甘特圖-project文件
- 下一篇:相參串脈沖matlab
評論
共有 條評論