# Long term spectral flatness measure voice activity detection

This is the Long term spectral flatness measure code that I have written so far. Can someone please help me, I don't know if I'm writing it correctly. It is working fine and gives high peak for speech region and sometimes output high flatness for regions where it should actually give high peaks.

nfft = 1024;
s_bin = ceil(nfft*(500/fs))+1;
e_bin = ceil(nfft*(4000/fs));

M = 10;
R = 30;
spec_size = size(S,2);

SS(1:spec_size) = 0;
AM(1:e_bin) = 0;
GM(1:e_bin) = 1;
RR(1:spec_size) = 0;

for m=1:spec_size
for wk=s_bin:e_bin
for n=m-R+1:m
if n>0
c = 0;
for p=n-M+1:n
if p>0
SS(n) = SS(n) + abs(S(wk,p))^2; c=c+1;
end
end
if c<M
AM(wk) = AM(wk)+ SS(n)/c;
GM(wk) = GM(wk)*(SS(n)/c);
else
AM(wk) = AM(wk)+ SS(n)/M;
GM(wk) = GM(wk)*(SS(n)/M);
end
SS(n) = 0;
end
end
if m<=R && c>0
AM(wk) = AM(wk)/m;
GM(wk) = nthroot(GM(wk),m);
elseif m>R
AM(wk) = AM(wk)/R;
GM(wk) = nthroot(GM(wk),R);
else
AM(wk) = 0;GM(wk)=0;
end
RR(m) = RR(m) + log10(GM(wk)/AM(wk));

end

L(m) = RR(m);

AM(1:e_bin) = 0;
GM(1:e_bin) = 1;
RR(m) = 0;
end


Or you can try and implement the adaptive threshold method: This is taken from the EURASIP Paper which i have implemented.

UnlikeM and R, a fixed threshold would lose its efficiency when facing varying acoustic environments. Therefore, it is more suitable to design an adaptive threshold [22]. From Equations 2 to 4, we can conclude that (R +M−1) frame (0.39 s for fixed R = 30 and M = 10) information is needed to acquire the first LSFM feature value. In our implementations, the initial 1.39 s of the test signal x(n) is always assumed to be non-speech. From this 1.39 s of x(n), 100 realizations of LN can be collected and saved to ψINL. The threshold is initialized to be THRINL = min(ψINL). (8) To update the threshold at the mth frame, we used two buffers ψS + N and ψN. ψS + N stores the LSFMmeasures of the last 100 long windowending at themth frame which was decided as containing speech; similarly, ψN stores the LSFM measures of the last 100 long window ending at the mth frame which was decided as including nonspeech information only. The adaptive threshold for the mth frame is then updated as: THR(m) = λ×min(ψS+N)+(1−λ)×max(ψN), (9) where λ is the parameter of the convex combination. We experimentally found that λ = 0.55 results in the maximum accuracy rate in VAD decisions over the TIMIT training set.

• Looks like you are an expert in the field and have probably come across/thought of this,however maybe this may help.This wont change the peaks, but perhaps it will change your threshold to adapt to the unusual peak.Hope this helps. – Debayan Ghosh Feb 1 '17 at 16:52
• On running your code, Im getting similar values as yours. I am assuming the author of the paper has missed out on particular details.I assumed I hadn't implemented it correctly, but after running your code I am sure certain things in the paper which aren't so explicitly explained. – Debayan Ghosh Feb 1 '17 at 17:56

This is an excerpt form my code.

 x_axis=[1:num_frame];
for i=1:num_frame
frame(1:len_frame,i) = x(len_frame*(i-1)+1:len_frame*i,1);
%ene(i)= sum(frame(1:len_frame,i).* frame(1:len_frame,i));
end
segmentLength=len_frame;
noverlap=len_frame/2;
l=pwelch(frame(:,123),segmentLength,noverlap,512);
XK2=[];
for i=1:num_frame

XK2(:,i)=pwelch(frame(:,i),segmentLength,noverlap,512);

end
XK2;

lengtha= length(XK2(:,9))
SN=zeros(lengtha,num_frame);
for i=1:num_frame
if(i-M>=0)
for n=i-M+1:i
SN(:,i)=XK2(:,n)+SN(:,i);
end
SN(:,i)= SN(:,i)/M;

else
SN(:,i)=XK2(:,i);
end

end
% R=10;
SN;
SN2=SN';
SN2(123,:);
l1=length(SN2(1,:));
=-1.5;
SFM=[]
% phi_speech=[];
% phi_nonspeech=[];
count_speech=1;
count_nonspeech=1;
for i=1:num_frame
TEMP=[];
if(i-R>=0)
for n=i-R+1:i
TEMP=[TEMP ; SN2(n,:)];

end

GM=geomean(TEMP);

AM=mean(TEMP);
SFM(i,:)=GM./AM;
else
SFM(i,:)=ones(1,l1);
end

end

len=length(SFM(2,:))
SFM=SFM';
SFMDB=log10(SFM);
L1=length(SFM(:,2));
lx=[];
th=0;
count=0;
th1=[];
for i=1:num_frame

lx(i)=sum(SFMDB(:,i));
if(lx(i)==(-Inf))
lx(i)=-100;
end

%     if(ref(i)==1)
%         th=th+lx(i);
%         count=count+1;
%         th1=[th1 lx(i)];
%     end
%
end
lx
th=th/count;

thresh=-10
thresh1=-20.5;
th_plot=[];
voice_flags=[];
% lam=0.295;
% phi_seech=NaN.*ones(1,100);
phi_speech(1)=thresh;
phi_nonspeech(1)=thresh;
c1=10;
% phi_nonspeech=NaN.*ones(1,100);
for i=1:num_frame

th_plot=[th_plot thresh];
if(count_speech==c1)
count_speech=1;
end
if(count_nonspeech==c1)
count_nonspeech=1;

end

if(lx(i)<0)
if(lx(i)<thresh)
voice_flags(i)=1;
phi_speech(count_speech)=lx(i);
count_speech=count_speech+1;
else
voice_flags(i)=0;
phi_nonspeech(count_nonspeech)=lx(i);
count_nonspeech=count_nonspeech+1;
end
else
voice_flags(i)=0;
end
thresh=lam*min(phi_speech)+(1-lam)*max(phi_nonspeech);

end