Opentk/Source/Examples/OpenAL/1.1/Playback.cs
2011-01-18 11:40:49 +00:00

111 lines
4.1 KiB
C#

// This code was written for the OpenTK library and has been released
// to the Public Domain.
// It is provided "as is" without express or implied warranty of any kind.
using System;
using System.Diagnostics;
using System.Threading;
using System.IO;
using OpenTK.Audio;
using OpenTK.Audio.OpenAL;
namespace Examples
{
[Example("Playback", ExampleCategory.OpenAL, "1.1", Documentation="Playback")]
public class Playback
{
static readonly string filename = Path.Combine(Path.Combine("Data", "Audio"), "the_ring_that_fell.wav");
// Loads a wave/riff audio file.
public static byte[] LoadWave(Stream stream, out int channels, out int bits, out int rate)
{
if (stream == null)
throw new ArgumentNullException("stream");
using (BinaryReader reader = new BinaryReader(stream))
{
// RIFF header
string signature = new string(reader.ReadChars(4));
if (signature != "RIFF")
throw new NotSupportedException("Specified stream is not a wave file.");
int riff_chunck_size = reader.ReadInt32();
string format = new string(reader.ReadChars(4));
if (format != "WAVE")
throw new NotSupportedException("Specified stream is not a wave file.");
// WAVE header
string format_signature = new string(reader.ReadChars(4));
if (format_signature != "fmt ")
throw new NotSupportedException("Specified wave file is not supported.");
int format_chunk_size = reader.ReadInt32();
int audio_format = reader.ReadInt16();
int num_channels = reader.ReadInt16();
int sample_rate = reader.ReadInt32();
int byte_rate = reader.ReadInt32();
int block_align = reader.ReadInt16();
int bits_per_sample = reader.ReadInt16();
string data_signature = new string(reader.ReadChars(4));
if (data_signature != "data")
throw new NotSupportedException("Specified wave file is not supported.");
int data_chunk_size = reader.ReadInt32();
channels = num_channels;
bits = bits_per_sample;
rate = sample_rate;
return reader.ReadBytes((int)reader.BaseStream.Length);
}
}
public static ALFormat GetSoundFormat(int channels, int bits)
{
switch (channels)
{
case 1: return bits == 8 ? ALFormat.Mono8 : ALFormat.Mono16;
case 2: return bits == 8 ? ALFormat.Stereo8 : ALFormat.Stereo16;
default: throw new NotSupportedException("The specified sound format is not supported.");
}
}
public static void Main()
{
using (AudioContext context = new AudioContext())
{
int buffer = AL.GenBuffer();
int source = AL.GenSource();
int state;
int channels, bits_per_sample, sample_rate;
byte[] sound_data = LoadWave(File.Open(filename, FileMode.Open), out channels, out bits_per_sample, out sample_rate);
AL.BufferData(buffer, GetSoundFormat(channels, bits_per_sample), sound_data, sound_data.Length, sample_rate);
AL.Source(source, ALSourcei.Buffer, buffer);
AL.SourcePlay(source);
Trace.Write("Playing");
// Query the source to find out when it stops playing.
do
{
Thread.Sleep(250);
Trace.Write(".");
AL.GetSource(source, ALGetSourcei.SourceState, out state);
}
while ((ALSourceState)state == ALSourceState.Playing);
Trace.WriteLine("");
AL.SourceStop(source);
AL.DeleteSource(source);
AL.DeleteBuffer(buffer);
}
}
}
}