FFT結果があります。これらは、実部配列と虚部配列の2つのdouble
配列に格納されます。これらの配列の各要素に対応する周波数を決定するにはどうすればよいですか?
言い換えれば、FFTの各実数成分と虚数成分の周波数を保存する配列を作成したいと思います。
FFTの最初のビンはDC(0 Hz)、2番目のビンはFs / N
です。ここで、Fs
はサンプルレート、N
はFFT。次のビンは2 * Fs / N
です。これを一般的な用語で表現すると、nth binはn * Fs / N
です。
したがって、サンプルレートFs
が44.1 kHzで、FFTサイズN
が1024の場合、FFT出力ビンは次のようになります。
0: 0 * 44100 / 1024 = 0.0 Hz
1: 1 * 44100 / 1024 = 43.1 Hz
2: 2 * 44100 / 1024 = 86.1 Hz
3: 3 * 44100 / 1024 = 129.2 Hz
4: ...
5: ...
...
511: 511 * 44100 / 1024 = 22006.9 Hz
実入力信号(虚部はすべてゼロ)の場合、FFTの後半(N / 2 + 1
からN - 1
のビン)には有用な追加情報が含まれないことに注意してください(最初のN / 2 - 1
bins)。最後の有用なビン(実際の用途)はN / 2 - 1
にあり、これは上記の例の22006.9 Hzに対応します。 N / 2
のビンは、ナイキスト周波数でのエネルギー、つまりFs / 2
(この例では= 22050 Hz)を表しますが、これは一般的にアンチエイリアスフィルターが減衰するため、実用的ではありません。 Fs / 2
以上のシグナル。
私の答えを見てください こちら 。
コメントへの回答:
FFTは、等間隔の周波数範囲で正弦関数と余弦関数(基底関数)を使用して、入力信号の 相互相関 を実際に計算します。与えられたFFT出力に対して、私が投稿した回答によって与えられる対応する周波数(F)があります。出力サンプルの実数部は、入力信号とcos(2*pi*F*t)
との相互相関であり、虚数部は、入力信号とsin(2*pi*F*t)
との相互相関です。入力信号がsin
およびcos
関数と相関している理由は、入力信号と基底関数間の位相差を考慮するためです。
複素FFT出力の大きさを取得することにより、入力信号の位相に関係なく、入力信号が一連の周波数で正弦波とどの程度相関しているかを測定できます。信号の周波数成分を分析するだけの場合、ほとんどの場合、FFTの複素出力の振幅または振幅の2乗を取ります。
私は次を使用しました:
public static double Index2Freq(int i, double samples, int nFFT) {
return (double) i * (samples / nFFT / 2.);
}
public static int Freq2Index(double freq, double samples, int nFFT) {
return (int) (freq / (samples / nFFT / 2.0));
}
入力は次のとおりです。
i
:アクセスするビンsamples
:サンプリングレート(ヘルツ)(つまり、8000 Hz、44100Hzなど)nFFT
:FFTベクトルのサイズFFT出力係数(サイズNの複素数入力の場合)は、0〜N-1で、[LOW、MID、HI、HI、MID、LOW]周波数としてグループ化されます。
実データの場合、FFT [N-k] = FFT [k]の複素共役なので、kの要素はN-kの要素と同じ周波数を持っていると考えます。
低周波数から高周波数へのスキャンの順序は
0,
1,
N-1,
2,
N-2
...
[N/2] - 1,
N - ([N/2] - 1) = [N/2]+1,
[N/2]
インデックスi = 0から[N/2]までの[N/2] +1個の周波数グループがあり、それぞれにfrequency = i * SamplingFrequency / N
があります
したがって、ビンFFT [k]の周波数は次のとおりです。
if k <= [N/2] then k * SamplingFrequency / N
if k >= [N/2] then (N-k) * SamplingFrequency / N
あなたのk番目 FFT結果の周波数は2 * pi * k/Nです。