]> git.localhorst.tv Git - blank.git/commitdiff
the sound thing
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Fri, 14 Aug 2015 09:39:39 +0000 (11:39 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Fri, 14 Aug 2015 09:45:14 +0000 (11:45 +0200)
TODO
src/app/IntervalTimer.hpp
src/app/app.cpp
src/audio/Audio.hpp
src/audio/Sound.hpp
src/audio/audio.cpp

diff --git a/TODO b/TODO
index 9bd2aaa629f35a60f8122b5b88c218a8bc444876..b77cdae4859fa7d4c4b23d1352824f98bfae72e4 100644 (file)
--- a/TODO
+++ b/TODO
@@ -21,11 +21,6 @@ command line
 
        usefull for development and later on world administration
 
-audio
-
-       do the sources thing rightâ„¢
-       (or at least in a way that it doesn't error out on shutdown :P )
-
 persistence
 
        merge IO counters, so number of operations per frame is kept
index bcf1baef29e290fafbe90079d4daabc05052914b..06caa5e21b9bb5c805a1f2e73d68d89c855f8996 100644 (file)
@@ -13,7 +13,7 @@ class IntervalTimer {
 public:
        /// Create a timer that hits every interval_ms milliseconds.
        /// Initial state is stopped.
-       explicit IntervalTimer(int interval_ms) noexcept
+       explicit IntervalTimer(int interval_ms = 0) noexcept
        : intv(interval_ms) { }
 
        void Start() noexcept {
@@ -35,7 +35,7 @@ public:
                return Running() && value % intv < last_dt;
        }
        bool HitOnce() const noexcept {
-               return value >= intv;
+               return Running() && value >= intv;
        }
        int Elapsed() const noexcept {
                return value;
index 8f3801c3893709a0bc0c92ee652158e25c40c6fd..a6acade2c30f3f8eaf898160b922e84b0b810cac 100644 (file)
@@ -129,6 +129,7 @@ void Application::Handle(const SDL_WindowEvent &event) {
 
 void Application::Update(int dt) {
        env.counter.EnterUpdate();
+       env.audio.Update(dt);
        if (HasState()) {
                GetState().Update(dt);
        }
index fe5364db45c787285ef53a8be42a2eeffa2a4c1d..bfd6d47594f4e81b175aa7a860269d51fb0439bd 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef BLANK_AUDIO_AUDIO_HPP_
 #define BLANK_AUDIO_AUDIO_HPP_
 
+#include "../app/IntervalTimer.hpp"
+
 #include <al.h>
 #include <glm/glm.hpp>
 
@@ -32,9 +34,16 @@ public:
 
        void StopAll() noexcept;
 
+       void Update(int dt) noexcept;
+
+private:
+       int NextFree() noexcept;
+
 private:
-       static constexpr std::size_t NUM_SRC = 1;
+       static constexpr std::size_t NUM_SRC = 16;
        ALuint source[NUM_SRC];
+       IntervalTimer timer[NUM_SRC];
+       int last_free;
 
 };
 
index abbb27bd07ff388816f7b9e99d905d67c5d57089..abd31784211fc7b1831e7c3b988165a28d1693d1 100644 (file)
@@ -22,8 +22,12 @@ public:
 public:
        void Bind(ALuint src) const;
 
+       /// full duration in milliseconds
+       int Duration() const noexcept { return duration; }
+
 private:
        ALuint handle;
+       int duration;
 
 };
 
index eed5dac170e514999074ca7948ec803c90328c1a..426745f7912b60383f16b32739c151f486e24f6b 100644 (file)
@@ -92,14 +92,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];
+       IntervalTimer &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 = IntervalTimer(sound.Duration());
+       t.Start();
 }
 
 void Audio::StopAll() noexcept {
@@ -109,9 +118,35 @@ 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;
+               }
+       }
+}
+
+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) {
+: handle(AL_NONE)
+, duration(0) {
        alGenBuffers(1, &handle);
        ALenum err = alGetError();
        if (err != AL_NO_ERROR) {
@@ -124,6 +159,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() {