Zero Crossing Rate plotting

27 vues (au cours des 30 derniers jours)
Hardik Ruparel
Hardik Ruparel le 4 Fév 2021
Commenté : Mathieu NOE le 9 Fév 2021
I am writing a code to detect voiced vs un-voiced segment in a signal. I believe I have the correct approach and code. However, I am having difficulty trying to overlay the original signal and the zero crossing rate in the same plot. I need this to test, how effective the zero crossing rate is.
Additionally, is there any normalization that I may be missing ?
% Algorithm to identify presence of voice activity using zero crossing rate and energy
% of speech signal
clear all; clc; close all;
%% Read the input signal
[y, fs] = audioread('ISTS-16s-44100.wav');
N = length(y);
t = (0:N-1)/fs;
framelen = 128;
numframes = floor(N/framelen);
overlap = 0;
zcr = [];
for k = 1:numframes
arry = [];
zcr_frame = [];
frame = y((k-1)*framelen+1 : framelen*k) ;
for i = 2:length(frame)
arry(i) = sgn(frame(i)) - sgn(frame(i-1));
end
zcr_frame = sum(abs(arry));
zcr = [zcr zcr_frame] ;
end
figure (1); clf; hold on;
grid on;
plot(t,y);
xlabel('time(secs)'); ylabel('linear output')
t_zcr = (0:framelen:N-framelen)/fs ;
plot(t_zcr,zcr);

Réponse acceptée

Mathieu NOE
Mathieu NOE le 5 Fév 2021
hello again
this is an improved code - no inner for loop needed
clear all; clc; close all;
%% Read the input signal
[y, fs] = audioread('test_voice.wav');
N = length(y);
t = (0:N-1)/fs;
framelen = 128;
numframes = floor(N/framelen);
overlap = 0;
zcr = [];
for k = 1:numframes
frame = y((k-1)*framelen+1 : framelen*k) ;
arry = sign(frame(2:framelen)) - sign(frame(1:framelen-1));
zcr_frame = sum(abs(arry));
zcr = [zcr; zcr_frame] ;
end
% normalisation
zcr = zcr./max(zcr);
y = y./max(abs(y));
figure (1);
% t_zcr = (0:framelen:N-framelen)/fs ; % time stamp positionned at beginning of frame
t_zcr = (framelen/2:framelen:N-framelen/2)/fs ; % time stamp positionned at center of frame
plot(t,y,'b',t_zcr,zcr -1.5,'r');grid on;
xlabel('time(secs)'); ylabel('linear output')
  2 commentaires
Hardik Ruparel
Hardik Ruparel le 8 Fév 2021
Thank you for the response.
1.You are correct. There is no function by the name is sgn. Its the sign function with a minor adjustment. For each element of x, sign(x) returns 1 if the element is greater than or equal to zero, and -1 if it is less than zero.
2. Yes, zcr output is expected to be low with speech signal present
3. Any reason why you the t_zcr was shifted to the center of the frame and what benefit would I attain with that ?
Mathieu NOE
Mathieu NOE le 9 Fév 2021
hello
3. as the ZCR info is computed on a frame , for me it was more evident that the time index associated with it should be at the center of the frame rather that one or the other end. But this is just a belief. It's like when you plot a spectrogram, for me the spectral info which is an average of what the signal says in one buffer should be associated with time at the center of the buffer, not the begining

Connectez-vous pour commenter.

Plus de réponses (1)

Mathieu NOE
Mathieu NOE le 5 Fév 2021
hello
I am not aware of a function sgn in matlab , I believe this must be sign ?
so this is modified and somehow I introduced normalisation for both signal and zcr values. The time vector associated with zcr I put the time values at the center of the frame (my 2 cents)
i plotted the two on the same plot simply shifting zcr below the audio wave so easier to see.
I assume that zcr output must be low when speech is present (which seems to be the case on my test signal)
clear all; clc; close all;
%% Read the input signal
[y, fs] = audioread('test_voice.wav');
N = length(y);
t = (0:N-1)/fs;
framelen = 128;
numframes = floor(N/framelen);
overlap = 0;
zcr = [];
for k = 1:numframes
arry = [];
zcr_frame = [];
frame = y((k-1)*framelen+1 : framelen*k) ;
for i = 2:length(frame)
arry(i) = sign(frame(i)) - sign(frame(i-1));
end
zcr_frame = sum(abs(arry));
zcr = [zcr zcr_frame] ;
end
% normalisation
zcr = zcr./max(zcr);
y = y./max(abs(y));
figure (1);
% t_zcr = (0:framelen:N-framelen)/fs ; % time stamp positionned at beginning of frame
t_zcr = (framelen/2:framelen:N-framelen/2)/fs ; % time stamp positionned at center of frame
plot(t,y,'b',t_zcr,zcr -1.5,'r');grid on;
legend('audio signal','zrc output');
xlabel('time(secs)'); ylabel('linear output')

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by