0% found this document useful (0 votes)
212 views4 pages

SSBoll 79

This document contains MATLAB code for spectral subtraction based noise reduction. The code segments an input noisy signal, estimates the noise spectrum, performs spectral subtraction to enhance speech segments, and reconstructs the output signal. Key steps include magnitude averaging, voice activity detection using spectral distance, updating the noise estimate, and applying overlap-add synthesis.

Uploaded by

Thanh Trung Bui
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
212 views4 pages

SSBoll 79

This document contains MATLAB code for spectral subtraction based noise reduction. The code segments an input noisy signal, estimates the noise spectrum, performs spectral subtraction to enhance speech segments, and reconstructs the output signal. Key steps include magnitude averaging, voice activity detection using spectral distance, updating the noise estimate, and applying overlap-add synthesis.

Uploaded by

Thanh Trung Bui
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

SSBoll79.

5/9/2012

function [output,Speech]=SSBoll79(signal,fs,IS) % OUTPUT=SSBOLL79(S,FS,IS) % Spectral Subtraction based on Boll 79. Amplitude spectral subtraction % Includes Magnitude Averaging and Residual noise Reduction % % INPUT: Signal is the noisy signal, fs is the sampling frequency and IS is the initial % silence (noise only) length in seconds (default value is .25 sec) % % OUTPUT: output is enhanced speech signal; Speech is VAD vector % % April-05 % Esfandiar Zavarehei %G:\Lab3-SE\15dB\050912-090824.WAV addpath G:\Lab3-SE\15dB; % addpath %[signal,fs]=wavread('sp01VN_babble_sn15.wav'); [signal,fs]=wavread('050912-090824.WAV'); if (nargin<3 || isstruct(IS)) IS=.25; % seconds % IS is the initial silence (noise only) length in seconds ( default value is .25 sec ) end W=fix(.025*fs); %Window length is 25 ms nfft=W; SP=.4; %Shift percentage is 40% (10ms) %Overlap-Add method works good with this value(.4) wnd=hamming(W); % Dung Hamming vi giam thieu duoc side-lope va hien tuong Gibbs % se mang lai hieu suat cai thien thoai cao hon cac cua so % khac. % wnd=rectwin(W); % IGNORE THIS SECTION FOR CAMPATIBALITY WITH ANOTHER PROGRAM FROM HERE..... if (nargin>=3 && isstruct(IS))%This option is for compatibility with another programme W=IS.windowsize; SP=IS.shiftsize/W; nfft=IS.nfft; wnd=IS.window; if isfield(IS,'IS') IS=IS.IS; else IS=.25; end end % .......IGNORE THIS SECTION FOR CAMPATIBALITY WITH ANOTHER PROGRAM T0 HERE NIS=fix((IS*fs-W)/(SP*W) +1);%number of initial silence segments Gamma=1; % (1 for magnitude spectral subtraction 2 for power spectrum subtraction) disp(' Segmentation'); y=segment(signal,W,SP,wnd); % Tap hop cac mau t/h trong cung mot frame sau khi dc phan tich o dau vao % goi la mot "segment". % Voi cach thuc hien phan tich va lien ket cac frame bang phuong phap % overlap va adding thi tin hieu cua chung ta thu duoc sau khi xu ly triet % nhieu se khong bi meo dang va se khong xuat hien hien tuong "giam nhieu". disp('FFT'); Y=fft(y,nfft); YPhase=angle(Y(1:fix(end/2)+1,:)); %Noisy Speech Phase Y=abs(Y(1:fix(end/2)+1,:)).^Gamma;%Specrogram numberOfFrames=size(Y,2); FreqResol=size(Y,1); 1

