【发布时间】:2012-09-14 07:34:02
【问题描述】:
我有一个来自 WAV 文件的采样数据列表。我想将这些值传递到库中,并获取 WAV 文件中播放音乐的频率。现在,我将在 WAV 文件中有 1 个频率,我想找到一个与 Android 兼容的库。我知道我需要使用 FFT 来获取频域。有什么好的图书馆吗?我发现 [KissFFT][1] 很受欢迎,但我不太确定它在 Android 上的兼容性如何。有没有更简单好用的库可以完成我想要的任务?
编辑: 我尝试使用 JTransforms 来获取 WAV 文件的 FFT,但始终无法获取文件的正确频率。目前,WAV 文件包含 440Hz 的正弦曲线,音符 A4。然而,我得到的结果是 441。然后我试图得到 G4 的频率,我得到的结果是 882Hz,这是不正确的。 G4的频率应该是783Hz。会不会是样本不够?如果是,我应该抽取多少样本?
//DFT
DoubleFFT_1D fft = new DoubleFFT_1D(numOfFrames);
double max_fftval = -1;
int max_i = -1;
double[] fftData = new double[numOfFrames * 2];
for (int i = 0; i < numOfFrames; i++) {
// copying audio data to the fft data buffer, imaginary part is 0
fftData[2 * i] = buffer[i];
fftData[2 * i + 1] = 0;
}
fft.complexForward(fftData);
for (int i = 0; i < fftData.length; i += 2) {
// complex numbers -> vectors, so we compute the length of the vector, which is sqrt(realpart^2+imaginarypart^2)
double vlen = Math.sqrt((fftData[i] * fftData[i]) + (fftData[i + 1] * fftData[i + 1]));
//fd.append(Double.toString(vlen));
// fd.append(",");
if (max_fftval < vlen) {
// if this length is bigger than our stored biggest length
max_fftval = vlen;
max_i = i;
}
}
//double dominantFreq = ((double)max_i / fftData.length) * sampleRate;
double dominantFreq = (max_i/2.0) * sampleRate / numOfFrames;
fd.append(Double.toString(dominantFreq));
谁能帮帮我?
EDIT2:我设法通过将样本数增加到 100000 来解决上述问题,但是,有时我会得到泛音作为频率。知道如何解决吗?我应该使用谐波积频率还是自相关算法?
【问题讨论】:
-
在 SO 上有很多关于这个主题的相关问题已经有一些非常好的答案 - 尝试阅读其中的一些,如果您仍有具体问题,然后再回来。
-
嗨,保罗,我实际上阅读了其中的一些内容,并且对他们的回答更加困惑。我实际上是在尝试使用 FFT 来获取频率(使用与 stackoverflow.com/questions/8325241/… 相同的 FFT 和 Complex 类)。我知道调用 fft 函数的结果是一个 Complex[]。但是,我的代码总是在“Complex[] fftArray = FFT.fft(fftTempArray);”处崩溃我不知道为什么。我需要输入“FFT.fft”才能从 FFT 类调用函数。
-
这是一个相当复杂的主题,基于 FFT 的方法不一定是最佳解决方案,但假设您使用 FFT,那么您可能希望让 FFT 自己工作第一的。一旦你完成了这项工作并理解了 FFT 的作用,你就可以开始添加其他构建块:窗口函数、音高提取等。
-
好的。通过使用 JTransform,我设法使 FFT 工作(或者至少我认为是)。从stackoverflow.com/questions/4364823/…,我认为 peakFrequency = index * SampleRate / NumSample。但是,我总是无法获得正确的频率。我用我的代码更新了帖子。
-
如果您要确定乐器的音高,那么它比仅确定频谱中的最大峰值要复杂得多。这是给吉他调音师还是类似的东西?
标签: java android fft frequency pitch