diff --git a/libs/audio/include/psemek/audio/combine/duplicate.hpp b/libs/audio/include/psemek/audio/combine/duplicate.hpp index 491a2eab..f55a673d 100644 --- a/libs/audio/include/psemek/audio/combine/duplicate.hpp +++ b/libs/audio/include/psemek/audio/combine/duplicate.hpp @@ -10,16 +10,7 @@ namespace psemek::audio { track_ptr make_duplicator(std::shared_ptr recorder); - - inline track_ptr make_duplicator(stream_ptr stream) - { - return make_duplicator(make_recorder(std::move(stream))); - } - - inline std::pair duplicate(stream_ptr stream) - { - auto track = make_duplicator(std::move(stream)); - return {track->stream(), track->stream()}; - } + track_ptr make_duplicator(stream_ptr stream); + std::pair duplicate(stream_ptr stream); } diff --git a/libs/audio/include/psemek/audio/recorder.hpp b/libs/audio/include/psemek/audio/recorder.hpp index f25b20e9..10cf9d80 100644 --- a/libs/audio/include/psemek/audio/recorder.hpp +++ b/libs/audio/include/psemek/audio/recorder.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -10,17 +11,18 @@ namespace psemek::audio struct recorder { - virtual std::optional length() const = 0; + virtual channel_ptr channel() = 0; virtual std::size_t request(std::size_t samples) = 0; virtual util::span buffer() const = 0; + virtual std::vector grab_buffer() = 0; + virtual ~recorder() {} }; + std::shared_ptr make_recorder(); std::shared_ptr make_recorder(stream_ptr stream); - std::shared_ptr make_recorder(std::vector samples); - std::shared_ptr make_recorder(util::span samples); } diff --git a/libs/audio/source/combine/duplicate.cpp b/libs/audio/source/combine/duplicate.cpp index 74f7f56c..c8f921d0 100644 --- a/libs/audio/source/combine/duplicate.cpp +++ b/libs/audio/source/combine/duplicate.cpp @@ -17,7 +17,7 @@ namespace psemek::audio std::optional length() const override { - return recorder_->length(); + return recorder_->channel()->stream()->length(); } std::size_t played() const override @@ -60,7 +60,7 @@ namespace psemek::audio std::optional length() const override { - return recorder_->length(); + return recorder_->channel()->stream()->length(); } private: @@ -74,4 +74,15 @@ namespace psemek::audio return std::make_shared(std::move(recorder)); } + track_ptr make_duplicator(stream_ptr stream) + { + return make_duplicator(make_recorder(std::move(stream))); + } + + std::pair duplicate(stream_ptr stream) + { + auto track = make_duplicator(std::move(stream)); + return {track->stream(), track->stream()}; + } + } diff --git a/libs/audio/source/recorder.cpp b/libs/audio/source/recorder.cpp index 74e76f2b..87a260a9 100644 --- a/libs/audio/source/recorder.cpp +++ b/libs/audio/source/recorder.cpp @@ -11,38 +11,36 @@ namespace psemek::audio struct recorder_impl : recorder { - recorder_impl(stream_ptr stream) - : stream_(std::move(stream)) + recorder_impl() + : channel_(std::make_shared()) {} - recorder_impl(std::vector samples) - : storage_(std::move(samples)) - , samples_(storage_) - {} - - recorder_impl(util::span samples) - : samples_(samples) - {} - - std::optional length() const override + channel_ptr channel() override { - return stream_ ? stream_->length() : storage_.size(); + return channel_; } - std::size_t request(std::size_t samples) override + std::size_t request(std::size_t sample_count) override { - if (!stream_) - return 0; + std::size_t count = 0; - if (storage_.size() < samples_.size() + samples) + if (storage_.size() < samples_.size() + sample_count) { - storage_.resize(std::max(samples, storage_.size() * 2)); + storage_.resize(std::max(sample_count, storage_.size() * 2)); samples_ = {storage_.data(), storage_.data() + samples_.size()}; } - auto count = stream_->read({storage_.data() + samples_.size(), samples}); - samples_ = {storage_.data(), storage_.data() + samples_.size() + count}; - return count; + if (auto stream = channel_->stream()) + { + count = stream->read({storage_.data() + samples_.size(), sample_count}); + if (count < sample_count) + channel_->stop(); + } + + std::fill(storage_.data() + samples_.size() + count, storage_.data() + samples_.size() + sample_count, 0.f); + samples_ = {storage_.data(), storage_.data() + samples_.size() + sample_count}; + + return sample_count; } util::span buffer() const override @@ -50,31 +48,31 @@ namespace psemek::audio return samples_; } + std::vector grab_buffer() override + { + storage_.resize(samples_.size()); + samples_ = {}; + return std::move(storage_); + } + private: - stream_ptr stream_; + channel_ptr channel_; std::vector storage_; util::span samples_; }; } + std::shared_ptr make_recorder() + { + return std::make_shared(); + } + std::shared_ptr make_recorder(stream_ptr stream) { - return std::make_shared(std::move(stream)); - } - - std::shared_ptr make_recorder(std::vector samples) - { - if ((samples.size() % 2) != 0) - throw std::runtime_error("bad sample count"); - return std::make_shared(std::move(samples)); - } - - std::shared_ptr make_recorder(util::span samples) - { - if ((samples.size() % 2) != 0) - throw std::runtime_error("bad sample count"); - return std::make_shared(samples); + auto recorder = make_recorder(); + recorder->channel()->stream(std::move(stream)); + return recorder; } }