# Harmonic Product Spectrum from FFT output to the fundamental frequency

I'm trying to do the HPS algorithm on my FFT output, but I'm stuck here. My signal is from a bass (cable), 16bits, 48.000Hz.

I split in time domain the array of the whole record into multiple arrays of 24.000 frames (miniBuffer).

I'm applying a Hamming window once it's split, like this:

miniBuffer [m] = miniBuffer [m] * 0.5 * (1.0 - Math.cos(2.0*Math.PI*m/24000));

Then, I compute FFT on each array.

Finally I try the HPS:

 double mag[] = new double[miniBuffer.length]; //Saves magnitude of the fft values

double m_max0 = miniBuffer;

for (int i=0; i < miniBuffer.length / 2 - 1; i++) {
double real = miniBuffer[2*i];
double imag = miniBuffer[2*i+1];
//Gets magnitude
mag[i] = (float)Math.sqrt(real*real + imag * imag);

if (miniBuffer[i] > m_max0 && i>0) {
m_max0 = miniBuffer[i];
}
}

int i_max = 0;
double m_max = miniBuffer; //max
m_max = m_max0;

double sum [] = new double[miniBuffer.length];
int fund_freq = 0;

//HPS

for(int k = 0; k < 24000/48 ; k++)
{
sum[k] = miniBuffer[k] * miniBuffer[2*k] * miniBuffer[3*k];
// find fundamental frequency (maximum value in plot)
if( sum[k] > m_max && k > 0 )
{
m_max = sum[k];
i_max = k;
}
}
fund_freq = i_max * 48000 / 24000;
System.out.println(fund_freq);


The values of the max magnitude are the frequency that is recording the program, but when i apply the HPS, for example, to a 220Hz sound, the HPS returns me 26 or 30.

I think that this values come from the frequencies limiter that doesn't works (I want to cap before 37Hz and after 440):


double hz = ((double)( miniBuffer.length * 2)) /48000;

for(int z = 0; z<(37*hz); z++) {
miniBuffer[z] = Double.NEGATIVE_INFINITY;
}
for(int z = 0; z>(440*hz); z++) {
miniBuffer[z] = Double.NEGATIVE_INFINITY;
}


If I delete this, HPS returns me 0 in every output.

So:

• Is the window correctly applied?
• Is the HPS a good algorithm for bass pitch detection? (Low Frequency)
• What could i use for limit my values in a right way?
• How to fix my HPS algorithm?