Add the gain effect

This commit is contained in:
Jean Pierre Cimalando 2020-03-18 20:02:15 +01:00
parent 5cd5db877a
commit 55b710687a
4 changed files with 126 additions and 0 deletions

View file

@ -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)

View file

@ -16,6 +16,7 @@
#include "effects/Lofi.h"
#include "effects/Limiter.h"
#include "effects/Rectify.h"
#include "effects/Gain.h"
#include <algorithm>
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)

View file

@ -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<float> 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<const float> input { inputs[c], nframes };
absl::Span<float> output { outputs[c], nframes };
sfz::applyGain(absl::Span<const float> { gains }, input, output);
}
}
std::unique_ptr<Effect> Gain::makeInstance(absl::Span<const Opcode> members)
{
auto fx = absl::make_unique<Gain>();
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

50
src/sfizz/effects/Gain.h Normal file
View file

@ -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 <effect> block.
*/
static std::unique_ptr<Effect> makeInstance(absl::Span<const Opcode> members);
private:
float _gain = 0; // in dB
AudioBuffer<float, 1> _tempBuffer { 1, config::defaultSamplesPerBlock };
};
} // namespace fx
} // namespace sfz