C#NAudio FFT输出解释

时间:2017-04-12 17:33:04

标签: c# xna fft naudio

我目前正在使用NAudio和XNA对MusicPlayer进行编码,虽然使用类似于Monstercat视频的所有频率的强度来显示图表是一个不错的主意(例如:watch?v = VGh5DV0D3wk) 。 经过短暂的互联网搜索后,我发现了FFT,并使用NAudio方法将其实现到我的程序中。然后我尝试将结果可视化,但它几乎不像频率/振幅图。

我使用此视频的不同频率进行了一些测试:观看?v = 4Av788P9stk 我想在这里添加图片,但我没有足够的声誉。

100hz 5000hz

public static void UpdateWaveBuffer()
    {
        buffer = new byte[bufferLength];
        WaveBuffer = new float[bufferLength / 4];

        if (Channel32 != null && Channel32Reader != null)
        {
            // I have two WaveChannel32 objects, one to play the song and another 
            // that reads the data from the current position in realtime
            // It's not the most efficient method but Im gonna improve that later
            Channel32Reader.Position = Channel32.Position;

            int Read = Channel32Reader.Read(buffer, 0, bufferLength);

            // Converting the byte buffer in readable data
            for (int i = 0; i < bufferLength / 4; i++)
                WaveBuffer[i] = BitConverter.ToSingle(buffer, i * 4);
        }
    }

public static void UpdateFFTbuffer()
    {
        Complex[] tempbuffer = new Complex[WaveBuffer.Length];

        for (int i = 0; i < tempbuffer.Length; i++)
        {
            tempbuffer[i].X = (float)(WaveBuffer[i] * FastFourierTransform.BlackmannHarrisWindow(i, WaveBuffer.Length));
            tempbuffer[i].Y = 0;
        }

        FastFourierTransform.FFT(true, (int)Math.Log(tempbuffer.Length, 2.0), tempbuffer);

        FFToutput = new float[tempbuffer.Length / 2 - 1];
        for (int i = 0; i < FFToutput.Length; i++)
        {
            FFToutput[i] = (float)Math.Sqrt(tempbuffer[i].X * tempbuffer[i].X) + (tempbuffer[i].Y * tempbuffer[i].Y);
        }
    }

绘制方法:

// FFT Line Graph
        if (VisSetting == Visualizations.fftline && Assets.Channel32 != null)
        {
            spriteBatch.Begin();

            //float Length = Assets.FFToutput.Length / 2f;
            float Length = Assets.FFToutput.Length;

            // Shadow
            for (int i = 0; i < Length; i++)
            {
                double value = Math.Sqrt(Assets.FFToutput[i]) * 1000;

                if (value > 100)
                    value = 100;

                Assets.DrawLine(new Vector2((i - 1) * Values.WindowSize.X / Length + 5,
                                Values.WindowSize.Y / 2f + (int)value + 5),

                                new Vector2(i * Values.WindowSize.X / Length + 5,
                                Values.WindowSize.Y / 2f - (int)value + 5),

                                2, Color.Black * 0.6f, spriteBatch);
            }

            for (int i = 0; i < Length; i++)
            {
                double value = Math.Sqrt(Assets.FFToutput[i]) * 1000;

                if (value > 100)
                    value = 100;

                Assets.DrawLine(new Vector2((i - 1) * Values.WindowSize.X / Length,
                                Values.WindowSize.Y / 2f + (int)value),

                                new Vector2(i * Values.WindowSize.X / Length,
                                Values.WindowSize.Y / 2f - (int)value),

                                2, Color.Lerp(primaryColor, secondaryColor, i / Length), spriteBatch);
            }

            spriteBatch.End();
        }

0 个答案:

没有答案