Add the EQ effect

This commit is contained in:
Jean Pierre Cimalando 2020-03-12 14:49:31 +01:00 committed by Paul Fd
parent bfbbc6085b
commit 43262395c9
4 changed files with 156 additions and 0 deletions

View file

@ -17,6 +17,7 @@ set (SFIZZ_SOURCES
sfizz/Effects.cpp
sfizz/effects/Nothing.cpp
sfizz/effects/Filter.cpp
sfizz/effects/Eq.cpp
sfizz/effects/Lofi.cpp
)
include (SfizzSIMDSourceFiles)

View file

@ -11,6 +11,7 @@
#include "Config.h"
#include "effects/Nothing.h"
#include "effects/Filter.h"
#include "effects/Eq.h"
#include "effects/Lofi.h"
#include <algorithm>
@ -20,6 +21,7 @@ void EffectFactory::registerStandardEffectTypes()
{
// TODO
registerEffectType("filter", fx::Filter::makeInstance);
registerEffectType("eq", fx::Eq::makeInstance);
registerEffectType("lofi", fx::Lofi::makeInstance);
}

98
src/sfizz/effects/Eq.cpp Normal file
View file

@ -0,0 +1,98 @@
// 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): implementation status
- [x] eq_type
- [x] eq_freq
- [ ] eq_freq_oncc
- [x] eq_bw
- [ ] eq_bw_oncc
- [x] eq_gain
- [ ] eq_gain_oncc
*/
#include "Eq.h"
#include "Opcode.h"
#include "SIMDHelpers.h"
#include "Debug.h"
#include "absl/memory/memory.h"
namespace sfz {
namespace fx {
Eq::Eq(const EQDescription& desc)
: _desc(desc)
{
_filter.setType(desc.type);
_filter.setChannels(2);
}
void Eq::setSampleRate(double sampleRate)
{
_filter.init(sampleRate);
_filter.clear();
}
void Eq::setSamplesPerBlock(int samplesPerBlock)
{
_tempBuffer.resize(samplesPerBlock);
}
void Eq::clear()
{
_filter.clear();
}
void Eq::process(const float* const inputs[], float* const outputs[], unsigned nframes)
{
absl::Span<float> cutoff = _tempBuffer.getSpan(0).first(nframes);
absl::Span<float> bw = _tempBuffer.getSpan(1).first(nframes);
absl::Span<float> pksh = _tempBuffer.getSpan(2).first(nframes);
sfz::fill(cutoff, _desc.frequency);
sfz::fill(bw, _desc.bandwidth);
sfz::fill(pksh, _desc.gain);
_filter.processModulated(inputs, outputs, cutoff.data(), bw.data(), pksh.data(), nframes);
}
std::unique_ptr<Effect> Eq::makeInstance(absl::Span<const Opcode> members)
{
EQDescription desc;
for (const Opcode& opc : members) {
switch (hash(opc.value)) {
case hash("eq_freq"):
setValueFromOpcode(opc, desc.frequency, Default::eqFrequencyRange);
break;
case hash("eq_bw"):
setValueFromOpcode(opc, desc.bandwidth, Default::eqBandwidthRange);
break;
case hash("eq_gain"):
setValueFromOpcode(opc, desc.gain, Default::eqGainRange);
break;
case hash("eq_type"):
{
absl::optional<EqType> ftype = sfz::FilterEq::typeFromName(opc.value);
if (ftype)
desc.type = *ftype;
else {
desc.type = EqType::kEqNone;
DBG("Unknown EQ type: " << std::string(opcode.value));
}
break;
}
}
}
return absl::make_unique<Eq>(desc);
}
} // namespace fx
} // namespace sfz

55
src/sfizz/effects/Eq.h Normal file
View file

@ -0,0 +1,55 @@
// 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"
#include "EQDescription.h"
#include "SfzFilter.h"
namespace sfz {
namespace fx {
/**
* @brief Effect which passes signal through a filter
*/
class Eq : public Effect {
public:
explicit Eq(const EQDescription& desc);
/**
* @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:
sfz::FilterEq _filter;
EQDescription _desc;
AudioBuffer<float> _tempBuffer { 3, config::defaultSamplesPerBlock };
};
} // namespace fx
} // namespace sfz