title: Problem writing binary data with ofstream
body: <p>Hey all, I'm writing an application which records microphone input to a WAV file. Previously, I had written this to fill a buffer of a specified size and that worked fine.  Now, I'd like to be able to record to an arbitrary length.  Here's what I'm trying to do:</p>
  
  <ul>
  <li>Set up 32 small audio buffers (circular buffering)</li>
  <li>Start a WAV file with ofstream -- write the header with PCM length set to 0</li>
  <li>Add a buffer to input</li>
  <li>When a buffer completes, append its data to the WAV file and update the header; recycle the buffer</li>
  <li>When the user hits "stop", write the remaining buffers to file and close</li>
  </ul>
  
  <p>It kind of works in that the files are coming out to the correct length (header and file size and are correct).  However, the data is wonky as hell.  I can make out a semblance of what I said -- and the timing is correct -- but there's this repetitive block of distortion.  It basically sounds like only half the data is getting into the file.</p>
  
  <p>Here are some variables the code uses (in header)</p>
  
  <pre><code>// File writing
  ofstream mFile;
  WAVFILEHEADER mFileHeader;
  int16_t * mPcmBuffer;
  int32_t mPcmBufferPosition;
  int32_t mPcmBufferSize;
  uint32_t mPcmTotalSize;
  bool mRecording;
  </code></pre>
  
  <p>Here is the code that prepares the file:</p>
  
  <pre><code>// Start recording audio
  void CaptureApp::startRecording()
  {
  
      // Set flag
      mRecording = true;
  
      // Set size values
      mPcmBufferPosition = 0;
      mPcmTotalSize = 0;
  
      // Open file for streaming
      mFile.open("c:\my.wav", ios::binary|ios::trunc);
  
  }
  </code></pre>
  
  <p>Here's the code that receives the buffer.  This assumes the incoming data is correct -- it <em>should</em> be, but I haven't ruled out that it isn't.</p>
  
  <pre><code>// Append file buffer to output WAV
  void CaptureApp::writeData()
  {
  
      // Update header with new PCM length
      mPcmBufferPosition *= sizeof(int16_t);
      mPcmTotalSize += mPcmBufferPosition;
      mFileHeader.bytes = mPcmTotalSize + sizeof(WAVFILEHEADER);
      mFileHeader.pcmbytes = mPcmTotalSize;
      mFile.seekp(0);
      mFile.write(reinterpret_cast&lt;char *&gt;(&amp;mFileHeader), sizeof(mFileHeader));
  
      // Append PCM data
      if (mPcmBufferPosition &gt; 0)
      {
          mFile.seekp(mPcmTotalSize - mPcmBufferPosition + sizeof(WAVFILEHEADER));
          mFile.write(reinterpret_cast&lt;char *&gt;(&amp;mPcmBuffer), mPcmBufferPosition);
      }
  
      // Reset file buffer position
      mPcmBufferPosition = 0;
  
  }
  </code></pre>
  
  <p>And this is the code that closes the file:</p>
  
  <pre><code>// Stop recording
  void CaptureApp::stopRecording()
  {
  
      // Save remaining data
      if (mPcmBufferSize &gt; 0) 
          writeData();
  
      // Close file
      if (mFile.is_open())
      {
          mFile.flush();
          mFile.close();
      }
  
      // Turn off recording flag
      mRecording = false;
  
  }
  </code></pre>
  
  <p>If there's anything here that looks like it would result in bad data getting appended to the file, please let me know.  If not, I'll triple check the input data (in the callback).  This data <em>should</em> be good, because it works if I copy it to a larger buffer (eg, two minutes) and then save that out.</p>