1 模型
本文提出了一种语音增强算法,该算法以基于先验信噪比估计的维纳滤波法为基础。通过计算无声段的统计平均得到初始噪声功率谱,并平滑处理初始噪声功率谱和带噪语音功率谱,更新了噪声功率谱;最后,考虑了某频率点处噪声急剧增大的情况,做了相关验证,该算法能有效地抑制变化范围不大或是稳定的噪声,但是对实际中的变化范围很广的噪声效果不是很好。
1.1 语音增强的相关概念
嵌在语音系统中,语音信号不可避免的会受到周围噪声的干扰,从而影响语音的质量与可懂度。
语音增强:其实就是带噪语音中提取尽可能纯净的语音,改善语音质量和可懂度,提高噪声环境下语音通信系统的性能。
噪声都随机产生的,不可能完全消除。语音增强的目标是:减弱噪声、消除背景噪声、改进语音质量、使听着乐于接受,提高语音可懂度。
1.2 语音增强的相关算法
由于噪声来源众多,特性各不相同。语音增强处理系统的应用场合千差万别。
因此,不存在一种可以通用于各种噪声环境的语音增强算法。针对不同的环境,采取不同的语音增强算法。
语音增强算法按处理方式可以分为:基于语音周期性的增强算法,基于全极点模型的增强算法,基于短时谱估计的增强算法,基于信号子空间的增强算法和
基于HMM的增强算法。
从目前的发展来看,基于短时谱估计的方法是最有效的方法。具体包括谱减法、维纳滤波、最小均方误差短时谱幅度估计法(MMSE-STSA)和最小均方误差对数谱幅度估计法(MMSE-LSA)。本文主要讨论使用维纳滤波器实现语音的增强处理。
2 部分代码
function varargout = adsp_project(varargin) % ADSP_PROJECT MATLAB code for adsp_project.fig % ADSP_PROJECT, by itself, creates a new ADSP_PROJECT or raises the existing % singleton*. % % H = ADSP_PROJECT returns the handle to a new ADSP_PROJECT or the handle to % the existing singleton*. % % ADSP_PROJECT('CALLBACK',hObject,eventData,handles,...) calls the local % function named CALLBACK in ADSP_PROJECT.M with the given input arguments. % % ADSP_PROJECT('Property','Value',...) creates a new ADSP_PROJECT or raises the % existing singleton*. Starting from the left, property value pairs are % applied to the GUI before adsp_project_OpeningFcn gets called. An % unrecognized property name or invalid value makes property application % stop. All inputs are passed to adsp_project_OpeningFcn via varargin. % % *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one % instance to run (singleton)". % % See also: GUIDE, GUIDATA, GUIHANDLES % Edit the above text to modify the response to help adsp_project % Last Modified by GUIDE v2.5 15-Dec-2014 18:26:21 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @adsp_project_OpeningFcn, ... 'gui_OutputFcn', @adsp_project_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin && ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT % --- Executes just before adsp_project is made visible. function adsp_project_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to adsp_project (see VARARGIN) % Choose default command line output for adsp_project handles.output = hObject; % Update handles structure guidata(hObject, handles); % UIWAIT makes adsp_project wait for user response (see UIRESUME) % uiwait(handles.figure1); % --- Outputs from this function are returned to the command line. function varargout = adsp_project_OutputFcn(hObject, eventdata, handles) % varargout cell array for returning output args (see VARARGOUT); % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Get default command line output from handles structure varargout{1} = handles.output; % --- Executes on button press in pushbutton1. function pushbutton1_Callback(hObject, eventdata, handles) global xk; global fs; global noise_type; noise_type=1; [FileName,PathName] = uigetfile('*.wav','Select the voice-file'); [x,fs]=wavread(FileName); ls=length(x); xk=x(1:ls); set(handles.text_fs,'string',num2str(fs)); set(handles.text_ls,'string',num2str(ls)); axes(handles.axes_freq); %xaxis1=linspace(0,0.5,250); plot(abs(fft(xk))); %xk 音频的句柄 用来做按键响应函数 axis([0,14000,0,300]) ; axes(handles.axes_wave); %xaxis1=linspace(0,0.5,250); h_xk=plot(xk); %xk 音频的句柄 用来做按键响应函数 axis([0,30000,-1.5,1.5]) ; set(h_xk,'ButtonDownFcn',@axes_waveCallback); %grid on; %set(gca,'xtick',(0:0.02:0.5),'ytick',[0:100:500]); %axis([0.25 0.45 0 500]); % hObject handle to pushbutton1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % --- Executes on button press in pushbutton2. function pushbutton2_Callback(hObject, eventdata, handles) global xk; global SNR; global fs; global xs; global noise_type; noise_type=1;%高斯噪声 SNR_slider=get(handles.slider_SNR,'value'); SNR_slider=floor(SNR_slider); SNR=num2str(SNR_slider); set(handles.text_snr,'string',SNR); xs=awgn(xk,SNR_slider,0);%加入高斯白噪声,信噪比30 axes(handles.axes_freq); plot(abs(fft(xs))); %xk 音频的句柄 用来做按键响应函数 axis([0,14000,0,300]) ; axes(handles.axes_noise); h_xs=plot(xs); axis([0,30000,-1.5,1.5]) ; set(h_xs,'ButtonDownFcn',@axes_noiseCallback); % hObject handle to pushbutton2 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % --- Executes on button press in pushbutton3. % hObject handle to pushbutton3 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % --- Executes on selection change in popupmenu1. function popupmenu1_Callback(hObject, eventdata, handles) % hObject handle to popupmenu1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: contents = cellstr(get(hObject,'String')) returns popupmenu1 contents as cell array % contents{get(hObject,'Value')} returns selected item from popupmenu1 % --- Executes during object creation, after setting all properties. function popupmenu1_CreateFcn(hObject, eventdata, handles) % hObject handle to popupmenu1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: popupmenu controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes on key press with focus on pushbutton1 and none of its controls. function pushbutton1_KeyPressFcn(hObject, eventdata, handles) % hObject handle to pushbutton1 (see GCBO) % eventdata structure with the following fields (see UICONTROL) %Key: name of the key that was pressed, in lower case %Character: character interpretation of the key(s) that was pressed %Modifier: name(s) of the modifier key(s) (i.e., control, shift) pressed % handles structure with handles and user data (see GUIDATA) % --- If Enable == 'on', executes on mouse press in 5 pixel border. % --- Otherwise, executes on mouse press in 5 pixel border or over pushbutton1. function pushbutton1_ButtonDownFcn(hObject, eventdata, handles) % hObject handle to pushbutton1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % --- Executes on slider movement. function slider2_Callback(hObject, eventdata, handles) % hObject handle to slider2 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'Value') returns position of slider % get(hObject,'Min') and get(hObject,'Max') to determine range of slider % --- Executes during object creation, after setting all properties. function slider2_CreateFcn(hObject, eventdata, handles) % hObject handle to slider2 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: slider controls usually have a light gray background. if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor',[.9 .9 .9]); end % --- Executes on slider movement. function slider_SNR_Callback(hObject, eventdata, handles) global xk; global SNR; global xs; global noise_type; global realtime_filter_flag; if noise_type==1 SNR_slider=get(handles.slider_SNR,'value'); SNR_slider=floor(SNR_slider); SNR=num2str(SNR_slider); set(handles.text_snr,'string',SNR); xs=awgn(xk,SNR_slider,0);%加入高斯白噪声,信噪比30 axes(handles.axes_freq); plot(abs(fft(xs))); %xk 音频的句柄 用来做按键响应函数 axis([0,14000,0,300]) ; axes(handles.axes_noise); h_xs=plot(xs); axis([0,30000,-1.5,1.5]) ; set(h_xs,'ButtonDownFcn',@axes_noiseCallback); else xs=xk; SNR_slider=get(handles.slider_SNR,'value'); SNR_slider=floor(SNR_slider); SNR=num2str(SNR_slider); set(handles.text_snr,'string',SNR); step=2500; lenth=800; xs(1:2000)=awgn(xk(1:2000),SNR_slider,0); %最前面的底噪 不然segment出错 for i=3:8 xs(i*step:i*step+lenth)=awgn(xk(i*step:i*step+lenth),SNR_slider,0);%加入高斯白噪声,信噪比30 end axes(handles.axes_freq); plot(abs(fft(xs))); %xk 音频的句柄 用来做按键响应函数 axis([0,14000,0,300]) ; axes(handles.axes_noise); h_xs=plot(xs); axis([0,30000,-1.5,1.5]) ; set(h_xs,'ButtonDownFcn',@axes_noiseCallback); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%维纳滤波 global fs; global filtered; global flen; global freq_uf; global freq_f; global filtered_flag; if realtime_filter_flag==1; flen=get(handles.f_lenth_slider,'value'); %每帧长度 FLEN=num2str(flen); set(handles.text_f_lenth,'string',FLEN); % [filtered,freq_uf,freq_f]=WienerScalart96m(xs,fs,0.25,flen);%freq_uf 滤波前 freq_f 滤波后 filtered_flag=1; axes(handles.axes_freq); plot(abs(fft(filtered))); %xk 音频的句柄 用来做按键响应函数 axis([0,14000,0,300]) ; axes(handles.axes_cleaned); h_filtered=plot(filtered); axis([0,30000,-1.5,1.5]) ; set(h_filtered,'ButtonDownFcn',@axes_filteredCallback); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%维纳滤波 % hObject handle to slider_SNR (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'Value') returns position of slider % get(hObject,'Min') and get(hObject,'Max') to determine range of slider % --- Executes during object creation, after setting all properties. function slider_SNR_CreateFcn(hObject, eventdata, handles) % hObject handle to slider_SNR (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: slider controls usually have a light gray background. if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor',[.9 .9 .9]); end % --- Executes on slider movement. function slider5_Callback(hObject, eventdata, handles) % hObject handle to slider5 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'Value') returns position of slider % get(hObject,'Min') and get(hObject,'Max') to determine range of slider % --- Executes during object creation, after setting all properties. function slider5_CreateFcn(hObject, eventdata, handles) % hObject handle to slider5 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: slider controls usually have a light gray background. if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor',[.9 .9 .9]); end % --- Executes on slider movement. function pre_noice_slider_Callback(hObject, eventdata, handles) global fs; global xs; global filtered; global flen; global pre_noice; global filtered_flag; pre_noice=get(handles.pre_noice_slider,'value');%前导噪声 flen=get(handles.f_lenth_slider,'value'); %每帧长度 FLEN=num2str(flen); PRE_NOICE=num2str(pre_noice); set(handles.text_f_lenth,'string',FLEN); set(handles.pre_noice_text,'string',PRE_NOICE); % [filtered,freq_uf,freq_f]=WienerScalart96m(xs,fs,0.25,flen);%freq_uf 滤波前 freq_f 滤波后 filtered_flag=1; axes(handles.axes_cleaned); h_filtered=plot(filtered); axis([0,30000,-1.5,1.5]) ; set(h_filtered,'ButtonDownFcn',@axes_filteredCallback); % hObject handle to pre_noice_slider (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'Value') returns position of slider % get(hObject,'Min') and get(hObject,'Max') to determine range of slider % --- Executes during object creation, after setting all properties. function pre_noice_slider_CreateFcn(hObject, eventdata, handles) % hObject handle to pre_noice_slider (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: slider controls usually have a light gray background. if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor',[.9 .9 .9]); end % --- Executes on selection change in popupmenu2. function popupmenu2_Callback(hObject, eventdata, handles) % hObject handle to popupmenu2 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: contents = cellstr(get(hObject,'String')) returns popupmenu2 contents as cell array % contents{get(hObject,'Value')} returns selected item from popupmenu2 % --- Executes during object creation, after setting all properties. function popupmenu2_CreateFcn(hObject, eventdata, handles) % hObject handle to popupmenu2 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: popupmenu controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes on slider movement. function f_lenth_slider_Callback(hObject, eventdata, handles) global fs; global xs; global filtered; global flen; global freq_uf; global freq_f; global filtered_flag; flen=get(handles.f_lenth_slider,'value'); %每帧长度 FLEN=num2str(flen); set(handles.text_f_lenth,'string',FLEN); [filtered,freq_uf,freq_f]=WienerScalart96m(xs,fs,0.25,flen);%freq_uf 滤波前 freq_f 滤波后 filtered_flag=1;;%freq_uf 滤波前 freq_f 滤波后 axes(handles.axes_freq); plot(abs(fft(filtered))); %xk 音频的句柄 用来做按键响应函数 axis([0,14000,0,300]) ; axes(handles.axes_cleaned); h_filtered=plot(filtered); axis([0,30000,-1.5,1.5]) ; set(h_filtered,'ButtonDownFcn',@axes_filteredCallback); % hObject handle to f_lenth_slider (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'Value') returns position of slider % get(hObject,'Min') and get(hObject,'Max') to determine range of slider % --- Executes during object creation, after setting all properties. function f_lenth_slider_CreateFcn(hObject, eventdata, handles) % hObject handle to f_lenth_slider (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: slider controls usually have a light gray background. if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor',[.9 .9 .9]); end % --- Executes on button press in pushbutton3. function pushbutton3_Callback(hObject, eventdata, handles) global fs; global xs; global filtered; global flen; global freq_uf; global freq_f; global filtered_flag; flen=get(handles.f_lenth_slider,'value'); %每帧长度 FLEN=num2str(flen); set(handles.text_f_lenth,'string',FLEN); % [filtered,freq_uf,freq_f]=WienerScalart96m(xs,fs,0.25,flen);%freq_uf 滤波前 freq_f 滤波后 filtered_flag=1;%freq_uf 滤波前 freq_f 滤波后 axes(handles.axes_freq); plot(abs(fft(filtered))); %xk 音频的句柄 用来做按键响应函数 axis([0,14000,0,300]) ; axes(handles.axes_cleaned); h_filtered=plot(filtered); axis([0,30000,-1.5,1.5]) ; set(h_filtered,'ButtonDownFcn',@axes_filteredCallback); % hObject handle to pushbutton3 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % --- Executes during object deletion, before destroying properties. function pushbutton1_DeleteFcn(hObject, eventdata, handles) % hObject handle to pushbutton1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % --- Executes on mouse press over axes background. function axes_wave_ButtonDownFcn(hObject, eventdata, handles) % hObject handle to axes_wave (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % --- Executes during object creation, after setting all properties. function axes_waveCallback(hObject, eventdata, handles) global fs; global xk; sound(xk,fs); function axes_noiseCallback(hObject, eventdata, handles) global fs; global xs; sound(xs,fs); function axes_filteredCallback(hObject, eventdata, handles) global fs; global filtered; sound(filtered,fs); % --- Executes during object creation, after setting all properties. function axes_wave_CreateFcn(hObject, eventdata, handles) % hObject handle to axes_wave (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: place code in OpeningFcn to populate axes_wave % --- Executes on button press in pushbutton4. function pushbutton4_Callback(hObject, eventdata, handles) global xk; global SNR; global fs; global xs; global noise_type; noise_type=2; xs=xk; SNR_slider=get(handles.slider_SNR,'value'); SNR_slider=floor(SNR_slider); SNR=num2str(SNR_slider); set(handles.text_snr,'string',SNR); step=2500; lenth=800; xs(1:2000)=awgn(xk(1:2000),SNR_slider,0); for i=3:8 xs(i*step:i*step+lenth)=awgn(xk(i*step:i*step+lenth),SNR_slider,0);%加入高斯白噪声,信噪比30 end axes(handles.axes_freq); plot(abs(fft(xs))); %xk 音频的句柄 用来做按键响应函数 axis([0,14000,0,300]) ; axes(handles.axes_noise); h_xs=plot(xs); axis([0,30000,-1.5,1.5]) ; set(h_xs,'ButtonDownFcn',@axes_noiseCallback); % hObject handle to pushbutton4 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % --- Executes on button press in pushbutton5. function pushbutton5_Callback(hObject, eventdata, handles) global realtime_filter_flag; string1='实时滤波'; string2=' 开'; string3=' 关'; if realtime_filter_flag==1 realtime_filter_flag=0; set(handles.pushbutton5,'string',[string1 string3]); else set(handles.pushbutton5,'string',[string1 string2]); realtime_filter_flag=1; end % hObject handle to pushbutton5 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % --- Executes on button press in pushbutton6. function pushbutton6_Callback(hObject, eventdata, handles) global flen; global xk; global xs; global filtered; global fs; global freq_uf; global freq_f; global filtered_flag; if(filtered_flag) figure(1); a=size(freq_uf);%获取矩阵大小 subplot(1,2,1); imagesc(0:1:a(1),0:1:a(2),freq_uf); title('滤波前'); subplot(1,2,2); b=size(freq_f);%获取矩阵大小 imagesc(0:1:b(1),0:1:b(2),freq_f); title('滤波后'); else errordlg('请先进行滤波','MATLAB error') ; end % specgram(xk,flen,fs,flen,2*flen/5); % % figure(2); % specgram(xs,flen,fs,flen,2*flen/5); % % figure(3); % specgram(filtered,flen,fs,flen,2*flen/5); % hObject handle to pushbutton6 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)
3 仿真结果
4 参考文献
[1]张亮, 龚卫国. 一种改进的维纳滤波语音增强算法[J]. 计算机工程与应用, 2010(26):133-135.