summaryrefslogtreecommitdiff
path: root/src/audio.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio.cpp')
-rw-r--r--src/audio.cpp56
1 files changed, 51 insertions, 5 deletions
diff --git a/src/audio.cpp b/src/audio.cpp
index c3f152e..194c01c 100644
--- a/src/audio.cpp
+++ b/src/audio.cpp
@@ -1,13 +1,19 @@
#define PKE_AUDIO_IMPL_PIPEWIRE
-#include "audio.hpp"
-
+#include "asset-manager.hpp"
#include "audio-impl-pw.hpp"
+#include "audio.hpp"
+#include "pk.h"
struct pke_audio_master pke_audio_mstr{};
void pke_audio_init() {
+ pke_audio_mstr.master_volume = 1.f;
pke_audio_mstr.channel_count = 2;
+ pke_audio_mstr.bkt_transient = pk_mem_bucket_create("pke_audio", PK_MEM_DEFAULT_BUCKET_SIZE, PK_MEMBUCKET_FLAG_TRANSIENT);
+ for (uint8_t i = 0; i < pke_audio_mstr.channel_count; ++i) {
+ pke_audio_mstr.source_volumes[i] = 1.f;
+ }
#ifdef PKE_AUDIO_IMPL_PIPEWIRE
pke_audio_pw_init();
#endif
@@ -16,12 +22,13 @@ void pke_audio_teardown() {
#ifdef PKE_AUDIO_IMPL_PIPEWIRE
pke_audio_pw_teardown();
#endif
+ pk_mem_bucket_destroy(pke_audio_mstr.bkt_transient);
}
void pke_audio_tick(double delta) {
(void)delta;
#ifdef PKE_AUDIO_IMPL_PIPEWIRE
if (pke_audio_pw.is_needing_output_remapped == true) {
- pke_audio_pw.is_needing_output_remapped = !pke_audio_pw_remap_outputs();
+ pke_audio_pw_remap_outputs();
}
#endif
}
@@ -34,5 +41,44 @@ void pke_audio_set_volume(pke_audio_source source, float volume) {
pke_audio_mstr.source_volumes[static_cast<pke_audio_source_T>(source)] = volume;
}
-void pke_audio_play(AssetHandle handle, pke_audio_source audio_source, pke_audio_flags flags);
-void pke_audio_stop_all();
+bool pke_audio_playing_objects_find_first_by_key(void *user_data, void *arr_data) {
+ std::tuple<AssetHandle, pke_audio_source> &tup = *reinterpret_cast<std::tuple<AssetHandle, pke_audio_source>*>(user_data);
+ pke_audio_obj &audio_obj = *reinterpret_cast<pke_audio_obj*>(arr_data);
+ return std::get<0>(tup) == audio_obj.handle && std::get<1>(tup) == audio_obj.source;
+}
+void pke_audio_play(AssetHandle handle, pke_audio_source audio_source, glm::vec3 position_source, pke_audio_flags flags) {
+ // TODO validation: audio length (does it fit in uint32_t), etc
+ // TODO rethink threading: first-pass only mutex
+ std::tuple<AssetHandle, pke_audio_source> tup {handle, audio_source};
+ pke_audio_mstr.mtx_buffer.lock();
+ uint32_t idx = pk_arr_find_first_index(&pke_audio_mstr.playing_objects, &tup, pke_audio_playing_objects_find_first_by_key);
+ pke_audio_obj *aobj = NULL;
+ if (idx == uint32_t(-1)) {
+ AM_Get(handle); // keep the asset in memory, freed when play_count hits 0
+ pk_arr_append_t(&pke_audio_mstr.playing_objects, {});
+ aobj = &pke_audio_mstr.playing_objects[pke_audio_mstr.playing_objects.next-1];
+ memset(aobj, 0, sizeof(pke_audio_obj));
+ aobj->handle = handle;
+ aobj->source = audio_source;
+ aobj->play_count = 1;
+ idx = 0;
+ } else {
+ aobj = &pke_audio_mstr.playing_objects[idx];
+ idx = aobj->play_count;
+ aobj->play_count += 1;
+ }
+ aobj->position_source[idx] = position_source;
+ aobj->flags[idx] = flags;
+ aobj->play_heads[idx] = 0;
+ pke_audio_mstr.mtx_buffer.unlock();
+}
+void pke_audio_stop_all() {
+ // TODO fade-out instead of hard-cut? Maybe that should be a separate function.
+ uint32_t i;
+ pke_audio_mstr.mtx_buffer.lock();
+ for (i = 0; i < pke_audio_mstr.playing_objects.next; ++i) {
+ AM_Release(pke_audio_mstr.playing_objects[i].handle);
+ }
+ pk_arr_clear(&pke_audio_mstr.playing_objects);
+ pke_audio_mstr.mtx_buffer.unlock();
+}