This example shows how to estimate a speaker's fundamental frequency using the complex cepstrum. The example also estimates the fundamental frequency using a zero-crossing method and compares the results.
Load the speech signal. The recording is a woman saying "MATLAB". The sampling frequency is 7418 Hz.
The preceding code loads the speech waveform, mtlb, and the sampling frequency, Fs, in the MATLAB® workspace.
Use the spectrogram to identify a voiced segment for analysis.
segmentlen = 100; noverlap = 90; NFFT = 128; [y,f,t,p] = spectrogram(mtlb,segmentlen,noverlap,NFFT,Fs); surf(t,f,10*log10(abs(p)),'EdgeColor','none'); axis xy; axis tight; colormap(jet); view(0,90); xlabel('Time'); ylabel('Frequency (Hz)');
Extract the segment from 0.1 to 0.25 seconds for analysis. The extracted segment corresponds roughly to the first vowel, /ae/, in "MATLAB".
dt = 1/Fs; I0 = round(0.1/dt); Iend = round(0.25/dt); x = mtlb(I0:Iend);
Obtain the complex cepstrum.
c = cceps(x);
Plot the cepstrum for times ranging from 2 to 10 msec corresponding to a frequency range of approximately 100 to 500 Hz. Identify the peak in the cepstrum and find the frequency corresponding to the peak. Use the peak as the estimate of the fundamental frequency.
t = 0:dt:length(x)*dt-dt; plot(t(15:75).*1e3,c(15:75)); xlabel('msec'); [~,I] = max(c(15:55)); fprintf('Complex cepstrum F0 estimate is %3.2f Hz.\n', 1/(t(I+15)));
Use a zero-crossing detector on a lowpass-filtered and rectified form of the vowel to estimate the fundamental frequency.
[b0,a0]=butter(2,325/(Fs/2)); xin = abs(x); xin=filter(b0,a0,xin); xin = xin-mean(xin); x2=zeros(length(xin),1); x2(1:length(x)-1)=xin(2:length(x)); zc=length(find((xin>0 & x2<0) | (xin<0 & x2>0))); F0=0.5*Fs*zc/length(x); fprintf('Zero-crossing F0 estimate is %3.2f Hz.\n',F0);
The estimate of the fundamental frequency obtained with the complex cepstrum is 231.81 Hz and the estimate with the zero-crossing detector is 233.27 Hz.