1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
using System;
using System.IO;
using OpenTK.Audio.OpenAL;
namespace Microsoft.Xna.Framework.Audio
{
internal class AudioLoader
{
private AudioLoader ()
{
}
private static ALFormat GetSoundFormat(int channels, int bits)
{
switch (channels)
{
case 1: return bits == 8 ? OpenTK.Audio.OpenAL.ALFormat.Mono8 : OpenTK.Audio.OpenAL.ALFormat.Mono16;
case 2: return bits == 8 ? OpenTK.Audio.OpenAL.ALFormat.Stereo8 : OpenTK.Audio.OpenAL.ALFormat.Stereo16;
default: throw new NotSupportedException("The specified sound format is not supported.");
}
}
public static byte[] Load (Stream data, out ALFormat format, out int size, out int frequency)
{
byte[] audioData = null;
format = ALFormat.Mono8;
size = 0;
frequency = 0;
using (BinaryReader reader = new BinaryReader(data))
{
// decide which data type is this
// for now we'll only support wave files
audioData = LoadWave(reader, out format, out size, out frequency);
}
return audioData;
}
private static byte[] LoadWave (BinaryReader reader, out ALFormat format, out int size, out int frequency)
{
// code based on opentk exemple
byte[] audioData;
//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 wformat = new string(reader.ReadChars(4));
if (wformat != "WAVE")
{
throw new NotSupportedException("Specified stream is not a wave file.");
}
// WAVE header
string format_signature = new string(reader.ReadChars(4));
while (format_signature != "fmt ") {
reader.ReadBytes(reader.ReadInt32());
format_signature = new string(reader.ReadChars(4));
}
int format_chunk_size = reader.ReadInt32();
// total bytes read: tbp
int audio_format = reader.ReadInt16(); // 2
int num_channels = reader.ReadInt16(); // 4
int sample_rate = reader.ReadInt32(); // 8
int byte_rate = reader.ReadInt32(); // 12
int block_align = reader.ReadInt16(); // 14
int bits_per_sample = reader.ReadInt16(); // 16
if (audio_format != 1)
{
throw new NotSupportedException("Wave compression is not supported.");
}
// reads residual bytes
if (format_chunk_size > 16)
reader.ReadBytes(format_chunk_size - 16);
string data_signature = new string(reader.ReadChars(4));
while (data_signature.ToLower() != "data")
{
reader.ReadBytes(reader.ReadInt32());
data_signature = new string(reader.ReadChars(4));
}
int data_chunk_size = reader.ReadInt32();
frequency = sample_rate;
format = GetSoundFormat(num_channels, bits_per_sample);
audioData = reader.ReadBytes((int)reader.BaseStream.Length);
size = data_chunk_size;
return audioData;
}
}
}
|