Example #1
0
        private double[] FFT_from_PCM(double[] pcm)
        {
            // use the largest FFT size we can given the data (must be a power of 2)
            int fftPoints = 2;

            while (fftPoints * 2 <= pcm.Length)
            {
                fftPoints *= 2;
            }

            // prepare the complex data which will be FFT'd (using a window function)
            NAudio.Dsp.Complex[] fftFull = new NAudio.Dsp.Complex[fftPoints];
            for (int i = 0; i < fftPoints; i++)
            {
                fftFull[i].X = (float)(pcm[i] * NAudio.Dsp.FastFourierTransform.HammingWindow(i, fftPoints));
            }

            // perform the FFT
            NAudio.Dsp.FastFourierTransform.FFT(true, (int)Math.Log(fftPoints, 2.0), fftFull);

            // average (sum) the mirror image frequency powers
            double[] fft = new double[fftPoints / 2];
            for (int i = 0; i < fftPoints / 2; i++)
            {
                double fftLeft  = Math.Abs(fftFull[i].X + fftFull[i].Y);
                double fftRight = Math.Abs(fftFull[fftPoints - i - 1].X + fftFull[fftPoints - i - 1].Y);
                fft[i] = fftLeft + fftRight;
            }

            return(fft);
        }
Example #2
0
        private void updateFFT()
        {
            // the PCM size to be analyzed with FFT must be a power of 2
            int fftPoints = 2;

            while (fftPoints * 2 <= dataPcm.Length)
            {
                fftPoints *= 2;
            }

            // apply a Hamming window function as we load the FFT array then calculate the FFT
            NAudio.Dsp.Complex[] fftFull = new NAudio.Dsp.Complex[fftPoints];
            for (int i = 0; i < fftPoints; i++)
            {
                fftFull[i].X = (float)(dataPcm[i] * NAudio.Dsp.FastFourierTransform.HammingWindow(i, fftPoints));
            }
            NAudio.Dsp.FastFourierTransform.FFT(true, (int)Math.Log(fftPoints, 2.0), fftFull);

            // copy the complex values into the double array that will be plotted
            if (dataFft == null)
            {
                dataFft = new double[fftPoints];
            }
            for (int i = 0; i < fftPoints; i++)
            {
                double fftLeft  = Math.Abs(fftFull[i].X + fftFull[i].Y);
                double fftRight = Math.Abs(fftFull[fftPoints - i - 1].X + fftFull[fftPoints - i - 1].Y);
                dataFft[i] = fftLeft + fftRight;
                //dataFft[i] = Math.Sqrt(fftFull[i].X * fftFull[i].X + fftFull[i].Y * fftFull[i].Y);
            }
        }
Example #3
0
        private void updateFFT()
        {
            // размер PCM для анализа с помощью БПФ должен быть степенью 2
            int fftPoints = 2;

            while (fftPoints * 2 <= dataPcm.Length)
            {
                fftPoints *= 2;
            }
            // применяем оконную функцию Хэмминга при загрузке массива FFT, затем вычисляем FFT
            NAudio.Dsp.Complex[] fftFull = new NAudio.Dsp.Complex[fftPoints];
            for (int i = 0; i < fftPoints; i++)
            {
                fftFull[i].X = (float)(dataPcm[i] * NAudio.Dsp.FastFourierTransform.HammingWindow(i, fftPoints));
            }
            NAudio.Dsp.FastFourierTransform.FFT(true, (int)Math.Log(fftPoints, 2.0), fftFull);

            // копируем комплексные значения в двойной массив, который будет построен
            if (dataFft == null)
            {
                dataFft = new double[fftPoints / 2];
            }
            for (int i = 0; i < fftPoints / 2; i++)
            {
                double fftLeft  = Math.Abs(fftFull[i].X + fftFull[i].Y);
                double fftRight = Math.Abs(fftFull[fftPoints - i - 1].X + fftFull[fftPoints - i - 1].Y);
                dataFft[i] = fftLeft + fftRight;
            }
        }
Example #4
0
        private void updateFFT()
        {
            if (dataPcm == null)
            {
                return;
            }

            int fftPoints = 2;

            while (fftPoints * 2 <= dataPcm.Length)
            {
                fftPoints *= 2;
            }

            NAudio.Dsp.Complex[] fftFull = new NAudio.Dsp.Complex[fftPoints];
            for (int i = 0; i < fftPoints; i++)
            {
                fftFull[i].X = (float)(dataPcm[i] * NAudio.Dsp.FastFourierTransform.HammingWindow(i, fftPoints));
            }

            NAudio.Dsp.FastFourierTransform.FFT(true, (int)Math.Log(fftPoints, 2.0), fftFull);

            if (dataFft == null)
            {
                dataFft = new double[fftPoints / 2];
            }
            for (int i = 0; i < fftPoints / 2; i++)
            {
                double fftLeft  = Math.Abs(fftFull[i].X + fftFull[i].Y);
                double fftRight = Math.Abs(fftFull[fftPoints - i - 1].X + fftFull[fftPoints - i - 1].Y);
                dataFft[i] = fftLeft + fftRight;
            }
        }
