private void WriteWaveHeader()
{
if (_raw)
{
// Don't write any header for RAW files...
_doneHeader = true;
return;
}
ushort nChannels = NumChannels;
if (nChannels == 0)
{
throw new NotSupportedException("Number of channels cannot be zero");
}
ushort bPerSample = BitsPerSample;
if (bPerSample == 0)
{
throw new NotSupportedException("Bits per sample cannot be zero");
}
uint sRate = SampleRate;
if (sRate == 0)
{
throw new NotSupportedException("Sample rate cannot be zero");
}
ushort blockSize = (ushort)((nChannels * bPerSample) / 8);
uint dataSize = (uint)(Iterations * blockSize);
uint fmtSize = (uint)(_audioFormat == WaveFormat.EXTENSIBLE ? 40 : 16);
// Write Riff ///////////////////////////////////////////////
_w.Write('R');
_w.Write('I');
_w.Write('F');
_w.Write('F');
// RIFF size: size of the rest of the riff chunk following this
// = size of "WAVE" + size of 'fmt' + size of "DATA" + datasize
// = size of the entire file (bytes) - 8
uint riffSize = 4 + (8 + fmtSize) + (8 + dataSize);
_w.Write((uint)riffSize);
// Write Wave //////////////////////////////////////////////
_w.Write('W');
_w.Write('A');
_w.Write('V');
_w.Write('E');
// Write Format ////////////////////////////////////////////
_w.Write('f');
_w.Write('m');
_w.Write('t');
_w.Write(' ');
_w.Write((uint)fmtSize); // size of the fmt block
_w.Write((ushort)_audioFormat); // wave format
_w.Write((ushort)nChannels); // Number of channels
_w.Write((uint)sRate); // SampleRate (Hz)
_w.Write((uint)(blockSize * sRate)); //ByteRate
_w.Write((ushort)blockSize); //BlockAlign
_w.Write((ushort)bPerSample); //BitsPerSample
if (_audioFormat == WaveFormat.EXTENSIBLE)
{
_w.Write((UInt16)22); // size of this block
_w.Write((UInt16)bPerSample); // union{} = valid bits per sample, in this case
_w.Write((UInt32)_channelMask); // channel mask
_w.Write(_formatEx.guid.ToByteArray()); // GUID, 16 bytes
}
// Write Data ///////////////////////////////////////////////
_w.Write('d');
_w.Write('a');
_w.Write('t');
_w.Write('a');
// Write Data Size //////////////////////////////////////////
_w.Write((uint)dataSize);
_doneHeader = true;
}