Diff of /Wiener.m [000000] .. [d29046]

Switch to unified view

a b/Wiener.m
1
function [output,time] = Wiener(signal,fs,type,IS)
2
3
if (nargin<4 || isstruct(IS))
4
    IS=.25; %Initial Silence or Noise Only part in seconds
5
end
6
7
W=fix(.025*fs); %Window length is 25 ms
8
SP=.4; %Shift percentage is 40% (10ms) %Overlap-Add method works good with this value(.4)
9
wnd=hann(W);
10
11
pre_emph=0;
12
signal=filter([1 -pre_emph],1,signal);
13
14
NIS=fix((IS*fs-W)/(SP*W) +1);%number of initial silence segments
15
16
y=segment(signal,W,SP,wnd); % This function chops the signal into frames
17
Y=fft(y);
18
YPhase=angle(Y(1:fix(end/2)+1,:)); %Noisy Speech Phase
19
Y=abs(Y(1:fix(end/2)+1,:));%Specrogram
20
numberOfFrames=size(Y,2);
21
FreqResol=size(Y,1);
22
23
N=mean(Y(:,1:NIS)')'; %initial Noise Power Spectrum mean
24
LambdaD=mean((Y(:,1:NIS)').^2)';%initial Noise Power Spectrum variance
25
alpha=.99; %used in smoothing xi (For Deciesion Directed method for estimation of A Priori SNR)
26
NoiseCounter=0;
27
NoiseLength=9;%This is a smoothing factor for the noise updating
28
G=ones(size(N));%Initial Gain used in calculation of the new xi
29
Gamma=G;
30
31
X=zeros(size(Y)); % Initialize X (memory allocation)
32
33
h=waitbar(0,'Wait...');
34
35
for i=1:numberOfFrames
36
    %%%%%%%%%%%%%%%%VAD and Noise Estimation START
37
    if i<=NIS % If initial silence ignore VAD
38
        SpeechFlag=0;
39
        NoiseCounter=100;
40
    else % Else Do VAD
41
        [NoiseFlag, SpeechFlag, NoiseCounter, Dist]=vad(Y(:,i),N,NoiseCounter); %Magnitude Spectrum Distance VAD
42
    end
43
    
44
    if SpeechFlag==0 % If not Speech Update Noise Parameters
45
        N=(NoiseLength*N+Y(:,i))/(NoiseLength+1); %Update and smooth noise mean
46
        LambdaD=(NoiseLength*LambdaD+(Y(:,i).^2))./(1+NoiseLength); %Update and smooth noise variance
47
    end
48
    %%%%%%%%%%%%%%%%%%%VAD and Noise Estimation END
49
    
50
    gammaNew=(Y(:,i).^2)./LambdaD; %A postiriori SNR
51
    xi=alpha*(G.^2).*Gamma+(1-alpha).*max(gammaNew-1,0); %Decision Directed Method for A Priori SNR
52
    Gamma=gammaNew;
53
    
54
    G=(xi./(xi+1));
55
    
56
    X(:,i)=G.*Y(:,i); %Obtain the new Cleaned value
57
    
58
    waitbar(i/numberOfFrames,h,num2str(fix(100*i/numberOfFrames)));
59
end
60
61
close(h);
62
output = OverlapAdd2(X,YPhase,W,SP*W); %Overlap-add Synthesis of speech
63
output = filter(1,[1 -pre_emph],output); %Undo the effect of Pre-emphasis
64
65
num = [0.00247553277809987,0.00495106555619995,0.00247553277809975];
66
den = [1,-1.80098109524571,0.810883226358106];
67
68
output = filter(num,den,output);
69
time = (0:1/fs:(size(output,1)-1)/fs);
70
71
if type == 1
72
    output = 100.*output;
73
end
74
75
76
function ReconstructedSignal=OverlapAdd2(XNEW,yphase,windowLen,ShiftLen)
77
78
if nargin<2
79
    yphase=angle(XNEW);
80
end
81
if nargin<3
82
    windowLen=size(XNEW,1)*2;
83
end
84
if nargin<4
85
    ShiftLen=windowLen/2;
86
end
87
if fix(ShiftLen)~=ShiftLen
88
    ShiftLen=fix(ShiftLen);
89
    disp('The shift length have to be an integer as it is the number of samples.')
90
    disp(['shift length is fixed to ' num2str(ShiftLen)])
91
end
92
93
[FreqRes, FrameNum]=size(XNEW);
94
95
Spec=XNEW.*exp(1i*yphase);
96
97
if mod(windowLen,2) %if FreqResol is odd
98
    Spec=[Spec;flipud(conj(Spec(2:end,:)))];
99
else
100
    Spec=[Spec;flipud(conj(Spec(2:end-1,:)))];
101
end
102
sig=zeros((FrameNum-1)*ShiftLen+windowLen,1);
103
weight=sig;
104
for i=1:FrameNum
105
    start=(i-1)*ShiftLen+1;    
106
    spec=Spec(:,i);
107
    sig(start:start+windowLen-1)=sig(start:start+windowLen-1)+real(ifft(spec,windowLen));    
108
end
109
ReconstructedSignal=sig;
110
111
function Seg=segment(signal,W,SP,Window)
112
113
if nargin<3
114
    SP=.4;
115
end
116
if nargin<2
117
    W=256;
118
end
119
if nargin<4
120
    Window=hamming(W);
121
end
122
Window=Window(:); %make it a column vector
123
124
L=length(signal);
125
SP=fix(W.*SP);
126
N=fix((L-W)/SP +1); %number of segments
127
128
Index=(repmat(1:W,N,1)+repmat((0:(N-1))'*SP,1,W))';
129
hw=repmat(Window,1,N);
130
Seg=signal(Index).*hw;
131
132
function [NoiseFlag, SpeechFlag, NoiseCounter, Dist]=vad(signal,noise,NoiseCounter,NoiseMargin,Hangover)
133
134
if nargin<4
135
    NoiseMargin=3;
136
end
137
if nargin<5
138
    Hangover=8;
139
end
140
if nargin<3
141
    NoiseCounter=0;
142
end
143
    
144
FreqResol=length(signal);
145
146
SpectralDist= 20*(log10(signal)-log10(noise));
147
SpectralDist(SpectralDist<0)=0;
148
149
Dist=mean(SpectralDist); 
150
if (Dist < NoiseMargin) 
151
    NoiseFlag=1; 
152
    NoiseCounter=NoiseCounter+1;
153
else
154
    NoiseFlag=0;
155
    NoiseCounter=0;
156
end
157
158
% Detect noise only periods and attenuate the signal     
159
if (NoiseCounter > Hangover) 
160
    SpeechFlag=0;    
161
else 
162
    SpeechFlag=1; 
163
end