Example #5
0
        public override void Draw()
        {
            Graphics.SetColor(1, 1, 1);
            if (buffer == null)
            {
                Graphics.Print("No buffer available");
                return;
            }

            int len = buffer.FloatBuffer.Length / 8;

            // fft
            NAudio.Dsp.Complex[] values = new NAudio.Dsp.Complex[len];
            for (int i = 0; i < len; i++)
            {
                values[i].Y = 0;
                values[i].X = buffer.FloatBuffer[i];
            }
            NAudio.Dsp.FastFourierTransform.FFT(true, M, values);

            float size = (float)WindowWidth / ((float)Math.Pow(2, M) / 2);

            for (int i = 1; i < Math.Pow(2, M) / 2; i++)
            {
                //Graphics.Print(i.ToString() + ": " + values[i].X.ToString("N2") + " i " + (values[i].Y + 0.50f).ToString("N2"), 0, (i + 1) * 16);
                Graphics.Rectangle(DrawMode.Fill, (i - 1) * size, WindowHeight / 2, size, -Math.Abs(values[i].X) * (WindowHeight / 2) * 10);
            }
        }
Example #6
0
        public static float[] FFT(float[] values, WindowFunction window = WindowFunction.hanning)
        {
            int fftSize = values.Length;

            if (!IsPowerOfTwo(fftSize))
            {
                throw new ArgumentException("FFT Size must be a power of 2");
            }

            NAudio.Dsp.Complex[] fft_buffer = new NAudio.Dsp.Complex[fftSize];
            for (int i = 0; i < fftSize; i++)
            {
                fft_buffer[i].X = (float)values[i];
                fft_buffer[i].Y = 0;

                switch (window)
                {
                case WindowFunction.none:
                    break;

                case WindowFunction.hanning:
                    fft_buffer[i].X *= (float)NAudio.Dsp.FastFourierTransform.HammingWindow(i, fftSize);
                    break;

                case WindowFunction.triangle:
                    fft_buffer[i].X *= (float)TriangleWindow(i, fftSize);
                    break;

                default:
                    throw new NotImplementedException("unsupported window function");
                }
            }

            NAudio.Dsp.FastFourierTransform.FFT(true, (int)Math.Log(fftSize, 2.0), fft_buffer);

            float[] fft = new float[fftSize / 2];
            for (int i = 0; i < fft.Length; i++)
            {
                var fftL = fft_buffer[i];
                var fftR = fft_buffer[fft_buffer.Length - i - 1];

                // note that this is different than just taking the absolute value
                float absL = (float)Math.Sqrt(fftL.X * fftL.X + fftL.Y * fftL.Y);
                float absR = (float)Math.Sqrt(fftR.X * fftR.X + fftR.Y * fftR.Y);
                fft[i] = (absL + absR) / 2;
            }

            return(fft);
        }
        private void SetDataFFT(WaveInEventArgs args)
        {
            int bytesPerSample  = _wi.WaveFormat.BitsPerSample / 8;
            int samplesRecorded = args.BytesRecorded / bytesPerSample;

            Int16[] dataPcm = new Int16[samplesRecorded];
            for (int i = 0; i < samplesRecorded; i++)
            {
                dataPcm[i] = BitConverter.ToInt16(args.Buffer, i * bytesPerSample);
            }

            // the PCM size to be analyzed with FFT must be a power of 2
            int fftPoints = 2;

            while (fftPoints * 2 <= dataPcm.Length)
            {
                fftPoints *= 2;
            }

            // apply a Hamming window function as we load the FFT array then calculate the FFT
            NAudio.Dsp.Complex[] fftFull = new NAudio.Dsp.Complex[fftPoints];
            for (int i = 0; i < fftPoints; i++)
            {
                fftFull[i].X = (float)(dataPcm[i] * NAudio.Dsp.FastFourierTransform.HammingWindow(i, fftPoints));
            }
            NAudio.Dsp.FastFourierTransform.FFT(true, (int)Math.Log(fftPoints, 2.0), fftFull);

            double[] dataFft = new double[fftPoints / 2];
            byte[]   data    = new byte[fftPoints / 2];

            for (int i = 0; i < fftPoints / 2; i++)
            {
                double fftLeft  = Math.Abs(fftFull[i].X + fftFull[i].Y);
                double fftRight = Math.Abs(fftFull[fftPoints - i - 1].X + fftFull[fftPoints - i - 1].Y);
                dataFft[i] = fftLeft + fftRight;
                data[i]    = (byte)(fftLeft + fftRight);
            }

            /*if(SpectrumVisualizer.GetType().Name == "CircleSpectrumVisualizer")
             *  SpectrumVisualizer.Set(GetNiceCircleFFT(data));
             * else
             *  SpectrumVisualizer.Set(data);*/

            SpectrumVisualizer.Set(GetNiceFftData(data, SpectrumVisualizer.GetType().Name == "CircleSpectrumVisualizer"));
        }
