3

KissFFT の real 関数を使用して、実際のオーディオ信号を変換しています。nfft サンプルの実際の信号を入力したため、混乱していますが、結果は nfft/2+1複素周波数ビンになります。

KissFFT の README から:

実際の (つまり、複雑ではない) 最適化コードは、偶数の長さの fft に対してのみ機能します。2 つの半分の長さの FFT を並列に実行し (real&imag にパック)、いじりながらそれらを結合します。結果は、DC からナイキストまでの nfft/2+1 複素周波数ビンです。

したがって、結果をどのように解釈するかについての具体的な知識はありません。私の仮定では、データは次のようにパックされていますr[0]i[0]r[1]i[1]...r[nfft/2]i[nfft/2]。ここで、r[0] は DC、i[0] は最初の周波数ビン、r[1] は 2 番目などです。これは事実ですか?

4

2 に答える 2

4

はい。Kiss_fftr が Nfft/2+1 ビンのみを作成する理由は、実信号の DFT が共役対称であるためです。負の周波数 ( -pi:0 または pi:2pi 、それについて考えるのが好きな方) に対応する係数は、[0:pi) からの共役係数です。

out[0] および out[Nfft/2] ビン (DC およびナイキスト) の虚部はゼロであることに注意してください。私はいくつかのライブラリがこれら 2 つの実際の部分を最初の複合体にまとめているのを見てきましたが、それは診断が難しく、ほぼ正しいバグにつながる契約違反だと私は考えています。

ヒント: データ型に float を使用している場合 (デフォルト)、出力配列を float complex* (c99) または std::complex* (c++) にキャストできます。kiss_fft_cpx 構造体のパッキングは互換性があります。デフォルトでこれらを使用しない理由は、kiss_fft が float と double 以外の他の型で動作し、これらの機能がない古い ANSI C コンパイラで動作するためです。

これは不自然な例です (c99 コンパイラと type==float を想定)

float get_nth_bin_phase(const float * in, int nfft, int whichbin )
{
  kiss_fftr_cfg st = kiss_fftr_alloc(1024,0,0,0);
  float complex * out = malloc(sizeof(float complex)*(nfft/2+1));
  kiss_fftr(st,in,(kiss_fft_cpx*)out);

  whichbin %= nfft;
  if ( whichbin <= nfft/2 ) 
    ph = cargf(out[whichbin]);
  else
    ph = cargf( conjf( out[nfft-whichbin] ) );
  free(out);
  kiss_fft_free(st);
  return ph;
}
于 2011-11-02T11:15:57.840 に答える
0

fftr の結果の r[1] と i[1] は複素数ベクトルを構成します。これらを合わせると、最初の周波数ビンの振幅 (2 つの成分の 2 乗の和の sqrt) と位相 (atan2() 経由) が得られます。

于 2011-11-01T23:09:11.643 に答える