I am trying to detect a pitch in a narrow range of the audio spectrum with minimal samples. This corresponds to the rattling of certain mechanical systems. For example, the hum of an engine.

To do this, I am hoping to identify if there is a frequency at at a certain range such as 550hz-555hz.

  1. I spoke with a learned fellow about this problem and he mentioned that there is a variation of the FFT that only targets the desired frequency range. What is this called?

  2. I was hoping to avoid an amplitude (volume) training period by distinguishing peaks from white-noise in the frequency domain. Can anybody point me to a tunable parameter that will enable me to identify if a certain range has a peak? I was thinking of comparing the max height to the average.

  3. I was wondering if anybody knew of a good method to do this.


3 Answers 3


A few points

  1. I'd carefully verify the underlying assumptions: most engine noises, hums or buzzes, have lots of harmonics and are therefore a very wide spectrum. The fundamental is rarely the strongest component in there.
  2. 5 Hz seems like an awfully narrow bandwidth. You can only get 10 independents samples per second out of a signal that narrow. So if you need 50 samples to make a decision, it'll take you 5 seconds.
  3. You may be more interested in the "transient event", i.e. the hum starting or stopping. The transient has a much higher bandwidth (and is probably easier to detect) than the steady state noise.
  4. One way to do this is "down-mixing". Multiply the signal sine wave of, say, 550 Hz and then lowpass filter with the desired bandwidth, 5 Hz, for example. You can then downsample if you want

One suggestion for an algorithm

  1. Multiply signal with 550Hz
  2. Form x[n] by low pass filtering with 5 Hz, measure energy
  3. Form y[n] by low pass filter with 50 Hz, measure energy
  4. If the energies of x[n] and y[n] are about the same, then your engine is on, otherwise it's off

Here is how it works: You look at the spectrum of your signal with a bandwidth of 10Hz and 100Hz around the center frequency. If the spectrum is mostly white (or pink as audio typically is), than the energy in the 100Hz band should be about 10 times larger than the energy in the 10Hz band. Now if you have a very narrow but strong spectral component in the 10 Hz band, than this dominates the energy in the 100 Hz band as well and therefore the energies in both bands will be roughly the same.


It could have been Goertzel's algorithm, though it looks at a single frequency rather than a specific band.

Another approach is to apply modulation techniques to shift the central frequency of your range of interest into the baseband, aka "zoom FFT".

Your intuition about the max to average ratio is good. Another "peakedness" metric is the ratio of geometric mean to arithmetic mean.

  • $\begingroup$ Is there a name for the max to average ratio of the spectrum? I am using this in a project, too, but I don't know if it has a nice name like "spectral flatness". $\endgroup$
    – endolith
    Aug 26, 2012 at 2:14
  • $\begingroup$ @endolith I believe its called Crest Factor. $\endgroup$
    – Spacey
    Aug 26, 2012 at 2:35
  • 1
    $\begingroup$ @Mohammad: Crest factor is based on RMS, not average, and is a time-domain measurement $\endgroup$
    – endolith
    Aug 26, 2012 at 3:35
  • 1
    $\begingroup$ @endolith I think it's still ok to use that term. Consider, the linguistic usage is 'peak to average ratio', which is exactly what we want. For uses in time domain, the RMS was used instead of average because it was quickly realized that with oscillatory, zero mean signals, we get $\frac{Peak}{0}$ far too easily, thereby rendering the measurement meaningless. Hence RMS normalization was used. However for uses in F-domain, we are ostensibly looking at $|X(\omega)|$, in which case we can use the definition as it was intended, ie, a peak-to-average ratio, or crest factor. My 0.02. ;-) $\endgroup$
    – Spacey
    Aug 26, 2012 at 13:49
  • 1
    $\begingroup$ @endolith I had a very very similar problem. I got around it by simply doing crestFactor[$x$+$min(x) + 1$]. This guaranteed that I never had to deal with any zero values, but still maintain a coherent measure of peakiness. Not sure about your exact problem set but you might try it and see if it helps. :-) $\endgroup$
    – Spacey
    Aug 26, 2012 at 19:41

If you are looking for "pitch" e.g. vibration periodicity, and not spectral frequency (which are 2 different things), then forget using either the FFT or the Goertzel algorithm, as these only work if the fundamental frequency of the periodic signal is clearly and always the strongest spectral element (as opposed to all the possible harmonics). For some types of system "rattles", the system response might transmit one or multiple harmonics out of the system more strongly than the vibration impulse frequency.

For vibration pitch, try autocorrelation (or the related AMDF or ASDF methods) and look for a peak at a time lag within the range of periodicity for the frequencies which you are hoping to identify (e.g. 1.802 to 1.818 mS for your example). The window size required to find a peak with this accuracy will depend on your signal to noise ratio.

If you have characterized the background noise, you can set a threshold for the peak above the background based on the statistics of that noise, and depending on your desired error rates.

  • $\begingroup$ "as these only work if the fundamental frequency of the periodic signal is clearly and always the strongest spectral element" Where did they say they were only looking for the strongest spectral element? $\endgroup$
    – endolith
    Aug 26, 2012 at 2:15
  • $\begingroup$ @endolith: They didn't. Thus my answer. $\endgroup$
    – hotpaw2
    Aug 26, 2012 at 3:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.