Android库从WAV文件中获取音调

时间:2012-09-14 07:34:03

标签: java android fft frequency pitch

我有一个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来解决上面提到的问题,但是,有时候我会将频率作为频率。知道怎么解决吗?我应该使用谐波产品频率还是自相关算法?

1 个答案:

答案 0 :(得分:0)

我意识到自己的错误。如果我采取更多样本,准确度将增加。然而,这种方法仍然不完整,因为我在获得钢琴/声音的准确结果方面仍然存在一些问题。