#include #include #include namespace psemek::audio { namespace { struct recorder_impl : recorder { recorder_impl() : channel_(std::make_shared()) {} channel_ptr channel() override { return channel_; } std::size_t request(std::size_t sample_count) override { std::size_t count = 0; if (storage_.size() < samples_.size() + sample_count) { storage_.resize(std::max(samples_.size() + sample_count, storage_.size() * 2)); samples_ = {storage_.data(), storage_.data() + samples_.size()}; } 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 { return samples_; } std::vector grab_buffer() override { storage_.resize(samples_.size()); samples_ = {}; return std::move(storage_); } private: 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) { auto recorder = make_recorder(); recorder->channel()->stream(std::move(stream)); return recorder; } std::shared_ptr record(stream_ptr stream) { if (!stream->length()) throw util::exception("Cannot record an infinite stream"); return record(stream, *stream->length()); } std::shared_ptr record(stream_ptr stream, duration duration) { auto recorder = make_recorder(std::move(stream)); recorder->request(duration.samples()); return load_raw(recorder->grab_buffer()); } }