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アルゴリズムを使用する必要がありますか?