FFT问题,输出正确吗?

时间:2014-10-08 12:21:19

标签: c# audio fft aforge

此代码应采用.wav文件,将原始数据转换为字节数组并将其转换为short数组,然后转换为复数。然后我从复数中取出一个5000的长度部分来从AForge.Math中提取FFT。这些结果复杂数字看起来是否正确?如果我认为一个是freq而另一个放大器在频率上,我在这里不正确吗?

以下是输出的几个示例:

( - 2.16700013595762,0.68302023531242),(4.22590168063363,4.0661547909796),( - 5.001069934509754,-0.16041726303182),( - 1.46395152700116,-6.23087698868018),( - 2.9017908067037,0.439816425795027),

这是我的代码。

class Main
{

    WaveFileReader reader;
    short[] sample;
    Complex[] tmpComplexArray;

    public Main()
    {
        reader = new WaveFileReader("C:\\Users\\minford\\Downloads\\Adolf_Hitler_speeches_HD_English_Subtitles_.wav");

        byte[] buffer = new byte[reader.Length];
        reader.Read(buffer, 0 , buffer.Length);
        sample = new short[reader.Length];
        for (int n = 0; n < buffer.Length; n += 2)
        {
            sample[n] = BitConverter.ToInt16(buffer, n);

        }


        //convert short to complex
       Complex[] complexData = new Complex[sample.Length];
        for (int i = 0; i < complexData.Length; i++)
        {
            Complex tmp = new Complex(sample[i],0);

            complexData[i] = tmp;

        }



        //to get first 500 for testing.
        tmpComplexArray = new Complex[5000];
        int x = 0;

        for (int i =50000; i < 55000; i++)
        {
           Complex a = new Complex(complexData[i]);
           tmpComplexArray[x] = a;
           x++;
        }


        //run FFT
        FourierTransform.DFT(tmpComplexArray ,FourierTransform.Direction.Forward);



       //print out sample of conversion
        for (int i = 0; i < tmpComplexArray.Length; i++)
        {

            Console.Write(i+" :"+tmpComplexArray[i]+ ", ");
        }

        Console.Write("complete, ");
    }

}

编辑:

我创建了一个正弦波并将其存储在一个短阵列中,然后通过FFT将其传递给一个复杂的数组。我的问题我不知道我在结果中寻找什么。 DSP的新手

结果的一小部分是: (0,0),(2.21689333557151E-15,-7.34284855141709E-15),(-2.89901436190121E-15,-1.0077605416825E-14),(-6.53699316899292E-15,-5.64637225863862E-15),(-1.67688085639384 E-14,-8.32711677389852E-15),(1.4495071809506E-14,4.91429119620079E-15),(1.8701484805205​​8E-14,2.4891200212096E-15),(2.78532752417959E-15,-1.7036594357478E-14),( - 7.33280103304423E-15,8.1326056999842E-15),(-2.14868123293854E-14,-4.16955359128224E-15),(1.56319401867222E-14,1.70135017185657E-14),(-1.00044417195022E-14,3.97015753605956E-14), (-1.53​​477230924182E-15,-2.25943708187515E-14),( - 2.36468622460961E-14,8.33955127177433E-15),(4.03588273911737E-15,-3.4597213982579E-14),( - 1.26192389870994E-14,-3.72946118432083E -15),(-1.9554136088118E-14,-2.36486386029355E-14),(-3.17754711431917E-14,3.35198535594827E-15),(-1.48929757415317E-14,-5.97566440774244E-14),(3.50723894371185E-14 ,-3.57420759655724E-14),(1.65414348884951E-14,4.11670697531008E-15),( - 1.69393388205208E-14,4.49968950988477E-14),( - 2.0111 2015929539E-13,9.97060212171164E-14),(2.32660113397287E-13,1.59641189156901E-14)

Heres是我的代码:

        int sampleRate = 8000;
        short[] buffer = new short[8000];
        double amplitude = 0.25 * short.MaxValue;
        double frequency = 500;
        for (int n = 0; n < buffer.Length; n++)
        {
            buffer[n] = (short)(amplitude * Math.Sin((2 * Math.PI * n * frequency) /sampleRate));
        }

        Complex[] complexData = new Complex[buffer.Length];
          for (int i = 0; i < buffer.Length; i++)
         {
            Complex tmp = new Complex(buffer[i],0);

           complexData[i] = tmp;

          }



        FourierTransform.DFT(complexData ,FourierTransform.Direction.Forward);



       //print out sample of conversion
        for (int i = 0; i < complexData.Length; i++)
        {

            Console.Write(i+" :"+complexData[i]+ ", ");
        }

        Console.Write("complete, ");

编辑:

我正在正确的垃圾箱里飙升。我看到两个,你提到的是因为它们是镜像的。你能解释一下为什么会这样吗?

2 个答案:

答案 0 :(得分:2)

我将从最简单的情况开始(频率正弦波&#39; x&#39;)并验证在获取FFT输出的实际值时,在与x对应的频率仓中得到尖峰。如果这样可行,那么您可以开始担心复数中表示的阶段信息。

答案 1 :(得分:1)

有两个问题:

1)您需要将数据标准化为-1.0到1.0范围。否则,Aforge DFT算法将溢出。

Complex[] complexData = new Complex[buffer.Length];
for (int i = 0; i < buffer.Length; i++)
{
    Complex tmp = new Complex(buffer[i]/(double)short.MaxValue, 0);
    complexData[i] = tmp;
}

2)如果你看一下复数的幅度,你将能够更容易地看到峰值。

for (int i = 0; i < complexData.Length; i++)
{
     Console.Write(i+" :"+complexData[i].Magnitude+ ", ");
}

由于您的DFT长度为8000,因此每个bin为1Hz宽。因此,500Hz正弦波的峰值将位于bin 500中。