/* audio/buffers.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include #include "audio/audio.h" #include "audio/buffers.h" #include "audio/pcm.h" #include "audio/vorbisfile.h" #include "audio/wavfile.h" #include "sys/sys.h" namespace audio { std::map Buffers::registry; size_t Buffers::index; ALuint Buffers::buffers[MAXBUFFERS]; void Buffers::init() { clear(); alGenBuffers(MAXBUFFERS, buffers); int error; if ((error = alGetError()) != AL_NO_ERROR) { con_warn << "Error " << error << " initializing OpenAL buffers!" << std::endl; return; } } void Buffers::shutdown() { alDeleteBuffers(MAXBUFFERS, buffers); int error; if ((error = alGetError()) != AL_NO_ERROR) { con_warn << "Error " << error << " clearing OpenAL buffers!" << std::endl; return; } clear(); } void Buffers::clear() { registry.clear(); memset(buffers, 0, sizeof(buffers)); index = 0; } size_t Buffers::load(std::string name) { // check if it is already loaded iterator it = registry.find(name); if (it != registry.end()) return (*it).second; // check if the audio subsystem has been initialized if (!initialized()) { registry[name] = 0; return 0; } std::string filename; PCM *pcm = 0; // try the .oga version if (!pcm) { filename.assign("sounds/"); filename.append(name); filename.append(".oga"); pcm = Vorbis::load(filename); } // try the .ogg version if (!pcm) { filename.assign("sounds/"); filename.append(name); filename.append(".ogg"); pcm = Vorbis::load(filename); } // try the .wav version if (!pcm) { filename.assign("sounds/"); filename.append(name); filename.append(".wav"); pcm = Wav::load(filename); } if (!pcm) { con_warn << "Could not open sound " << name << std::endl; registry[name] = 0; return 0; } if (index == MAXBUFFERS) { con_error << "Buffer limit " << MAXBUFFERS << " exceeded!" << std::endl; delete pcm; registry[name] = 0; return 0; } ALenum format = 0; if (pcm->bitspersample() == 16) { if (pcm->channels() == 1) { format = AL_FORMAT_MONO16; } else if (pcm->channels() == 2) { format = AL_FORMAT_STEREO16; }; } else if (pcm->bitspersample() == 8) { if (pcm->channels() == 1) { format = AL_FORMAT_MONO8; } else if (pcm->channels() == 2) { format = AL_FORMAT_STEREO8; }; } size_t id = index; alBufferData(buffers[id], format, pcm->data(), pcm->size(), pcm->samplerate()); if (alGetError() != AL_NO_ERROR) { con_warn << "Error loading PCM data " << name << std::endl; } registry[name] = id; index++; delete pcm; return id; } size_t Buffers::find(std::string name) { size_t id = 0; iterator it = registry.find(name); if (it != registry.end()) id = (*it).second; return id; } void Buffers::bind(ALuint source, size_t id) { int error; alSourcei(source, AL_BUFFER, buffers[id]); if ((error = alGetError()) != AL_NO_ERROR) { con_warn << "Error " << error << " binding buffer " << buffers[id] << " to source " << source << std::endl; } } void Buffers::bind(ALuint source, std::string name) { bind(source, find(name)); } }