WavFileLoader.h
Go to the documentation of this file.00001 #ifndef WAV_FILE_LOADER_H_
00002 #define WAV_FILE_LOADER_H_
00003
00004 #include <stdexcept>
00005 #include "OpenAL.h"
00006
00007 class InputStream;
00008
00009 namespace sound
00010 {
00011
00018 class WavFileLoader
00019 {
00020 public:
00021
00027 static ALuint LoadFromStream (InputStream& stream)
00028 {
00029
00030 char magic[5];
00031 magic[4] = '\0';
00032 typedef StreamBase::byte_type byte;
00033
00034 byte temp[256];
00035
00036 int format = 0;
00037
00038
00039 stream.read(reinterpret_cast<byte*> (magic), 4);
00040
00041 if (std::string(magic) != "RIFF") {
00042 throw std::runtime_error("No wav file");
00043 }
00044
00045
00046 unsigned int size;
00047 stream.read(reinterpret_cast<byte*> (&size), 4);
00048
00049
00050 stream.read(reinterpret_cast<byte*> (magic), 4);
00051 if (std::string(magic) != "WAVE") {
00052 throw std::runtime_error("Wrong wav file format");
00053 }
00054
00055
00056 stream.read(reinterpret_cast<byte*> (magic), 4);
00057 if (std::string(magic) != "fmt ") {
00058 throw std::runtime_error("No 'fmt ' subchunk.");
00059 }
00060
00061
00062 unsigned int subChunk1Size(0);
00063 stream.read(reinterpret_cast<byte*> (&subChunk1Size), 4);
00064
00065 if (subChunk1Size < 16) {
00066 throw std::runtime_error("'fmt ' chunk too small.");
00067 }
00068
00069
00070 unsigned short audioFormat(0);
00071 stream.read(reinterpret_cast<byte*> (&audioFormat), 2);
00072
00073 if (audioFormat != 1) {
00074 throw std::runtime_error("Audio format is not PCM.");
00075 }
00076
00077
00078 unsigned short channels(0);
00079 stream.read(reinterpret_cast<byte*> (&channels), 2);
00080
00081
00082 unsigned int freq = 0;
00083 stream.read(reinterpret_cast<byte*> (&freq), 4);
00084
00085
00086 stream.read(temp, 6);
00087
00088
00089 unsigned short bps = 0;
00090 stream.read(reinterpret_cast<byte*> (&bps), 2);
00091
00092 int bufferSize = 0;
00093
00094 if (channels == 1) {
00095 if (bps == 8) {
00096 format = AL_FORMAT_MONO8;
00097
00098 bufferSize = freq / 4;
00099 } else {
00100 format = AL_FORMAT_MONO16;
00101
00102 bufferSize = freq >> 1;
00103
00104 bufferSize -= (bufferSize % 2);
00105 }
00106 } else {
00107 if (bps == 8) {
00108 format = AL_FORMAT_STEREO16;
00109
00110 bufferSize = freq >> 1;
00111
00112 bufferSize -= (bufferSize % 2);
00113 } else {
00114 format = AL_FORMAT_STEREO16;
00115
00116 bufferSize = freq;
00117
00118 bufferSize -= (bufferSize % 4);
00119 }
00120 }
00121
00122
00123 stream.read(reinterpret_cast<byte*> (magic), 4);
00124 if (std::string(magic) != "data" && std::string(magic) != "fact") {
00125 throw std::runtime_error("No 'data' subchunk.");
00126 }
00127
00128
00129 if (std::string(magic) == "fact") {
00130 stream.read(temp, 8);
00131
00132
00133 stream.read(reinterpret_cast<byte*> (magic), 4);
00134 if (std::string(magic) != "data") {
00135 throw std::runtime_error("No 'data' subchunk.");
00136 }
00137 }
00138
00139
00140 unsigned int remainingSize = 0;
00141 stream.read(reinterpret_cast<byte*> (&remainingSize), 4);
00142
00143 ALuint bufferNum = 0;
00144 alGenBuffers(1, &bufferNum);
00145
00146 byte* buffer = new byte[remainingSize];
00147 stream.read(buffer, remainingSize);
00148
00149 alBufferData(bufferNum, format, buffer, static_cast<ALsizei> (remainingSize), freq);
00150
00151 delete[] buffer;
00152
00153 return bufferNum;
00154 }
00155 };
00156
00157 }
00158
00159 #endif