using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; namespace GetCardData { public class WavFile { private string _fileName; private FileStream _reader; private WavFormatInformation _info; private long _numberOfSamples; private long _dataPosition; public class WavFormatInformation { private FormatCode _formatCode; private ushort _numberOfChannels; private uint _samplingRate; private uint _dataRate; private ushort _blockSize; private ushort _bitsPerSample; public enum FormatCode { WAVE_FORMAT_PCM = 0x0001, WAVE_FORMAT_IEEE_FLOAT = 0x0003, WAVE_FORMAT_ALAW = 0x0006, WAVE_FORMAT_MULAW = 0x0007, WAVE_FORMAT_EXTENSIBLE = 0xFFFE }; public WavFormatInformation(byte[] fmt) { _formatCode = (FormatCode)BitConverter.ToLEUShort16(fmt, 0); _numberOfChannels = BitConverter.ToLEUShort16(fmt, 2); _samplingRate = BitConverter.ToLEUInt32(fmt, 4); _dataRate = BitConverter.ToLEUInt32(fmt, 8); _blockSize = BitConverter.ToLEUShort16(fmt, 12); _bitsPerSample = BitConverter.ToLEUShort16(fmt, 14); } }; public WavFormatInformation Info { get { return _info; } } public bool IsAtEndOfFile { get { return (_reader.Position >= _reader.Length); } } public long DataStartPosition { get { return _dataPosition; } } public WavFile(string fileName) { if (!IsValidWavFile(fileName)) throw new InvalidOperationException("Not a valid WAV file"); _fileName = fileName; _reader = new FileStream(fileName, FileMode.Open); //Start reading chunks _reader.Seek(12, SeekOrigin.Begin); bool foundFmt = false; bool foundData = false; byte[] tag = new byte[4]; byte[] size = new byte[4]; do { _reader.Read(tag, 0, 4); _reader.Read(size, 0, 4); switch (BitConverter.ToString(tag, 0, 4)) { case "fmt ": { foundFmt = true; long backup = _reader.Position; byte[] fmt = new byte[16]; _reader.Read(fmt, 0, fmt.Length); _info = new WavFormatInformation(fmt); _reader.Seek(BitConverter.ToLEUInt32(size, 0) + backup, SeekOrigin.Begin); break; } case "data": { foundData = true; _dataPosition = _reader.Position; _reader.Seek(BitConverter.ToLEUInt32(size, 0), SeekOrigin.Current); _numberOfSamples = BitConverter.ToLEUInt32(size, 0) / 2; break; } } } while (!foundFmt || !foundData); //Seek to start of DATA chunk _reader.Seek(_dataPosition, SeekOrigin.Begin); } public void Seek(long position) { _reader.Seek(position, SeekOrigin.Begin); } public short[] GetSamples(int count) { byte[] raw = new byte[count * 2]; short[] ret = new short[count]; _reader.Read(raw, 0, count * 2); int j = 0; for (int i = 0; i < raw.Length; i += 2) { ret[j] = (short)(raw[i] | ((raw[i + 1] << 8) & 0xFF00)); j++; } return ret; } public void Close() { _reader.Close(); } public static bool IsValidWavFile(string fileName) { bool ret = false; if (File.Exists(fileName)) { if (Path.GetExtension(fileName).ToLower().Trim(new char[] { '.' }) == "wav") { var file = new BinaryReader(new FileStream(fileName, FileMode.Open)); string header = new String(file.ReadChars(4)); var size = file.ReadBytes(4); string waveHeader = new String(file.ReadChars(4)); file.Close(); if (header == "RIFF" && waveHeader == "WAVE") ret = true; } } return ret; } } }