【问题标题】:Why DFT from AForge.Math doesn't work?为什么来自 AForge.Math 的 DFT 不起作用?
【发布时间】:2012-04-01 01:12:10
【问题描述】:

我尝试获取 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);,但也没用!

【问题讨论】:

    标签: c# c#-4.0 fft aforge dft


    【解决方案1】:

    整个音频文件的 FFT 不是分析语音或其他非固定信息的好方法。它也会很慢。更常见的技术是使用较短的 FFT 分析长度为几到几十毫秒的短重叠帧,或使用重叠相加/保存 FFT 快速卷积处理连续帧。

    单个 IFFT 将是 FFT 的正确反函数。否则你可能会得到一个错误缩放的向后结果。

    【讨论】:

    • 我没理解对!我想你的意思是我划分我的波阵列并逐部分分析它。我理解正确吗?
    【解决方案2】:

    在读取和播放数据之间,您似乎对数据运行了 3 次正向 DFT。所以当然听起来不像原版。

    【讨论】:

    • 只有运行一次正向 DFT 和一次反向 DFT 才能恢复到原始数据。
    • 但是还是太慢了。没有解决办法吗?
    • @ahmadalishafiee:获取整个波形文件的 DFT/FFT 可能会很慢(嗯,这取决于文件的大小)。为什么要这样做?
    • 首先:fft 比 dft 快(非常快!)。我想分析声音并从中获取一些信息。 fft 可以帮我做到这一点!
    • @ahmadalishafiee:是的,FFT 和 DFT 在数学上是等价的,但 FFT 通常要快得多。
    【解决方案3】:

    我会将 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 对象,然后再将其带回一个数组?从头开始使用数组更有效。

    【讨论】:

    • 这不是为什么它不起作用的答案,你只是优化它!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多