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

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

于 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 回答