Some folks have been trying to compute the cepstrum in real time on the Tympan. Cool! They’ve been having trouble. That’s less cool. Sorry!
As a bit of background, the cepstrum is taking the FFT of an FFT. See here and here. Common uses:
-
Finding the Fundamental Frequency: Often, the cepstrum is used to pick out the fundamental frequency given a signal with a lot of harmonic content (like the human voice). Once you copute the spectrum (the first FFT), a harmonic series will show up as evenly-spaced peaks. The spacing of these peaks wil be equal to the fundamental frequency of the sound. So, by taking an FFT of the FFT, this periodicity will show up as a peak at the fundamental frequency. Cool.
-
Finding a Missing Fundamental: In some musical instruments, the sound is rich with harmonics but the fundamental itself is actually a lot quieter. There may be no peak that shows up in the spectrum; we only see the harmonics. The cepstrum doesn’t care, however. It will detect the periodicity of the harmonics and show a peak at the fundamental frequency. That’s very cool.
-
Distinguishing Pure vs Complex Tones: Some sounds are much more simple than that produced by a musical instrument or human voice. If you were to whistle, for example, it is close to a pure sine wave. A pure sine wave has no harmonics. For a whistle, the spectrum may show a very strong peak, but because it lacks harmonics, the cepstrum will come up empty. The cepstrum, therefore, can be used to quantify the amount of harmonic content, which lets you easily differentiate between simple vs complex tones. That’s also very cool.
Doing FFTs in a real-time can be difficult to set up exactly right. So, you can imagine that setting up an FFT of an FFT is even harder to get right. To help people get started, I just added a cepstrum example to the Tympan Library.
Hopefully it’s helpful!
Chip
Generic Cepstrum Algorithm (Matlab pseudocode):
% Compute spectrum
fft_wav = fft(my_wav);
fft_mag2 = fft_wav .* conj(fft_wav); %here is your spectrum (magnitude squared)
freq_Hz = ([1:N]-1))/N * fs_Hz; %here is the frequency for each bin
% Compute cepstrum
fft_log = log(fft_mag2); %beware of taking the log of zero
ceps = fft(fft_log);
ceps_mag2 = ceps .*conj(ceps); %here is your cepstrum (magnitude squared)
quef_Hz = fs_Hz ./ ([1:N]-1); %here is the "quefrency" for each bin