/// <summary>Reads a new WAVE format section from the specified stream.</summary> /// <param name="preRead">Pre-parsed <see cref="RiffChunk"/> header.</param> /// <param name="source">Source stream to read data from.</param> /// <param name="waveFormat">Format of the data section to be parsed.</param> /// <exception cref="InvalidOperationException">WAVE format or extra parameters section too small, wave file corrupted.</exception> public WaveDataChunk(RiffChunk preRead, Stream source, WaveFormatChunk waveFormat) : base(preRead, RiffTypeID) { m_waveFormat = waveFormat; m_sampleBlocks = new List<LittleBinaryValue[]>(); int blockSize = waveFormat.BlockAlignment; int sampleSize = waveFormat.BitsPerSample / 8; byte[] buffer = new byte[blockSize]; int channels = waveFormat.Channels; TypeCode sampleTypeCode = m_waveFormat.GetSampleTypeCode(); LittleBinaryValue[] sampleBlock; int bytesRead = source.Read(buffer, 0, blockSize); while (bytesRead == blockSize) { // Create a new sample block, one little-endian formatted binary sample value for each channel sampleBlock = new LittleBinaryValue[channels]; for (int x = 0; x < channels; x++) { sampleBlock[x] = new LittleBinaryValue(sampleTypeCode, buffer, x * sampleSize, sampleSize); } m_sampleBlocks.Add(sampleBlock); bytesRead = source.Read(buffer, 0, blockSize); } }
/// <summary>Reads a new RIFF header from the specified stream.</summary> /// <param name="preRead">Pre-parsed <see cref="RiffChunk"/> header.</param> /// <param name="source">Source stream to read data from.</param> /// <param name="format">Expected RIFF media format (e.g., "WAVE").</param> /// <exception cref="ArgumentNullException"><paramref name="format"/> cannot be null.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="format"/> must be extactly 4 characters in length.</exception> public RiffHeaderChunk(RiffChunk preRead, Stream source, string format) : base(preRead, RiffTypeID) { Format = format; int length = BinaryLength - preRead.BinaryLength; byte[] buffer = new byte[length]; int bytesRead = source.Read(buffer, 0, length); if (bytesRead < length) throw new InvalidOperationException("RIFF format section too small, media file corrupted."); // Read and validate format stored in RIFF section format = Encoding.ASCII.GetString(buffer, 0, 4); if (format != Format) throw new InvalidDataException(string.Format("{0} format expected but got {1}, this does not appear to be a valid {0} file", Format, format)); m_format = format; }
/// <summary>Reads a new WAVE format section from the specified stream.</summary> /// <param name="preRead">Pre-parsed RIFF chunk header.</param> /// <param name="source">Source stream to read data from.</param> /// <exception cref="InvalidOperationException">WAVE format or extra parameters section too small, wave file corrupted.</exception> public WaveFormatChunk(RiffChunk preRead, Stream source) : base(preRead, RiffTypeID) { int length = ChunkSize; byte[] buffer = new byte[length]; int bytesRead = source.Read(buffer, 0, length); if (bytesRead < length) throw new InvalidOperationException("WAVE format section too small, wave file corrupted."); m_audioFormat = EndianOrder.LittleEndian.ToUInt16(buffer, 0); m_channels = EndianOrder.LittleEndian.ToInt16(buffer, 2); m_sampleRate = EndianOrder.LittleEndian.ToInt32(buffer, 4); m_byteRate = EndianOrder.LittleEndian.ToInt32(buffer, 8); m_blockAlignment = EndianOrder.LittleEndian.ToInt16(buffer, 12); m_bitsPerSample = EndianOrder.LittleEndian.ToInt16(buffer, 14); if (m_bitsPerSample % 8 != 0) throw new InvalidDataException("Invalid bit rate encountered - wave file bit rates must be a multiple of 8"); if (length > 16) { m_extraParametersSize = EndianOrder.LittleEndian.ToInt16(buffer, 16); // Read extra parameters, if any if (m_extraParametersSize > 0) { m_extraParameters = new byte[m_extraParametersSize]; bytesRead = source.Read(m_extraParameters, 0, m_extraParametersSize); if (bytesRead < m_extraParametersSize) throw new InvalidOperationException("WAVE extra parameters section too small, wave file corrupted."); } } }
protected RiffChunk(RiffChunk preRead, string typeID) { if (typeID != preRead.TypeID) throw new InvalidDataException(string.Format("{0} chunk expected but got {1}, file does not appear to be valid.", typeID, preRead.TypeID)); m_typeID = preRead.TypeID; m_chunkSize = preRead.ChunkSize; }
// Static Methods public static RiffChunk ReadNext(Stream source) { RiffChunk riffChunk = new RiffChunk(); int length = riffChunk.BinaryLength; byte[] buffer = new byte[length]; int bytesRead = source.Read(buffer, 0, length); if (bytesRead < length) throw new InvalidOperationException("RIFF chunk too small, media file corrupted."); riffChunk.TypeID = Encoding.ASCII.GetString(buffer, 0, 4); riffChunk.ChunkSize = EndianOrder.LittleEndian.ToInt32(buffer, 4); return riffChunk; }
public RiffChunk Clone() { RiffChunk riffChunk = new RiffChunk(m_typeID); riffChunk.ChunkSize = m_chunkSize; return riffChunk; }