SSBoll79.m %size(Y), disp(' Noise Initialization'); N=mean(Y(:,1:NIS)')'; %initial Noise Power Spectrum mean NRM=zeros(size(N));% Noise Residual Maximum (Initialization) NoiseCounter=0; NoiseLength=9;%This is a smoothing factor for the noise updating Beta=.03; % he so nen nhieu. disp(' Magnitude Averaged'); % E. Magnitude Averaging YS=Y; %Y Magnitude Averaged for i=2:(numberOfFrames-1) YS(:,i)=(Y(:,i-1)+Y(:,i)+Y(:,i+1))/3; end

5/9/2012

disp(' Spectral Subtraction'); % C. Spectral Subtraction Estimator X=zeros(FreqResol,numberOfFrames); for i=1:numberOfFrames [NoiseFlag, SpeechFlag, NoiseCounter, Dist]=vad(Y(:,i).^(1/Gamma),N.^(1/ Gamma),NoiseCounter); %Magnitude Spectrum Distance VAD Speech(i,1)=SpeechFlag; if SpeechFlag==0 N=(NoiseLength*N+Y(:,i))/(NoiseLength+1); %Update and smooth noise NRM=max(NRM,YS(:,i)-N);%Update Maximum Noise Residue X(:,i)=Beta*Y(:,i); else D=YS(:,i)-N; % Specral Subtraction if i>1 && i<numberOfFrames %Residual Noise Reduction for j=1:length(D) if D(j)<NRM(j) D(j)=min([D(j) YS(j,i-1)-N(j) YS(j,i+1)-N(j)]); end end end X(:,i)=max(D,0); % Half- Wave Rectification end end disp(' Synthesis'); output=OverlapAdd2(X.^(1/Gamma),YPhase,W,SP*W); soundview(output,fs); wavwrite(output,fs,'G:\Lab3-SE\output11.wav'); %auwrite(output,fs,'G:\Lab3-SE\output12.wav'); %%%%%%%%% RECONSTRUCTED SIGNAL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function ReconstructedSignal=OverlapAdd2(XNEW,yphase,windowLen,ShiftLen); %Y=OverlapAdd(X,A,W,S); %Y is the signal reconstructed signal from its spectrogram. X is a matrix %with each column being the fft of a segment of signal. A is the phase %angle of the spectrum which should have the same dimension as X. if it is %not given the phase angle of X is used which in the case of real values is %zero (assuming that its the magnitude). W is the window length of time %domain segments if not given the length is assumed to be twice as long as %fft window length. S is the shift length of the segmentation process ( for %example in the case of non overlapping signals it is equal to W and in the %case of %50 overlap is equal to W/2. if not givven W/2 is used. Y is the %reconstructed time domain signal. %Sep-04 %Esfandiar Zavarehei if nargin<2 yphase=angle(XNEW); end if nargin<3 2

SSBoll79.m

5/9/2012

windowLen=size(XNEW,1)*2; end if nargin<4 ShiftLen=windowLen/2; end if fix(ShiftLen)~=ShiftLen ShiftLen=fix(ShiftLen); disp('The shift length have to be an integer as it is the number of samples.') disp(['shift length is fixed to' num2str(ShiftLen)]) end [FreqRes FrameNum]=size(XNEW); Spec=XNEW.*exp(j*yphase); if mod(windowLen,2) %if FreqResol is odd Spec=[Spec;flipud(conj(Spec(2:end,:)))]; else Spec=[Spec;flipud(conj(Spec(2:end-1,:)))]; end sig=zeros((FrameNum-1)*ShiftLen+windowLen,1); weight=sig; for i=1:FrameNum start=(i-1)*ShiftLen+1; spec=Spec(:,i); sig(start:start+windowLen-1)=sig(start:start+windowLen-1)+real(ifft(spec, windowLen)); end ReconstructedSignal=sig; %%%%%%%%%%%%%% VOICE ACTIVITY DETECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [NoiseFlag, SpeechFlag, NoiseCounter, Dist]=vad(signal,noise, NoiseCounter,NoiseMargin,Hangover) %[NOISEFLAG, SPEECHFLAG, NOISECOUNTER, DIST]=vad(SIGNAL,NOISE,NOISECOUNTER,NOISEMARGIN,HANGOVER) %Spectral Distance Voice Activity Detector %SIGNAL is the the current frames magnitude spectrum which is to labeld as %noise or speech, NOISE is noise magnitude spectrum template (estimation), %NOISECOUNTER is the number of imediate previous noise frames, NOISEMARGIN %(default 3)is the spectral distance threshold. HANGOVER ( default 8 )is %the number of noise segments after which the SPEECHFLAG is reset (goes to %zero). NOISEFLAG is set to one if the the segment is labeld as noise %NOISECOUNTER returns the number of previous noise segments, this value is %reset (to zero) whenever a speech segment is detected. DIST is the spectral distance. % %Saeed Vaseghi %edited by Esfandiar Zavarehei %Sep-04 if nargin<4 NoiseMargin=2; end if nargin<5 Hangover=8; end if nargin<3 NoiseCounter=0; end FreqResol=length(signal);

SSBoll79.m SpectralDist= 20*(log10(signal)-log10(noise)); % ??? SpectralDist(find(SpectralDist<0))=0; Dist=mean(SpectralDist); %DIST is the spectral distance. if (Dist < NoiseMargin) NoiseFlag=1; NoiseCounter=NoiseCounter+1; else NoiseFlag=0; NoiseCounter=0; end

5/9/2012

% Detect noise only periods and attenuate the signal if (NoiseCounter > Hangover) % HANGOVER (default 8)is the number of noise segments % after which the SPEECHFLAG is reset (goes to zero) SpeechFlag=0; else SpeechFlag=1; end %%%%%%%%% SEGMENT %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function Seg=segment(signal,W,SP,Window) % % % % % % % % % SEGMENT chops a signal to overlapping windowed segments A= SEGMENT(X,W,SP,WIN) returns a matrix which its columns are segmented and windowed frames of the input one dimentional signal, X. W is the number of samples per window, default value W=256. SP is the shift percentage, default value SP=0.4. WIN is the window that is multiplied by each segment and its length should be W. the default window is hamming window. 06-Sep-04 Esfandiar Zavarehei

if nargin<3 SP=.4; end if nargin<2 W=256; end if nargin<4 Window=hamming(W); end Window=Window(:); %make it a column vector L=length(signal); SP=fix(W.*SP); N=fix((L-W)/SP +1); %number of segments % repmat: replicate and tile array. Index=(repmat(1:W,N,1)+repmat((0:(N-1))'*SP,1,W))'; %Indextemp=(repmat(1:W,N,1)+ repmat((0:(N-1))))'; hw=repmat(Window,1,N); Seg=signal(Index).*hw;

You might also like