This is a continuation of a previous question.

I'm trying to analyze breathing and snoring sounds, and while I can fairly well detect snoring now, breathing is a bigger challenge.

I've learned that if I break the analyzed frequency range (about 4KHz, sampled at about 8KHz, with a framesize of 1024) into about 5 subranges, very often one of the subranges exhibits a good sensitivity (using spectral difference) that is buried in the noise in the overall range. The trick is to determine which subrange to "trust" when.

Presumably the "trustworthy" subrange would exhibit variability at a rate between about 2Hz and 0.05Hz, while the "bad" subranges would behave more randomly, with most of their variation being at shorter intervals.

I could cobble together some sort of algorithm to smooth the values at a sub-second resolution and then calculate the variability over longer intervals, but I wonder if there isn't a "canned" algorithm for this sort of things -- something with maybe a modicum of theory behind it?

Any suggestions?

[Note: I realize that one could, in theory, use an FFT to extract this info, but that seems like using a baseball bat to kill a flea. Maybe something a little more lightweight?]


In a sense (to use an analogy) I'm trying to detect a "baseband" signal in an RF transmission (only the "RF" is audio frequencies, and the "baseband" is below 8Hz). And, in a sense, the "RF" is "spread spectrum" -- the sounds I want to detect tend to generate lots of harmonics and/or have several separate frequency components, so if one band of the spectrum is too noisy I can probably make use of another. The goal is to basically determine some metric resembling SNR for the various frequency bands, on the assumption that most "noise" is > 2Hz and my signal is less than 2Hz.

I have as input to this algorithm the raw amplitudes (sum of FFT amplitudes at all included frequencies) for each band, measured at 8Hz intervals.

(It should be noted that, while I have not done any formal SNR measurements, the overall SNR across the processed spectrum appears to frequently be near or below 1.0 -- if you visually observe the sound envelope in a tool like Audacity no modulation of the envelope is noticeable (even though the ear can clearly discern breathing sounds). This is why it's necessary to analyze bands to find those with decent SNR.)

  • $\begingroup$ By variability, do you mean in time or across frequencies? $\endgroup$ – Phonon Feb 2 '12 at 5:00
  • $\begingroup$ Variability across time. At a rate between roughly 0.05Hz and 2Hz, ignoring variability at longer or shorter intervals. $\endgroup$ – Daniel R Hicks Feb 2 '12 at 17:25
  • 1
    $\begingroup$ @DanielRHicks What are we trying to detect for here exactly? I want to make sure I understand the question(s) - Im trying to quantify the feature(s) you want to measure first. $\endgroup$ – Spacey Feb 2 '12 at 22:39
  • $\begingroup$ See the added details. $\endgroup$ – Daniel R Hicks Feb 3 '12 at 0:57


Upon re-reading your question, it appears that what I have learned to be known as the 'Gabor Bandwidth" might be useful to you in this case, for you trying to measure 'spectral variability'. (Dilip provided a good answer to my question on Spectral Moments here).

When I studied it further, the Gabor-Bandwidth seems to really just be a measure of how 'spread' the spectrum is from its mean. (Hence the manipulation of moments).

Take a look and see what you think.


Have you tried out spectral flux. There is MATLAB implementation here: http://blog.weisu.org/2009/12/spectral-flux-sf-in-audio.html

  • 1
    $\begingroup$ Spectral flux is essentially the same as the "spectral difference" which I am using. $\endgroup$ – Daniel R Hicks Feb 3 '12 at 1:07

What you need seems far bigger than a flea. So you may need to go in the opposite direction, and do more than just an FFT. Perhaps low frequency cepstrum or cepstral analysis to find your "exiter" frequency.

  • $\begingroup$ Yeah, that looks like it's worth looking into (or should I say otni?). $\endgroup$ – Daniel R Hicks Feb 3 '12 at 12:58
  • $\begingroup$ I guess I'm not seeing an obvious way to apply "cepstrum" to my data to analyze time intervals longer than my frame interval. $\endgroup$ – Daniel R Hicks Feb 3 '12 at 17:54

Your input is a low-res spectrogram-like representation $X(m, n)$ where m is the frame index and n the band (subrange index). Right?

Here is what I suggest:

For each n:

  • Compute the autocorrelation $r_n(l)$ of the sequence $X(:, n)$
  • Compute any peakedness measure of $r_n(l)$ for a lag l in the 0.05 to 2 Hz range (8 to 31 assuming a 50% overlap between frames).

Pick the subband with highest autocorrelation peakedness (= the more "pitchy").

Peakedness measures to look at:

  • maximum of the normalized autocorrelation over the considered range. $\max_{l \in L} \frac{r_n(l)}{r_n(0)}$
  • kurtosis
  • ratio of geometric to arithmetic mean

These kind of metrics are eg used to distinguish voiced/unvoiced speech.

  • $\begingroup$ Can you please elaborate of what value the geometric mean over the arithmatic mean gives? Also, when you mention maximum of the normalized autocorrelation over the autocorrelation at tau=0, why is that a figure of merit? $\endgroup$ – Spacey Mar 22 '12 at 3:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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