#include #include #include namespace psemek::audio { namespace { struct data_holder { std::vector storage; util::blob blob_storage; util::span samples; data_holder(util::span samples) : samples(samples) {} data_holder(std::vector storage) : storage(std::move(storage)) , samples(this->storage) {} data_holder(util::blob storage) : blob_storage(std::move(storage)) , samples(util::cast(util::span(blob_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(util::span samples) { if ((samples.size() % 2) != 0) throw util::exception("Sample count must be even"); return std::make_shared(std::make_shared(samples)); } track_ptr load_raw(util::blob samples) { if ((samples.size() % 4) != 0) throw util::exception("Byte count must be a multiple of 4"); if ((samples.size() % 8) != 0) throw util::exception("Sample count must be even"); return std::make_shared(std::make_shared(std::move(samples))); } track_ptr load_raw(std::vector samples) { if ((samples.size() % 2) != 0) throw util::exception("Sample count must be even"); return std::make_shared(std::make_shared(std::move(samples))); } }