//WriteFloatingRIFF // Subroutine to Write a RIFF waveform to a memory Stream (no disc access) public bool WriteRIFFStream(ref MemoryStream WaveStream, int intSampleRate, int intFmtChunkLength, ref byte[] aryWaveData) { //************************************************************************* // Here is where the file will be created. A // wave file is a RIFF file, which has chunks // of data that describe what the file contains. // A wave RIFF file is put together like this: // The 12 byte RIFF chunk is constructed like this: // Bytes(0 - 3) 'R' 'I' 'F' 'F' // Bytes 4 - 7 : Length of file, minus the first 8 bytes of the RIFF description. // (4 bytes for "WAVE" + 24 bytes for format chunk length + // 8 bytes for data chunk description + actual sample data size.) // Bytes(8 - 11) 'W' 'A' 'V' 'E' // The 24 byte FORMAT chunk is constructed like this: // Bytes(0 - 3) 'f' 'm' 't' ' ' // Bytes 4 - 7 : The format chunk length. This is 16 or 18 // Bytes 8 - 9 : File padding. Always 1. // Bytes 10- 11: Number of channels. Either 1 for mono, or 2 for stereo. // Bytes 12- 15: Sample rate. // Bytes 16- 19: Number of bytes per second. // Bytes 20- 21: Bytes per sample. 1 for 8 bit mono, 2 for 8 bit stereo or // 16 bit mono, 4 for 16 bit stereo. // Bytes 22- 23: Number of bits per sample. // The DATA chunk is constructed like this: // Bytes(0 - 3) 'd' 'a' 't' 'a' // Bytes 4 - 7 : Length of data, in bytes. // Bytes 8 -...: Actual sample data. //************************************************************************** //TODO: Test of "back porch" extension for PTT //ReDim Preserve aryWaveData(aryWaveData.Length + 1023) ' Adds 42.6 ms additional dead time before removal of PTT byte[] bytTemp = new byte[-1 + 1]; if (intFmtChunkLength == 16) { if ((WaveStream != null)) { WaveStream.Flush(); } WaveStream = new MemoryStream(43 + aryWaveData.Length); } else if (intFmtChunkLength == 18) { if ((WaveStream != null)) { WaveStream.Flush(); } WaveStream = new MemoryStream(45 + aryWaveData.Length); } else { return(false); } // Set up file with RIFF chunk info. short shPad = 1; // File padding int intLength = 0; if (intFmtChunkLength == 16) { intLength = aryWaveData.Length + 36; // File length, minus first 8 bytes of RIFF description. } else if (intFmtChunkLength == 18) { intLength = aryWaveData.Length + 38; // File length, minus first 8 bytes of RIFF description. } short shBytesPerSample = 2; // Bytes per sample. // Fill in the riff info for the wave file. AppendBytes(ref bytTemp, Globals.GetBytes("RIFF")); AppendBytes(ref bytTemp, Int32ToBytes(intLength)); AppendBytes(ref bytTemp, Globals.GetBytes("WAVE")); AppendBytes(ref bytTemp, Globals.GetBytes("fmt ")); AppendBytes(ref bytTemp, Int32ToBytes(intFmtChunkLength)); AppendBytes(ref bytTemp, Int16ToBytes(shPad)); AppendBytes(ref bytTemp, Int16ToBytes(1)); // mono AppendBytes(ref bytTemp, Int32ToBytes(intSampleRate)); AppendBytes(ref bytTemp, Int32ToBytes(2 * intSampleRate)); AppendBytes(ref bytTemp, Int16ToBytes(2)); // bytes/sample if (intFmtChunkLength == 18) { AppendBytes(ref bytTemp, Int16ToBytes(2)); // bytes/sample } AppendBytes(ref bytTemp, Int16ToBytes(16)); // bits/sample // DateTime.Now fill in the data chunk. AppendBytes(ref bytTemp, Globals.GetBytes("data")); AppendBytes(ref bytTemp, Int32ToBytes(aryWaveData.Length)); AppendBytes(ref bytTemp, aryWaveData); WaveStream.Write(bytTemp, 0, bytTemp.Length); return(true); }