aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-09-28 17:07:56 +0200
committerLoek Le Blansch <loek@pipeframe.xyz>2024-09-28 17:07:56 +0200
commit3cb7227c3c9678141ff74915331b706265c380cb (patch)
treed47d662b4d26908b3d3d83f4a4df32a0cc489b72 /src
parent506090032a07f2f3a74a44d8c8774cbdd252c947 (diff)
more WIP audio facade
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt15
-rw-r--r--src/crepe/CMakeLists.txt6
-rw-r--r--src/crepe/Sound.cpp19
-rw-r--r--src/crepe/Sound.h54
-rw-r--r--src/crepe/SoundSystem.cpp25
-rw-r--r--src/crepe/SoundSystem.h27
-rw-r--r--src/crepe/api/CMakeLists.txt9
-rw-r--r--src/crepe/api/Resource.cpp12
-rw-r--r--src/crepe/api/Resource.h11
-rw-r--r--src/dummy_audio.cpp37
10 files changed, 199 insertions, 16 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index cc71435..232d330 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -15,13 +15,22 @@ project(crepe C CXX)
add_library(crepe SHARED)
target_include_directories(crepe
- SYSTEM INTERFACE .
+ PUBLIC SYSTEM INTERFACE .
)
-# NOTE: all libraries *must* be linked as PRIVATE
+# TODO: libraries should be linked as PRIVATE
target_link_libraries(crepe
- PRIVATE soloud
+ PUBLIC soloud
)
add_subdirectory(crepe)
+install(
+ TARGETS crepe
+ FILE_SET HEADERS DESTINATION include/crepe
+)
+
+
+add_executable(dummy_audio dummy_audio.cpp)
+target_link_libraries(dummy_audio PUBLIC crepe)
+
diff --git a/src/crepe/CMakeLists.txt b/src/crepe/CMakeLists.txt
index aa64262..13d9be5 100644
--- a/src/crepe/CMakeLists.txt
+++ b/src/crepe/CMakeLists.txt
@@ -1,5 +1,11 @@
target_sources(crepe PUBLIC
Sound.cpp
+ SoundSystem.cpp
+)
+
+target_sources(crepe PUBLIC FILE_SET HEADERS FILES
+ Sound.h
+ SoundSystem.h
)
add_subdirectory(api)
diff --git a/src/crepe/Sound.cpp b/src/crepe/Sound.cpp
index f45a697..d48393c 100644
--- a/src/crepe/Sound.cpp
+++ b/src/crepe/Sound.cpp
@@ -1,9 +1,24 @@
#include "Sound.h"
+#include "SoundSystem.h"
using namespace crepe;
-Sound::Sound(std::unique_ptr<api::Resource> res) {
- _res = std::move(res);
+Sound::Sound(std::unique_ptr<api::Resource> res, SoundSystem & system) : system(system) {
+ this->res = std::move(res);
}
+void Sound::play() {
+ if (this->system.engine.getPause(this->handle)) {
+ // resume if paused
+ this->system.engine.setPause(this->handle, false);
+ } else {
+ // or start new sound
+ this->handle = this->system.engine.play(this->sample);
+ }
+}
+
+void Sound::pause() {
+ if (this->system.engine.getPause(this->handle)) return;
+ this->system.engine.setPause(this->handle, true);
+}
diff --git a/src/crepe/Sound.h b/src/crepe/Sound.h
index ac4b7f4..71fe390 100644
--- a/src/crepe/Sound.h
+++ b/src/crepe/Sound.h
@@ -1,6 +1,7 @@
#pragma once
#include <soloud.h>
+#include <soloud_wav.h>
#include <memory>
@@ -8,22 +9,61 @@
namespace crepe {
-class Sound {
-public:
- Sound(std::unique_ptr<api::Resource> res);
- virtual ~Sound() = default;
+class SoundSystem;
+class Sound {
public:
+ /**
+ * \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();
+ /**
+ * \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();
+ /**
+ * \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();
+ /**
+ * \brief Set playback volume / gain
+ *
+ * \param volume Volume (0 = muted, 1 = full volume)
+ */
void set_volume(float volume);
+ /**
+ * \brief Set looping behavior for this sample
+ *
+ * \param looping Looping behavior (false = one-shot, true = loop)
+ */
void set_looping(bool looping);
private:
- std::unique_ptr<api::Resource> _res;
- SoLoud::handle _handle;
- bool _paused;
+ Sound(std::unique_ptr<api::Resource> res, SoundSystem & system);
+ SoundSystem & system;
+ friend class SoundSystem;
+
+private:
+ std::unique_ptr<api::Resource> res;
+ SoLoud::Wav sample;
+ SoLoud::handle handle;
+ bool paused;
};
}
diff --git a/src/crepe/SoundSystem.cpp b/src/crepe/SoundSystem.cpp
new file mode 100644
index 0000000..30b0157
--- /dev/null
+++ b/src/crepe/SoundSystem.cpp
@@ -0,0 +1,25 @@
+#include "SoundSystem.h"
+#include <memory>
+
+using namespace crepe;
+
+SoundSystem SoundSystem::instance { };
+
+std::unique_ptr<Sound> SoundSystem::sound(const std::string & src) {
+ auto res = std::make_unique<api::Resource>(src);
+ return SoundSystem::sound(std::move(res));
+}
+
+std::unique_ptr<Sound> SoundSystem::sound(std::unique_ptr<api::Resource> res) {
+ Sound * out = new Sound(std::move(res), SoundSystem::instance);
+ return std::unique_ptr<Sound>(out);
+}
+
+SoundSystem::SoundSystem() {
+ engine.init();
+}
+
+SoundSystem::~SoundSystem() {
+ engine.deinit();
+}
+
diff --git a/src/crepe/SoundSystem.h b/src/crepe/SoundSystem.h
new file mode 100644
index 0000000..23bb00a
--- /dev/null
+++ b/src/crepe/SoundSystem.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <soloud.h>
+
+#include <memory>
+
+#include "Sound.h"
+
+namespace crepe {
+
+class SoundSystem {
+public:
+ static std::unique_ptr<Sound> sound(const std::string & res);
+ static std::unique_ptr<Sound> sound(std::unique_ptr<api::Resource> res);
+
+private:
+ SoundSystem();
+ virtual ~SoundSystem();
+ static SoundSystem instance;
+
+private:
+ SoLoud::Soloud engine;
+ friend class Sound;
+};
+
+}
+
diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt
index 94617a4..feb03ef 100644
--- a/src/crepe/api/CMakeLists.txt
+++ b/src/crepe/api/CMakeLists.txt
@@ -1,4 +1,11 @@
target_sources(crepe PUBLIC
- AudioSource.cpp
+ # AudioSource.cpp
+ Resource.cpp
+)
+
+target_sources(crepe PUBLIC FILE_SET HEADERS FILES
+ AudioSource.h
+ Component.h
+ Resource.h
)
diff --git a/src/crepe/api/Resource.cpp b/src/crepe/api/Resource.cpp
new file mode 100644
index 0000000..a38900b
--- /dev/null
+++ b/src/crepe/api/Resource.cpp
@@ -0,0 +1,12 @@
+#include "Resource.h"
+
+using namespace crepe::api;
+
+Resource::Resource(const std::string & src) : src(src) {
+ this->file = std::ifstream(src, std::ios::in | std::ios::binary);
+}
+
+const std::istream & Resource::read() {
+ return this->file;
+}
+
diff --git a/src/crepe/api/Resource.h b/src/crepe/api/Resource.h
index 620a10e..2260b1a 100644
--- a/src/crepe/api/Resource.h
+++ b/src/crepe/api/Resource.h
@@ -1,16 +1,21 @@
#pragma once
#include <string>
+#include <fstream>
+#include <iostream>
namespace crepe::api {
class Resource {
public:
- Resource(const std::string & source);
- virtual ~Resource();
+ Resource(const std::string & src);
+
+public:
+ const std::istream & read();
private:
- std::string _source;
+ std::string src;
+ std::ifstream file;
};
}
diff --git a/src/dummy_audio.cpp b/src/dummy_audio.cpp
new file mode 100644
index 0000000..5e0000e
--- /dev/null
+++ b/src/dummy_audio.cpp
@@ -0,0 +1,37 @@
+#include "crepe/SoundSystem.h"
+
+#include <chrono>
+#include <thread>
+
+using namespace crepe;
+using namespace std;
+using namespace std::chrono_literals;
+
+int main() {
+ auto bgm = SoundSystem::sound("../mwe/audio/bgm.ogg");
+ auto sfx1 = SoundSystem::sound("../mwe/audio/sfx1.wav");
+ auto sfx2 = SoundSystem::sound("../mwe/audio/sfx2.wav");
+ auto sfx3 = SoundSystem::sound("../mwe/audio/sfx3.wav");
+
+ bgm->play();
+
+ // play each sample sequentially
+ this_thread::sleep_for(500ms);
+ sfx1->play();
+ this_thread::sleep_for(500ms);
+ sfx2->play();
+ bgm->pause();
+ this_thread::sleep_for(500ms);
+ sfx3->play();
+ bgm->play();
+ this_thread::sleep_for(500ms);
+
+ // play all samples simultaniously
+ sfx1->play();
+ sfx2->play();
+ sfx3->play();
+ this_thread::sleep_for(1000ms);
+
+ return 0;
+}
+