aboutsummaryrefslogtreecommitdiff
path: root/src/crepe
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-11-29 17:30:45 +0100
committerLoek Le Blansch <loek@pipeframe.xyz>2024-11-29 17:30:45 +0100
commit693355f55193cb2ea4c29616073227e37665afc1 (patch)
tree37d2bd3e916b909fbac58ae836e8001166edf384 /src/crepe
parentc59d460f12e1393e0ddbaaa1c6f5522eb12f8ff9 (diff)
more audio system WIP
Diffstat (limited to 'src/crepe')
-rw-r--r--src/crepe/facade/Sound.cpp64
-rw-r--r--src/crepe/facade/Sound.h66
-rw-r--r--src/crepe/facade/SoundContext.h3
-rw-r--r--src/crepe/system/AudioSystem.cpp29
-rw-r--r--src/crepe/system/AudioSystem.h26
-rw-r--r--src/crepe/util/Private.cpp5
-rw-r--r--src/crepe/util/Private.h6
-rw-r--r--src/crepe/util/Private.hpp4
8 files changed, 92 insertions, 111 deletions
diff --git a/src/crepe/facade/Sound.cpp b/src/crepe/facade/Sound.cpp
index 52496af..0df1f48 100644
--- a/src/crepe/facade/Sound.cpp
+++ b/src/crepe/facade/Sound.cpp
@@ -13,36 +13,36 @@ Sound::Sound(const Asset & src) : Resource(src) {
}
Sound::~Sound() { dbg_trace(); }
-void Sound::play(SoundContext & ctx) {
- if (ctx.engine.getPause(this->handle)) {
- // resume if paused
- ctx.engine.setPause(this->handle, false);
- } else {
- // or start new sound
- this->handle = ctx.engine.play(this->sample, this->volume);
- ctx.engine.setLooping(this->handle, this->looping);
- }
-}
-
-void Sound::pause(SoundContext & ctx) {
- if (ctx.engine.getPause(this->handle)) return;
- ctx.engine.setPause(this->handle, true);
-}
-
-void Sound::rewind(SoundContext & ctx) {
- if (!ctx.engine.isValidVoiceHandle(this->handle)) return;
- ctx.engine.seek(this->handle, 0);
-}
-
-void Sound::set_volume(SoundContext & ctx, float volume) {
- this->volume = volume;
- if (!ctx.engine.isValidVoiceHandle(this->handle)) return;
- ctx.engine.setVolume(this->handle, this->volume);
-}
-
-void Sound::set_looping(SoundContext & ctx, bool looping) {
- this->looping = looping;
- if (!ctx.engine.isValidVoiceHandle(this->handle)) return;
- ctx.engine.setLooping(this->handle, this->looping);
-}
+// void Sound::play(SoundContext & ctx) {
+// if (ctx.engine.getPause(this->handle)) {
+// // resume if paused
+// ctx.engine.setPause(this->handle, false);
+// } else {
+// // or start new sound
+// this->handle = ctx.engine.play(this->sample, this->volume);
+// ctx.engine.setLooping(this->handle, this->looping);
+// }
+// }
+//
+// void Sound::pause(SoundContext & ctx) {
+// if (ctx.engine.getPause(this->handle)) return;
+// ctx.engine.setPause(this->handle, true);
+// }
+//
+// void Sound::rewind(SoundContext & ctx) {
+// if (!ctx.engine.isValidVoiceHandle(this->handle)) return;
+// ctx.engine.seek(this->handle, 0);
+// }
+//
+// void Sound::set_volume(SoundContext & ctx, float volume) {
+// this->volume = volume;
+// if (!ctx.engine.isValidVoiceHandle(this->handle)) return;
+// ctx.engine.setVolume(this->handle, this->volume);
+// }
+//
+// void Sound::set_looping(SoundContext & ctx, bool looping) {
+// this->looping = looping;
+// if (!ctx.engine.isValidVoiceHandle(this->handle)) return;
+// ctx.engine.setLooping(this->handle, this->looping);
+// }
diff --git a/src/crepe/facade/Sound.h b/src/crepe/facade/Sound.h
index f33ee58..10d7c3c 100644
--- a/src/crepe/facade/Sound.h
+++ b/src/crepe/facade/Sound.h
@@ -9,10 +9,6 @@ namespace crepe {
class SoundContext;
-struct SoundHandle {
- SoLoud::handle handle;
-};
-
/**
* \brief Sound resource facade
*
@@ -23,62 +19,20 @@ class Sound : public Resource {
public:
Sound(const Asset & src);
~Sound(); // dbg_trace
- /**
- * \brief Pause this sample
- *
- * Pauses this sound if it is playing, or does nothing if it is already paused. The playhead
- * position is saved, such that calling \c play() after this function makes the sound resume.
- */
- void pause(SoundContext & ctx);
- /**
- * \brief Play this sample
- *
- * Resume playback if this sound is paused, or start from the beginning of the sample.
- *
- * \note This class only saves a reference to the most recent 'voice' of this sound. Calling
- * \c play() while the sound is already playing causes multiple instances of the sample to
- * play simultaniously. The sample started last is the one that is controlled afterwards.
- */
- void play(SoundContext & ctx);
- /**
- * \brief Reset playhead position
- *
- * Resets the playhead position so that calling \c play() after this function makes it play
- * from the start of the sample. If the sound is not paused before calling this function,
- * this function will stop playback.
- */
- void rewind(SoundContext & ctx);
- /**
- * \brief Set playback volume / gain
- *
- * \param volume Volume (0 = muted, 1 = full volume)
- */
- void set_volume(SoundContext & ctx, float volume);
- /**
- * \brief Get playback volume / gain
- *
- * \return Volume
- */
- float get_volume() const { return this->volume; }
- /**
- * \brief Set looping behavior for this sample
- *
- * \param looping Looping behavior (false = one-shot, true = loop)
- */
- void set_looping(SoundContext & ctx, bool looping);
- /**
- * \brief Get looping behavior
- *
- * \return true if looping, false if one-shot
- */
- bool get_looping() const { return this->looping; }
+
+ class Handle {
+ private:
+ SoLoud::handle handle;
+ float volume = 1.0f;
+ bool looping = false;
+
+ friend class SoundContext;
+ };
private:
SoLoud::Wav sample;
- SoLoud::handle handle;
- float volume = 1.0f;
- bool looping = false;
+ friend class SoundContext;
};
} // namespace crepe
diff --git a/src/crepe/facade/SoundContext.h b/src/crepe/facade/SoundContext.h
index d22ff7a..286ced8 100644
--- a/src/crepe/facade/SoundContext.h
+++ b/src/crepe/facade/SoundContext.h
@@ -22,10 +22,9 @@ public:
SoundContext & operator=(const SoundContext &) = delete;
SoundContext & operator=(SoundContext &&) = delete;
+
private:
SoLoud::Soloud engine;
- //! Sound directly calls methods on \c engine
- friend class Sound;
};
} // namespace crepe
diff --git a/src/crepe/system/AudioSystem.cpp b/src/crepe/system/AudioSystem.cpp
index 0f943be..191dbbb 100644
--- a/src/crepe/system/AudioSystem.cpp
+++ b/src/crepe/system/AudioSystem.cpp
@@ -15,18 +15,35 @@ void AudioSystem::update() {
for (AudioSource & component : components) {
if (!component.active) continue;
- Sound & sound = resource_manager.get<Sound>(component.source);
- if (component.private_data.empty())
- component.private_data.set<ComponentPrivate>();
+ Sound & resource = resource_manager.get<Sound>(component.source);
+
+ if (component.private_data.empty()) {
+ auto & data = component.private_data.set<ComponentPrivate>();
+ this->update_last(component, data);
+ }
auto & data = component.private_data.get<ComponentPrivate>();
- // TODO: lots of state diffing
+ this->diff_update(component, data, resource);
+
+ this->update_last(component, data);
+ }
+}
+
+void AudioSystem::diff_update(AudioSource & component, const ComponentPrivate & data, Sound & resource) {
+ bool update_playing = component.playing != data.last_playing;
+ bool update_volume = component.volume != data.last_volume;
+ bool update_loop = component.loop != data.last_loop;
+ bool update_active = component.active != data.last_active;
- this->update_private(component, data);
+ if (update_active)
+ if (component.rewind) {
+ component.playing = false;
+ // this->context.rewind(resource, data.handle);
}
+
}
-void AudioSystem::update_private(const AudioSource & component, ComponentPrivate & data) {
+void AudioSystem::update_last(const AudioSource & component, ComponentPrivate & data) {
data.last_active = component.active;
data.last_loop = component.loop;
data.last_playing = component.playing;
diff --git a/src/crepe/system/AudioSystem.h b/src/crepe/system/AudioSystem.h
index 7f41fda..4650178 100644
--- a/src/crepe/system/AudioSystem.h
+++ b/src/crepe/system/AudioSystem.h
@@ -1,6 +1,7 @@
#pragma once
#include "../facade/SoundContext.h"
+#include "../facade/Sound.h"
#include "../api/AudioSource.h"
#include "System.h"
@@ -18,19 +19,22 @@ private:
*/
struct ComponentPrivate {
//! This sample's voice handle
- SoLoud::handle handle;
-
- //! Value of \c active after last system update
- bool last_active = false;
- //! Value of \c playing after last system update
- bool last_playing = false;
- //! Value of \c volume after last system update
- float last_volume = 1.0;
- //! Value of \c loop after last system update
- bool last_loop = false;
+ Sound::Handle handle;
+
+ /**
+ * \name State diffing variables
+ * \{
+ */
+ typeof(AudioSource::active) last_active;
+ typeof(AudioSource::playing) last_playing;
+ typeof(AudioSource::volume) last_volume;
+ typeof(AudioSource::loop) last_loop;
+ //! \}
};
- void update_private(const AudioSource & component, ComponentPrivate & data);
+ void update_last(const AudioSource & component, ComponentPrivate & data);
+
+ void diff_update(AudioSource & component, const ComponentPrivate & data, Sound & resource);
private:
SoundContext context {};
diff --git a/src/crepe/util/Private.cpp b/src/crepe/util/Private.cpp
index c5b5b30..cb4cb5b 100644
--- a/src/crepe/util/Private.cpp
+++ b/src/crepe/util/Private.cpp
@@ -27,3 +27,8 @@ Private & Private::operator=(Private && other) {
return *this;
}
+Private::Private(const Private & other) { }
+Private & Private::operator=(const Private & other) {
+ return *this;
+}
+
diff --git a/src/crepe/util/Private.h b/src/crepe/util/Private.h
index fc3728f..6dd28bb 100644
--- a/src/crepe/util/Private.h
+++ b/src/crepe/util/Private.h
@@ -9,16 +9,16 @@ class Private {
public:
Private() = default;
~Private();
+ Private(const Private &);
Private(Private &&);
+ Private & operator=(const Private &);
Private & operator=(Private &&);
- Private(const Private &) = delete;
- Private & operator=(const Private &) = delete;
template <typename T>
T & get();
template <typename T, typename... Args>
- void set(Args &&... args);
+ T & set(Args &&... args);
bool empty() const noexcept;
diff --git a/src/crepe/util/Private.hpp b/src/crepe/util/Private.hpp
index 30c8146..d6ab23f 100644
--- a/src/crepe/util/Private.hpp
+++ b/src/crepe/util/Private.hpp
@@ -8,13 +8,15 @@
namespace crepe {
template <typename T, typename... Args>
-void Private::set(Args &&... args) {
+T & Private::set(Args &&... args) {
+ if (!this->empty()) this->destructor(this->instance);
T * instance = new T(std::forward<Args>(args)...);
this->instance = static_cast<void*>(instance);
this->destructor = [](void * instance) {
delete static_cast<T*>(instance);
};
this->type = typeid(T);
+ return *instance;
}
template <typename T>