title: Incrementing a counter inside a timer (System.Windows.Forms.Timer) C#
body: <p>I'm writing a Windows Forms application using C# which gets frequencies from user input into the device's microphone, I want to get frequencies calculated at certain intervals,</p>
  
  <p>I was hoping to achieve this by assigning the last calculated frequency to a global variable and when the timer.tick event is raised assign the value to an index of an array (userFrequencies),</p>
  
  <p>Below is the code: </p>
  
  <pre><code>   private void getFreqTimer_Tick(object sender, EventArgs e)
      {
        if (cIndex &lt; userFrequencies.Length)
          {
              userFrequencies[cIndex] = currentFreq;
              cIndex++; // Also tried ++cIndex;
          }
      }
  </code></pre>
  
  <p>The problem which I am having is cIndex is being incremented sometimes by 1 and sometimes by 2, therefore not assigning values to the array properly,</p>
  
  <p>I know that the timer can be off by around 15ms and there is a lot going on in the background of the form - could this be a factor, making the events fire differently during compiling?</p>
  
  <p>Any help would be greatly appreciated!</p>
  
  <p>EDIT: Additional code as requested:</p>
  
  <pre><code>using NAudio.Dsp;
  using NAudio.Wave;
  using System;
  using System.Data.SqlClient;
  using System.Diagnostics;
  using System.Drawing;
  using System.Drawing.Imaging;
  using System.Runtime.InteropServices;
  using System.Threading;
  using System.Windows.Forms;
  using System.Windows.Forms.DataVisualization.Charting;
  
  namespace VocalWarmUpFYP
  {
      public partial class Form1 : Form
      {
          private WaveIn waveIn;
          public WaveFileWriter waveFile = null;
  
      string timeHour = (DateTime.Now.Hour).ToString();
      string timeSecond = (DateTime.Now.Second).ToString();
      string timeMinute = (DateTime.Now.Minute).ToString();
      string timeDay = (DateTime.Now.Day).ToString();
      string chartImagePath;
      int callStopBtnClick;
      int timeForExercise;
      int timerSecs;
  
      private static int fftLength = 2048;
      private static int sampleRate = 44100;
      private SampleAggregator sampleAggregator = new SampleAggregator(fftLength);
  
      bool CompFFT = false;
      int userId = HelpData.UserID;
  
      double[] userFrequencies = new double[20];
      double[] desiredFrequencies;
      double currentFreq = 0;
      public int cIndex = 0;
  
      public Form1()
      {
  
          InitializeComponent();
      }
  
      private void Form1_Load(object sender, EventArgs e)
      {
          StartBtn.BackColor = HelpData.formBackColour;
          StopBtn.BackColor = HelpData.formBackColour;
          BackBtn.BackColor = HelpData.formBackColour;
          BackColor = HelpData.formBackColour;
          timer1.Tick += timer1_Tick;
          getFreqTimer.Tick += getFreqTimer_Tick;
          raiseStopTimer.Tick += raiseStopTimer_Tick;
          chart1.Series.Clear();
          chart1.BackColor = HelpData.formBackColour;
  
          switch (HelpData.selectedWarmUp)
          {
              case 1:
                  warmupImg.Image = Image.FromFile(Environment.GetFolderPath(Environment.SpecialFolder.Personal) + @"\Visual Studio 2015\Projects\VocalWarmUpFYP\Images\BumbleBee.png");
                  getFreqTimer.Interval = 750;
                  timeForExercise = 13;
                  break;
              case 2:
                  warmupImg.Image = Image.FromFile(Environment.GetFolderPath(Environment.SpecialFolder.Personal) + @"\Visual Studio 2015\Projects\VocalWarmUpFYP\Images\Lips.png");
                  getFreqTimer.Interval = 450;
                  timeForExercise = 7;
                  break;
              case 3:
                  warmupImg.Image = Image.FromFile(Environment.GetFolderPath(Environment.SpecialFolder.Personal) + @"\Visual Studio 2015\Projects\VocalWarmUpFYP\Images\Siren.png");
                  getFreqTimer.Interval = 700;
                  timeForExercise = 12;
                  break;
              case 4:
                  warmupImg.Image = Image.FromFile(Environment.GetFolderPath(Environment.SpecialFolder.Personal) + @"\Visual Studio 2015\Projects\VocalWarmUpFYP\Images\Mum.png");
                  getFreqTimer.Interval = 800;
                  timeForExercise = 14;
                  break;
              case 5:
                  warmupImg.Image = Image.FromFile(Environment.GetFolderPath(Environment.SpecialFolder.Personal) + @"\Visual Studio 2015\Projects\VocalWarmUpFYP\Images\HummingBird.png");
                  getFreqTimer.Interval = 450;
                  timeForExercise = 7;
                  break;
          }
  
  
          if (chart1.Series.Count == 0) // Check to make sure Series 0 exists
          {
              var series = chart1.Series.Add("Frequency"); // If it doesn't exist then create it.
              series.ChartType = SeriesChartType.FastLine;
              series.ChartArea = "ChartArea1";
              series.IsVisibleInLegend = false;
              series.LabelBackColor = HelpData.formBackColour;
              series.Color = Color.White;
              series.BorderWidth = 5;
          }
  
          chart1.ChartAreas["ChartArea1"].BackColor = HelpData.formBackColour;
          chart1.ChartAreas["ChartArea1"].AxisX.MinorGrid.Enabled = false;
          chart1.ChartAreas["ChartArea1"].AxisX.MajorGrid.Enabled = false;
          chart1.ChartAreas["ChartArea1"].AxisY.MajorGrid.Enabled = false;
          chart1.ChartAreas["ChartArea1"].AxisX.MajorTickMark.Enabled = false;
          chart1.ChartAreas["ChartArea1"].AxisX.MinorTickMark.Enabled = false;
          chart1.ChartAreas["ChartArea1"].AxisX.Interval = 0;
          chart1.ChartAreas["ChartArea1"].AxisY.LabelStyle.Enabled = false;
          chart1.ChartAreas["ChartArea1"].AxisY.MajorTickMark.Enabled = false;
          chart1.ChartAreas["ChartArea1"].AxisY.MinorTickMark.Enabled = false;
          chart1.ChartAreas["ChartArea1"].AxisX.LineWidth = 0;
          chart1.ChartAreas["ChartArea1"].AxisY.LineWidth = 0;
  
          chart1.Visible = false;
      }
  
      private void StopBtn_Click(object sender, EventArgs e)
      {
          timer1.Stop();
          getFreqTimer.Stop();
          raiseStopTimer.Stop();
          string currentTimeStamp = timeDay + timeHour + timeMinute + timeSecond;
          waveIn.StopRecording();
          waveFile.Dispose();
          waveIn.Dispose();
  
          StartBtn.Visible = true;
          StopBtn.Visible = false;
  
          chart1.SaveImage(@"C:\Temp\TestChart" + currentTimeStamp, ChartImageFormat.Png);
          chartImagePath = @"C:\Temp\TestChart" + currentTimeStamp + ".Png";
  
          NameRecording NameRecording = new NameRecording();
          NameRecording.Tag = this;
          NameRecording.Show(this);
  
          for (int i = 0; i &lt; userFrequencies.Length; i++)
          {
              Debug.WriteLine("User frequency at index " + i + ": " + userFrequencies[i]);
          }
  
      /*    
          var con = new SqlConnection("Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=C:\\USERS\\OWNER\\DOCUMENTS\\VISUAL STUDIO 2015\\PROJECTS\\VOCALWARMUPFYP\\VOCALWARMUPFYP\\NEWDATABASE.MDF;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False");
  
          using (con)
          {
  
              string oString = "SELECT COUNT (*) FROM VocalDetails";
              string oString2 = "INSERT INTO VocalDetails (VocalID, FreqImg, Name, Accuracy, Id, TimeStamp, RecordingRef) VALUES (@vocalid, @freqimg, @name, @accuracy, @userid, @timestamp, @filereference)";
              con.Open();
  
              SqlCommand oCmd = new SqlCommand(oString, con);
  
              int newVocalID = (Convert.ToInt32(oCmd.ExecuteScalar()) + 1);
              string recordingName = HelpData.userRecordingName;
              string timeStamp = DateTime.Now.ToShortDateString();
              string freqImg = chartImagePath;
              SqlCommand oCmd2 = new SqlCommand(oString2, con);
  
              oCmd2.Parameters.AddWithValue("@vocalid", newVocalID);
              oCmd2.Parameters.AddWithValue("@freqimg", freqImg);
              oCmd2.Parameters.AddWithValue("@name", recordingName);
              oCmd2.Parameters.AddWithValue("@accuracy", Accuracy);
              oCmd2.Parameters.AddWithValue("@userid", userId);
              oCmd2.Parameters.AddWithValue("@timestamp", timeStamp);
              oCmd2.Parameters.AddWithValue("@filereference", fileReference);
  
          }
          con.Close();
          con.Dispose();
  */
          }
  
  
      private void StartBtn_Click(object sender, EventArgs e)
      {
          StartBtn.Visible = false;
          StopBtn.Visible = true;
          warmupImg.Visible = false;
          chart1.Visible = true;
          string currentTimeStamp = timeDay + timeHour + timeMinute + timeSecond;
          string fileToProcess = @"C:\Temp\Test" + currentTimeStamp + ".wav";
  
          sampleAggregator.PerformFFT = true;
          sampleAggregator.FftCalculated += new EventHandler&lt;FftEventArgs&gt;(FftCalculated);
          BufferedWaveProvider wavprov = new BufferedWaveProvider(new WaveFormat(sampleRate, 2));
  
          waveIn = new WaveIn();
          waveIn.WaveFormat = new WaveFormat(44100, WaveIn.GetCapabilities(0).Channels);
          waveIn.DeviceNumber = 0;
          waveFile = new WaveFileWriter(fileToProcess, waveIn.WaveFormat);
          timerSecs = DateTime.Now.AddSeconds(timeForExercise).Second;
  
          waveIn.DataAvailable += OnDataAvailable;
          waveIn.StartRecording();
  
          timer1.Start();
          getFreqTimer.Start();
          raiseStopTimer.Start();
      }
  
      void OnDataAvailable(object sender, WaveInEventArgs e)
      {
          if (InvokeRequired)
          {
              BeginInvoke(new EventHandler&lt;WaveInEventArgs&gt;(OnDataAvailable), sender, e);
          }
          else
          {
              byte[] buffer = e.Buffer;
              int bytesRecorded = e.BytesRecorded;
              int bufferIncrement = waveIn.WaveFormat.BlockAlign;
  
              for (int index = 0; index &lt; bytesRecorded; index += bufferIncrement)
              {
                  float sample32 = BitConverter.ToInt16(buffer, index);
                  sampleAggregator.Add(sample32);
              }
  
              if (waveFile != null)
              {
                  waveFile.Write(e.Buffer, 0, e.BytesRecorded);
                  waveFile.Flush();
              }
          }
      }
  
      class SampleAggregator
      {
          // FFT
          public event EventHandler&lt;FftEventArgs&gt; FftCalculated;
          public bool PerformFFT { get; set; }
  
          private Complex[] fftBuffer;
          private FftEventArgs fftArgs;
          private int fftPos;
          private int fftLength;
          private int m;
  
          public SampleAggregator(int fftLength)
          {
              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);
          }
  
          bool IsPowerOfTwo(int x)
          {
              return (x &amp; (x - 1)) == 0;
          }
  
          public void Add(float value)
          {
              if (PerformFFT &amp;&amp; FftCalculated != null)
              {
                  fftBuffer[fftPos].X = (float)(value * FastFourierTransform.HannWindow(fftPos, fftLength));
                  fftBuffer[fftPos].Y = 0; // This is always zero with audio.
                  fftPos++;
                  if (fftPos &gt;= 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; }
      }
  
      private void FftCalculated(object sender, FftEventArgs e)
      {
          double[] Magnitude = new double[(e.Result.Length / 2) - 1];
          double Freq;
          double Power;
          int Index = 0;
  
          if (CompFFT == true)
          {
              for (int i = 1; i &lt; (e.Result.Length / 2) - 1; i++)
              {
                  if (chart1.Series.Count &lt;= fftLength) //&lt;&lt;======Now it wont give exception**
                  {
                      if (InvokeRequired == false) //&lt;&lt;====== Invoke method used to allow access to the chart control from custom event**
                      {
  
                          this.Invoke(new MethodInvoker(delegate
                          {
  
                              var series = 0;
                              double Max_Magnitude = 0;
                              double Max_Index = -1;
  
                              for (int j = 0; j &lt; (e.Result.Length / 2) - 1; j++)
                              {
  
                                  e.Result[j].Y = 0;
                                  Power = (e.Result[j].X * e.Result[j].X) + (e.Result[j].Y * e.Result[j].Y);
                                  Magnitude[j] = Math.Sqrt(Power);
                              }
  
                              for (int j = 0; j &lt; Magnitude.Length; j++)
                              {
  
                                  if (Magnitude[j] &gt; Max_Magnitude &amp;&amp; j != 0 &amp;&amp; Magnitude[j] &gt; 1)
                                  {
                                      Index = j;
                                      Max_Magnitude = Magnitude[Index];
                                      Max_Index = Index;
                                  }
                              }
  
                              Freq = ((Max_Index * sampleRate) / fftLength);
  
                              if (Freq &gt; 0)
                              {
                                  currentFreq = Freq;
                              }
  
                              chart1.DataSource = Freq;
                              chart1.Series[series].Points.Add(Freq);
  
                              CompFFT = false;
                          }));
                          return;
                      }
                  }
  
                  chart1.Update();
              }
          }
      }
  
      private void timer1_Tick(object sender, EventArgs e)
      {
          CompFFT = true;
      }
  
      private void BackBtn_Click(object sender, EventArgs e)
      {
          SelectWarmUp SelectWarmUp = new SelectWarmUp();
          SelectWarmUp.Tag = this;
          SelectWarmUp.Show(this);
          Hide();
      }
  
      private void getFreqTimer_Tick(object sender, EventArgs e)
      {
        if (cIndex &lt; userFrequencies.Length)
          {
              userFrequencies[cIndex] = currentFreq;
              cIndex++;
          }
          Debug.WriteLine("cIndex: " + cIndex);
      }
  
      private void raiseStopTimer_Tick(object sender, EventArgs e)
      {
          callStopBtnClick = DateTime.Now.Second;
  
          if (callStopBtnClick == timerSecs + 2)
          {
              StopBtn.PerformClick();
          }
      }
  }
  }
  </code></pre>
  
  <p>The interval for timer1: 25ms
  The interval for getFreqTimer: 750ms</p>
  
  <p>The application is run for 15 seconds before the StopBtn_Click event is automatically called - this should give a maximum of 20 values</p>
  
  <p>Output from @Eminem suggestion:</p>
  
  <pre><code>cIndex: 1
  x: 1
  cIndex: 2
  x: 2
  cIndex: 3
  x: 3
  cIndex: 4
  x: 4
  cIndex: 5
  x: 5
  cIndex: 6
  x: 6
  cIndex: 7
  x: 7
  cIndex: 8
  x: 8
  cIndex: 9
  x: 9
  cIndex: 10
  x: 10
  cIndex: 11
  x: 11
  cIndex: 12
  x: 12
  cIndex: 13
  x: 13
  cIndex: 14
  x: 14
  cIndex: 15
  x: 15
  cIndex: 16
  x: 16
  cIndex: 17
  x: 17
  cIndex: 18
  x: 18
  cIndex: 19
  x: 19
  cIndex: 20
  x: 20
  cIndex: 20
  x: 21
  cIndex: 20
  x: 22
  cIndex: 20
  x: 23
  cIndex: 20
  x: 24
  cIndex: 20
  x: 25
  cIndex: 20
  x: 26
  cIndex: 20
  x: 27
  cIndex: 20
  x: 28
  cIndex: 20
  x: 29
  cIndex: 20
  x: 30
  cIndex: 20
  x: 31 
  cIndex: 20
  x: 32
  cIndex: 20
  x: 33
  cIndex: 20
  x: 34
  cIndex: 20
  x: 35
  cIndex: 20
  x: 36
  cIndex: 20
  x: 37
  cIndex: 20
  x: 38
  
  User frequency at index 0: 172.265625
  User frequency at index 1: 172.265625
  User frequency at index 2: 279.931640625
  User frequency at index 3: 279.931640625
  User frequency at index 4: 193.798828125
  User frequency at index 5: 193.798828125
  User frequency at index 6: 279.931640625
  User frequency at index 7: 279.931640625
  User frequency at index 8: 387.59765625
  User frequency at index 9: 387.59765625
  User frequency at index 10: 236.865234375
  User frequency at index 11: 236.865234375
  User frequency at index 12: 1098.193359375
  User frequency at index 13: 1098.193359375
  User frequency at index 14: 559.86328125
  User frequency at index 15: 559.86328125
  User frequency at index 16: 258.3984375
  User frequency at index 17: 258.3984375
  User frequency at index 18: 279.931640625
  User frequency at index 19: 279.931640625 
  </code></pre>