Audio recorder & duplicator refactor
This commit is contained in:
parent
cbd5a15ce8
commit
3b5ad89ba0
4 changed files with 55 additions and 53 deletions
|
|
@ -10,16 +10,7 @@ namespace psemek::audio
|
|||
{
|
||||
|
||||
track_ptr make_duplicator(std::shared_ptr<recorder> recorder);
|
||||
|
||||
inline track_ptr make_duplicator(stream_ptr stream)
|
||||
{
|
||||
return make_duplicator(make_recorder(std::move(stream)));
|
||||
}
|
||||
|
||||
inline std::pair<stream_ptr, stream_ptr> 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<stream_ptr, stream_ptr> duplicate(stream_ptr stream);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <psemek/audio/stream.hpp>
|
||||
#include <psemek/audio/channel.hpp>
|
||||
#include <psemek/util/span.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
|
@ -10,17 +11,18 @@ namespace psemek::audio
|
|||
|
||||
struct recorder
|
||||
{
|
||||
virtual std::optional<std::size_t> length() const = 0;
|
||||
virtual channel_ptr channel() = 0;
|
||||
|
||||
virtual std::size_t request(std::size_t samples) = 0;
|
||||
|
||||
virtual util::span<float const> buffer() const = 0;
|
||||
|
||||
virtual std::vector<float> grab_buffer() = 0;
|
||||
|
||||
virtual ~recorder() {}
|
||||
};
|
||||
|
||||
std::shared_ptr<recorder> make_recorder();
|
||||
std::shared_ptr<recorder> make_recorder(stream_ptr stream);
|
||||
std::shared_ptr<recorder> make_recorder(std::vector<float> samples);
|
||||
std::shared_ptr<recorder> make_recorder(util::span<float const> samples);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace psemek::audio
|
|||
|
||||
std::optional<std::size_t> 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<std::size_t> length() const override
|
||||
{
|
||||
return recorder_->length();
|
||||
return recorder_->channel()->stream()->length();
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -74,4 +74,15 @@ namespace psemek::audio
|
|||
return std::make_shared<duplicate_track_impl>(std::move(recorder));
|
||||
}
|
||||
|
||||
track_ptr make_duplicator(stream_ptr stream)
|
||||
{
|
||||
return make_duplicator(make_recorder(std::move(stream)));
|
||||
}
|
||||
|
||||
std::pair<stream_ptr, stream_ptr> duplicate(stream_ptr stream)
|
||||
{
|
||||
auto track = make_duplicator(std::move(stream));
|
||||
return {track->stream(), track->stream()};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<audio::channel>())
|
||||
{}
|
||||
|
||||
recorder_impl(std::vector<float> samples)
|
||||
: storage_(std::move(samples))
|
||||
, samples_(storage_)
|
||||
{}
|
||||
|
||||
recorder_impl(util::span<float const> samples)
|
||||
: samples_(samples)
|
||||
{}
|
||||
|
||||
std::optional<std::size_t> 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<std::size_t>(samples, storage_.size() * 2));
|
||||
storage_.resize(std::max<std::size_t>(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<float const> buffer() const override
|
||||
|
|
@ -50,31 +48,31 @@ namespace psemek::audio
|
|||
return samples_;
|
||||
}
|
||||
|
||||
std::vector<float> grab_buffer() override
|
||||
{
|
||||
storage_.resize(samples_.size());
|
||||
samples_ = {};
|
||||
return std::move(storage_);
|
||||
}
|
||||
|
||||
private:
|
||||
stream_ptr stream_;
|
||||
channel_ptr channel_;
|
||||
std::vector<float> storage_;
|
||||
util::span<float const> samples_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<recorder> make_recorder()
|
||||
{
|
||||
return std::make_shared<recorder_impl>();
|
||||
}
|
||||
|
||||
std::shared_ptr<recorder> make_recorder(stream_ptr stream)
|
||||
{
|
||||
return std::make_shared<recorder_impl>(std::move(stream));
|
||||
}
|
||||
|
||||
std::shared_ptr<recorder> make_recorder(std::vector<float> samples)
|
||||
{
|
||||
if ((samples.size() % 2) != 0)
|
||||
throw std::runtime_error("bad sample count");
|
||||
return std::make_shared<recorder_impl>(std::move(samples));
|
||||
}
|
||||
|
||||
std::shared_ptr<recorder> make_recorder(util::span<float const> samples)
|
||||
{
|
||||
if ((samples.size() % 2) != 0)
|
||||
throw std::runtime_error("bad sample count");
|
||||
return std::make_shared<recorder_impl>(samples);
|
||||
auto recorder = make_recorder();
|
||||
recorder->channel()->stream(std::move(stream));
|
||||
return recorder;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue