title: NAudio Get Audio Samples
body: <p>I am using NAudio to get the sample from the song that is currently playing and draw the waveform as the song plays. I am using <code>AudioFileReader</code> and <code>ToSampleProvider</code> to get all samples as <code>float</code> and then I plot them into an <code>InkCanvas</code> while the song is playing. My problem is that the samples don't seem to match the sound. I also have verify this by using this same song in the WPF example that is located in the source code of NAudio. In the example the waveform matches the sound, but in my application it doesn't. So I was wondering if someone could help me find out what I am doing (or reading) wrong or if maybe my drawing logic is wrong.</p>
  
  <p>Here is my current code:</p>
  
  <pre><code>public partial class MainWindow : Window, INotifyPropertyChanged
  {
      private ISampleProvider provider;
      private DispatcherTimer timer;
      private AudioFileReader reader;
  
      private WaveOut waveOut;
      private StylusPointCollection topPoints, bottomPoints;
      private DrawingAttributes attr;
  
      private double canvasHeight, canvasWidth;
      private int samplesGroupSize;
      private double drawPos = 0;
  
      private StrokeCollection _WaveformLines;
      public StrokeCollection WaveformLines
      {
          get { return _WaveformLines; } 
          set
          {
              _WaveformLines = value;
              OnPropertyChanged("WaveformLines");
          }
      }
  
      public MainWindow()
      {
          InitializeComponent();
          this.DataContext = this;
      }
  
      private void Window_Loaded(object sender, RoutedEventArgs e)
      {
          reader = new AudioFileReader("C:\\Users\\Agustin\\Desktop\\DragonRider.mp3");
          waveOut = new WaveOut();
          waveOut.Init(reader);
  
          provider = reader.ToSampleProvider(); //Here I get the samples
          reader.Position = 0; //Go to the position 0 after reading the samples
  
          canvasHeight = Waveform.ActualHeight;
          canvasWidth = Waveform.ActualWidth;
  
          WaveformLines = new StrokeCollection();
          topPoints = new StylusPointCollection();
          topPoints.Add(new StylusPoint(0, (canvasHeight / 2)));
          topPoints.Changed += topPoints_Changed;
          bottomPoints = new StylusPointCollection();
          bottomPoints.Add(new StylusPoint(0, (canvasHeight / 2)));
          bottomPoints.Changed += topPoints_Changed;
          WaveformLines.Add(new Stroke(topPoints));
          WaveformLines.Add(new Stroke(bottomPoints));
  
          attr = new DrawingAttributes();
          attr.Color = Colors.Green;
          attr.Width = 1.5;
          attr.Height = 1;
  
          timer = new DispatcherTimer();
          timer.Interval = TimeSpan.FromMilliseconds(1);
          timer.Tick += timer_Tick;
          timer.Start();
          samplesGroupSize = (int)(timer.Interval.TotalSeconds * reader.WaveFormat.SampleRate); //The value for this is 44.
      }
  
      private void PlayButton_Click(object sender, RoutedEventArgs e)
      {
          waveOut.Play();
      }
      private void PauseButton_Click(object sender, RoutedEventArgs e)
      {
          waveOut.Pause();
      }
  
      private void timer_Tick(object sender, EventArgs e)
      {
          if (waveOut.PlaybackState == PlaybackState.Playing)
          {
              TimeLabel.Content = string.Format("Time: {0}", reader.CurrentTime.ToString(@"mm\:ss\:ff")); //NEED TO KEEP WORKING
              float[] samps = new float[samplesGroupSize];
              provider.Read(samps, 0, samps.Length);
              float max = Max(samps);
              float min = Min(samps);
              topPoints.Add(new StylusPoint(drawPos, (canvasHeight / 2) - ((canvasHeight / 2) * max)));
              bottomPoints.Add(new StylusPoint(drawPos, (canvasHeight / 2) - ((canvasHeight / 2) * min)));
              drawPos += 2;
              if (drawPos &gt; canvasWidth)
              {
                  WaveformLines.Clear();
                  topPoints = new StylusPointCollection();
                  topPoints.Add(new StylusPoint(0, (canvasHeight / 2)));
                  bottomPoints = new StylusPointCollection();
                  bottomPoints.Add(new StylusPoint(0, (canvasHeight / 2)));
                  WaveformLines.Add(new Stroke(topPoints));
                  WaveformLines.Add(new Stroke(bottomPoints));
                  drawPos = 0;
              }
          }
      }
  
      private float Min(float[] samps)
      {
          float max = samps[0];
          foreach (float s in samps)
          {
              if (s &gt; max)
                  max = s;
          }
          return max;
      }
      private float Max(float[] samps)
      {
          float min = samps[0];
          foreach (float s in samps)
          {
              if (s &lt; min)
                  min = s;
          }
          return min;
      }
  
      //I excluded the INotifyPropertyChanged implementation, but in the
      //actual code is located here
  }
  </code></pre>
  
  <p>I know this drawing algorithm is not very good but I have tried others and they also seem to not follow the audio.</p>
  
  <p>Thanks.</p>
  
  <p>NOTE: I know that there are similar question, but the other questions suggest to use things like <code>AudioFileReader</code> or <code>ToSampleProvider</code> which I am already using. My error is probably more into how I am reading the samples, maybe I am missing some bytes or have to skip some byte, or maybe some missing property that I am not setting.</p>