/* audio/buffers.h 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/buffers.h" #include "audio/pcm.h" #include "audio/wav.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; // load wav file PCM *pcm = Wav::load(name); if (!pcm) { 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)); } }