diff --git a/eMeta b/eMeta index fb1b10e0..0c99a07c 160000 --- a/eMeta +++ b/eMeta @@ -1 +1 @@ -Subproject commit fb1b10e0a9aa0f65c2a1ed8163dd07c0d71d1ac6 +Subproject commit 0c99a07ca1fa1fcd04b5498206f3611c4c034226 diff --git a/include/easy/dsp/random/pink_noise_generator.hpp b/include/easy/dsp/random/pink_noise_generator.hpp new file mode 100644 index 00000000..3e9ee52c --- /dev/null +++ b/include/easy/dsp/random/pink_noise_generator.hpp @@ -0,0 +1,62 @@ +/* + * EasyDSP, A cross-platform Digital Signal Processing library written in modern C++. + * Copyright (C) 2018 Mohammed Boujemaoui Boulaghmoudi + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along withº + * this program. If not, see + * + * Filename: pink_noise.hpp + * Author: Mohammed Boujemaoui + * Date: 31/7/2018 + */ +#ifndef EASYDSP_PINK_NOISE_HPP +#define EASYDSP_PINK_NOISE_HPP + +#include "white_noise_generator.hpp" + +namespace easy { namespace dsp { namespace random { + + template + struct PinkNoiseGenerator { + using result_type = T; + inline PinkNoiseGenerator(result_type min, result_type max) : + generator_(WhiteNoiseGenerator(min, max)) { + + } + + inline result_type operator()() { + result_type white = generator_(); + b0 = 0.99886 * b0 + white * 0.0555179; + b1 = 0.99332 * b1 + white * 0.0750759; + b2 = 0.96900 * b2 + white * 0.1538520; + b3 = 0.86650 * b3 + white * 0.3104856; + b4 = 0.55000 * b4 + white * 0.5329522; + b5 = -0.7616 * b5 - white * 0.0168980; + result_type output = (b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362) * 0.11; + b6 = white * 0.115926; + return output; + } + private: + result_type b0{0}; + result_type b1{0}; + result_type b2{0}; + result_type b3{0}; + result_type b4{0}; + result_type b5{0}; + result_type b6{0}; + WhiteNoiseGenerator generator_; + }; + +}}} + +#endif // EASYDSP_PINK_NOISE_HPP diff --git a/include/easy/dsp/random/random_generator.hpp b/include/easy/dsp/random/random_generator.hpp new file mode 100644 index 00000000..2f696da1 --- /dev/null +++ b/include/easy/dsp/random/random_generator.hpp @@ -0,0 +1,151 @@ +/* + * EasyDSP, A cross-platform Digital Signal Processing library written in modern C++. + * Copyright (C) 2018 Mohammed Boujemaoui Boulaghmoudi + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along withº + * this program. If not, see + * + * Filename: random_generator.hpp + * Author: Mohammed Boujemaoui + * Date: 31/7/2018 + */ +#ifndef EASYDSP_FISHER_DISTRIBUTION_HPP +#define EASYDSP_FISHER_DISTRIBUTION_HPP + +#include +#include + +namespace easy { namespace dsp { namespace random { + + enum class Distribution { + Uniform, + Bernoulli, + Binomial, + Geometric, + Poisson, + Exponential, + Gamma, + Weibull, + ExtremeValue, + Normal, + LogNormal, + ChiSquared, + Cauchy, + Fisher, + Student, + Discrete, + PieceWiseConstant, + PieceWiseLinear + }; + + namespace { + template + struct RandomGeneratorImpl { + template + RandomGeneratorImpl(Args... arg) : + generator_(Engine(static_cast(std::chrono::system_clock::now() + .time_since_epoch() + .count()))), + distribution_(Distribution(std::forward(arg...))) + {} + + inline result_type operator()() { + return static_cast(distribution_(generator_)); + } + + private: + Engine generator_; + Distribution distribution_; + }; + + template + struct _RandomGenerator; + + template + struct _RandomGenerator + : public RandomGeneratorImpl> {}; + + template + struct _RandomGenerator + : public RandomGeneratorImpl {}; + + template + struct _RandomGenerator + : public RandomGeneratorImpl> {}; + + template + struct _RandomGenerator + : public RandomGeneratorImpl> {}; + + template + struct _RandomGenerator + : public RandomGeneratorImpl> {}; + + template + struct _RandomGenerator + : public RandomGeneratorImpl> {}; + + template + struct _RandomGenerator + : public RandomGeneratorImpl> {}; + + template + struct _RandomGenerator + : public RandomGeneratorImpl> {}; + + template + struct _RandomGenerator + : public RandomGeneratorImpl> {}; + + template + struct _RandomGenerator + : public RandomGeneratorImpl> {}; + + template + struct _RandomGenerator + : public RandomGeneratorImpl> {}; + + template + struct _RandomGenerator + : public RandomGeneratorImpl> {}; + + template + struct _RandomGenerator + : public RandomGeneratorImpl> {}; + + template + struct _RandomGenerator + : public RandomGeneratorImpl> {}; + + template + struct _RandomGenerator + : public RandomGeneratorImpl> {}; + + template + struct _RandomGenerator + : public RandomGeneratorImpl> {}; + + template + struct _RandomGenerator + : public RandomGeneratorImpl> {}; + + } + + template + struct RandomGenerator : public _RandomGenerator {}; + +}}} + +#endif // EASYDSP_FISHER_DISTRIBUTION_HPP diff --git a/include/easy/dsp/random/white_noise_generator.hpp b/include/easy/dsp/random/white_noise_generator.hpp new file mode 100644 index 00000000..9a30a1e6 --- /dev/null +++ b/include/easy/dsp/random/white_noise_generator.hpp @@ -0,0 +1,53 @@ +/* + * EasyDSP, A cross-platform Digital Signal Processing library written in modern C++. + * Copyright (C) 2018 Mohammed Boujemaoui Boulaghmoudi + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along withº + * this program. If not, see + * + * Filename: white_noise.hpp + * Author: Mohammed Boujemaoui + * Date: 31/7/2018 + */ +#ifndef EASYDSP_WHITE_NOISE_HPP +#define EASYDSP_WHITE_NOISE_HPP + +#include +#include + +namespace easy { namespace dsp { namespace random { + + template + struct WhiteNoiseGenerator { + using result_type = T; + inline WhiteNoiseGenerator(result_type min, result_type max) : + generator_(Engine(static_cast(std::chrono::system_clock::now() + .time_since_epoch() + .count()))), + distribution_(std::uniform_int_distribution(min, max)) { + + } + + inline result_type operator()() { + return static_cast(distribution_(generator_)); + } + private: + Engine generator_; + std::uniform_int_distribution distribution_; + }; + +}}} + + + +#endif // EASYDSP_WHITE_NOISE_HPP diff --git a/include/easy/dsp/utilities/envelope_follower.hpp b/include/easy/dsp/utilities/envelope_follower.hpp new file mode 100644 index 00000000..913278dd --- /dev/null +++ b/include/easy/dsp/utilities/envelope_follower.hpp @@ -0,0 +1,147 @@ +/* + * EasyDSP, A cross-platform Digital Signal Processing library written in modern C++. + * Copyright (C) 2018 Mohammed Boujemaoui Boulaghmoudi + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along withº + * this program. If not, see + * + * Filename: envelope_follower.hpp + * Author: Mohammed Boujemaoui + * Date: 14/6/2018 + */ +#ifndef EASYDSP_FEATURE_TEMPORAL_ENVELOPE_HPP +#define EASYDSP_FEATURE_TEMPORAL_ENVELOPE_HPP + +#include +#include +#include + +namespace easy { namespace dsp { + + template + class Envelope { + public: + using value_type = T; + using size_type = std::size_t; + + constexpr Envelope(value_type samplerate, + value_type attackTime, + value_type releaseTime, + bool rectify = false) noexcept; + constexpr value_type sampleRate() const noexcept; + constexpr void setSampleRate(value_type samplerate) noexcept; + constexpr value_type attackTime() const noexcept; + constexpr void setAttackTime(value_type attackTime) noexcept; + constexpr value_type releaseTime() const noexcept; + constexpr void setReleaseTime(value_type releaseTime) noexcept; + constexpr bool isRectificationEnabled() const noexcept; + constexpr void enableRectification(bool enabled) noexcept; + constexpr void reset() noexcept; + + template + constexpr void apply(BiIterator first, BiIterator last); + + template + constexpr void apply(InputIterator first, InputIterator last, OutputIterator out); + + private: + value_type samplerate_{44100}; + value_type attack_time_{10}; + value_type attack_gain_{0}; + value_type release_time_{1500}; + value_type release_gain_{0}; + value_type last_{0}; + bool rectification_{false}; + }; + + template + constexpr Envelope::Envelope(value_type samplerate, value_type attack_time, value_type release_time, + bool rectify) noexcept : + samplerate_(samplerate), + attack_time_(attack_time), + release_time_(release_time), + rectification_(rectify) { + reset(); + } + + template + constexpr typename Envelope::value_type Envelope::sampleRate() const noexcept { + return samplerate_; + } + + template + constexpr void Envelope::setSampleRate(value_type samplerate) noexcept { + samplerate_ = samplerate; + reset(); + } + + template + constexpr typename Envelope::value_type Envelope::attackTime() const noexcept { + return attack_time_; + } + + template + constexpr void Envelope::setAttackTime(value_type attack_time) noexcept { + attack_time_ = attack_time; + reset(); + } + + template + constexpr typename Envelope::value_type Envelope::releaseTime() const noexcept { + return release_time_; + } + + template + constexpr void Envelope::setReleaseTime(value_type release_time) noexcept { + release_time_ = release_time; + reset(); + } + + template + constexpr bool Envelope::isRectificationEnabled() const noexcept { + return rectification_; + } + + template + constexpr void Envelope::enableRectification(bool enabled) noexcept { + rectification_ = enabled; + } + + template + constexpr void Envelope::reset() noexcept { + attack_gain_ = (attack_gain_ > 0) ? static_cast(std::exp(-1 / (attack_time_ * samplerate_))) : 0; + release_gain_ = (release_gain_ > 0) ? static_cast(std::exp(-1 / (release_time_ * samplerate_))) : 0; + last_ = 0; + } + + template + template + constexpr void Envelope::apply(BiIterator first, BiIterator last) { + apply(first, last, first); + } + + template + template + constexpr void Envelope::apply(InputIterator first, InputIterator last, OutputIterator out) { + for (; first != last; ++first, ++out) { + const auto rectified = rectification_ ? std::abs(*first) : *first; + const auto current = (last_ < rectified) ? (1 - attack_gain_) * rectified + attack_gain_ * last_ + : (1 - release_gain_) * rectified + release_gain_ * last_; + last_ = meta::is_denormal(current) ? 0 : current; + *out = last_; + } + } + +}} // namespace easy::dsp + +#endif // EASYDSP_FEATURE_TEMPORAL_ENVELOPE_HPP