Pregunta

I tried to get fft and then get dft of a wave using this code:

        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();
        }

the problem is this: when I give a wav file to general code, after a long time the method trying to play the final wav (tmp.wav) but it isn't like the general file.

Update 1:

I also tried FourierTransform.DFT(sou, FourierTransform.Direction.Backward); but it didn't work too!

¿Fue útil?

Solución

An FFT of an entire audio file is not a good way of analyzing voice or other non-stationary information. It would also be very slow. A more common technique would be to analyse short overlapping frames of a few to few dozen milliseconds in length using shorter FFTs, or to process successive frames using overlap-add/save FFT fast convolution.

A single IFFT would be the proper inverse function to an FFT. Otherwise you might end up with a mis-scaled backwards result.

Otros consejos

It seems you are running a forward DFT three times on your data between reading it and playing it. So of course it's not going to sound like the original.

I would rewrite the DoubleToComplex function as:

    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;
    }

Why first create a list to create all the Complex object, to bring it later on back to an Array? To use an Array from the beginning is more efficient.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top