Add the filter effect

This commit is contained in:
Jean Pierre Cimalando 2020-03-12 14:27:39 +01:00 committed by Paul Fd
parent 344e318b19
commit bfbbc6085b
4 changed files with 159 additions and 0 deletions

View file

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

View file

@ -10,6 +10,7 @@
#include "SIMDHelpers.h"
#include "Config.h"
#include "effects/Nothing.h"
#include "effects/Filter.h"
#include "effects/Lofi.h"
#include <algorithm>
@ -18,6 +19,7 @@ namespace sfz {
void EffectFactory::registerStandardEffectTypes()
{
// TODO
registerEffectType("filter", fx::Filter::makeInstance);
registerEffectType("lofi", fx::Lofi::makeInstance);
}

View file

@ -0,0 +1,101 @@
// 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] filter_type
- [x] filter_cutoff
- [ ] filter_cutoff_oncc
- [x] filter_resonance
- [ ] filter_resonance_oncc
Potential extensions (like ARIA)
- [/] filter_gain
- [ ] filter_gain_oncc
*/
#include "Filter.h"
#include "Opcode.h"
#include "SIMDHelpers.h"
#include "Debug.h"
#include "absl/memory/memory.h"
namespace sfz {
namespace fx {
Filter::Filter(const FilterDescription& desc)
: _desc(desc)
{
_filter.setType(desc.type);
_filter.setChannels(2);
}
void Filter::setSampleRate(double sampleRate)
{
_filter.init(sampleRate);
_filter.clear();
}
void Filter::setSamplesPerBlock(int samplesPerBlock)
{
_tempBuffer.resize(samplesPerBlock);
}
void Filter::clear()
{
_filter.clear();
}
void Filter::process(const float* const inputs[], float* const outputs[], unsigned nframes)
{
absl::Span<float> cutoff = _tempBuffer.getSpan(0).first(nframes);
absl::Span<float> q = _tempBuffer.getSpan(1).first(nframes);
absl::Span<float> pksh = _tempBuffer.getSpan(2).first(nframes);
sfz::fill(cutoff, _desc.cutoff);
sfz::fill(q, _desc.resonance);
sfz::fill(pksh, _desc.gain);
_filter.processModulated(inputs, outputs, cutoff.data(), q.data(), pksh.data(), nframes);
}
std::unique_ptr<Effect> Filter::makeInstance(absl::Span<const Opcode> members)
{
FilterDescription desc;
for (const Opcode& opc : members) {
switch (hash(opc.value)) {
case hash("filter_cutoff"):
setValueFromOpcode(opc, desc.cutoff, Default::filterCutoffRange);
break;
case hash("filter_resonance"):
setValueFromOpcode(opc, desc.resonance, Default::filterResonanceRange);
break;
case hash("filter_type"):
{
absl::optional<FilterType> ftype = sfz::Filter::typeFromName(opc.value);
if (ftype)
desc.type = *ftype;
else {
desc.type = FilterType::kFilterNone;
DBG("Unknown filter type: " << std::string(opcode.value));
}
break;
}
// extension
case hash("sfizz:filter_gain"):
setValueFromOpcode(opc, desc.gain, Default::filterGainRange);
break;
}
}
return absl::make_unique<Filter>(desc);
}
} // namespace fx
} // namespace sfz

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