Unverified Commit 0144423d authored by Justice's avatar Justice

second section : 2/3 done.

parent 2b55d778
function output=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
% S 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)
%
% April-05
% Esfandiar Zavarehei
if (nargin<3 | isstruct(IS))
IS=.25; %seconds
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);
% 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;%Magnitude Power (1 for magnitude spectral subtraction 2 for power spectrum subtraction)
y=segment(signal,W,SP,wnd);
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);
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;
YS=Y; %Y Magnitude Averaged
for i=2:(numberOfFrames-1)
YS(:,i)=(Y(:,i-1)+Y(:,i)+Y(:,i+1))/3;
end
for i=1:numberOfFrames
[NoiseFlag, SpeechFlag, NoiseCounter, Dist]=vad(Y(:,i).^(1/Gamma),N.^(1/Gamma),NoiseCounter); %Magnitude Spectrum Distance VAD
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);
end
end
output=OverlapAdd2(X.^(1/Gamma),YPhase,W,SP*W);
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
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;
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=3;
end
if nargin<5
Hangover=8;
end
if nargin<3
NoiseCounter=0;
end
FreqResol=length(signal);
SpectralDist= 20*(log10(signal)-log10(noise));
SpectralDist(find(SpectralDist<0))=0;
Dist=mean(SpectralDist);
if (Dist < NoiseMargin)
NoiseFlag=1;
NoiseCounter=NoiseCounter+1;
else
NoiseFlag=0;
NoiseCounter=0;
end
% Detect noise only periods and attenuate the signal
if (NoiseCounter > Hangover)
SpeechFlag=0;
else
SpeechFlag=1;
end
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
Index=(repmat(1:W,N,1)+repmat((0:(N-1))'*SP,1,W))';
hw=repmat(Window,1,N);
Seg=signal(Index).*hw;
......@@ -7,5 +7,7 @@
\@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces طیف توان برای صدای ضبط شده زن شماره 10\relax }}{3}}
\@writefile{toc}{\contentsline {subsection}{\numberline {1.3}اوج صدا}{4}}
\@writefile{toc}{\contentsline {subsection}{\numberline {1.4}تشخیص جنسیت}{4}}
\@writefile{toc}{\contentsline {section}{\numberline {2} الگوریتم بهبود صدا}{5}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}تشخیص جنسیت}{5}}
\@writefile{toc}{\contentsline {section}{\numberline {2} الگوریتم هایی برای بهبود صدا}{5}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}معرفی مختصری از الگوریتم تفاضل طیف}{5}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2}پیاده سازی و نکات آن}{6}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3}تست الگوریتم در مقابل نویزهای متفاوت}{7}}
......@@ -105,11 +105,35 @@ voices/v9.wav women\\
پیشنهاد برای افزایش دقت: ما چون فقط بر اساس یک ماکزیمم درحال تصمیم گیری هستیم خطای بالایی داریم بهتر است برای بهینه کردن و افزایش دقت مجموعه ای از ماکسیمم ها و مینیمم های محلی را پیدا کنیم و الگوی انها را با الگوی اکسترمم های محلی هر جنسیت تطابق دهیم. البته چون ویس های ما زیاد نویز ندارند پس زیاد فرکانس ها تغییر نکرده اند و با همان پیک فرکانس میتوان به راحتی تشخیص داد.
برای این کار میتوان از تابع \lr{findpeaks} استفاده کرد که در نرم افزار \lr{octave} در پکیج \lr{signal} است.
\lr{convolve}
\section{ الگوریتم هایی برای بهبود صدا}
\section{ الگوریتم بهبود صدا}
\subsection{معرفی مختصری از الگوریتم تفاضل طیف}
\subsection{تشخیص جنسیت}
الگوریتم تفاضل طیف یکی از قدیمی ترین و مشهورترین روش های بهسازی سیگنال گفتار است که برای بازیابی طیف توان سیگنال آلوده به نویز استفاده می شود. در این روش طیف توان نویز تخمین زده شده را از طیف توان سیگنال نویزی کم کرده و سیگنال بهسازی شده را تولید می کند.
این الگوریتم یک الگوریتم تک کاناله است روش های دیگر چند کاناله ای هم وجود دارند مثل استفاده از دو میکروفون یکی برای ضبط صدا و یکی برای ضبط نویز محیط که به کمک یک سیستم وفقی میتوانستیم صدای ضبط شده را بهبود ببخشیم.
در روش تفاضل طیفی ، تخمین اندازه طیف توان نویز با استفاده از نواحی سکوت و از طریق میانگین گیری اندازه طیف توان نویز در پنجره های مختلف این نواحی انجام می شود. اساسی ترین مشکل این روش وجود نویزی آزار دهنده بنام نویز موزیکال در سیگنال بهسازی شده است که دلیل اصلی آن عدم دقت در تخمین طیف نویز است.
میدانیم که عواملی مانند طول فریم و… روی دقت تخمین طیف نویز موثر هستند و به طور خاص اثر آن بر روی نویز موزیکال ایجاد شده مورد مطالعه قرار می گیرد. مطالعات انجام شده نشان می دهند که هر چقدر طول فریم کمتر باشد و به عبارتی پنجره کوتاهتر باشد به علت \lr{convolve} شدن طیف گفتار و طیف پنجره، طیف سیگنال گفتار نیز به این طریق خراب خواهد شد.
همه عوامل فوق ما را به این سمت سوق می دهند که طول فریم را بزرگ انتخاب کنیم. بزرگتر گرفتن طول فریم دقت تخمین طیف نویز را افزایش داده و بنابراین موجب کاهش نویز موزیکال و افزایش کیفیت سیگنال شنیداری بهسازی شده می گردد و ثانیأ اگر دقت تخمین طیف بیشتر باشد می توان در روش تفریق طیفی،ضریب تفریق را بزرگتر انتخاب کرده و مقدار بهبود \lr{SNR} را افزایش داد.
هرچه میزان سکوت نویزی اول صدا بیشتر باشد تخمین بهتری زده خواهد شد.
نسبت سیگنال به نویز \lr{(SNR - Signal to Noise ratio) } معیاری برای نمایش میزان سیگنال مفید در مقابل سیگنال مزاحم (یا نویز) در سیستم‌های الکتریکی است. این عدد، نسبت توان سیگنال به توان نویز است، و آن را بر حسب دسی‌بل بیان می‌کنند.
\subsection{پیاده سازی و نکات آن}
ایده اصلی این الگوریتم برای حذف نویز صحبت در سال 1975 توسط ویس ارائه شد و نتیجه عملی آن در سال 1979 توسط بول منتشر گردید.
ابتدائا برای حذف نویز های سفید و ایسا طراحی شده بود و محدود عملی زیادی داشت که از جمله آن نویز های موزیکال بودند.
این روش بعد ها اصلاح شد و الگوریتم های پیچیده و روش های غیر خطی به کار گرفته شد تا علاوه بر حذف نویزهای واقعی محیط نویز موزیکال را نیز کاهش دهد.
ما در اینجا الگوریتم بول را پیاده سازی کرده‌ایم که در فایل
\lr{SSBoll79.m}
قرار دارد.
\subsection{تست الگوریتم در مقابل نویزهای متفاوت}
\end{document}
......@@ -133,5 +157,35 @@ voices/v9.wav women\\
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment