title: DirectSound Timing and sample-count
body: <p>I am using DirectSound to write a sine wave to the audio card.  The sample-size is 16-bit, one channel.  My question is, how many samples should it take to make a five-second sound?  The sample rate is 44100 samples per second.  The math is simple: 220500 is the answer.  This is driving me crazy, though, because my code plays only roughly half that time!!  Here's my code:</p>
  
  <pre><code>using Microsoft.DirectX.DirectSound; 
  using System;
  namespace Audio
  {
      // The class 
      public class Oscillator
      {
          static void Main(string[] args)
          {
  
              // Set up wave format 
              WaveFormat waveFormat = new WaveFormat();
              waveFormat.FormatTag = WaveFormatTag.Pcm;
              waveFormat.Channels = 1;
              waveFormat.BitsPerSample = 16;
              waveFormat.SamplesPerSecond = 44100;
              waveFormat.BlockAlign = (short)(waveFormat.Channels * waveFormat.BitsPerSample / 8);
              waveFormat.AverageBytesPerSecond = waveFormat.BlockAlign * waveFormat.SamplesPerSecond;
  
              // Set up buffer description 
              BufferDescription bufferDesc = new BufferDescription(waveFormat);
              bufferDesc.Control3D = false;
              bufferDesc.ControlEffects = false;
              bufferDesc.ControlFrequency = true;
              bufferDesc.ControlPan = true;
              bufferDesc.ControlVolume = true;
              bufferDesc.DeferLocation = true;
              bufferDesc.GlobalFocus = true;
  
              Device d = new Device();
              d.SetCooperativeLevel(new System.Windows.Forms.Control(), CooperativeLevel.Priority);
  
  
              int samples = 5 * waveFormat.SamplesPerSecond * waveFormat.Channels;
              char[] buffer = new char[samples];
  
              // Set buffer length 
              bufferDesc.BufferBytes = buffer.Length * waveFormat.BlockAlign;
  
              // Set initial amplitude and frequency 
              double frequency = 500;
              double amplitude = short.MaxValue / 3;
              double two_pi = 2 * Math.PI;
              // Iterate through time 
              for (int i = 0; i &lt; buffer.Length; i++)
              {
                  // Add to sine 
                  buffer[i] = (char)(amplitude *
                      Math.Sin(i * two_pi * frequency / waveFormat.SamplesPerSecond));
              }
  
              SecondaryBuffer bufferSound = new SecondaryBuffer(bufferDesc, d);
              bufferSound.Volume = (int)Volume.Max;
              bufferSound.Write(0, buffer, LockFlag.None);
              bufferSound.Play(0, BufferPlayFlags.Default);
              System.Threading.Thread.Sleep(10000);
          }
      }
  }
  </code></pre>
  
  <p>By my calculations, this should play for 5 seconds.  It plays for half-time.  If I change</p>
  
  <pre><code> int samples = 5 * waveFormat.SamplesPerSecond * waveFormat.Channels;
  </code></pre>
  
  <p>to </p>
  
  <pre><code>  int samples = 5 * waveFormat.SamplesPerSecond * waveFormat.Channels
        * waveFormat.BlockAlign;
  </code></pre>
  
  <p>Then the sound works alright, but that's an hack, right?  Surely I'm doing something wrong, but I can't tell what.</p>
  
  <p>Thanks for your time.</p>