Add the filter effect
This commit is contained in:
parent
344e318b19
commit
bfbbc6085b
4 changed files with 159 additions and 0 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
101
src/sfizz/effects/Filter.cpp
Normal file
101
src/sfizz/effects/Filter.cpp
Normal 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
|
||||
55
src/sfizz/effects/Filter.h
Normal file
55
src/sfizz/effects/Filter.h
Normal 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
|
||||
Loading…
Add table
Reference in a new issue