如何对值进行非规范化以进行谐波积谱
How to denormalize values to do the Harmonic Product Spectrum
我正在尝试执行 HPS 算法,但结果不正确。 (48000Hz, 16 位)
我已经将记录的频率应用于缓冲区,然后是 Hanning window,最后是 FFT。
我在每个 FFT 中都获得了一个峰值,该峰值与我使用的频率或其八度音阶相对应。但是当我做HPS时,基频的结果是0,因为我做和(乘)的数组的数量太少了,超过了我在原始FFT中的峰值。
这是 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("");
原来的HPS代码是HERE
我不知道为什么总和的值很少,什么时候应该比前面的大,总和的峰值也是。我已经应用了 RealFordward FFT,可能是 -1 到 1 范围有问题,这使得我的总和在乘以它时减少。
知道如何修复它,做 HPS 吗?
我如何进行逆归一化?
问题是我试图在总和数组(HPS 数组)上获得更高的振幅值,并且我的一组值被归一化了,因为我对它们应用了 FFT 算法。
这是我创建的解决方案,在乘法之前将总和数组的各个值乘以 10。
数字10是我选择的系数,但在某些高频情况下可能是错误的,这个系数可能是另一个更高的数字。
'''
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;
}
}
'''
频率范围是 24000/48 = 500,所以它在 0 到 499 Hz 之间,比我需要的贝司频率高。
如果整个数组的拆分小于 24000,我应该减少数字 48,这是可以接受的,因为下采样数组是 24000/3 和 24000/2,所以这个值可以减少到 3,它应该可以工作嗯
我正在尝试执行 HPS 算法,但结果不正确。 (48000Hz, 16 位) 我已经将记录的频率应用于缓冲区,然后是 Hanning window,最后是 FFT。
我在每个 FFT 中都获得了一个峰值,该峰值与我使用的频率或其八度音阶相对应。但是当我做HPS时,基频的结果是0,因为我做和(乘)的数组的数量太少了,超过了我在原始FFT中的峰值。 这是 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("");
原来的HPS代码是HERE
我不知道为什么总和的值很少,什么时候应该比前面的大,总和的峰值也是。我已经应用了 RealFordward FFT,可能是 -1 到 1 范围有问题,这使得我的总和在乘以它时减少。
知道如何修复它,做 HPS 吗? 我如何进行逆归一化?
问题是我试图在总和数组(HPS 数组)上获得更高的振幅值,并且我的一组值被归一化了,因为我对它们应用了 FFT 算法。 这是我创建的解决方案,在乘法之前将总和数组的各个值乘以 10。
数字10是我选择的系数,但在某些高频情况下可能是错误的,这个系数可能是另一个更高的数字。
'''
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;
}
}
'''
频率范围是 24000/48 = 500,所以它在 0 到 499 Hz 之间,比我需要的贝司频率高。 如果整个数组的拆分小于 24000,我应该减少数字 48,这是可以接受的,因为下采样数组是 24000/3 和 24000/2,所以这个值可以减少到 3,它应该可以工作嗯