10
$\begingroup$

I've made a pitch detection algorithm using HPS and I'm facing a problem. I'm a beginner with signal processing and this site helped me before, so I though I should ask.

For higher pitches ( eg. >C6:1046.50hz ) I'm starting to get garbage data from the HPS. The higher the pitch the more garbage I get (by garbage I mean frequencies that are not octave errors nor harmonics and are around 1Hz-20Hz)

What I've empirical observed:

  1. the results are worst for higher pitches, if the fundamental is above A6 or so, I get only garbage data.

  2. the FFT works fine even for a very high pitch, (by fine I mean that its peak shows either the fundamental or one of its harmonics, but not garbage)

  3. if I lower the number of harmonics I take in consideration for the HPS, the garbage diminishes, but that makes it harder to discriminate between the fundamental and the harmonics.

Here is my algorithm:

->raw buffer -> hann window, 16384 samples, 50% overlap -> zero padding -> FFT -> HPS

Any help is appreciated!

UPDATE 1: So, there are a few more things I want to add:

  1. The sample rate I'm recording at is 44100 Hz
  2. I've observed that this behavior is barely visible on a guitar, but very visible on an digital piano (for the same played note)
  3. Here is my hps algorithm, maybe someone with greater experience can spot a problem.

    int hps(float* spectrum, int spectrumSize, int harmonics) {
    
    int i, j, maxSearchIndex, maxBin;
    maxSearchIndex = spectrumSize/harmonics;
    
    maxBin = 1;
    for (j=1; j<=maxSearchIndex; j++) {
        for (i=1; i<=harmonics; i++) { 
            spectrum[j] *= spectrum[j*i];
        }
        if (spectrum[j] > spectrum[maxBin]) {
            maxBin = j;
        }
    }
    
    // Fixing octave too high errors    
    int correctMaxBin = 1;
    int maxsearch = maxBin * 3 / 4;
    for (i=2; i<maxsearch; i++) {
        if (spectrum[i] > spectrum[correctMaxBin]) {
            correctMaxBin = i;
        }
    }
    if (abs(correctMaxBin * 2 - maxBin) < 4) {
        if (spectrum[correctMaxBin]/spectrum[maxBin] > 0.2) {
            maxBin = correctMaxBin;
        }
    }
    
    return maxBin;
    }
    
$\endgroup$
  • 1
    $\begingroup$ What's your sample rate? What anti-aliasing filter have you got before the ADC? $\endgroup$ – Martin Thompson Nov 3 '11 at 13:03
  • $\begingroup$ My recording sample rate is 44100 Hz, sorry I didn't mention it before. $\endgroup$ – Valentin Radu Nov 3 '11 at 13:28
  • $\begingroup$ 1. You need to plot the intermediate spectra and products used in the HPS calculation and see where it's getting the wrong values from. 2. Guitar and piano are inharmonic, which will cause the peaks to not line up perfectly. Not sure how much of an effect this would have, but HPS assumes perfectly harmonic spectra. $\endgroup$ – endolith Aug 27 '12 at 14:51
3
$\begingroup$

It could be that too few harmonic partials are present in the signal at these higher pitches. The HPS algorithm is pretty simple and relies on those upper harmonics to keep stacking up until the fundamental emerges from the background. Of course, we should wonder, what's your sampling rate? If it's 8000 hz, then there's only room for 3 harmonics of a 1000 hz pitch...

$\endgroup$
  • $\begingroup$ I'm recording at 44100 Hz, but still your answer made me think about it. Maybe its something related and I should decide how many harmonics to consider in my hps depending on how many peaks I found in my original FFT. Another thing Ive observed is that it works way better with string instruments than with my electric piano, could this be because the harmonics are weeker in piano's case? $\endgroup$ – Valentin Radu Nov 3 '11 at 13:37
  • $\begingroup$ @mindnoise: Bowed string instruments are harmonic, while plucked or struck string instruments have en.wikipedia.org/wiki/Inharmonicity. Not sure if that's part of the problem $\endgroup$ – endolith Nov 3 '11 at 13:56
  • $\begingroup$ @endolith could be especially because: "The less elastic the strings are (that is, the shorter, thicker, and stiffer they are), the more inharmonicity they exhibit." and I'm getting the error exactly on those types of strings(high notes). Actually, the fundamental is always the strongest freq in my FFT when the bug happens, so it definitely has to do with harmonics or the hps algorithm, however I'm not sure why I get 20-50hz garbage for a fundamental of 1500 hz. will post the hps algorithm. $\endgroup$ – Valentin Radu Nov 3 '11 at 14:36
  • 1
    $\begingroup$ @mindnoise: "Inharmonicity largely affects the lowest and highest notes in the piano ... The lowest strings, which would have to be the longest, are most limited by the size of the piano. The designer of a short piano is forced to use thick strings to increase mass density and is thus driven into inharmonicity. The highest strings have to be under the greatest tension, yet must also be thin to allow for a low mass density. The limited strength of steel forces the piano designer to use very short strings whose short wavelengths thus generate inharmonicity." $\endgroup$ – endolith Nov 3 '11 at 15:08
2
$\begingroup$

For some instruments, the number of significant harmonics produced may change over different pitch ranges. The partials of the very lowest and highest notes for some physical instruments may exhibit greater inharmonicity. The number of harmonics that can fit below the anti-alias filter cutoff below Fs/2 will certainly be lower for very high notes. Your HPS pitch estimator mdy want to take those factors into account.

The attack transient of some instruments may produce an aharmonic spectral band of noise which may overlap with the HPS search region of some pitches or their significant harmonics.

Potentially, the overtones of very high frequencies might even wrap around Fs/2 if the low pass filter before the audio ADC doesn't have a good enough stop band attenuation.

$\endgroup$

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.