Spectrum and Cepstrum

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!


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

If you do try the example, it is set up by default to print the spectrum and cepstrum to via the USB serial link back to the PC. You are welcome to watch the values roll by on the SerialMonitor, but it may be more fun to watch then in the Arduino SerialPlotter!

Once the code has compiled and is running on the Tympan, can open the SerialPlotter via the “Tools” menu in the Arduino IDE.

Once the plotter is open, sing into your Tympan. Here is me singing “AAAAAHHHHH” for several seconds…

The SerialPlotter isn’t pretty and it isn’t flexible, but it is better than nothing. Notice that you see a few copies of the data. The red line is the spectrum and the green line is the cepstrum at the corresponding frequencies. (Be aware that the values are in dB but that the baseline is arbitrary…so don’t think that it represents SPL or anything like that.)

Notice that the red line shows the harmonics of my voice. Notice that the strongest frequencies are some of the upper harmonics, not the fundamental. Notice, however, that the green cepstrum line only peaks underneath the fundamental. This is the power of the cepstrum: it finds the fundamental in a harmonic series!


*** Update: I tried to improve the usefulness of the sketch’s interaction with the Arduino SerialPlotter. Now, it looks like this:

As before, the labels on the x-axis are arbitrary (it’s whatever the SerialPlotter chooses to put there). Instead, x-axis is supposed to be frequency. The frequency values are shown by the blue line…spanning 0 Hz up to just about 4 kHz. The red line is the spectrum and the green line is the cepstrum. The sketch computes them as dB, but then I shift and scale the values to fit this plot. So, really, this real-time plot is useful for seeing how the spectrum relates to the cepstrum. This is me singing “AAAHHH”. The red spectrum clearly shows the harmonics. The green cepstrum has correctly picked out the fundamental frequency. Cool.