From 05af18ba3f7bfed4831b984286e9dd35ab0c69cf Mon Sep 17 00:00:00 2001 From: lisyarus Date: Mon, 11 Mar 2024 01:00:24 +0300 Subject: [PATCH] Implement lazy-loading audio tracks --- libs/audio/include/psemek/audio/track.hpp | 3 ++ libs/audio/source/track_lazy.cpp | 59 +++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 libs/audio/source/track_lazy.cpp diff --git a/libs/audio/include/psemek/audio/track.hpp b/libs/audio/include/psemek/audio/track.hpp index 286d2ea8..669d39f8 100644 --- a/libs/audio/include/psemek/audio/track.hpp +++ b/libs/audio/include/psemek/audio/track.hpp @@ -6,6 +6,7 @@ #include #include +#include namespace psemek::audio { @@ -31,4 +32,6 @@ namespace psemek::audio track_ptr load_mp3(util::blob data); track_ptr load_mp3(std::vector data); + track_ptr load_lazy(std::filesystem::path const & path); + } diff --git a/libs/audio/source/track_lazy.cpp b/libs/audio/source/track_lazy.cpp new file mode 100644 index 00000000..22c8111b --- /dev/null +++ b/libs/audio/source/track_lazy.cpp @@ -0,0 +1,59 @@ +#include +#include +#include + +namespace psemek::audio +{ + + namespace + { + + struct lazy_track_impl + : track + { + lazy_track_impl(std::filesystem::path const & path) + : path_(path) + {} + + stream_ptr stream() const override + { + load_proxy(); + return proxy_->stream(); + } + + std::optional length() const override + { + load_proxy(); + return proxy_->length(); + } + + private: + std::filesystem::path path_; + mutable track_ptr proxy_; + + void load_proxy() const + { + if (proxy_) + return; + + auto data = io::read_full(io::file_istream(path_)); + auto const extension = path_.extension(); + if (extension == ".mp3") + proxy_ = load_mp3(std::move(data)); + else if (extension == ".wav") + proxy_ = load_wav(std::move(data)); + else if (extension == ".raw") + proxy_ = load_raw(std::move(data)); + else + throw util::exception("Unknown audio format: " + extension.string()); + } + }; + + } + + track_ptr load_lazy(std::filesystem::path const & path) + { + return std::make_shared(path); + } + +}