Newer
Older
EARS-LINUX / audiotest / WavFile.cs
using System;
using System.IO;
using System.Text;
using OpenTK.Audio.OpenAL;

public class WavFile
{
    public byte[] Data;
    public ALFormat Format;      // Al.FORMAT_*
    public int SampleRate;

    public static WavFile Load(string path)
    {
        using (var fs = File.OpenRead(path))
        using (var br = new BinaryReader(fs))
        {
            if (new string(br.ReadChars(4)) != "RIFF") throw new Exception("Not RIFF: " + path);
            br.ReadInt32();
            if (new string(br.ReadChars(4)) != "WAVE") throw new Exception("Not WAVE: " + path);

            short channels = 0, bits = 0;
            int rate = 0;
            byte[] data = null;

            while (fs.Position < fs.Length - 8)
            {
                string id  = new string(br.ReadChars(4));
                int    len = br.ReadInt32();

                if (id == "fmt ")
                {
                    br.ReadInt16();                 // audio format (1 = PCM)
                    channels = br.ReadInt16();
                    rate     = br.ReadInt32();
                    br.ReadInt32();                 // byte rate
                    br.ReadInt16();                 // block align
                    bits     = br.ReadInt16();
                    if (len > 16) br.ReadBytes(len - 16);
                }
                else if (id == "data")
                {
                    data = br.ReadBytes(len);
                }
                else
                {
                    br.ReadBytes(len);              // skip unknown chunk
                }

                if ((len & 1) == 1) br.ReadByte();  // chunks are word-aligned
            }

            if (data == null) throw new Exception("No data chunk: " + path);

            ALFormat fmt;
            if      (channels == 1 && bits == 8)  fmt = ALFormat.Mono8;
            else if (channels == 1 && bits == 16) fmt = ALFormat.Mono16;
            else if (channels == 2 && bits == 8)  fmt = ALFormat.Stereo8;
            else if (channels == 2 && bits == 16) fmt = ALFormat.Stereo16;
            else throw new Exception("Unsupported WAV: " + channels + "ch " + bits + "bit");

            return new WavFile { Data = data, Format = fmt, SampleRate = rate };
        }
    }
}