Update fx with faust helpers, change oversampling strategy
This commit is contained in:
parent
cd43cac59b
commit
5c5c434297
10 changed files with 88 additions and 82 deletions
|
|
@ -340,6 +340,44 @@ foreach(filter_type
|
|||
"sfizz/gen/filters/sfz2ch${filter_type}.hxx")
|
||||
endforeach()
|
||||
|
||||
# Faust effects
|
||||
add_faust_command(
|
||||
"sfizz/effects/dsp/compressor.dsp"
|
||||
"sfizz/effects/gen/compressor.hxx"
|
||||
IN_PLACE
|
||||
CLASS_NAME "faustCompressor"
|
||||
IMPORT_DIRS "sfizz/dsp")
|
||||
add_faust_command(
|
||||
"sfizz/effects/dsp/disto_stage.dsp"
|
||||
"sfizz/effects/gen/disto_stage.hxx"
|
||||
IN_PLACE
|
||||
CLASS_NAME "faustDisto"
|
||||
IMPORT_DIRS "sfizz/dsp")
|
||||
add_faust_command(
|
||||
"sfizz/effects/dsp/fverb.dsp"
|
||||
"sfizz/effects/gen/fverb.hxx"
|
||||
IN_PLACE
|
||||
CLASS_NAME "faustFverb"
|
||||
IMPORT_DIRS "sfizz/dsp")
|
||||
add_faust_command(
|
||||
"sfizz/effects/dsp/gate.dsp"
|
||||
"sfizz/effects/gen/gate.hxx"
|
||||
IN_PLACE
|
||||
CLASS_NAME "faustGate"
|
||||
IMPORT_DIRS "sfizz/dsp")
|
||||
add_faust_command(
|
||||
"sfizz/effects/dsp/limiter.dsp"
|
||||
"sfizz/effects/gen/limiter.hxx"
|
||||
IN_PLACE
|
||||
CLASS_NAME "faustLimiter"
|
||||
IMPORT_DIRS "sfizz/dsp")
|
||||
target_sources(sfizz_internal PRIVATE
|
||||
"sfizz/effects/gen/compressor.hxx"
|
||||
"sfizz/effects/gen/disto_stage.hxx"
|
||||
"sfizz/effects/gen/fverb.hxx"
|
||||
"sfizz/effects/gen/gate.hxx"
|
||||
"sfizz/effects/gen/limiter.hxx")
|
||||
|
||||
# Windows installer
|
||||
if(WIN32)
|
||||
include(VSTConfig)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
*/
|
||||
|
||||
#include "Compressor.h"
|
||||
#include "gen/compressor.hxx"
|
||||
#include "Opcode.h"
|
||||
#include "AudioSpan.h"
|
||||
#include "MathHelpers.h"
|
||||
|
|
@ -24,8 +25,6 @@
|
|||
#include "absl/memory/memory.h"
|
||||
|
||||
static constexpr int _oversampling = 2;
|
||||
#define FAUST_UIMACROS 1
|
||||
#include "gen/compressor.hxx"
|
||||
|
||||
namespace sfz {
|
||||
namespace fx {
|
||||
|
|
@ -38,12 +37,6 @@ namespace fx {
|
|||
AudioBuffer<float, 2> _gain2x { 2, _oversampling * config::defaultSamplesPerBlock };
|
||||
hiir::Downsampler2x<12> _downsampler2x[EffectChannels];
|
||||
hiir::Upsampler2x<12> _upsampler2x[EffectChannels];
|
||||
|
||||
#define DEFINE_SET_GET(type, ident, name, var, def, min, max, step) \
|
||||
float get_##ident(size_t i) const noexcept { return _compressor[i].var; } \
|
||||
void set_##ident(size_t i, float value) noexcept { _compressor[i].var = value; }
|
||||
FAUST_LIST_ACTIVES(DEFINE_SET_GET);
|
||||
#undef DEFINE_SET_GET
|
||||
};
|
||||
|
||||
Compressor::Compressor()
|
||||
|
|
@ -62,8 +55,8 @@ namespace fx {
|
|||
{
|
||||
Impl& impl = *_impl;
|
||||
for (faustCompressor& comp : impl._compressor) {
|
||||
comp.classInit(sampleRate);
|
||||
comp.instanceConstants(sampleRate);
|
||||
comp.classInit(_oversampling * sampleRate);
|
||||
comp.instanceConstants(_oversampling * sampleRate);
|
||||
}
|
||||
|
||||
for (unsigned c = 0; c < EffectChannels; ++c) {
|
||||
|
|
@ -164,29 +157,29 @@ namespace fx {
|
|||
case hash("comp_attack"):
|
||||
{
|
||||
auto value = opc.read(Default::compAttack);
|
||||
for (size_t c = 0; c < 2; ++c)
|
||||
impl.set_Attack(c, value);
|
||||
for (faustCompressor& comp : impl._compressor)
|
||||
comp.setAttack(value);
|
||||
}
|
||||
break;
|
||||
case hash("comp_release"):
|
||||
{
|
||||
auto value = opc.read(Default::compRelease);
|
||||
for (size_t c = 0; c < 2; ++c)
|
||||
impl.set_Release(c, value);
|
||||
for (faustCompressor& comp : impl._compressor)
|
||||
comp.setRelease(value);
|
||||
}
|
||||
break;
|
||||
case hash("comp_threshold"):
|
||||
{
|
||||
auto value = opc.read(Default::compThreshold);
|
||||
for (size_t c = 0; c < 2; ++c)
|
||||
impl.set_Threshold(c, value);
|
||||
for (faustCompressor& comp : impl._compressor)
|
||||
comp.setThreshold(value);
|
||||
}
|
||||
break;
|
||||
case hash("comp_ratio"):
|
||||
{
|
||||
auto value = opc.read(Default::compRatio);
|
||||
for (size_t c = 0; c < 2; ++c)
|
||||
impl.set_Ratio(c, value);
|
||||
for (faustCompressor& comp : impl._compressor)
|
||||
comp.setRatio(value);
|
||||
}
|
||||
break;
|
||||
case hash("comp_gain"):
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
|
||||
#include "Disto.h"
|
||||
#include "gen/disto_stage.hxx"
|
||||
#include "Opcode.h"
|
||||
#include "Config.h"
|
||||
#include "MathHelpers.h"
|
||||
|
|
@ -27,8 +28,6 @@
|
|||
#include <cmath>
|
||||
|
||||
static constexpr int _oversampling = 8;
|
||||
#define FAUST_UIMACROS 1
|
||||
#include "gen/disto_stage.hxx"
|
||||
|
||||
namespace sfz {
|
||||
namespace fx {
|
||||
|
|
@ -56,12 +55,6 @@ struct Disto::Impl {
|
|||
float mk = 21.0f + _tone * 1.08f;
|
||||
return 440.0f * std::exp2((mk - 69.0f) * (1.0f / 12.0f));
|
||||
}
|
||||
|
||||
#define DEFINE_SET_GET(type, ident, name, var, def, min, max, step) \
|
||||
float get_##ident(size_t c, size_t s) const noexcept { return _stages[c][s].var; } \
|
||||
void set_##ident(size_t c, size_t s, float value) noexcept { _stages[c][s].var = value; }
|
||||
FAUST_LIST_ACTIVES(DEFINE_SET_GET);
|
||||
#undef DEFINE_SET_GET
|
||||
};
|
||||
|
||||
Disto::Disto()
|
||||
|
|
@ -71,7 +64,7 @@ Disto::Disto()
|
|||
|
||||
for (unsigned c = 0; c < EffectChannels; ++c) {
|
||||
for (faustDisto& stage : impl._stages[c])
|
||||
stage.init(config::defaultSampleRate);
|
||||
stage.init(_oversampling * config::defaultSampleRate);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -86,8 +79,8 @@ void Disto::setSampleRate(double sampleRate)
|
|||
|
||||
for (unsigned c = 0; c < EffectChannels; ++c) {
|
||||
for (faustDisto& stage : impl._stages[c]) {
|
||||
stage.classInit(sampleRate);
|
||||
stage.instanceConstants(sampleRate);
|
||||
stage.classInit(_oversampling * sampleRate);
|
||||
stage.instanceConstants(_oversampling * sampleRate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -150,7 +143,7 @@ void Disto::process(const float* const inputs[], float* const outputs[], unsigne
|
|||
absl::Span<float> stageInOut = upsamplerOut;
|
||||
for (unsigned s = 0, numStages = impl._numStages; s < numStages; ++s) {
|
||||
// set depth parameter (TODO modulation)
|
||||
impl.set_Depth(c, s, depth);
|
||||
impl._stages[c][s].setDepth(depth);
|
||||
//
|
||||
float *faustIn[] = { stageInOut.data() };
|
||||
float *faustOut[] = { stageInOut.data() };
|
||||
|
|
|
|||
|
|
@ -5,14 +5,13 @@
|
|||
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||
|
||||
#include "Fverb.h"
|
||||
#include "gen/fverb.hxx"
|
||||
#include "Opcode.h"
|
||||
#include "Config.h"
|
||||
#include "MathHelpers.h"
|
||||
#include <absl/memory/memory.h>
|
||||
#include <absl/strings/ascii.h>
|
||||
#include <cmath>
|
||||
#define FAUST_UIMACROS 1
|
||||
#include "gen/fverb.hxx"
|
||||
|
||||
/**
|
||||
Note(jpc): implementation status
|
||||
|
|
@ -40,12 +39,6 @@ namespace fx {
|
|||
struct Fverb::Impl {
|
||||
faustFverb dsp;
|
||||
|
||||
#define DEFINE_SET_GET(type, ident, name, var, def, min, max, step) \
|
||||
float get_##ident() const noexcept { return dsp.var; } \
|
||||
void set_##ident(float value) noexcept { dsp.var = value; }
|
||||
FAUST_LIST_ACTIVES(DEFINE_SET_GET);
|
||||
#undef DEFINE_SET_GET
|
||||
|
||||
struct Profile {
|
||||
float tailDensity; // %
|
||||
float decayAtMaxSize; // %
|
||||
|
|
@ -240,17 +233,18 @@ namespace fx {
|
|||
const float decayMin = decayMax * 0.5f;
|
||||
|
||||
Impl& impl = *reverb->impl_;
|
||||
impl.set_Predelay(predelay * 1e3);
|
||||
impl.set_Tail_density(profile->tailDensity);
|
||||
impl.set_Decay(decayMax * size * 0.01f + decayMin * (1.0f - size * 0.01f));
|
||||
impl.set_Modulator_frequency(profile->modulationFrequency);
|
||||
impl.set_Modulator_depth(profile->modulationDepth);
|
||||
impl.set_Dry(profile->dry * dry * 0.01f);
|
||||
impl.set_Wet(profile->wet * wet * 0.01f);
|
||||
impl.set_Input_amount(input);
|
||||
impl.set_Input_low_pass_cutoff(Impl::lpfCutoff(tone));
|
||||
faustFverb& dsp = impl.dsp;
|
||||
dsp.setPredelay(predelay * 1e3);
|
||||
dsp.setTailDensity(profile->tailDensity);
|
||||
dsp.setDecay(decayMax * size * 0.01f + decayMin * (1.0f - size * 0.01f));
|
||||
dsp.setModulatorFrequency(profile->modulationFrequency);
|
||||
dsp.setModulatorDepth(profile->modulationDepth);
|
||||
dsp.setDry(profile->dry * dry * 0.01f);
|
||||
dsp.setWet(profile->wet * wet * 0.01f);
|
||||
dsp.setInputAmount(input);
|
||||
dsp.setInputLowPassCutoff(Impl::lpfCutoff(tone));
|
||||
// NOTE(jpc): damp formula not well calibrated, but sounds ok-ish
|
||||
impl.set_Damping(Impl::lpfCutoff(100 - 0.5 * damp));
|
||||
dsp.setDamping(Impl::lpfCutoff(100 - 0.5 * damp));
|
||||
|
||||
return fx;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
|
||||
#include "Gate.h"
|
||||
#include "gen/gate.hxx"
|
||||
#include "Opcode.h"
|
||||
#include "AudioSpan.h"
|
||||
#include "MathHelpers.h"
|
||||
|
|
@ -27,8 +28,6 @@
|
|||
#include "absl/memory/memory.h"
|
||||
|
||||
static constexpr int _oversampling = 2;
|
||||
#define FAUST_UIMACROS 1
|
||||
#include "gen/gate.hxx"
|
||||
|
||||
namespace sfz {
|
||||
namespace fx {
|
||||
|
|
@ -41,12 +40,6 @@ namespace fx {
|
|||
AudioBuffer<float, 2> _gain2x { 2, _oversampling * config::defaultSamplesPerBlock };
|
||||
hiir::Downsampler2x<12> _downsampler2x[EffectChannels];
|
||||
hiir::Upsampler2x<12> _upsampler2x[EffectChannels];
|
||||
|
||||
#define DEFINE_SET_GET(type, ident, name, var, def, min, max, step) \
|
||||
float get_##ident(size_t i) const noexcept { return _gate[i].var; } \
|
||||
void set_##ident(size_t i, float value) noexcept { _gate[i].var = value; }
|
||||
FAUST_LIST_ACTIVES(DEFINE_SET_GET);
|
||||
#undef DEFINE_SET_GET
|
||||
};
|
||||
|
||||
Gate::Gate()
|
||||
|
|
@ -65,8 +58,8 @@ namespace fx {
|
|||
{
|
||||
Impl& impl = *_impl;
|
||||
for (faustGate& gate : impl._gate) {
|
||||
gate.classInit(sampleRate);
|
||||
gate.instanceConstants(sampleRate);
|
||||
gate.classInit(_oversampling * sampleRate);
|
||||
gate.instanceConstants(_oversampling * sampleRate);
|
||||
}
|
||||
|
||||
for (unsigned c = 0; c < EffectChannels; ++c) {
|
||||
|
|
@ -167,29 +160,29 @@ namespace fx {
|
|||
case hash("gate_attack"):
|
||||
{
|
||||
auto value = opc.read(Default::gateAttack);
|
||||
for (size_t c = 0; c < 2; ++c)
|
||||
impl.set_Attack(c, value);
|
||||
for (faustGate& gate : impl._gate)
|
||||
gate.setAttack(value);
|
||||
}
|
||||
break;
|
||||
case hash("gate_hold"):
|
||||
{
|
||||
auto value = opc.read(Default::gateHold);
|
||||
for (size_t c = 0; c < 2; ++c)
|
||||
impl.set_Hold(c, value);
|
||||
for (faustGate& gate : impl._gate)
|
||||
gate.setHold(value);
|
||||
}
|
||||
break;
|
||||
case hash("gate_release"):
|
||||
{
|
||||
auto value = opc.read(Default::gateRelease);
|
||||
for (size_t c = 0; c < 2; ++c)
|
||||
impl.set_Release(c, value);
|
||||
for (faustGate& gate : impl._gate)
|
||||
gate.setRelease(value);
|
||||
}
|
||||
break;
|
||||
case hash("gate_threshold"):
|
||||
{
|
||||
auto value = opc.read(Default::gateThreshold);
|
||||
for (size_t c = 0; c < 2; ++c)
|
||||
impl.set_Threshold(c, value);
|
||||
for (faustGate& gate : impl._gate)
|
||||
gate.setThreshold(value);
|
||||
}
|
||||
break;
|
||||
case hash("gate_stlink"):
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@
|
|||
*/
|
||||
|
||||
#include "Limiter.h"
|
||||
#include "gen/limiter.hxx"
|
||||
#include "Opcode.h"
|
||||
#include "AudioSpan.h"
|
||||
#include "absl/memory/memory.h"
|
||||
|
||||
static constexpr int _oversampling = 2;
|
||||
#include "gen/limiter.hxx"
|
||||
|
||||
namespace sfz {
|
||||
namespace fx {
|
||||
|
|
@ -33,8 +33,8 @@ namespace fx {
|
|||
|
||||
void Limiter::setSampleRate(double sampleRate)
|
||||
{
|
||||
_limiter->classInit(sampleRate);
|
||||
_limiter->instanceConstants(sampleRate);
|
||||
_limiter->classInit(_oversampling * sampleRate);
|
||||
_limiter->instanceConstants(_oversampling * sampleRate);
|
||||
|
||||
for (unsigned c = 0; c < EffectChannels; ++c) {
|
||||
_downsampler2x[c].set_coefs(OSCoeffs2x);
|
||||
|
|
|
|||
|
|
@ -3,9 +3,8 @@ import("stdfaust.lib");
|
|||
cgain = co.compression_gain_mono(ratio, thresh, att, rel) with {
|
||||
ratio = hslider("[1] Ratio", 1.0, 1.0, 20.0, 0.01);
|
||||
thresh = hslider("[2] Threshold [unit:dB]", 0.0, -60.0, 0.0, 0.01);
|
||||
over = fconstant(int _oversampling, <math.h>);
|
||||
att = hslider("[3] Attack [unit:s]", 0.0, 0.0, 0.5, 1e-3) : *(over);
|
||||
rel = hslider("[4] Release [unit:s]", 0.0, 0.0, 5.0, 1e-3) : *(over);
|
||||
att = hslider("[3] Attack [unit:s]", 0.0, 0.0, 0.5, 1e-3);
|
||||
rel = hslider("[4] Release [unit:s]", 0.0, 0.0, 5.0, 1e-3);
|
||||
};
|
||||
|
||||
process = cgain;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,12 @@
|
|||
import("stdfaust.lib");
|
||||
|
||||
disto_stage(depth, x) = shs*hh(x)+(1.0-shs)*lh(x) : fi.dcblockerat(5.0) with {
|
||||
over = fconstant(int _oversampling, <math.h>);
|
||||
|
||||
// sigmoid parameters
|
||||
a = depth*0.2+2.0;
|
||||
b = 2.0;
|
||||
|
||||
// smooth hysteresis transition
|
||||
shs = hs : si.smooth(ba.tau2pole(10e-3*over));
|
||||
shs = hs : si.smooth(ba.tau2pole(10e-3));
|
||||
|
||||
// the low and high hysteresis
|
||||
lh(x) = sig(a*x)*b;
|
||||
|
|
|
|||
|
|
@ -2,10 +2,9 @@ import("stdfaust.lib");
|
|||
|
||||
ggain = ef.gate_gain_mono(thresh, att, hold, rel) with {
|
||||
thresh = hslider("[1] Threshold [unit:dB]", 0.0, -60.0, 0.0, 0.01);
|
||||
over = fconstant(int _oversampling, <math.h>);
|
||||
att = hslider("[2] Attack [unit:s]", 0.0, 0.0, 10.0, 1e-3) : *(over);
|
||||
hold = hslider("[3] Hold [unit:s]", 0.0, 0.0, 10.0, 1e-3) : *(over);
|
||||
rel = hslider("[4] Release [unit:s]", 0.0, 0.0, 5.0, 1e-3) : *(over);
|
||||
att = hslider("[2] Attack [unit:s]", 0.0, 0.0, 10.0, 1e-3);
|
||||
hold = hslider("[3] Hold [unit:s]", 0.0, 0.0, 10.0, 1e-3);
|
||||
rel = hslider("[4] Release [unit:s]", 0.0, 0.0, 5.0, 1e-3);
|
||||
};
|
||||
|
||||
process = ggain;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
import("stdfaust.lib");
|
||||
|
||||
limiter(x) = gain*x with {
|
||||
att = 0.0008 * over;
|
||||
rel = 0.5 * over;
|
||||
over = fconstant(int _oversampling, <math.h>);
|
||||
att = 0.0008;
|
||||
rel = 0.5;
|
||||
peak = x : an.amp_follower_ud(att, rel);
|
||||
gain = ba.if(peak>1.0, 1.0/peak, 1.0) : si.smooth(ba.tau2pole(0.5*att));
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue