From 6f6add1cabc92b0d173b63bc4e5f18be36d9e072 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Sat, 8 Oct 2022 21:31:44 +0300 Subject: [PATCH] Add distortion effect --- .../psemek/audio/effect/distortion.hpp | 17 +++++ libs/audio/source/effect/distortion.cpp | 65 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 libs/audio/include/psemek/audio/effect/distortion.hpp create mode 100644 libs/audio/source/effect/distortion.cpp diff --git a/libs/audio/include/psemek/audio/effect/distortion.hpp b/libs/audio/include/psemek/audio/effect/distortion.hpp new file mode 100644 index 00000000..26017935 --- /dev/null +++ b/libs/audio/include/psemek/audio/effect/distortion.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include + +namespace psemek::audio +{ + + struct distortion_control + : stream + { + virtual float strength() const = 0; + virtual float strength(float value) = 0; + }; + + stream_ptr distortion(stream_ptr stream, float strength = 100.f); + +} diff --git a/libs/audio/source/effect/distortion.cpp b/libs/audio/source/effect/distortion.cpp new file mode 100644 index 00000000..f8a0be5d --- /dev/null +++ b/libs/audio/source/effect/distortion.cpp @@ -0,0 +1,65 @@ +#include + +#include +#include + +namespace psemek::audio +{ + + namespace + { + + struct distortion_impl + : distortion_control + { + distortion_impl(stream_ptr stream, float strength) + : stream_(std::move(stream)) + , strength_(strength) + {} + + float strength() const override + { + return strength_.load(); + } + + float strength(float value) override + { + return strength_.exchange(value); + } + + std::optional length() const override + { + return stream_->length(); + } + + std::size_t read(float * data, std::size_t sample_count) override + { + auto result = stream_->read(data, sample_count); + float strength = strength_.load(); + + for (std::size_t i = 0; i < result; ++i) + { + data[i] = std::tanh(strength * data[i]); + } + + return result; + } + + std::size_t played() const override + { + return stream_->played(); + } + + private: + stream_ptr stream_; + std::atomic strength_; + }; + + } + + stream_ptr distortion(stream_ptr stream, float strength) + { + return std::make_shared(std::move(stream), strength); + } + +}