title: C# Application: Sample Audio from Audio Output -> FFT Algorithm -> Visualize
body: <p>I am a novice audio programmer and I use FFT for the first time. I want to sample audio from my audio output. After that I want to compute this data with a FFT algorithm. I am using <code>Naudio.dll</code>.</p>
  
  <p>Requirements for sampling:</p>
  
  <ul>
  <li>Sample from audio output</li>
  <li>The sample frequency must be adjustable on the GUI</li>
  <li>The buffer size must be adjustable on the GUI</li>
  <li>The amplitude values must be raw (no logarithmic filter/no sqrt() filter...)</li>
  </ul>
  
  <p>How can I solve this problem? Which dll to use?</p>
  
  <p>I tried to use NAudio's sample aggregator. But I don't know how.</p>
  
  <p>Thanks in advance</p>
  
  <pre><code>public class SampleAggregator : ISampleProvider
  {
      public event EventHandler&lt;MaxSampleEventArgs&gt; MaximumCalculated;
      private float maxValue;
      private float minValue;
      public int NotificationCount { get; set; }
      int count;
  
      public event EventHandler&lt;FftEventArgs&gt; FftCalculated;
      public bool PerformFFT { get; set; }
      private readonly Complex[] fftBuffer;
      private readonly FftEventArgs fftArgs;
      private int fftPos;
      private readonly int fftLength;
      private readonly int m;
      private readonly ISampleProvider source;
  
      private readonly int channels;
  
      public SampleAggregator(ISampleProvider source, int fftLength = 1024)
      {
          channels = source.WaveFormat.Channels;
          if (!IsPowerOfTwo(fftLength))
          {
              throw new ArgumentException("FFT Length must be a power of two");
          }
          m = (int)Math.Log(fftLength, 2.0);
          this.fftLength = fftLength;
          fftBuffer = new Complex[fftLength];
          fftArgs = new FftEventArgs(fftBuffer);
          this.source = source;
      }
  
      static bool IsPowerOfTwo(int x)
      {
          return (x &amp; (x - 1)) == 0;
      }
  
  
      public void Reset()
      {
          count = 0;
          maxValue = minValue = 0;
      }
  
      private void Add(float value)
      {
          if (PerformFFT &amp;&amp; FftCalculated != null)
          {
              fftBuffer[fftPos].X = (float)(value * FastFourierTransform.HammingWindow(fftPos, fftLength));
              fftBuffer[fftPos].Y = 0;
              fftPos++;
              if (fftPos &gt;= fftBuffer.Length)
              {
                  fftPos = 0;
                  // 1024 = 2^10
                  FastFourierTransform.FFT(true, m, fftBuffer);
                  FftCalculated(this, fftArgs);
              }
          }
  
          maxValue = Math.Max(maxValue, value);
          minValue = Math.Min(minValue, value);
          count++;
          if (count &gt;= NotificationCount &amp;&amp; NotificationCount &gt; 0)
          {
              MaximumCalculated?.Invoke(this, new MaxSampleEventArgs(minValue, maxValue));
              Reset();
          }
      }
  
      public WaveFormat WaveFormat =&gt; source.WaveFormat;
  
      public int Read(float[] buffer, int offset, int count)
      {
          var samplesRead = source.Read(buffer, offset, count);
  
          for (int n = 0; n &lt; samplesRead; n+=channels)
          {
              Add(buffer[n+offset]);
          }
          return samplesRead;
      }
  }
  
  public class MaxSampleEventArgs : EventArgs
  {
      [DebuggerStepThrough]
      public MaxSampleEventArgs(float minValue, float maxValue)
      {
          MaxSample = maxValue;
          MinSample = minValue;
      }
      public float MaxSample { get; private set; }
      public float MinSample { get; private set; }
  }
  
  public class FftEventArgs : EventArgs
  {
      [DebuggerStepThrough]
      public FftEventArgs(Complex[] result)
      {
          Result = result;
      }
      public Complex[] Result { get; private set; }
  }
  </code></pre>