我正在编写一个应用程序,我需要在其中找到由长号产生的音符的基频。为此,我从麦克风中获取音频数据的 FFT,然后使用从这个问题中获取的自相关代码。
完成此操作后,我将尝试通过查找最高和第二高峰位置以及它们分开的样本数量来找到基本频率。然后,我找到一个样本以 44100 的采样率持续的时间量,并将其乘以两个峰值之间的样本数,得到基频的周期。最后我使用 1/period 来找到基频本身。这是我为此编写的代码(用Java):
public double findFundamentalFrequency(double[] autoCorrelatedData){
double max = Integer.MIN_VALUE;
double secondMax = Integer.MIN_VALUE;
int maxLoc = Integer.MIN_VALUE;
int secondMaxLoc = Integer.MIN_VALUE;
for(int i = 0; i < autoCorrelatedData.length; i++){
if(autoCorrelatedData[i] > max){
secondMaxLoc = maxLoc;
secondMax = max;
max = autoCorrelatedData[i];
maxLoc = i;
}
else if(autoCorrelatedData[i] > secondMax){
secondMax = autoCorrelatedData[i];
secondMaxLoc = i;
}
}
double samplingPeriod = 1/44100.0;
//Log.i("a", String.valueOf(maxLoc));
//Log.i("b", String.valueOf(secondMaxLoc));
double period = samplingPeriod * Math.abs(maxLoc - secondMaxLoc);
double fundamentalFreq = 1.0/period;
return fundamentalFreq;
}
这是使用自相关找到基频的正确方法吗?这给出的答案似乎是不正确的,所以我不确定我是否在某个地方犯了错误,或者我是否以错误的方式解决这个问题。