Quantcast
Channel: NAudio
Viewing all articles
Browse latest Browse all 5831

New Post: My program gets very slow to respond/stuck while fft is calculated

$
0
0
Im trying to get the pitch of microphone input in real time. I have a capture base class which includes the sample rate, channels etc., and the sample aggregator class has taken from Mark's WPF demo

Capture Base
    public class CaptureBase : IDisposable
    {
        static int fftLength = 1024;
        const int samplingFrequency = 44100;
        const int channels = 1;
        const int noOfBuffers = 5;
        const int bufferMilisecs = 10;
        const int latency = 50;
        WaveIn sourceStream;
        DirectSoundOut soundOut;
        SampleAggregator sampleAggregator;
        bool disposed = false;
        bool isCapturing = false;

        public void StartCapture(Guid selectedDevice)
        {
            isCapturing = true;
           
            sampleAggregator = new SampleAggregator(fftLength);
            sampleAggregator.FftCalculated += new EventHandler<FftEventArgs>(FftCalculated);
            sampleAggregator.PerformFFT = true;

            sourceStream = new WaveIn();
            sourceStream.NumberOfBuffers = noOfBuffers;
            sourceStream.BufferMilliseconds = bufferMilisecs;
            sourceStream.WaveFormat = new WaveFormat(samplingFrequency, channels);
            sourceStream.DataAvailable += new EventHandler<WaveInEventArgs>(sourceStream_DataAvailable);
            sourceStream.StartRecording();
        }

        private void FftCalculated(object sender, FftEventArgs e)
        {
            for (var i = 0; i < e.Result.Length; i++)
            {
                Debug.WriteLine("FFT output.");
                Debug.WriteLine(e.Result[i].X);
                Debug.WriteLine(e.Result[i].Y);
                //Analysis.HPS hps = new Analysis.HPS();
                //hps.HarmonicProductSpectrum(e.Result);
            }
        }

        public SampleAggregator SampleAggregator
        {
            get
            {
                return sampleAggregator;
            }
        }
      
        private void sourceStream_DataAvailable(object sender, WaveInEventArgs e)
        {
            byte[] buffer = e.Buffer;
            int bytesRecorded = e.BytesRecorded;
           
            for (int i = 0; i < e.BytesRecorded; i += 2)
            {
                short sample = (short)((buffer[i + 1] << 8) | buffer[i + 0]);
                float sample32 = (sample / 32758f);
                sampleAggregator.Add(sample32);
            }
        }

        public void Stop()
        {
            if (isCapturing)
            {
                isCapturing = false;
            }
        }

        public void Dispose(bool disposing)
        {
            if (disposed) return;

            disposed = true;
            GC.SuppressFinalize(this);
            if (isCapturing) Stop();
        }

        void IDisposable.Dispose()
        {
            Dispose(true);
        }
    }
}
Sample Aggregator
 public class SampleAggregator
    {
        private readonly Complex[] fftBuffer;
        private readonly FftEventArgs fftArgs;
        private int fftPos;
        private readonly int fftLength;
        private int m;
        public event EventHandler<FftEventArgs> FftCalculated;

        public bool PerformFFT { get; set; }

        public SampleAggregator(int fftLength)
        {
            if (!IsPowerOfTwo(fftLength))
            {
                throw new ArgumentException("FFT Length must be a power of two");
            }
            this.m = (int)Math.Log(fftLength, 2.0);
            this.fftLength = fftLength;
            this.fftBuffer = new Complex[fftLength];
            this.fftArgs = new FftEventArgs(fftBuffer);
        }

        bool IsPowerOfTwo(int x)
        {
            return (x & (x - 1)) == 0;
        }

        public void Add(float value)
        {
            if (PerformFFT && FftCalculated != null)
            {
                // Remember the window function! There are many others as well.
                fftBuffer[fftPos].X = (float)(value * FastFourierTransform.HammingWindow(fftPos, fftLength));
                fftBuffer[fftPos].Y = 0; // This is always zero with audio.
                fftPos++;
                if (fftPos >= fftLength)
                {
                    fftPos = 0;
                    FastFourierTransform.FFT(true, m, fftBuffer);
                    FftCalculated(this, fftArgs);
                }
            }
        }
    }

    public class FftEventArgs : EventArgs
    {
        [DebuggerStepThrough]
        public FftEventArgs(Complex[] result)
        {
            this.Result = result;
        }
        public Complex[] Result { get; private set; }
    }
}
}
Please can someone explain what i have done wrong.

Viewing all articles
Browse latest Browse all 5831

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>