From 55b710687aaa8ef7e79e61011c501dfb497d4bcf Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Wed, 18 Mar 2020 20:02:15 +0100 Subject: [PATCH] Add the gain effect --- src/CMakeLists.txt | 1 + src/sfizz/Effects.cpp | 2 ++ src/sfizz/effects/Gain.cpp | 73 ++++++++++++++++++++++++++++++++++++++ src/sfizz/effects/Gain.h | 50 ++++++++++++++++++++++++++ 4 files changed, 126 insertions(+) create mode 100644 src/sfizz/effects/Gain.cpp create mode 100644 src/sfizz/effects/Gain.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2fcaeb88..d4c738d2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,6 +26,7 @@ set (SFIZZ_SOURCES sfizz/effects/Lofi.cpp sfizz/effects/Limiter.cpp sfizz/effects/Rectify.cpp + sfizz/effects/Gain.cpp ) include (SfizzSIMDSourceFiles) diff --git a/src/sfizz/Effects.cpp b/src/sfizz/Effects.cpp index eb6625f3..bfa8f52c 100644 --- a/src/sfizz/Effects.cpp +++ b/src/sfizz/Effects.cpp @@ -16,6 +16,7 @@ #include "effects/Lofi.h" #include "effects/Limiter.h" #include "effects/Rectify.h" +#include "effects/Gain.h" #include namespace sfz { @@ -31,6 +32,7 @@ void EffectFactory::registerStandardEffectTypes() // extensions (book) registerEffectType("rectify", fx::Rectify::makeInstance); + registerEffectType("gain", fx::Gain::makeInstance); } void EffectFactory::registerEffectType(absl::string_view name, Effect::MakeInstance& make) diff --git a/src/sfizz/effects/Gain.cpp b/src/sfizz/effects/Gain.cpp new file mode 100644 index 00000000..e5b46acc --- /dev/null +++ b/src/sfizz/effects/Gain.cpp @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: BSD-2-Clause + +// This code is part of the sfizz library and is licensed under a BSD 2-clause +// license. You should have receive a LICENSE.md file along with the code. +// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz + + +/** + Note(jpc): this effect is book-only, mentioned but not documented + + Note(jpc): implementation status + +- [x] gain +- [ ] gain_oncc + */ + +#include "Gain.h" +#include "Opcode.h" +#include "SIMDHelpers.h" +#include "absl/memory/memory.h" + +namespace sfz { +namespace fx { + + void Gain::setSampleRate(double sampleRate) + { + (void)sampleRate; + } + + void Gain::setSamplesPerBlock(int samplesPerBlock) + { + _tempBuffer.resize(samplesPerBlock); + } + + void Gain::clear() + { + } + + void Gain::process(const float* const inputs[], float* const outputs[], unsigned nframes) + { + const float baseGain = _gain; + + absl::Span gains = _tempBuffer.getSpan(0); + std::fill(gains.begin(), gains.end(), baseGain); + + // to linear + for (unsigned i = 0; i < nframes; ++i) + gains[i] = std::pow(10.0f, 0.05f * gains[i]); + + for (unsigned c = 0; c < EffectChannels; ++c) { + absl::Span input { inputs[c], nframes }; + absl::Span output { outputs[c], nframes }; + sfz::applyGain(absl::Span { gains }, input, output); + } + } + + std::unique_ptr Gain::makeInstance(absl::Span members) + { + auto fx = absl::make_unique(); + + for (const Opcode& opc : members) { + switch (opc.lettersOnlyHash) { + case hash("gain"): + setValueFromOpcode(opc, fx->_gain, {-96.0f, 96.0f}); + break; + } + } + + return CXX11_MOVE(fx); + } + +} // namespace fx +} // namespace sfz diff --git a/src/sfizz/effects/Gain.h b/src/sfizz/effects/Gain.h new file mode 100644 index 00000000..20a95f59 --- /dev/null +++ b/src/sfizz/effects/Gain.h @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: BSD-2-Clause + +// This code is part of the sfizz library and is licensed under a BSD 2-clause +// license. You should have receive a LICENSE.md file along with the code. +// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz + +#pragma once +#include "Effects.h" + +namespace sfz { +namespace fx { + + /** + * @brief Gain effect + */ + class Gain : public Effect { + public: + /** + * @brief Initializes with the given sample rate. + */ + void setSampleRate(double sampleRate) override; + + /** + * @brief Sets the maximum number of frames to render at a time. The actual + * value can be lower but should never be higher. + */ + void setSamplesPerBlock(int samplesPerBlock) override; + + /** + * @brief Reset the state to initial. + */ + void clear() override; + + /** + * @brief Copy the input signal to the output + */ + void process(const float* const inputs[], float* const outputs[], unsigned nframes) override; + + /** + * @brief Instantiates given the contents of the block. + */ + static std::unique_ptr makeInstance(absl::Span members); + + private: + float _gain = 0; // in dB + AudioBuffer _tempBuffer { 1, config::defaultSamplesPerBlock }; + }; + +} // namespace fx +} // namespace sfz