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:
the results are worst for higher pitches, if the fundamental is above A6 or so, I get only garbage data.
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)
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:
- The sample rate I'm recording at is 44100 Hz
- I've observed that this behavior is barely visible on a guitar, but very visible on an digital piano (for the same played note)
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; iif (spectrum[i] > spectrum[correctMaxBin]) {
correctMaxBin = i;
}
}
if (abs(correctMaxBin * 2 - maxBin) < 4) {
if (spectrum[correctMaxBin]/spectrum[maxBin] > 0.2) {
maxBin = correctMaxBin;
}
}
return maxBin;
}
No comments:
Post a Comment