title: Generating WAV File Tones
body: <p>I'm trying to programmatically construct an audio WAV file that contains <em>n</em> seconds of the standard UK ring ring tone that you hear when you dial a phone number.</p>
  
  <p>I have <a href="http://www-users.cs.york.ac.uk/~fisher/telecom/tones/" rel="nofollow">found a source</a> that documents the frequencies and duration of the tone, which is a sine wave of two frequencies: 400Hz and 450Hz.</p>
  
  <p>The code I have written generates a PCM WAV file in the correct format, which I can play using an audio player such as Windows Media Player, however the tone that it generates sounds like a much lower frequency than it should be, so don't think I've got the forumla quite right.</p>
  
  <p>This is currently what I'm doing:</p>
  
  <pre><code>var duration = 10;
  var bitsPerSample = 8;
  var samplesPerSec = 8000;
  var f1 = 400;
  var f2 = 450;
  var pattern = new[] {
              TimeSpan.FromMilliseconds(400),
              TimeSpan.FromMilliseconds(200),
              TimeSpan.FromMilliseconds(400),
              TimeSpan.FromMilliseconds(2000)
          };
  
  var wavdata = new byte[duration * samplesPerSec]; // 10 seconds of wav data @ 8000 samples per sec, 8 bits per sample, 1 channel 
  
  // Loop through each sample
  for (var i = 0; i &lt; wavdata.Length; i = i + (bitsPerSample / 8)) {
  
      // Get time in seconds of the current sample
      var time = Convert.ToDouble(i) / (Convert.ToDouble(bitsPerSample) / 8) / samplesPerSec;
  
      // Calculate the on off pattern
      var onoff = 0;
      var timeMilliseconds = time * 1000;
      var p = 0;
      while (timeMilliseconds &gt;= 0) {
          timeMilliseconds = timeMilliseconds - pattern[p].TotalMilliseconds;
          onoff = onoff == 1 ? 0 : 1;
          if (++p &gt;= pattern.Length) p = 0;
      }
  
      // Calculate the sample: (sin(time * 400) * 128 + sin(time * 450) * 128)) / 2
      var sample = onoff * (((Math.Sin(time * f1) * 128) + (Math.Sin(time * f2) * 128)) / 2);
  
      // Store sample
      wavdata[i] = Convert.ToByte(sample + 128);
  
  }
  </code></pre>
  
  <p>As you can see the formula I'm using is:</p>
  
  <pre><code>sin(time-of-sample * frequency) * amplitude
  </code></pre>
  
  <p>which I use twice for the two combined frequencies:</p>
  
  <pre><code>sin(time * 400) * 128
  sin(time * 450) * 128
  </code></pre>
  
  <p>I then add them together and divide by 2 to get the average. I then multiply by 1 or 0 to get silence in between the tones to get the ring ring sound. And finially I offset the sample by 128 when I store the value in the data array as WAV file data is represented as plus or minus data.</p>
  
  <p>What am I doing wrong? Why is the tone that this generates much lower in pitch than expected?</p>