diff options
Diffstat (limited to 'src/audio/buffers.cc')
-rw-r--r-- | src/audio/buffers.cc | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/src/audio/buffers.cc b/src/audio/buffers.cc new file mode 100644 index 0000000..9223380 --- /dev/null +++ b/src/audio/buffers.cc @@ -0,0 +1,112 @@ +/* + 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 "audio/buffers.h" +#include "audio/pcm.h" +#include "audio/wav.h" +#include "sys/sys.h" + +namespace audio { + +std::map<std::string, size_t> Buffers::registry; +size_t Buffers::index; +ALuint Buffers::buffers[MAXBUFFERS]; + +void Buffers::init() +{ + int error; + clear(); + + alGenBuffers(MAXBUFFERS, buffers); + + if ((error = alGetError()) != AL_NO_ERROR) { + con_warn << "Error " << error << " initializing OpenAL bufers!" << std::endl; + return; + } +} + +void Buffers::shutdown() +{ + alDeleteBuffers(MAXBUFFERS, buffers); + + 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()) + con_warn << "Error loading PCM data " << name << std::endl; + + registry[name] = id; + index++; + + 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, std::string name) +{ + int error; + size_t id = find(name); + alSourcei(source, AL_BUFFER, buffers[id]); + if ((error = alGetError()) != AL_NO_ERROR) { + con_warn << "Error " << std::hex << error << " binding " << name + << " source " << source << " buffer " << buffers[id] << std::endl; + } +} + +} |