title: Writing the wav header for multiple channels
body: <p>Following the <a href="https://ccrma.stanford.edu/courses/422/projects/WaveFormat/" rel="nofollow">wave file standard</a> to record audio data with Kinect, I wrote a <code>WriteWavHeader()</code> method which works perfect for 1 channel (PCM, Sample rate: 16 kHz, Bits/sample: 16). The problem is that when I try to record in stereo (<code>nChannels = 2</code>) it seems like the speed of the track doubles! Any ideas what I am doing wrong?</p>
  
  <pre><code>static void WriteWavHeader(Stream stream, int dataLength)
  {
      using (var memStream = new MemoryStream(64))
      {
          int cbFormat = 16; //sizeof(WAVEFORMATEX)
          WAVEFORMATEX format = new WAVEFORMATEX()
          {
              //Subchunk1Size ==  16 for PCM.
              wFormatTag = 1,
  
              //NumChannels  :    Mono = 1, Stereo = 2, etc.
              nChannels = 2,
  
              //SampleRate       8000, 44100
              nSamplesPerSec = 16000,
  
              //ByteRate         == SampleRate * NumChannels * BitsPerSample/8
              nAvgBytesPerSec = 32000*2,
  
              //BlockAlign       == NumChannels * BitsPerSample/8
              nBlockAlign = 2*2,
  
              //BitsPerSample    8 bits = 8, 16 bits = 16, etc.
              wBitsPerSample = 16
          };
  
          using (var binarywriter = new BinaryWriter(memStream))
          {
              //RIFF header
              WriteString(memStream, "RIFF");
              binarywriter.Write(dataLength+8 + cbFormat+8 + 4); 
              WriteString(memStream, "WAVE");
              WriteString(memStream, "fmt ");
              binarywriter.Write(cbFormat);
  
              //WAVEFORMATEX
              binarywriter.Write(format.wFormatTag);
              binarywriter.Write(format.nChannels);
              binarywriter.Write(format.nSamplesPerSec);
              binarywriter.Write(format.nAvgBytesPerSec);
              binarywriter.Write(format.nBlockAlign);
              binarywriter.Write(format.wBitsPerSample);
  
              //data header
              WriteString(memStream, "data");
  
              binarywriter.Write(dataLength);
              memStream.WriteTo(stream);
          }
      }
  }
  </code></pre>
  
  <p>And the recording method:</p>
  
  <pre><code>public void RecordAudio()
  {
      //Subchunk2Size    == NumSamples * NumChannels * BitsPerSample/8
      int recordingLength = 5 *16000* 2 *2;
      byte[] buffer = new byte[1024];
  
      using (FileStream _fileStream = new FileStream("c:\\kinectAudio.wav", FileMode.Create))
      {
          WriteWavHeader(_fileStream, recordingLength);
          int count, totalCount = 0;
          //Start capturing audio                               
          using (Stream audioStream = this.sensor.AudioSource.Start())
          {
  
              while ((count = audioStream.Read(buffer, 0, buffer.Length)) &gt; 0 &amp;&amp; totalCount &lt; recordingLength)
              {
                  _fileStream.Write(buffer, 0, count);
                  totalCount += count;
              }
          }
           //write the real wav header
          long prePosition = _fileStream.Position;
          _fileStream.Seek(0, SeekOrigin.Begin);
          WriteWavHeader(_fileStream, totalCount);
          _fileStream.Seek(prePosition, SeekOrigin.Begin);
          _fileStream.Flush();         
      }
  }
  </code></pre>