Example #8
0
        public static void NAaudioFFTTestUsingDouble(string CSVFilePath=null, double[] audio_data=null, int testLoopCount=1)
        {
            if (audio_data == null) {
                audio_data = GetSignalTestData();
            }

            int windowLength = audio_data.Length;

            int binaryExponentitation = (int)Math.Log(windowLength, 2);
            NAudio.Dsp.Complex[] complexArray = new NAudio.Dsp.Complex[windowLength];
            for (int i = 0; i < windowLength; i++) {
                complexArray[i].X = (float) audio_data[i];
                complexArray[i].Y = 0;
            }

            // loop if neccesary - e.g. for performance test purposes
            for (int i = 0; i < testLoopCount; i++) {
                // perform the FFT
                NAudio.Dsp.FastFourierTransform.FFT(true, binaryExponentitation, complexArray);
            }

            // get the result
            double[] spectrum_fft_real = new double[complexArray.Length];
            double[] spectrum_fft_imag = new double[complexArray.Length];
            double[] spectrum_fft_abs = new double[complexArray.Length];

            for (int i = 0; i < complexArray.Length; i++) {
                float re  = complexArray[i].X;
                float img = complexArray[i].Y;
                spectrum_fft_real[i] = re * windowLength;
                spectrum_fft_imag[i] = img * windowLength;
                spectrum_fft_abs[i] = (float) Math.Sqrt(re*re + img*img) * windowLength;
            }

            // perform the inverse FFT (IFFT)
            NAudio.Dsp.FastFourierTransform.FFT(false, binaryExponentitation, complexArray);

            // get the result
            double[] spectrum_inverse_real = new double[complexArray.Length];
            double[] spectrum_inverse_imag = new double[complexArray.Length];
            double[] spectrum_inverse_abs = new double[complexArray.Length];

            for (int i = 0; i < complexArray.Length; i++) {
                float re  = complexArray[i].X;
                float img = complexArray[i].Y;
                spectrum_inverse_real[i] = re;
                spectrum_inverse_imag[i] = img;
                spectrum_inverse_abs[i] = (float) Math.Sqrt(re*re + img*img);
            }

            if (CSVFilePath!=null) {
                CommonUtils.Export.exportCSV(CSVFilePath, audio_data, spectrum_fft_real, spectrum_fft_imag, spectrum_fft_abs, spectrum_inverse_real, spectrum_inverse_imag, spectrum_inverse_abs);
            }
        }
Example #9
0
        public void DrawVisualizerTimer(object sender, EventArgs e)
        {
            if (buffer == null)
            {
                Console.WriteLine("No buffer available");
                return;
            }

            int len = buffer.FloatBuffer.Length / 8;
            int M   = 6;

            // fft
            NAudio.Dsp.Complex[] values = new NAudio.Dsp.Complex[len];
            for (int i = 0; i < len; i++)
            {
                values[i].Y = 0;
                values[i].X = buffer.FloatBuffer[i];
            }
            NAudio.Dsp.FastFourierTransform.FFT(true, M, values);

            double scale = 0;

            for (int i = 0; i < Math.Pow(2, M) / 2; i++)
            {
                //Console.Write(" " + values[i].X.ToString("N2"));
                scale += values[i].X;
            }
            if (scale < 0)
            {
                scale *= -1;
            }
            audioScale = scale * 5;
            //Console.WriteLine(" > " + scale);

            if (audioScale > 0)
            {
                outterFireScaleTransform.BeginAnimation(ScaleTransform.ScaleXProperty, new DoubleAnimation(1, 1 + audioScale, TimeSpan.FromMilliseconds(100)));
                outterFireScaleTransform.BeginAnimation(ScaleTransform.ScaleYProperty, new DoubleAnimation(1, 1 + audioScale, TimeSpan.FromMilliseconds(100)));
                outterFireScaleTransform.BeginAnimation(ScaleTransform.ScaleXProperty, new DoubleAnimation(1 + audioScale, 1, TimeSpan.FromMilliseconds(100)));
                outterFireScaleTransform.BeginAnimation(ScaleTransform.ScaleYProperty, new DoubleAnimation(1 + audioScale, 1, TimeSpan.FromMilliseconds(100)));
            }

            if (audioScale > 0.05)
            {
                if (!faceControlTimer.IsEnabled)
                {
                    String leftBefore  = (String)leftEye.Content;
                    String rightBefore = (String)rightEye.Content;

                    leftEye.Content  = "^";
                    rightEye.Content = "^";

                    faceControlTimer = new DispatcherTimer {
                        Interval = TimeSpan.FromSeconds(2)
                    };
                    faceControlTimer.Start();
                    faceControlTimer.Tick += (s, args) =>
                    {
                        faceControlTimer.Stop();
                        leftEye.Content  = leftBefore;
                        rightEye.Content = rightBefore;
                    };
                }
            }
        }