kfr

Fast, modern C++ DSP framework, FFT, Sample Rate Conversion, FIR/IIR/Biquad Filters (SSE, AVX, AVX-512, ARM NEON)
Log | Files | Refs | README

commit fd59e97ef992756afee50f86d5e9f1a9225d0d10
parent 52ea73a786d3443fa92ce9bb7c42182f157a4cde
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date:   Tue,  8 Nov 2016 06:51:24 +0300

waveshaper.hpp: add two saturation algorithms

Diffstat:
Minclude/kfr/dsp/waveshaper.hpp | 47+++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+), 0 deletions(-)

diff --git a/include/kfr/dsp/waveshaper.hpp b/include/kfr/dsp/waveshaper.hpp @@ -27,6 +27,7 @@ #include "../base/clamp.hpp" #include "../base/hyperbolic.hpp" +#include "../base/operators.hpp" namespace kfr { @@ -41,4 +42,50 @@ inline auto waveshaper_tanh(E1&& input, double saturation) { return tanh(saturation * input) * (coth(saturation)); } + +template <typename T1, KFR_ENABLE_IF(is_numeric<T1>::value)> +CMT_FUNC flt_type<T1> saturate_I(const T1& x) +{ + const flt_type<T1> xx = -1 / (abs(static_cast<flt_type<T1>>(x)) + 1) + 1; + return mulsign(xx, static_cast<flt_type<T1>>(x)); +} +KFR_FN(saturate_I) + +template <typename T1, KFR_ENABLE_IF(is_numeric<T1>::value)> +CMT_FUNC flt_type<T1> saturate_II(const T1& x) +{ + const flt_type<T1> xx = sqr(abs(static_cast<flt_type<T1>>(x)) + 1); + return mulsign((xx - 1) / (xx + 1), static_cast<flt_type<T1>>(x)); +} +KFR_FN(saturate_II) + +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>::value)> +CMT_FUNC internal::expression_function<fn::saturate_II, E1> saturate_I(E1&& x) +{ + return { fn::saturate_I(), std::forward<E1>(x) }; +} + +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>::value)> +CMT_FUNC internal::expression_function<fn::saturate_II, E1> saturate_II(E1&& x) +{ + return { fn::saturate_II(), std::forward<E1>(x) }; +} + +template <typename E1> +inline auto waveshaper_saturate_I(E1&& input, double saturation) +{ + return saturate_I(saturation * input) / (saturate_I(saturation)); +} + +template <typename E1> +inline auto waveshaper_saturate_II(E1&& input, double saturation) +{ + return saturate_II(saturation * input) / (saturate_II(saturation)); +} + +template <typename E1, typename... Cs> +inline auto waveshaper_poly(E1&& input, fbase c1, fbase c3, Cs... cs) +{ + return horner_odd(input, c1, c3, static_cast<fbase>(cs)...); +} }