X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Faudio%2Faudio.cpp;h=c7ed554ee8304e880fb8ce2f2587437b76d27b1d;hb=e245d91528b1447cd1649533c587aebe278c3a53;hp=eed5dac170e514999074ca7948ec803c90328c1a;hpb=7c2a8b8285278b8a3077b311d82f05ea0463a96e;p=blank.git diff --git a/src/audio/audio.cpp b/src/audio/audio.cpp index eed5dac..c7ed554 100644 --- a/src/audio/audio.cpp +++ b/src/audio/audio.cpp @@ -1,6 +1,10 @@ #include "ALError.hpp" #include "Audio.hpp" #include "Sound.hpp" +#include "SoundBank.hpp" + +#include "../app/Assets.hpp" +#include "../shared/ResourceIndex.hpp" #include #include @@ -48,7 +52,8 @@ ALError::ALError(ALenum num, const std::string &msg) } -Audio::Audio() { +Audio::Audio() +: last_free(0) { alGenSources(NUM_SRC, source); ALenum err = alGetError(); if (err != AL_NO_ERROR) { @@ -92,14 +97,23 @@ void Audio::Play( const glm::vec3 &vel, const glm::vec3 &dir ) noexcept { - // TODO: find next free source - ALuint src = source[0]; + int i = NextFree(); + if (i < 0) { + std::cerr << "unable to find free audio source" << std::endl; + return; + } + + ALuint src = source[i]; + CoarseTimer &t = timer[i]; sound.Bind(src); alSourcefv(src, AL_POSITION, glm::value_ptr(pos)); alSourcefv(src, AL_VELOCITY, glm::value_ptr(vel)); alSourcefv(src, AL_DIRECTION, glm::value_ptr(dir)); alSourcePlay(src); + + t = CoarseTimer(sound.Duration()); + t.Start(); } void Audio::StopAll() noexcept { @@ -109,14 +123,36 @@ void Audio::StopAll() noexcept { } } +void Audio::Update(int dt) noexcept { + for (std::size_t i = 0; i < NUM_SRC; ++i) { + timer[i].Update(dt); + if (timer[i].HitOnce()) { + timer[i].Stop(); + alSourceStop(source[i]); + alSourcei(source[i], AL_BUFFER, AL_NONE); + last_free = i; + } + } +} -Sound::Sound() -: handle(AL_NONE) { - alGenBuffers(1, &handle); - ALenum err = alGetError(); - if (err != AL_NO_ERROR) { - throw ALError(err, "alGenBuffers"); +int Audio::NextFree() noexcept { + if (!timer[last_free].Running()) { + return last_free; } + for (int i = (last_free + 1) % NUM_SRC; i != last_free; i = (i + 1) % NUM_SRC) { + if (!timer[i].Running()) { + last_free = i; + return i; + } + } + return -1; +} + + +Sound::Sound() +: handle(AL_NONE) +, duration(0) { + } Sound::Sound(const char *file) @@ -124,6 +160,14 @@ Sound::Sound(const char *file) if (handle == AL_NONE) { throw ALError(alGetError(), "alutCreateBufferFromFile"); } + + ALint size, channels, bits, freq; + alGetBufferi(handle, AL_SIZE, &size); + alGetBufferi(handle, AL_CHANNELS, &channels); + alGetBufferi(handle, AL_BITS, &bits); + alGetBufferi(handle, AL_FREQUENCY, &freq); + + duration = size * 8 * 1000 / (channels * bits * freq); } Sound::~Sound() { @@ -132,18 +176,19 @@ Sound::~Sound() { ALenum err = alGetError(); if (err != AL_NO_ERROR) { std::cerr << "warning: alDeleteBuffers failed with " << al_error_string(err) << std::endl; - //throw ALError(err, "alDeleteBuffers"); } } } Sound::Sound(Sound &&other) -: handle(other.handle) { +: handle(other.handle) +, duration(other.duration) { other.handle = AL_NONE; } Sound &Sound::operator =(Sound &&other) { std::swap(handle, other.handle); + std::swap(duration, other.duration); return *this; } @@ -151,4 +196,18 @@ void Sound::Bind(ALuint src) const { alSourcei(src, AL_BUFFER, handle); } + +SoundBank::SoundBank() +: sounds() { + +} + +void SoundBank::Load(const AssetLoader &loader, const ResourceIndex &index) { + sounds.clear(); + sounds.resize(index.Size()); + for (const auto &entry : index.Entries()) { + sounds[entry.second] = loader.LoadSound(entry.first); + } +} + }