#region --- License ---
/* Licensed under the MIT/X11 license.
* Copyright (c) 2006-2008 the OpenTK Team.
* This notice may not be removed from any source distribution.
* See license.txt for licensing details.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace OpenTK.Audio
{
///
/// Encapsulates a sound stream and provides decoding and streaming capabilities.
///
///
public class SoundReader : IDisposable
{
static object reader_lock = new object();
static List readers = new List();
bool disposed;
Stream stream;
SoundReader implementation;
#region --- Constructors ---
#region static SoundReader()
static SoundReader()
{
// TODO: Plugin architecture for sound formats. This is overkill now that we only have a WaveLoader (future proofing).
readers.Add(new WaveReader());
}
#endregion
#region protected SoundReader()
protected SoundReader() { }
#endregion
#region public SoundReader(string filename)
/// Creates a new SoundReader that can read the specified sound file.
/// The path to the sound file.
/// A new OpenTK.Audio.SoundReader, which can be used to read from the specified sound file.
public SoundReader(string filename)
: this(new FileStream(filename, FileMode.Open))
{ }
#endregion
#region public SoundReader(Stream s)
/// Creates a new SoundReader that can read the specified soundstream.
/// The System.IO.Stream to read from.
/// A new OpenTK.Audio.SoundReader, which can be used to read from the specified sound stream.
public SoundReader(Stream s)
{
try
{
lock (reader_lock)
{
foreach (SoundReader reader in readers)
{
long pos = s.Position;
if (reader.Supports(s))
{
s.Position = pos;
implementation = (SoundReader)
reader.GetType().GetConstructor(
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Instance,
null,
new Type[] { typeof(Stream) },
null)
.Invoke(new object[] { s });
return;
}
s.Position = pos;
}
}
}
catch (Exception e)
{
s.Close();
throw;
}
throw new NotSupportedException("Could not find a decoder for the specified sound stream.");
}
#endregion
#endregion
#region --- Public Members ---
#region public virtual bool Supports(Stream s)
/// When overriden in a derived class, checks if the decoder supports the specified sound stream.
/// The System.IO.Stream to check.
/// True if the sound stream is supported; false otherwise.
public virtual bool Supports(Stream s)
{
if (implementation != null)
return implementation.Supports(s);
throw new NotImplementedException();
}
#endregion
#region public virtual SoundData ReadSamples(long count)
///
/// When overriden in a derived class, reads and decodes the specified number of samples from the sound stream.
///
/// The number of samples to read and decode.
/// An OpenTK.Audio.SoundData object that contains the decoded buffer.
public virtual SoundData ReadSamples(long count)
{
if (implementation != null)
return implementation.ReadSamples(count);
throw new NotImplementedException();
}
#endregion
#region public virtual SoundData ReadToEnd()
///
/// When overriden in a derived class, reads and decodes the sound stream.
///
/// An OpenTK.Audio.SoundData object that contains the decoded buffer.
public virtual SoundData ReadToEnd()
{
if (implementation != null)
return implementation.ReadToEnd();
throw new NotImplementedException();
}
#endregion
#region public virtual int Frequency
///
///
///
public virtual int Frequency
{
get
{
if (implementation != null)
return implementation.Frequency;
else
throw new NotImplementedException();
}
protected set
{
if (implementation != null)
implementation.Frequency = value;
else
throw new NotImplementedException();
}
}
#endregion
#region public bool EndOfFile
public bool EndOfFile
{
get { return stream.Position >= stream.Length; }
}
#endregion
#endregion
#region --- Protected Members ---
protected virtual Stream Stream
{
get { return stream; }
set { stream = value; }
}
#endregion
#region IDisposable Members
/// Closes the underlying Stream and disposes of the SoundReader resources.
public virtual void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
void Dispose(bool manual)
{
if (!disposed)
{
if (manual)
if (this.Stream != null)
this.Stream.Close();
disposed = true;
}
}
~SoundReader()
{
this.Dispose(false);
}
#endregion
}
}