From d19c93af33b256e66592051ffe5f28d8e964e3bc Mon Sep 17 00:00:00 2001 From: lisyarus Date: Thu, 6 Oct 2022 13:12:14 +0300 Subject: [PATCH] Support retrieving the number of already played samples from a stream --- libs/audio/include/psemek/audio/stream.hpp | 4 ++++ libs/audio/include/psemek/audio/wave/generator.hpp | 7 +++++++ libs/audio/source/duplicate.cpp | 5 +++++ libs/audio/source/effect/fade_in.cpp | 5 +++++ libs/audio/source/effect/fade_out.cpp | 5 +++++ libs/audio/source/effect/volume.cpp | 5 +++++ libs/audio/source/mixer.cpp | 9 +++++++++ libs/audio/source/stereo.cpp | 5 +++++ libs/audio/source/wave/silence.cpp | 9 +++++++++ 9 files changed, 54 insertions(+) diff --git a/libs/audio/include/psemek/audio/stream.hpp b/libs/audio/include/psemek/audio/stream.hpp index dbb5f65f..910d15bc 100644 --- a/libs/audio/include/psemek/audio/stream.hpp +++ b/libs/audio/include/psemek/audio/stream.hpp @@ -16,6 +16,10 @@ namespace psemek::audio // Must be called from mixing thread virtual std::size_t read(float * data, std::size_t sample_count) = 0; + // The number of samples already played from this stream + // Must be called from mixing thread + virtual std::size_t played() const = 0; + virtual ~stream() {} }; diff --git a/libs/audio/include/psemek/audio/wave/generator.hpp b/libs/audio/include/psemek/audio/wave/generator.hpp index 04c59cdc..c0540ed2 100644 --- a/libs/audio/include/psemek/audio/wave/generator.hpp +++ b/libs/audio/include/psemek/audio/wave/generator.hpp @@ -19,6 +19,11 @@ namespace psemek::audio return std::nullopt; } + std::size_t played() const override + { + return played_; + } + std::size_t read(float * data, std::size_t sample_count) override { auto end = data + sample_count; @@ -28,11 +33,13 @@ namespace psemek::audio *p++ = v; *p++ = v; } + played_ += sample_count; return sample_count; } private: Func func_; + std::size_t played_ = 0; }; } diff --git a/libs/audio/source/duplicate.cpp b/libs/audio/source/duplicate.cpp index 6bdeb0bd..c1964b59 100644 --- a/libs/audio/source/duplicate.cpp +++ b/libs/audio/source/duplicate.cpp @@ -32,6 +32,11 @@ namespace psemek::audio return common_->stream->length(); } + std::size_t played() const override + { + return common_->stream->played(); + } + std::size_t read(float * data, std::size_t sample_count) override { if (counter_ == common_->counter) diff --git a/libs/audio/source/effect/fade_in.cpp b/libs/audio/source/effect/fade_in.cpp index ba4c0700..c1be8153 100644 --- a/libs/audio/source/effect/fade_in.cpp +++ b/libs/audio/source/effect/fade_in.cpp @@ -23,6 +23,11 @@ namespace psemek::audio return stream_->length(); } + std::size_t played() const override + { + return stream_->played(); + } + std::size_t read(float * data, std::size_t sample_count) override { auto const result = stream_->read(data, sample_count); diff --git a/libs/audio/source/effect/fade_out.cpp b/libs/audio/source/effect/fade_out.cpp index 9f7b6266..6d0e2b09 100644 --- a/libs/audio/source/effect/fade_out.cpp +++ b/libs/audio/source/effect/fade_out.cpp @@ -24,6 +24,11 @@ namespace psemek::audio return stream_->length(); } + std::size_t played() const override + { + return stream_->played(); + } + std::size_t read(float * data, std::size_t sample_count) override { if (current_ >= length_) diff --git a/libs/audio/source/effect/volume.cpp b/libs/audio/source/effect/volume.cpp index 28a4584b..791fc0f2 100644 --- a/libs/audio/source/effect/volume.cpp +++ b/libs/audio/source/effect/volume.cpp @@ -26,6 +26,11 @@ namespace psemek::audio return stream_->length(); } + std::size_t played() const override + { + return stream_->played(); + } + std::size_t read(float * data, std::size_t sample_count) override { auto result = stream_->read(data, sample_count); diff --git a/libs/audio/source/mixer.cpp b/libs/audio/source/mixer.cpp index 460d4466..35af129a 100644 --- a/libs/audio/source/mixer.cpp +++ b/libs/audio/source/mixer.cpp @@ -23,6 +23,11 @@ namespace psemek::audio return std::nullopt; } + std::size_t played() const override + { + return played_; + } + private: std::vector channels_; std::vector alive_channels_; @@ -31,6 +36,8 @@ namespace psemek::audio std::mutex new_channels_mutex_; std::vector new_channels_; + + std::size_t played_ = 0; }; channel_ptr mixer_impl::add(stream_ptr stream) @@ -89,6 +96,8 @@ namespace psemek::audio std::swap(channels_, alive_channels_); alive_channels_.clear(); + played_ += sample_count; + return sample_count; } diff --git a/libs/audio/source/stereo.cpp b/libs/audio/source/stereo.cpp index b5c0b0c1..32bc9d13 100644 --- a/libs/audio/source/stereo.cpp +++ b/libs/audio/source/stereo.cpp @@ -29,6 +29,11 @@ namespace psemek::audio return right; } + std::size_t played() const override + { + return std::min(left_->played(), right_->played()); + } + std::size_t read(float * data, std::size_t sample_count) override { if (buffer_.size() < sample_count) diff --git a/libs/audio/source/wave/silence.cpp b/libs/audio/source/wave/silence.cpp index 7d3c1d3d..567752ed 100644 --- a/libs/audio/source/wave/silence.cpp +++ b/libs/audio/source/wave/silence.cpp @@ -12,6 +12,7 @@ namespace psemek::audio std::size_t read(float * data, std::size_t sample_count) override { std::fill(data, data + sample_count, 0.f); + played_ += sample_count; return sample_count; } @@ -19,6 +20,14 @@ namespace psemek::audio { return std::nullopt; } + + std::size_t played() const override + { + return played_; + } + + private: + std::size_t played_ = 0; }; }