From a67e00d60195f590d1267a31769870858e011c4f Mon Sep 17 00:00:00 2001 From: lisyarus Date: Tue, 10 Jan 2023 14:41:12 +0300 Subject: [PATCH] Implement raw audio::track from scratch, without dependence on recoder & duplicator --- libs/audio/source/track_raw.cpp | 89 +++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 5 deletions(-) diff --git a/libs/audio/source/track_raw.cpp b/libs/audio/source/track_raw.cpp index e0eb9def..eb27d525 100644 --- a/libs/audio/source/track_raw.cpp +++ b/libs/audio/source/track_raw.cpp @@ -1,17 +1,96 @@ #include -#include + +#include namespace psemek::audio { - track_ptr load_raw(util::span data) + namespace { - return make_duplicator(make_recorder(data)); + + struct data_holder + { + std::vector storage; + util::span samples; + + data_holder(util::span samples) + : samples(samples) + {} + + data_holder(std::vector storage) + : storage(std::move(storage)) + , samples(this->storage) + {} + }; + + struct raw_stream_impl + : stream + { + raw_stream_impl(std::shared_ptr data_holder) + : data_holder_(std::move(data_holder)) + {} + + std::optional length() const override + { + return data_holder_->samples.size(); + } + + std::size_t read(util::span samples) override + { + auto played = played_.load(); + + auto count = std::min(data_holder_->samples.size() - played, samples.size()); + std::copy(data_holder_->samples.begin() + played, data_holder_->samples.begin() + played + count, samples.begin()); + played_.fetch_add(count); + return count; + } + + std::size_t played() const override + { + return played_; + } + + + private: + std::shared_ptr data_holder_; + std::atomic played_{0}; + }; + + struct raw_track_impl + : track + { + raw_track_impl(std::shared_ptr data_holder) + : data_holder_(std::move(data_holder)) + {} + + stream_ptr stream() const override + { + return std::make_shared(data_holder_); + } + + std::optional length() const override + { + return data_holder_->samples.size(); + } + + private: + std::shared_ptr data_holder_; + }; + } - track_ptr load_raw(std::vector data) + track_ptr load_raw(util::span samples) { - return make_duplicator(make_recorder(std::move(data))); + if ((samples.size() % 2) != 0) + throw std::runtime_error("bad sample count"); + return std::make_shared(std::make_shared(samples)); + } + + track_ptr load_raw(std::vector samples) + { + if ((samples.size() % 2) != 0) + throw std::runtime_error("bad sample count"); + return std::make_shared(std::make_shared(std::move(samples))); } }