78 lines
1.6 KiB
C++
78 lines
1.6 KiB
C++
#include <psemek/audio/recorder.hpp>
|
|
|
|
#include <vector>
|
|
|
|
namespace psemek::audio
|
|
{
|
|
|
|
namespace
|
|
{
|
|
|
|
struct recorder_impl
|
|
: recorder
|
|
{
|
|
recorder_impl()
|
|
: channel_(std::make_shared<audio::channel>())
|
|
{}
|
|
|
|
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<std::size_t>(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<float const> buffer() const override
|
|
{
|
|
return samples_;
|
|
}
|
|
|
|
std::vector<float> grab_buffer() override
|
|
{
|
|
storage_.resize(samples_.size());
|
|
samples_ = {};
|
|
return std::move(storage_);
|
|
}
|
|
|
|
private:
|
|
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)
|
|
{
|
|
auto recorder = make_recorder();
|
|
recorder->channel()->stream(std::move(stream));
|
|
return recorder;
|
|
}
|
|
|
|
}
|