0

次のコードを使用して、fft を取得してから、波の dft を取得しようとしました。

        string s = textBox1.Text;
        double[] source = SourceToDouble(s);
        listBox2.DataSource = source;
        ToPowerOfTwo(ref source);
        List<Complex> Source = DoubleToComplex(source);
        Complex[] sou = Source.ToArray();
        FourierTransform.FFT(sou, FourierTransform.Direction.Forward);
        listBox1.DataSource = sou;
        FourierTransform.DFT(sou, FourierTransform.Direction.Forward);
        DoPlaySound(sou);

SourceToDouble(s):

private double[] SourceToDouble(string s)
    {
        List<double> Final = new List<double>();

        EricOulashin.WAVFile audioFile = new EricOulashin.WAVFile();
        String warning = audioFile.Open(s, WAVFile.WAVFileMode.READ);
        if (warning == "")
        {
            short audioSample = 0;
            for (int sampleNum = 0; sampleNum < audioFile.NumSamples; ++sampleNum)
            {
                audioSample = audioFile.GetNextSampleAs16Bit();
                Final.Add((double)audioSample);
            }
        }
        else
        {
            throw new Exception(warning);
        }

        return Final.ToArray();
    }

ToPowerOfTwo(ref source):

private void ToPowerOfTwo(ref double[] source)
    {
        List<long> TwoPowers = GetTwoPowers(100);
        long pCount = 0;

        for (int i = 0; i <= 100; i++)
        {
            if (source.Count() <= TwoPowers[i])
            {
                pCount = TwoPowers[i];
                break;
            }
        }

        List<double> f = new List<double>(source);

        while (f.Count < pCount)
        {
            f.Add(0.0);
        }
        //f.Add(0.0);
        source = f.ToArray();
    }

DoubleToComplex(source):

private static List<Complex> DoubleToComplex(double[] source)
    {
        List<Complex> Source = new List<Complex>();
        foreach (double dob in source)
        {
            Complex c = new Complex(dob, 0.0);
            Source.Add(c);
        }
        return Source;
    }

DoPlaySound(sou):

 private void DoPlaySound(Complex[] c)
        {
            FourierTransform.DFT(c, FourierTransform.Direction.Forward);
            double wav = c[0].Re;
            List<double> Big = ToBigger(100000, new double[] { wav });
            MakeWavFile(Big, "tmp.wav");
            System.Media.SoundPlayer s = new SoundPlayer("tmp.wav");
            s.PlayLooping();
        }

問題はこれです: 一般的なコードに wav ファイルを与えると、メソッドは最終的な wav (tmp.wav) を再生しようとしますが、一般的なファイルとは異なります。

更新 1:

私も試してみFourierTransform.DFT(sou, FourierTransform.Direction.Backward);ましたが、うまくいきませんでした!

4

3 に答える 3

2

データの読み取りと再生の間に、データに対してフォワード DFT を 3 回実行しているようです。もちろん、オリジナルのようには聞こえません。

于 2012-04-01T01:17:50.803 に答える
2

音声ファイル全体の FFT は、音声やその他の非定常情報を分析するのに適した方法ではありません。また、非常に遅くなります。より一般的な手法は、短い FFT を使用して長さが数ミリ秒から数十ミリ秒の短いオーバーラップ フレームを分析するか、オーバーラップ加算/保存 FFT 高速畳み込みを使用して連続するフレームを処理することです。

単一の IFFT は、FFT の適切な逆関数になります。そうしないと、誤った逆方向の結果になる可能性があります。

于 2012-04-02T00:49:15.297 に答える
1

DoubleToComplex 関数を次のように書き直します。

    private static Complex[] DoubleToComplex(double[] source)
    {
        Complex[] complexSource = new Complex[source.Length];
        for(int i =0; i< source.Length; i++ )
        {
            complexSource[i] = new Complex(source[i], 0.0);                
        }
        return complexSource;
    }

最初にリストを作成してすべての Complex オブジェクトを作成し、後でそれを配列に戻すのはなぜでしょうか? 最初から配列を使用する方が効率的です。

于 2012-04-17T07:26:32.950 に答える