Implement audio::duplicator properly (using recorder)
This commit is contained in:
parent
e4871da0c5
commit
63f7e9c32a
2 changed files with 32 additions and 31 deletions
|
|
@ -1,12 +1,21 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <psemek/audio/stream.hpp>
|
#include <psemek/audio/stream.hpp>
|
||||||
|
#include <psemek/util/function.hpp>
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace psemek::audio
|
namespace psemek::audio
|
||||||
{
|
{
|
||||||
|
|
||||||
std::pair<stream_ptr, stream_ptr> duplicate(stream_ptr stream);
|
using duplicator = util::function<stream_ptr()>;
|
||||||
|
|
||||||
|
duplicator make_duplicator(stream_ptr stream);
|
||||||
|
|
||||||
|
inline std::pair<stream_ptr, stream_ptr> duplicate(stream_ptr stream)
|
||||||
|
{
|
||||||
|
auto dup = make_duplicator(std::move(stream));
|
||||||
|
return {dup(), dup()};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include <psemek/audio/duplicate.hpp>
|
#include <psemek/audio/duplicate.hpp>
|
||||||
|
#include <psemek/audio/recorder.hpp>
|
||||||
|
|
||||||
#include <vector>
|
#include <atomic>
|
||||||
|
|
||||||
namespace psemek::audio
|
namespace psemek::audio
|
||||||
{
|
{
|
||||||
|
|
@ -8,61 +9,52 @@ namespace psemek::audio
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
struct duplicate_common
|
|
||||||
{
|
|
||||||
duplicate_common(stream_ptr stream)
|
|
||||||
: stream(std::move(stream))
|
|
||||||
{}
|
|
||||||
|
|
||||||
stream_ptr stream;
|
|
||||||
std::vector<float> buffer;
|
|
||||||
std::size_t counter = 0;
|
|
||||||
std::size_t read = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct duplicate_impl
|
struct duplicate_impl
|
||||||
: stream
|
: stream
|
||||||
{
|
{
|
||||||
duplicate_impl(std::shared_ptr<duplicate_common> common)
|
duplicate_impl(std::shared_ptr<audio::recorder> recorder)
|
||||||
: common_(std::move(common))
|
: recorder_(std::move(recorder))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::optional<std::size_t> length() const override
|
std::optional<std::size_t> length() const override
|
||||||
{
|
{
|
||||||
return common_->stream->length();
|
return recorder_->stream()->length();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t played() const override
|
std::size_t played() const override
|
||||||
{
|
{
|
||||||
return common_->stream->played();
|
return played_.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t read(float * data, std::size_t sample_count) override
|
std::size_t read(float * data, std::size_t sample_count) override
|
||||||
{
|
{
|
||||||
if (counter_ == common_->counter)
|
auto buffer = recorder_->buffer();
|
||||||
|
auto played = played_.load();
|
||||||
|
if (buffer.size() < played + sample_count)
|
||||||
{
|
{
|
||||||
++common_->counter;
|
recorder_->request(sample_count);
|
||||||
if (common_->buffer.size() < sample_count)
|
buffer = recorder_->buffer();
|
||||||
common_->buffer.resize(sample_count);
|
|
||||||
common_->read = common_->stream->read(common_->buffer.data(), sample_count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::copy(common_->buffer.data(), common_->buffer.data() + common_->read, data);
|
auto count = std::min<std::size_t>(sample_count, buffer.size() - played);
|
||||||
++counter_;
|
std::copy(buffer.data() + played, buffer.data() + played + count, data);
|
||||||
return common_->read;
|
played_.fetch_add(count);
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<duplicate_common> common_;
|
std::shared_ptr<recorder> recorder_;
|
||||||
std::size_t counter_ = 0;
|
std::atomic<std::size_t> played_{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<stream_ptr, stream_ptr> duplicate(stream_ptr stream)
|
duplicator make_duplicator(stream_ptr stream)
|
||||||
{
|
{
|
||||||
auto common = std::make_shared<duplicate_common>(std::move(stream));
|
auto recorder = make_recorder(std::move(stream));
|
||||||
return {std::make_shared<duplicate_impl>(common), std::make_shared<duplicate_impl>(common)};
|
return [recorder]{
|
||||||
|
return std::make_shared<duplicate_impl>(recorder);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue