95 lines
1.9 KiB
C++
95 lines
1.9 KiB
C++
#include <psemek/audio/effect/pause.hpp>
|
|
#include <psemek/audio/smooth.hpp>
|
|
|
|
#include <atomic>
|
|
|
|
namespace psemek::audio
|
|
{
|
|
|
|
namespace
|
|
{
|
|
|
|
struct pause_control_impl
|
|
: pause_control
|
|
{
|
|
pause_control_impl(stream_ptr stream, bool paused, duration length)
|
|
: stream_(std::move(stream))
|
|
, paused_{paused}
|
|
, length_(length)
|
|
, level_(paused ? 0 : length_.samples())
|
|
{}
|
|
|
|
bool paused() const override
|
|
{
|
|
return paused_.load();
|
|
}
|
|
|
|
bool paused(bool value) override
|
|
{
|
|
return paused_.exchange(value);
|
|
}
|
|
|
|
std::optional<std::size_t> length() const override
|
|
{
|
|
return stream_->length();
|
|
}
|
|
|
|
std::size_t read(util::span<float> samples) override
|
|
{
|
|
bool const paused = paused_.load();
|
|
|
|
if (paused)
|
|
{
|
|
auto count = stream_->read(samples.prefix(std::min(samples.size(), level_)));
|
|
|
|
for (std::size_t i = 0; i < count; i += 2)
|
|
{
|
|
float gain = static_cast<float>(level_) / length_.samples();
|
|
samples[i + 0] *= gain;
|
|
samples[i + 1] *= gain;
|
|
level_ -= 2;
|
|
}
|
|
|
|
std::fill(samples.begin() + count, samples.end(), 0.f);
|
|
return samples.size();
|
|
}
|
|
else
|
|
{
|
|
auto count = stream_->read(samples);
|
|
|
|
auto const max_level = static_cast<std::size_t>(length_.samples());
|
|
|
|
for (std::size_t i = 0; i < count; i += 2)
|
|
{
|
|
float gain = static_cast<float>(level_) / max_level;
|
|
samples[i + 0] *= gain;
|
|
samples[i + 1] *= gain;
|
|
|
|
if (level_ < max_level)
|
|
level_ += 2;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
}
|
|
|
|
std::size_t played() const override
|
|
{
|
|
return stream_->played();
|
|
}
|
|
|
|
private:
|
|
stream_ptr stream_;
|
|
std::atomic<bool> paused_;
|
|
duration length_;
|
|
std::size_t level_;
|
|
};
|
|
|
|
}
|
|
|
|
std::shared_ptr<pause_control> pause(stream_ptr stream, bool paused, duration length)
|
|
{
|
|
return std::make_shared<pause_control_impl>(std::move(stream), paused, length);
|
|
}
|
|
|
|
}
|