0

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に増やすことで上記の問題を解決できましたが、周波数として倍音が出ることがあります。それを修正する方法はありますか?Harmonic Product FrequencyまたはAutocorrelationアルゴリズムを使用する必要がありますか?

4

1 に答える 1

0

私は自分の間違いに気づきました。より多くのサンプルを取得すると、精度が向上します。ただし、ピアノ/ボイス サウンドの正確な結果を得るにはまだ問題があるため、この方法はまだ完全ではありません。

于 2012-09-28T09:36:20.610 に答える