using System; using System.Collections.Generic; using System.Linq; using System.IO; using System.Text; using System.Collections; using System.Collections.Specialized; namespace CrashDumpSender { public class WaveFileReader : IDisposable { BinaryReader m_reader; public riffChunk m_mainfile; public fmtChunk m_format; public dataChunk m_data; uint m_headerOffset; uint m_headerSize; uint m_dataOffset; uint m_dataSize; public WaveFileReader(string filename) { m_reader = new BinaryReader(new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read)); } public uint getHeaderOffset() { return m_headerOffset; } public uint getHeaderSize() { return m_headerSize; } public uint getDataOffset() { return m_dataOffset; } public uint getDataSize() { return m_dataSize; } public void seek(long position) { m_reader.BaseStream.Seek(position, SeekOrigin.Begin); } public void AdvanceToNext() { long NextOffset = (long)m_reader.ReadUInt32(); m_reader.BaseStream.Seek(NextOffset, SeekOrigin.Current); } #region Header Extraction Methods public long GetPosition() { return m_reader.BaseStream.Position; } public string GetChunkName() { return new string(m_reader.ReadChars(4)); } public byte[] copyData(uint count) { return m_reader.ReadBytes((int)count); } public void read() { WaveFile contents = new WaveFile(); contents.maindata = ReadMainFileHeader(); while (GetPosition() < (long)contents.maindata.dwFileLength) { string chunkName = GetChunkName(); uint chunckSize = m_reader.ReadUInt32(); if (chunkName == "fmt ") { m_headerOffset = (uint) GetPosition(); m_headerSize = chunckSize; contents.format = ReadFormatHeader(chunckSize); if (GetPosition() + chunckSize >= contents.maindata.dwFileLength) break; } else if (chunkName == "data") { m_dataOffset = (uint) GetPosition(); m_dataSize = chunckSize; contents.data = ReadDataHeader(chunckSize); if (GetPosition() + chunckSize >= contents.maindata.dwFileLength) break; } else { AdvanceToNext(); } } } public riffChunk ReadMainFileHeader() { m_mainfile = new riffChunk(); m_mainfile.sGroupID = new string(m_reader.ReadChars(4)); m_mainfile.dwFileLength = m_reader.ReadUInt32() + 8; m_mainfile.sRiffType = new string(m_reader.ReadChars(4)); return m_mainfile; } public fmtChunk ReadFormatHeader(uint count) { m_format = new fmtChunk(); m_format.sChunkID = "fmt "; m_format.dwChunkSize = count; m_format.wFormatTag = m_reader.ReadUInt16(); m_format.wChannels = m_reader.ReadUInt16(); m_format.dwSamplesPerSec = m_reader.ReadUInt32(); m_format.dwAvgBytesPerSec = m_reader.ReadUInt32(); m_format.wBlockAlign = m_reader.ReadUInt16(); m_format.wBitsPerSample = m_reader.ReadUInt16(); m_format.cbSize = 0; if ( m_format.dwChunkSize > 0x10 ) // sizeof(WAVEFORMAT) ) { byte c = new byte(); uint difference = m_format.dwChunkSize - 0x10; // sizeof(WAVEFORMAT) ) for (int i = 0; i < difference; ++i) c = m_reader.ReadByte(); } return m_format; } public dataChunk ReadDataHeader(uint count) { m_data = new dataChunk(); m_data.sChunkID = "data"; m_data.dwChunkSize = count; m_data.lFilePosition = m_reader.BaseStream.Position; m_data.dwNumSamples = m_data.dwChunkSize / (((uint)m_format.wBitsPerSample) / 8 * m_format.wChannels); m_data.dwMinLength = (m_data.dwChunkSize / m_format.dwAvgBytesPerSec) / 60; m_data.dSecLength = ((double)m_data.dwChunkSize / (double)m_format.dwAvgBytesPerSec); return m_data; } #endregion #region IDisposable Members public void Dispose() { if (m_reader != null) m_reader.Close(); } #endregion } }