0

dftの実装を書いたところです。これが私のコードです:

        int T = 2205;

        float[] sign = new float[T]; 
        for (int i = 0, j = 0; i < T; i++, j++)
            sign[i] = (float)Math.Sin(2.0f * Math.PI * 120.0f * i/ 44100.0f);

        float[] re = new float[T];
        float[] im = new float[T];
        float[] dft = new float[T];

        for (int k = 0; k < T; k++)
        {
            for (int n = 0; n < T; n++)
            {
                re[k] += sign[n] * (float)Math.Cos(2.0f* Math.PI * k * n / T);
                im[k] += sign[n] * (float)Math.Sin(2.0f* Math.PI * k * n / T);;
            }
            dft[k] = (float)Math.Sqrt(re[k] * re[k] + im[k] * im[k]);
        }

したがって、サンプリング周波数は44100 Hzで、120Hzの正弦波の50msのセグメントがあります。結果によると、ポント7と2200にdft関数のピークがあります。何か間違ったことをしましたか?そうでない場合は、結果をどのように解釈すればよいですか?


AFORGEのFFT法を試してみました。これが私のコードです。

      int T = 2048;

        float[] sign = new float[T];
        AForge.Math.Complex[] input = new AForge.Math.Complex[T];
        for (int i = 0; i < T; i++)
        {
            sign[i] = (float)Math.Sin(2.0f * Math.PI * 125.0f * i / 44100.0f);
            input[i].Re = sign[i];
            input[i].Im = 0.0;
        }

        AForge.Math.FourierTransform.FFT(input, AForge.Math.FourierTransform.Direction.Forward);
        AForge.Math.FourierTransform.FFT(input, AForge.Math.FourierTransform.Direction.Backward);

元の符号を取得することを期待していましたが、何か別のもの(正の値のみを持つ関数)を取得しました。それは正常ですか?前もって感謝します!

4

1 に答える 1

1

コードは正しいように見えますが、より効率的である可能性があります。DFTはFFTアルゴリズムによって解決されることがよくあります(高速フーリエ変換、新しい変換ではなく、DFTをより効率的に解決するためのアルゴリズムです)。

FFT(理解するのが少し難しく、形式のないデータで動作させるのが難しい)を実装したくない場合2^nや、オープンソースコードを使用したくない場合でも、実装を少し速くすることができます。たとえば2.0f * Math.PI * K / T、これは内部ループの外側の定数であるため、kごとに1回計算し(内部ループの外側に移動) 、関数nで乗算することができますcos/sin

位置と解釈に関しては、ドメインを変更しました。これで、テーブル内のデータのインデックスであるX軸は、時間ではなく頻度に対応します。のサンプリングがあり、サンプルの44100Hzキャプチャがあります2205。つまり、1つのサンプルごとに、に等しい周波数での入力信号の大きさが表されます44100Hz / 2205 = 20Hz。信号が120Hzであるため、マグニチュードのピークは7番目のポイント(インデックス6)にあります6 * 20Hz = 120Hz。これは、予想できることです。

44100Hz秒のピークは高周波数を表しているように見えるかもしれませんが、サンプリングレートが(ナイキストの法則)より高い周波数を測定できないため、これは単なるスプリアス信号44100Hz / 2です。カットオフポイントを設定すると、その周波数以降のDFTデータは無効になります。そのため、テーブルの後半は無効であり、基本的には前半ですが、ミラーリングされているため、無視してかまいません。

編集//質問から、オーディオ処理に興味があることがわかりました。オーディオおよびビジュアル処理用の優れたオープンソースライブラリであるNForge.Netライブラリをグーグルで検索すると、その作成者はcodeproject.comに関連する多くの優れた記事を掲載しています。その機能の多く。

于 2013-03-01T20:07:44.503 に答える