How to denormalize values to do the Harmonic Product Spectrum

196 views Asked by At

I'm trying to execute the HPS algorithm and the results are not right. (48000Hz, 16bits) I've applied to a buffer with the recorded frequency several splits, then a Hanning window, and finally the FFT.

I've obtained a peak in each FFT, that correspond with the frequency I am using, or an octave of it. But when i do the HPS, the results of the fundamental frequency are 0, because the numbers of the array where I make the sum(multiply) are too small, more than my peak in the original FFT. This is the code of the HPS:

                 int i_max_h = 0;
                 double m_max_h = miniBuffer[0];
                 //m_max is the value of the peak in the original time domain array
                 m_max_h = m_max;

                 //array for the sum
                 double sum [] = new double[miniBuffer.length];
                 int fund_freq = 0;

                 //It could be divide by 3, but I'm not going over 500Hz, so it should works
                 for(int k = 0; k < 24000/48 ; k++)
                 {
                     //HPS down sampling and multiply 
                     sum[k] = miniBuffer[k] * miniBuffer[2*k] * miniBuffer[3*k];
                     // find fundamental frequency (maximum value in plot)
                     if( sum[k] > m_max_h && k > 0 )
                     {
                         m_max_h = sum[k];
                         i_max_h = k;
                     }
                  }
                  //This should get the fundamental freq. from sum
                  fund_freq = (i_max_h * Fs / 24000);
                  System.out.print("Fundamental Freq.: ");
                  System.out.println(fund_freq);
                  System.out.println("");

The original HPS code is HERE

I don't know why the sum have little values, when it should be bigger than the previous, and the peak of the sum too. I've applied a RealFordward FFT, maybe there is a problem with the -1 to 1 range, that makes my sum decrease when I multiply it.

Any idea how to fix it, to do the HPS? How could i do the inverse normalize?

1

There are 1 answers

0
Meliodas On BEST ANSWER

The problem was that I was trying to get a higher value of amplitude on the sum array (the HPS array), and my set of values are normalize since I apply the FFT algorithm to them. This is the solution I've created, multiplying the individual values of the sum array by 10 before make the multiply.

The number 10 is a coefficient that I have selected, but it could be wrong in some high frequencies cases, this coefficient could be another higher number.

'''

    for(int k = 0; k < 24000/48 ; k++)
             {

                 sum[k] = ((miniBuffer[k]*10) * (miniBuffer[2*k]*10) * (miniBuffer[3*k]*10));
                 // find fundamental frequency (maximum value in plot)
                 if( sum[k] > m_max_h && k > 0 )
                 {
                     m_max_h = sum[k];
                     i_max_h = k;
                 }
              }

'''

The range of the frequencies is 24000/48 = 500, so it's between 0 and 499 Hz, more than I need in a bass. If the split of the full array is less than 24000, i should decrease the number 48, and this is admissible, because the down sampled arrays are 24000/3 and 24000/2, so this value could decrease to 3, and it should work well.