|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// This material may not be duplicated in whole or in part, except for
// personal use, without the express written consent of the author.
//
// Email: ianier@hotmail.com
//
// Copyright (C) 1999-2003 Ianier Munoz. All Rights Reserved.
//
// Istrib: fixed disposal removing hiding IDispose method and overriding Dispose(bool).
using System;
using System.IO;
namespace WaveLib
{
/// <summary>
/// Reads a Wave data (including header returned via Format property).
/// </summary>
public class WaveStream : Stream
{
private Stream m_Stream;
private long m_DataPos;
private long m_Length;
private WaveFormat m_Format;
public WaveFormat Format
{
get { return m_Format; }
}
private string ReadChunk(BinaryReader reader)
{
byte[] ch = new byte[4];
reader.Read(ch, 0, ch.Length);
return System.Text.Encoding.ASCII.GetString(ch);
}
private void ReadHeader()
{
BinaryReader Reader = new BinaryReader(m_Stream);
if (ReadChunk(Reader) != "RIFF")
throw new Exception("Invalid file format");
Reader.ReadInt32(); // File length minus first 8 bytes of RIFF description, we don't use it
if (ReadChunk(Reader) != "WAVE")
throw new Exception("Invalid file format");
if (ReadChunk(Reader) != "fmt ")
throw new Exception("Invalid file format");
int FormatLength = Reader.ReadInt32();
if ( FormatLength < 16) // bad format chunk length
throw new Exception("Invalid file format");
m_Format = new WaveFormat(22050, 16, 2); // initialize to any format
m_Format.wFormatTag = Reader.ReadInt16();
m_Format.nChannels = Reader.ReadInt16();
m_Format.nSamplesPerSec = Reader.ReadInt32();
m_Format.nAvgBytesPerSec = Reader.ReadInt32();
m_Format.nBlockAlign = Reader.ReadInt16();
m_Format.wBitsPerSample = Reader.ReadInt16();
if ( FormatLength > 16)
{
m_Stream.Position += (FormatLength-16);
}
// assume the data chunk is aligned
while(m_Stream.Position < m_Stream.Length && ReadChunk(Reader) != "data")
;
if (m_Stream.Position >= m_Stream.Length)
throw new Exception("Invalid file format");
m_Length = Reader.ReadInt32();
m_DataPos = m_Stream.Position;
Position = 0;
}
public WaveStream(string fileName) : this(new FileStream(fileName, FileMode.Open))
{
}
public WaveStream(Stream S)
{
m_Stream = S;
ReadHeader();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
m_Stream.Close();
}
}
public override bool CanRead
{
get { return true; }
}
public override bool CanSeek
{
get { return true; }
}
public override bool CanWrite
{
get { return false; }
}
public override long Length
{
get { return m_Length; }
}
public override long Position
{
get { return m_Stream.Position - m_DataPos; }
set { Seek(value, SeekOrigin.Begin); }
}
public override void Flush()
{
}
public override void SetLength(long len)
{
throw new InvalidOperationException();
}
public override long Seek(long pos, SeekOrigin o)
{
switch(o)
{
case SeekOrigin.Begin:
m_Stream.Position = pos + m_DataPos;
break;
case SeekOrigin.Current:
m_Stream.Seek(pos, SeekOrigin.Current);
break;
case SeekOrigin.End:
m_Stream.Position = m_DataPos + m_Length - pos;
break;
}
return this.Position;
}
public override int Read(byte[] buf, int ofs, int count)
{
int toread = (int)Math.Min(count, m_Length - Position);
return m_Stream.Read(buf, ofs, toread);
}
public override void Write(byte[] buf, int ofs, int count)
{
throw new InvalidOperationException();
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I am a .NET developer, working currently in the UK, though still strongly associated with Poland. Primary interests: business application, server-side, enterprise-scale solutions, SOA, thin but rich internet clients (Silverlight).
Apart from my everyday work, I spend a lot of time validating design patterns for newer technologies (like Silverlight, WCF, LINQ). My warzone is
www.nauka-slowek.org - a proof of concept for asynchrony, internet multimedia and command pattern in client-server apps. I also use that website myself as it is a great tool to effectively learn vocabulary (foreign languages), which aids my long being abroad.