From abfd4e401fd03eabcb26c59be2901274c513f117 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Wed, 11 Mar 2020 18:26:54 +0100 Subject: [PATCH 1/9] Implement eqN_type and the shelving EQs --- scripts/generate_filters.sh | 2 +- src/sfizz/EQDescription.h | 2 + src/sfizz/EQPool.cpp | 1 + src/sfizz/Region.cpp | 19 ++ src/sfizz/SfzFilter.cpp | 58 +++-- src/sfizz/SfzFilter.h | 19 ++ src/sfizz/SfzFilterImpls.cxx | 16 +- src/sfizz/dsp/filters/sfz_filters.dsp | 30 ++- src/sfizz/gen/filters/sfz2chBpf6p.cxx | 2 +- src/sfizz/gen/filters/sfz2chEqHshelf.cxx | 210 ++++++++++++++++++ src/sfizz/gen/filters/sfz2chEqLshelf.cxx | 210 ++++++++++++++++++ .../{sfz2chEq.cxx => sfz2chEqPeak.cxx} | 12 +- src/sfizz/gen/filters/sfzEqHshelf.cxx | 191 ++++++++++++++++ src/sfizz/gen/filters/sfzEqLshelf.cxx | 191 ++++++++++++++++ .../gen/filters/{sfzEq.cxx => sfzEqPeak.cxx} | 12 +- 15 files changed, 942 insertions(+), 33 deletions(-) create mode 100644 src/sfizz/gen/filters/sfz2chEqHshelf.cxx create mode 100644 src/sfizz/gen/filters/sfz2chEqLshelf.cxx rename src/sfizz/gen/filters/{sfz2chEq.cxx => sfz2chEqPeak.cxx} (95%) create mode 100644 src/sfizz/gen/filters/sfzEqHshelf.cxx create mode 100644 src/sfizz/gen/filters/sfzEqLshelf.cxx rename src/sfizz/gen/filters/{sfzEq.cxx => sfzEqPeak.cxx} (95%) diff --git a/scripts/generate_filters.sh b/scripts/generate_filters.sh index 04168241..dd1ef713 100755 --- a/scripts/generate_filters.sh +++ b/scripts/generate_filters.sh @@ -63,7 +63,7 @@ for f in \ Lsh Hsh Peq \ Pink \ Lpf2pSv Hpf2pSv Bpf2pSv Brf2pSv \ - Eq + EqPeak EqLshelf EqHshelf do faustgen "$f" faustgen "2ch$f" diff --git a/src/sfizz/EQDescription.h b/src/sfizz/EQDescription.h index 5953cf52..161207df 100644 --- a/src/sfizz/EQDescription.h +++ b/src/sfizz/EQDescription.h @@ -7,6 +7,7 @@ #pragma once #include "Config.h" #include "Defaults.h" +#include "SfzFilter.h" #include "CCMap.h" namespace sfz @@ -18,6 +19,7 @@ struct EQDescription float gain { Default::eqGain }; float vel2frequency { Default::eqVel2frequency }; float vel2gain { Default::eqVel2gain }; + EqType type { EqType::kEqPeak }; CCMap bandwidthCC { Default::eqBandwidthCC }; CCMap frequencyCC { Default::eqFrequencyCC }; CCMap gainCC { Default::eqGainCC }; diff --git a/src/sfizz/EQPool.cpp b/src/sfizz/EQPool.cpp index f38e8748..dca5ad1c 100644 --- a/src/sfizz/EQPool.cpp +++ b/src/sfizz/EQPool.cpp @@ -18,6 +18,7 @@ void sfz::EQHolder::reset() void sfz::EQHolder::setup(const EQDescription& description, unsigned numChannels, uint8_t velocity) { + eq.setType(description.type); eq.setChannels(numChannels); this->description = &description; const auto normalizedVelocity = normalizeVelocity(velocity); diff --git a/src/sfizz/Region.cpp b/src/sfizz/Region.cpp index ddf2a764..35daf0a6 100644 --- a/src/sfizz/Region.cpp +++ b/src/sfizz/Region.cpp @@ -621,6 +621,25 @@ bool sfz::Region::parseOpcode(const Opcode& opcode) setValueFromOpcode(opcode, equalizers[eqNumber - 1].vel2gain, Default::eqGainModRange); } break; + case hash("eq&_type"): + { + const auto eqNumber = opcode.parameters.front(); + if (eqNumber == 0) + return false; + if (!extendIfNecessary(equalizers, eqNumber, Default::numEQs)) + return false; + + switch (hash(opcode.value)) { + case hash("peak"): equalizers[eqNumber - 1].type = EqType::kEqPeak; break; + case hash("lshelf"): equalizers[eqNumber - 1].type = EqType::kEqLowShelf; break; + case hash("hshelf"): equalizers[eqNumber - 1].type = EqType::kEqHighShelf; break; + default: + equalizers[eqNumber - 1].type = EqType::kEqNone; + DBG("Unknown EQ type: " << std::string(opcode.value)); + } + } + break; + // Performance parameters: pitch case hash("pitch_keycenter"): setValueFromOpcode(opcode, pitchKeycenter, Default::keyRange); diff --git a/src/sfizz/SfzFilter.cpp b/src/sfizz/SfzFilter.cpp index 55f2444c..fa7d354c 100644 --- a/src/sfizz/SfzFilter.cpp +++ b/src/sfizz/SfzFilter.cpp @@ -263,13 +263,24 @@ sfzFilterDsp *Filter::Impl::getDsp(unsigned channels, FilterType type) struct FilterEq::Impl { + EqType fType = kEqNone; unsigned fChannels = 1; enum { maxChannels = 2 }; - sfzEq fDsp; - sfz2chEq fDsp2ch; + sfzEqPeak fDspPeak; + sfzEqLshelf fDspLshelf; + sfzEqHshelf fDspHshelf; - sfzFilterDsp *getDsp(unsigned channels); + sfz2chEqPeak fDsp2chPeak; + sfz2chEqLshelf fDsp2chLshelf; + sfz2chEqHshelf fDsp2chHshelf; + + sfzFilterDsp *getDsp(unsigned channels, EqType type); + + static constexpr uint32_t idDsp(unsigned channels, EqType type) + { + return static_cast(type)|(channels << 16); + } }; FilterEq::FilterEq() @@ -284,14 +295,17 @@ FilterEq::~FilterEq() void FilterEq::init(double sampleRate) { for (unsigned channels = 1; channels <= Impl::maxChannels; ++channels) { - sfzFilterDsp *dsp = P->getDsp(channels); - dsp->init(sampleRate); + EqType ftype = static_cast(1); + while (sfzFilterDsp *dsp = P->getDsp(channels, ftype)) { + dsp->init(sampleRate); + ftype = static_cast(static_cast(ftype) + 1); + } } } void FilterEq::clear() { - sfzFilterDsp *dsp = P->getDsp(P->fChannels); + sfzFilterDsp *dsp = P->getDsp(P->fChannels, P->fType); if (dsp) dsp->instanceClear(); @@ -299,7 +313,7 @@ void FilterEq::clear() void FilterEq::prepare(float cutoff, float bw, float pksh) { - sfzFilterDsp *dsp = P->getDsp(P->fChannels); + sfzFilterDsp *dsp = P->getDsp(P->fChannels, P->fType); if (!dsp) return; @@ -323,7 +337,7 @@ void FilterEq::prepare(float cutoff, float bw, float pksh) void FilterEq::process(const float *const in[], float *const out[], float cutoff, float bw, float pksh, unsigned nframes) { unsigned channels = P->fChannels; - sfzFilterDsp *dsp = P->getDsp(channels); + sfzFilterDsp *dsp = P->getDsp(channels, P->fType); if (!dsp) { for (unsigned c = 0; c < channels; ++c) @@ -338,7 +352,7 @@ void FilterEq::process(const float *const in[], float *const out[], float cutoff void FilterEq::processModulated(const float *const in[], float *const out[], const float *cutoff, const float *bw, const float *pksh, unsigned nframes) { unsigned channels = P->fChannels; - sfzFilterDsp *dsp = P->getDsp(channels); + sfzFilterDsp *dsp = P->getDsp(channels, P->fType); if (!dsp) { for (unsigned c = 0; c < channels; ++c) @@ -383,13 +397,31 @@ void FilterEq::setChannels(unsigned channels) } } -sfzFilterDsp *FilterEq::Impl::getDsp(unsigned channels) +EqType FilterEq::type() const { - switch (channels) { + return P->fType; +} + +void FilterEq::setType(EqType type) +{ + if (P->fType != type) { + P->fType = type; + clear(); + } +} + +sfzFilterDsp *FilterEq::Impl::getDsp(unsigned channels, EqType type) +{ + switch (idDsp(channels, type)) { default: return nullptr; - case 1: return &fDsp; - case 2: return &fDsp2ch; + case idDsp(1, kEqPeak): return &fDspPeak; + case idDsp(1, kEqLowShelf): return &fDspLshelf; + case idDsp(1, kEqHighShelf): return &fDspHshelf; + + case idDsp(2, kEqPeak): return &fDsp2chPeak; + case idDsp(2, kEqLowShelf): return &fDsp2chLshelf; + case idDsp(2, kEqHighShelf): return &fDsp2chHshelf; } } diff --git a/src/sfizz/SfzFilter.h b/src/sfizz/SfzFilter.h index 3fd71e25..ec6a8191 100644 --- a/src/sfizz/SfzFilter.h +++ b/src/sfizz/SfzFilter.h @@ -114,6 +114,8 @@ enum FilterType : int { kFilterPeq, }; +enum EqType : int; + /** Equalizer filter for SFZ v1 Available for mono and stereo. (channels=1, channels=2) @@ -175,9 +177,26 @@ public: */ void setChannels(unsigned channels); + /** + Get the type of filter. + */ + EqType type() const; + + /** + Set the type of filter. + */ + void setType(EqType type); + private: struct Impl; std::unique_ptr P; }; +enum EqType : int { + kEqNone, + kEqPeak, + kEqLowShelf, + kEqHighShelf, +}; + } // namespace sfz diff --git a/src/sfizz/SfzFilterImpls.cxx b/src/sfizz/SfzFilterImpls.cxx index 39cdd3cd..2a670d6d 100644 --- a/src/sfizz/SfzFilterImpls.cxx +++ b/src/sfizz/SfzFilterImpls.cxx @@ -63,7 +63,9 @@ protected: #include "gen/filters/sfzLsh.cxx" #include "gen/filters/sfzHsh.cxx" #include "gen/filters/sfzPeq.cxx" -#include "gen/filters/sfzEq.cxx" +#include "gen/filters/sfzEqPeak.cxx" +#include "gen/filters/sfzEqLshelf.cxx" +#include "gen/filters/sfzEqHshelf.cxx" #include "gen/filters/sfz2chApf1p.cxx" #include "gen/filters/sfz2chBpf1p.cxx" @@ -88,7 +90,9 @@ protected: #include "gen/filters/sfz2chLsh.cxx" #include "gen/filters/sfz2chHsh.cxx" #include "gen/filters/sfz2chPeq.cxx" -#include "gen/filters/sfz2chEq.cxx" +#include "gen/filters/sfz2chEqPeak.cxx" +#include "gen/filters/sfz2chEqLshelf.cxx" +#include "gen/filters/sfz2chEqHshelf.cxx" #if defined(__GNUC__) || defined(__clang__) #pragma GCC diagnostic pop @@ -182,7 +186,9 @@ struct sfzBrf2pSv final : public sfzFilter {}; struct sfzLsh final : public sfzFilterPkSh {}; struct sfzHsh final : public sfzFilterPkSh {}; struct sfzPeq final : public sfzFilterPkSh {}; -struct sfzEq final : public sfzFilterEq {}; +struct sfzEqPeak final : public sfzFilterEq {}; +struct sfzEqLshelf final : public sfzFilterEq {}; +struct sfzEqHshelf final : public sfzFilterEq {}; struct sfz2chLpf1p final : public sfzFilterNoQ {}; struct sfz2chLpf2p final : public sfzFilter {}; @@ -207,4 +213,6 @@ struct sfz2chBrf2pSv final : public sfzFilter {}; struct sfz2chLsh final : public sfzFilterPkSh {}; struct sfz2chHsh final : public sfzFilterPkSh {}; struct sfz2chPeq final : public sfzFilterPkSh {}; -struct sfz2chEq final : public sfzFilterEq {}; +struct sfz2chEqPeak final : public sfzFilterEq {}; +struct sfz2chEqLshelf final : public sfzFilterEq {}; +struct sfz2chEqHshelf final : public sfzFilterEq {}; diff --git a/src/sfizz/dsp/filters/sfz_filters.dsp b/src/sfizz/dsp/filters/sfz_filters.dsp index 07f3fcf9..d944d452 100644 --- a/src/sfizz/dsp/filters/sfz_filters.dsp +++ b/src/sfizz/dsp/filters/sfz_filters.dsp @@ -94,11 +94,35 @@ sfzHsh = fm.rbjHighShelfSmooth(smoothCoefs,cutoff,pkShGain,Q); sfzPeq = fm.rbjPeakingEqSmooth(smoothCoefs,cutoff,pkShGain,Q); // the SFZ equalizer band -sfzEq = fm.rbjPeakingEqSmooth(smoothCoefs,cutoff,pkShGain,Q) with { +sfzEqPeak = fm.rbjPeakingEqSmooth(smoothCoefs,cutoff,pkShGain,Q) with { Q = 1./(2.*ma.sinh(0.5*log(2)*bandwidth*w0/sin(w0))); w0 = 2*ma.PI*max(0,cutoff)/ma.SR; }; +// the SFZ low-shelf with EQ controls +sfzEqLshelf = fm.rbjLowShelfSmooth(smoothCoefs,cutoff,pkShGain,Q) with { + slope = bandwidth; // in this case eqN_bw meaning is not bandwith but slope + Q = sfzGetQFromSlope(slope); +}; + +// the SFZ high-shelf with EQ controls +sfzEqHshelf = fm.rbjHighShelfSmooth(smoothCoefs,cutoff,pkShGain,Q) with { + slope = bandwidth; // in this case eqN_bw meaning is not bandwith but slope + Q = sfzGetQFromSlope(slope); +}; + +//============================================================================== +// Utility + +// a common function that computes the EQ shelf parameter +sfzGetQFromSlope(slope) = 1.0/sqrt((A+1.0/A)*(1.0/S-1.0)+2.0) with { + // note(jpc) slope is a 0-1 control that is reduced into a domain of validity, + // and clamped to avoid the extremes at both sides. + S = (slope*root) : max(1e-2) : min(root-1e-2); + A = 10^(pkShGain/40); + root = (A*A+1)/((A-1)*(A-1)); // the root of the expression under sqrt() +}; + //============================================================================== // Filters (stereo) @@ -125,7 +149,9 @@ sfz2chBrf2pSv = par(i,2,sfzBrf2pSv); sfz2chLsh = par(i,2,sfzLsh); sfz2chHsh = par(i,2,sfzHsh); sfz2chPeq = par(i,2,sfzPeq); -sfz2chEq = par(i,2,sfzEq); +sfz2chEqPeak = par(i,2,sfzEqPeak); +sfz2chEqLshelf = par(i,2,sfzEqLshelf); +sfz2chEqHshelf = par(i,2,sfzEqHshelf); //============================================================================== // Filter parameters diff --git a/src/sfizz/gen/filters/sfz2chBpf6p.cxx b/src/sfizz/gen/filters/sfz2chBpf6p.cxx index 571d635e..27165c1e 100644 --- a/src/sfizz/gen/filters/sfz2chBpf6p.cxx +++ b/src/sfizz/gen/filters/sfz2chBpf6p.cxx @@ -196,7 +196,7 @@ class faust2chBpf6p : public sfzFilterDsp { fRec6[0] = (fSlow0 * fRec6[1]); fRec7[0] = ((fSlow0 * fRec7[1]) + fSlow11); fRec2[0] = ((((fRec3[0] * fRec0[0]) + (fRec6[0] * fRec3[1])) + (fRec7[0] * fRec3[2])) - ((fRec4[0] * fRec2[1]) + (fRec5[0] * fRec2[2]))); - fRec1[0] = ((((fRec0[0] * fRec2[0]) + (fRec6[0] * fRec2[1])) + (fRec7[0] * fRec2[2])) - ((fRec4[0] * fRec1[1]) + (fRec5[0] * fRec1[2]))); + fRec1[0] = (((fRec0[0] * fRec2[0]) + ((fRec6[0] * fRec2[1]) + (fRec7[0] * fRec2[2]))) - ((fRec4[0] * fRec1[1]) + (fRec5[0] * fRec1[2]))); output0[i] = FAUSTFLOAT((((fRec0[0] * fRec1[0]) + (fRec6[0] * fRec1[1])) + (fRec7[0] * fRec1[2]))); fRec10[0] = (fTemp1 - ((fRec4[0] * fRec10[1]) + (fRec5[0] * fRec10[2]))); fRec9[0] = ((((fRec0[0] * fRec10[0]) + (fRec6[0] * fRec10[1])) + (fRec7[0] * fRec10[2])) - ((fRec4[0] * fRec9[1]) + (fRec5[0] * fRec9[2]))); diff --git a/src/sfizz/gen/filters/sfz2chEqHshelf.cxx b/src/sfizz/gen/filters/sfz2chEqHshelf.cxx new file mode 100644 index 00000000..19349a51 --- /dev/null +++ b/src/sfizz/gen/filters/sfz2chEqHshelf.cxx @@ -0,0 +1,210 @@ +/* ------------------------------------------------------------ +author: "Jean Pierre Cimalando" +license: "BSD-2-Clause" +name: "sfz_filters" +Code generated with Faust 2.20.2 (https://faust.grame.fr) +Compilation options: -lang cpp -inpl -double -ftz 0 +------------------------------------------------------------ */ + +#ifndef __faust2chEqHshelf_H__ +#define __faust2chEqHshelf_H__ + +#ifndef FAUSTFLOAT +#define FAUSTFLOAT float +#endif + +#include +#include +#include + +static double faust2chEqHshelf_faustpower2_f(double value) { + return (value * value); +} + +#ifndef FAUSTCLASS +#define FAUSTCLASS faust2chEqHshelf +#endif + +#ifdef __APPLE__ +#define exp10f __exp10f +#define exp10 __exp10 +#endif + +class faust2chEqHshelf : public sfzFilterDsp { + + public: + + int fSampleRate; + double fConst0; + double fConst1; + FAUSTFLOAT fPkShGain; + double fConst2; + FAUSTFLOAT fCutoff; + FAUSTFLOAT fBandwidth; + double fRec1[2]; + double fRec2[2]; + double fRec0[3]; + double fRec3[2]; + double fRec4[2]; + double fRec5[2]; + double fRec6[3]; + + public: + + void metadata(Meta* m) { + } + + virtual int getNumInputs() { + return 2; + } + virtual int getNumOutputs() { + return 2; + } + virtual int getInputRate(int channel) { + int rate; + switch ((channel)) { + case 0: { + rate = 1; + break; + } + case 1: { + rate = 1; + break; + } + default: { + rate = -1; + break; + } + } + return rate; + } + virtual int getOutputRate(int channel) { + int rate; + switch ((channel)) { + case 0: { + rate = 1; + break; + } + case 1: { + rate = 1; + break; + } + default: { + rate = -1; + break; + } + } + return rate; + } + + static void classInit(int sample_rate) { + } + + virtual void instanceConstants(int sample_rate) { + fSampleRate = sample_rate; + fConst0 = std::min(192000.0, std::max(1.0, double(fSampleRate))); + fConst1 = std::exp((0.0 - (1000.0 / fConst0))); + fConst2 = (6.2831853071795862 / fConst0); + } + + virtual void instanceResetUserInterface() { + fPkShGain = FAUSTFLOAT(0.0); + fCutoff = FAUSTFLOAT(440.0); + fBandwidth = FAUSTFLOAT(1.0); + } + + virtual void instanceClear() { + for (int l0 = 0; (l0 < 2); l0 = (l0 + 1)) { + fRec1[l0] = 0.0; + } + for (int l1 = 0; (l1 < 2); l1 = (l1 + 1)) { + fRec2[l1] = 0.0; + } + for (int l2 = 0; (l2 < 3); l2 = (l2 + 1)) { + fRec0[l2] = 0.0; + } + for (int l3 = 0; (l3 < 2); l3 = (l3 + 1)) { + fRec3[l3] = 0.0; + } + for (int l4 = 0; (l4 < 2); l4 = (l4 + 1)) { + fRec4[l4] = 0.0; + } + for (int l5 = 0; (l5 < 2); l5 = (l5 + 1)) { + fRec5[l5] = 0.0; + } + for (int l6 = 0; (l6 < 3); l6 = (l6 + 1)) { + fRec6[l6] = 0.0; + } + } + + virtual void init(int sample_rate) { + classInit(sample_rate); + instanceInit(sample_rate); + } + virtual void instanceInit(int sample_rate) { + instanceConstants(sample_rate); + instanceResetUserInterface(); + instanceClear(); + } + + virtual faust2chEqHshelf* clone() { + return new faust2chEqHshelf(); + } + + virtual int getSampleRate() { + return fSampleRate; + } + + virtual void buildUserInterface(UI* ui_interface) { + } + + virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { + FAUSTFLOAT* input0 = inputs[0]; + FAUSTFLOAT* input1 = inputs[1]; + FAUSTFLOAT* output0 = outputs[0]; + FAUSTFLOAT* output1 = outputs[1]; + double fSlow0 = (fSmoothEnable ? fConst1 : 0.0); + double fSlow1 = std::pow(10.0, (0.025000000000000001 * double(fPkShGain))); + double fSlow2 = (fConst2 * std::max(0.0, double(fCutoff))); + double fSlow3 = std::cos(fSlow2); + double fSlow4 = (fSlow3 * (fSlow1 + 1.0)); + double fSlow5 = (faust2chEqHshelf_faustpower2_f(fSlow1) + 1.0); + double fSlow6 = (fSlow1 + -1.0); + double fSlow7 = faust2chEqHshelf_faustpower2_f(fSlow6); + double fSlow8 = ((std::sqrt(fSlow1) * std::sin(fSlow2)) / std::max(0.001, (1.0 / std::sqrt((((fSlow1 + (1.0 / fSlow1)) * ((1.0 / std::min(((fSlow5 / fSlow7) + -0.01), std::max(0.01, ((double(fBandwidth) * fSlow5) / fSlow7)))) + -1.0)) + 2.0))))); + double fSlow9 = (fSlow3 * fSlow6); + double fSlow10 = ((fSlow1 + fSlow8) + (1.0 - fSlow9)); + double fSlow11 = (1.0 - fSlow0); + double fSlow12 = ((2.0 * ((fSlow1 + (-1.0 - fSlow4)) / fSlow10)) * fSlow11); + double fSlow13 = (fSlow9 + fSlow8); + double fSlow14 = (((fSlow1 + (1.0 - fSlow13)) / fSlow10) * fSlow11); + double fSlow15 = (((fSlow1 * ((fSlow1 + fSlow13) + 1.0)) / fSlow10) * fSlow11); + double fSlow16 = ((((0.0 - (2.0 * fSlow1)) * ((fSlow1 + fSlow4) + -1.0)) / fSlow10) * fSlow11); + double fSlow17 = (((fSlow1 * ((fSlow1 + fSlow9) + (1.0 - fSlow8))) / fSlow10) * fSlow11); + for (int i = 0; (i < count); i = (i + 1)) { + double fTemp0 = double(input0[i]); + double fTemp1 = double(input1[i]); + fRec1[0] = ((fSlow0 * fRec1[1]) + fSlow12); + fRec2[0] = ((fSlow0 * fRec2[1]) + fSlow14); + fRec0[0] = (fTemp0 - ((fRec1[0] * fRec0[1]) + (fRec2[0] * fRec0[2]))); + fRec3[0] = ((fSlow0 * fRec3[1]) + fSlow15); + fRec4[0] = ((fSlow0 * fRec4[1]) + fSlow16); + fRec5[0] = ((fSlow0 * fRec5[1]) + fSlow17); + output0[i] = FAUSTFLOAT((((fRec0[0] * fRec3[0]) + (fRec4[0] * fRec0[1])) + (fRec5[0] * fRec0[2]))); + fRec6[0] = (fTemp1 - ((fRec1[0] * fRec6[1]) + (fRec2[0] * fRec6[2]))); + output1[i] = FAUSTFLOAT((((fRec3[0] * fRec6[0]) + (fRec4[0] * fRec6[1])) + (fRec5[0] * fRec6[2]))); + fRec1[1] = fRec1[0]; + fRec2[1] = fRec2[0]; + fRec0[2] = fRec0[1]; + fRec0[1] = fRec0[0]; + fRec3[1] = fRec3[0]; + fRec4[1] = fRec4[0]; + fRec5[1] = fRec5[0]; + fRec6[2] = fRec6[1]; + fRec6[1] = fRec6[0]; + } + } + +}; + +#endif diff --git a/src/sfizz/gen/filters/sfz2chEqLshelf.cxx b/src/sfizz/gen/filters/sfz2chEqLshelf.cxx new file mode 100644 index 00000000..3b69cf2e --- /dev/null +++ b/src/sfizz/gen/filters/sfz2chEqLshelf.cxx @@ -0,0 +1,210 @@ +/* ------------------------------------------------------------ +author: "Jean Pierre Cimalando" +license: "BSD-2-Clause" +name: "sfz_filters" +Code generated with Faust 2.20.2 (https://faust.grame.fr) +Compilation options: -lang cpp -inpl -double -ftz 0 +------------------------------------------------------------ */ + +#ifndef __faust2chEqLshelf_H__ +#define __faust2chEqLshelf_H__ + +#ifndef FAUSTFLOAT +#define FAUSTFLOAT float +#endif + +#include +#include +#include + +static double faust2chEqLshelf_faustpower2_f(double value) { + return (value * value); +} + +#ifndef FAUSTCLASS +#define FAUSTCLASS faust2chEqLshelf +#endif + +#ifdef __APPLE__ +#define exp10f __exp10f +#define exp10 __exp10 +#endif + +class faust2chEqLshelf : public sfzFilterDsp { + + public: + + int fSampleRate; + double fConst0; + double fConst1; + FAUSTFLOAT fPkShGain; + double fConst2; + FAUSTFLOAT fCutoff; + FAUSTFLOAT fBandwidth; + double fRec1[2]; + double fRec2[2]; + double fRec0[3]; + double fRec3[2]; + double fRec4[2]; + double fRec5[2]; + double fRec6[3]; + + public: + + void metadata(Meta* m) { + } + + virtual int getNumInputs() { + return 2; + } + virtual int getNumOutputs() { + return 2; + } + virtual int getInputRate(int channel) { + int rate; + switch ((channel)) { + case 0: { + rate = 1; + break; + } + case 1: { + rate = 1; + break; + } + default: { + rate = -1; + break; + } + } + return rate; + } + virtual int getOutputRate(int channel) { + int rate; + switch ((channel)) { + case 0: { + rate = 1; + break; + } + case 1: { + rate = 1; + break; + } + default: { + rate = -1; + break; + } + } + return rate; + } + + static void classInit(int sample_rate) { + } + + virtual void instanceConstants(int sample_rate) { + fSampleRate = sample_rate; + fConst0 = std::min(192000.0, std::max(1.0, double(fSampleRate))); + fConst1 = std::exp((0.0 - (1000.0 / fConst0))); + fConst2 = (6.2831853071795862 / fConst0); + } + + virtual void instanceResetUserInterface() { + fPkShGain = FAUSTFLOAT(0.0); + fCutoff = FAUSTFLOAT(440.0); + fBandwidth = FAUSTFLOAT(1.0); + } + + virtual void instanceClear() { + for (int l0 = 0; (l0 < 2); l0 = (l0 + 1)) { + fRec1[l0] = 0.0; + } + for (int l1 = 0; (l1 < 2); l1 = (l1 + 1)) { + fRec2[l1] = 0.0; + } + for (int l2 = 0; (l2 < 3); l2 = (l2 + 1)) { + fRec0[l2] = 0.0; + } + for (int l3 = 0; (l3 < 2); l3 = (l3 + 1)) { + fRec3[l3] = 0.0; + } + for (int l4 = 0; (l4 < 2); l4 = (l4 + 1)) { + fRec4[l4] = 0.0; + } + for (int l5 = 0; (l5 < 2); l5 = (l5 + 1)) { + fRec5[l5] = 0.0; + } + for (int l6 = 0; (l6 < 3); l6 = (l6 + 1)) { + fRec6[l6] = 0.0; + } + } + + virtual void init(int sample_rate) { + classInit(sample_rate); + instanceInit(sample_rate); + } + virtual void instanceInit(int sample_rate) { + instanceConstants(sample_rate); + instanceResetUserInterface(); + instanceClear(); + } + + virtual faust2chEqLshelf* clone() { + return new faust2chEqLshelf(); + } + + virtual int getSampleRate() { + return fSampleRate; + } + + virtual void buildUserInterface(UI* ui_interface) { + } + + virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { + FAUSTFLOAT* input0 = inputs[0]; + FAUSTFLOAT* input1 = inputs[1]; + FAUSTFLOAT* output0 = outputs[0]; + FAUSTFLOAT* output1 = outputs[1]; + double fSlow0 = (fSmoothEnable ? fConst1 : 0.0); + double fSlow1 = std::pow(10.0, (0.025000000000000001 * double(fPkShGain))); + double fSlow2 = (fConst2 * std::max(0.0, double(fCutoff))); + double fSlow3 = std::cos(fSlow2); + double fSlow4 = (fSlow3 * (fSlow1 + 1.0)); + double fSlow5 = (fSlow1 + -1.0); + double fSlow6 = (fSlow3 * fSlow5); + double fSlow7 = (faust2chEqLshelf_faustpower2_f(fSlow1) + 1.0); + double fSlow8 = faust2chEqLshelf_faustpower2_f(fSlow5); + double fSlow9 = ((std::sqrt(fSlow1) * std::sin(fSlow2)) / std::max(0.001, (1.0 / std::sqrt((((fSlow1 + (1.0 / fSlow1)) * ((1.0 / std::min(((fSlow7 / fSlow8) + -0.01), std::max(0.01, ((double(fBandwidth) * fSlow7) / fSlow8)))) + -1.0)) + 2.0))))); + double fSlow10 = (fSlow6 + fSlow9); + double fSlow11 = ((fSlow1 + fSlow10) + 1.0); + double fSlow12 = (1.0 - fSlow0); + double fSlow13 = (((0.0 - (2.0 * ((fSlow1 + fSlow4) + -1.0))) / fSlow11) * fSlow12); + double fSlow14 = ((((fSlow1 + fSlow6) + (1.0 - fSlow9)) / fSlow11) * fSlow12); + double fSlow15 = (((fSlow1 * ((fSlow1 + fSlow9) + (1.0 - fSlow6))) / fSlow11) * fSlow12); + double fSlow16 = ((2.0 * ((fSlow1 * (fSlow1 + (-1.0 - fSlow4))) / fSlow11)) * fSlow12); + double fSlow17 = (((fSlow1 * (fSlow1 + (1.0 - fSlow10))) / fSlow11) * fSlow12); + for (int i = 0; (i < count); i = (i + 1)) { + double fTemp0 = double(input0[i]); + double fTemp1 = double(input1[i]); + fRec1[0] = ((fSlow0 * fRec1[1]) + fSlow13); + fRec2[0] = ((fSlow0 * fRec2[1]) + fSlow14); + fRec0[0] = (fTemp0 - ((fRec1[0] * fRec0[1]) + (fRec2[0] * fRec0[2]))); + fRec3[0] = ((fSlow0 * fRec3[1]) + fSlow15); + fRec4[0] = ((fSlow0 * fRec4[1]) + fSlow16); + fRec5[0] = ((fSlow0 * fRec5[1]) + fSlow17); + output0[i] = FAUSTFLOAT((((fRec0[0] * fRec3[0]) + (fRec4[0] * fRec0[1])) + (fRec5[0] * fRec0[2]))); + fRec6[0] = (fTemp1 - ((fRec1[0] * fRec6[1]) + (fRec2[0] * fRec6[2]))); + output1[i] = FAUSTFLOAT((((fRec3[0] * fRec6[0]) + (fRec4[0] * fRec6[1])) + (fRec5[0] * fRec6[2]))); + fRec1[1] = fRec1[0]; + fRec2[1] = fRec2[0]; + fRec0[2] = fRec0[1]; + fRec0[1] = fRec0[0]; + fRec3[1] = fRec3[0]; + fRec4[1] = fRec4[0]; + fRec5[1] = fRec5[0]; + fRec6[2] = fRec6[1]; + fRec6[1] = fRec6[0]; + } + } + +}; + +#endif diff --git a/src/sfizz/gen/filters/sfz2chEq.cxx b/src/sfizz/gen/filters/sfz2chEqPeak.cxx similarity index 95% rename from src/sfizz/gen/filters/sfz2chEq.cxx rename to src/sfizz/gen/filters/sfz2chEqPeak.cxx index 73fbe5a7..8b653cbe 100644 --- a/src/sfizz/gen/filters/sfz2chEq.cxx +++ b/src/sfizz/gen/filters/sfz2chEqPeak.cxx @@ -6,8 +6,8 @@ Code generated with Faust 2.20.2 (https://faust.grame.fr) Compilation options: -lang cpp -inpl -double -ftz 0 ------------------------------------------------------------ */ -#ifndef __faust2chEq_H__ -#define __faust2chEq_H__ +#ifndef __faust2chEqPeak_H__ +#define __faust2chEqPeak_H__ #ifndef FAUSTFLOAT #define FAUSTFLOAT float @@ -20,7 +20,7 @@ Compilation options: -lang cpp -inpl -double -ftz 0 #ifndef FAUSTCLASS -#define FAUSTCLASS faust2chEq +#define FAUSTCLASS faust2chEqPeak #endif #ifdef __APPLE__ @@ -28,7 +28,7 @@ Compilation options: -lang cpp -inpl -double -ftz 0 #define exp10 __exp10 #endif -class faust2chEq : public sfzFilterDsp { +class faust2chEqPeak : public sfzFilterDsp { public: @@ -143,8 +143,8 @@ class faust2chEq : public sfzFilterDsp { instanceClear(); } - virtual faust2chEq* clone() { - return new faust2chEq(); + virtual faust2chEqPeak* clone() { + return new faust2chEqPeak(); } virtual int getSampleRate() { diff --git a/src/sfizz/gen/filters/sfzEqHshelf.cxx b/src/sfizz/gen/filters/sfzEqHshelf.cxx new file mode 100644 index 00000000..8d7227e5 --- /dev/null +++ b/src/sfizz/gen/filters/sfzEqHshelf.cxx @@ -0,0 +1,191 @@ +/* ------------------------------------------------------------ +author: "Jean Pierre Cimalando" +license: "BSD-2-Clause" +name: "sfz_filters" +Code generated with Faust 2.20.2 (https://faust.grame.fr) +Compilation options: -lang cpp -inpl -double -ftz 0 +------------------------------------------------------------ */ + +#ifndef __faustEqHshelf_H__ +#define __faustEqHshelf_H__ + +#ifndef FAUSTFLOAT +#define FAUSTFLOAT float +#endif + +#include +#include +#include + +static double faustEqHshelf_faustpower2_f(double value) { + return (value * value); +} + +#ifndef FAUSTCLASS +#define FAUSTCLASS faustEqHshelf +#endif + +#ifdef __APPLE__ +#define exp10f __exp10f +#define exp10 __exp10 +#endif + +class faustEqHshelf : public sfzFilterDsp { + + public: + + int fSampleRate; + double fConst0; + double fConst1; + FAUSTFLOAT fPkShGain; + double fConst2; + FAUSTFLOAT fCutoff; + FAUSTFLOAT fBandwidth; + double fRec1[2]; + double fRec2[2]; + double fRec0[3]; + double fRec3[2]; + double fRec4[2]; + double fRec5[2]; + + public: + + void metadata(Meta* m) { + } + + virtual int getNumInputs() { + return 1; + } + virtual int getNumOutputs() { + return 1; + } + virtual int getInputRate(int channel) { + int rate; + switch ((channel)) { + case 0: { + rate = 1; + break; + } + default: { + rate = -1; + break; + } + } + return rate; + } + virtual int getOutputRate(int channel) { + int rate; + switch ((channel)) { + case 0: { + rate = 1; + break; + } + default: { + rate = -1; + break; + } + } + return rate; + } + + static void classInit(int sample_rate) { + } + + virtual void instanceConstants(int sample_rate) { + fSampleRate = sample_rate; + fConst0 = std::min(192000.0, std::max(1.0, double(fSampleRate))); + fConst1 = std::exp((0.0 - (1000.0 / fConst0))); + fConst2 = (6.2831853071795862 / fConst0); + } + + virtual void instanceResetUserInterface() { + fPkShGain = FAUSTFLOAT(0.0); + fCutoff = FAUSTFLOAT(440.0); + fBandwidth = FAUSTFLOAT(1.0); + } + + virtual void instanceClear() { + for (int l0 = 0; (l0 < 2); l0 = (l0 + 1)) { + fRec1[l0] = 0.0; + } + for (int l1 = 0; (l1 < 2); l1 = (l1 + 1)) { + fRec2[l1] = 0.0; + } + for (int l2 = 0; (l2 < 3); l2 = (l2 + 1)) { + fRec0[l2] = 0.0; + } + for (int l3 = 0; (l3 < 2); l3 = (l3 + 1)) { + fRec3[l3] = 0.0; + } + for (int l4 = 0; (l4 < 2); l4 = (l4 + 1)) { + fRec4[l4] = 0.0; + } + for (int l5 = 0; (l5 < 2); l5 = (l5 + 1)) { + fRec5[l5] = 0.0; + } + } + + virtual void init(int sample_rate) { + classInit(sample_rate); + instanceInit(sample_rate); + } + virtual void instanceInit(int sample_rate) { + instanceConstants(sample_rate); + instanceResetUserInterface(); + instanceClear(); + } + + virtual faustEqHshelf* clone() { + return new faustEqHshelf(); + } + + virtual int getSampleRate() { + return fSampleRate; + } + + virtual void buildUserInterface(UI* ui_interface) { + } + + virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { + FAUSTFLOAT* input0 = inputs[0]; + FAUSTFLOAT* output0 = outputs[0]; + double fSlow0 = (fSmoothEnable ? fConst1 : 0.0); + double fSlow1 = std::pow(10.0, (0.025000000000000001 * double(fPkShGain))); + double fSlow2 = (fConst2 * std::max(0.0, double(fCutoff))); + double fSlow3 = std::cos(fSlow2); + double fSlow4 = (fSlow3 * (fSlow1 + 1.0)); + double fSlow5 = (faustEqHshelf_faustpower2_f(fSlow1) + 1.0); + double fSlow6 = (fSlow1 + -1.0); + double fSlow7 = faustEqHshelf_faustpower2_f(fSlow6); + double fSlow8 = ((std::sqrt(fSlow1) * std::sin(fSlow2)) / std::max(0.001, (1.0 / std::sqrt((((fSlow1 + (1.0 / fSlow1)) * ((1.0 / std::min(((fSlow5 / fSlow7) + -0.01), std::max(0.01, ((double(fBandwidth) * fSlow5) / fSlow7)))) + -1.0)) + 2.0))))); + double fSlow9 = (fSlow3 * fSlow6); + double fSlow10 = ((fSlow1 + fSlow8) + (1.0 - fSlow9)); + double fSlow11 = (1.0 - fSlow0); + double fSlow12 = ((2.0 * ((fSlow1 + (-1.0 - fSlow4)) / fSlow10)) * fSlow11); + double fSlow13 = (fSlow9 + fSlow8); + double fSlow14 = (((fSlow1 + (1.0 - fSlow13)) / fSlow10) * fSlow11); + double fSlow15 = (((fSlow1 * ((fSlow1 + fSlow13) + 1.0)) / fSlow10) * fSlow11); + double fSlow16 = ((((0.0 - (2.0 * fSlow1)) * ((fSlow1 + fSlow4) + -1.0)) / fSlow10) * fSlow11); + double fSlow17 = (((fSlow1 * ((fSlow1 + fSlow9) + (1.0 - fSlow8))) / fSlow10) * fSlow11); + for (int i = 0; (i < count); i = (i + 1)) { + double fTemp0 = double(input0[i]); + fRec1[0] = ((fSlow0 * fRec1[1]) + fSlow12); + fRec2[0] = ((fSlow0 * fRec2[1]) + fSlow14); + fRec0[0] = (fTemp0 - ((fRec1[0] * fRec0[1]) + (fRec2[0] * fRec0[2]))); + fRec3[0] = ((fSlow0 * fRec3[1]) + fSlow15); + fRec4[0] = ((fSlow0 * fRec4[1]) + fSlow16); + fRec5[0] = ((fSlow0 * fRec5[1]) + fSlow17); + output0[i] = FAUSTFLOAT((((fRec0[0] * fRec3[0]) + (fRec4[0] * fRec0[1])) + (fRec5[0] * fRec0[2]))); + fRec1[1] = fRec1[0]; + fRec2[1] = fRec2[0]; + fRec0[2] = fRec0[1]; + fRec0[1] = fRec0[0]; + fRec3[1] = fRec3[0]; + fRec4[1] = fRec4[0]; + fRec5[1] = fRec5[0]; + } + } + +}; + +#endif diff --git a/src/sfizz/gen/filters/sfzEqLshelf.cxx b/src/sfizz/gen/filters/sfzEqLshelf.cxx new file mode 100644 index 00000000..f9a45b4a --- /dev/null +++ b/src/sfizz/gen/filters/sfzEqLshelf.cxx @@ -0,0 +1,191 @@ +/* ------------------------------------------------------------ +author: "Jean Pierre Cimalando" +license: "BSD-2-Clause" +name: "sfz_filters" +Code generated with Faust 2.20.2 (https://faust.grame.fr) +Compilation options: -lang cpp -inpl -double -ftz 0 +------------------------------------------------------------ */ + +#ifndef __faustEqLshelf_H__ +#define __faustEqLshelf_H__ + +#ifndef FAUSTFLOAT +#define FAUSTFLOAT float +#endif + +#include +#include +#include + +static double faustEqLshelf_faustpower2_f(double value) { + return (value * value); +} + +#ifndef FAUSTCLASS +#define FAUSTCLASS faustEqLshelf +#endif + +#ifdef __APPLE__ +#define exp10f __exp10f +#define exp10 __exp10 +#endif + +class faustEqLshelf : public sfzFilterDsp { + + public: + + int fSampleRate; + double fConst0; + double fConst1; + FAUSTFLOAT fPkShGain; + double fConst2; + FAUSTFLOAT fCutoff; + FAUSTFLOAT fBandwidth; + double fRec1[2]; + double fRec2[2]; + double fRec0[3]; + double fRec3[2]; + double fRec4[2]; + double fRec5[2]; + + public: + + void metadata(Meta* m) { + } + + virtual int getNumInputs() { + return 1; + } + virtual int getNumOutputs() { + return 1; + } + virtual int getInputRate(int channel) { + int rate; + switch ((channel)) { + case 0: { + rate = 1; + break; + } + default: { + rate = -1; + break; + } + } + return rate; + } + virtual int getOutputRate(int channel) { + int rate; + switch ((channel)) { + case 0: { + rate = 1; + break; + } + default: { + rate = -1; + break; + } + } + return rate; + } + + static void classInit(int sample_rate) { + } + + virtual void instanceConstants(int sample_rate) { + fSampleRate = sample_rate; + fConst0 = std::min(192000.0, std::max(1.0, double(fSampleRate))); + fConst1 = std::exp((0.0 - (1000.0 / fConst0))); + fConst2 = (6.2831853071795862 / fConst0); + } + + virtual void instanceResetUserInterface() { + fPkShGain = FAUSTFLOAT(0.0); + fCutoff = FAUSTFLOAT(440.0); + fBandwidth = FAUSTFLOAT(1.0); + } + + virtual void instanceClear() { + for (int l0 = 0; (l0 < 2); l0 = (l0 + 1)) { + fRec1[l0] = 0.0; + } + for (int l1 = 0; (l1 < 2); l1 = (l1 + 1)) { + fRec2[l1] = 0.0; + } + for (int l2 = 0; (l2 < 3); l2 = (l2 + 1)) { + fRec0[l2] = 0.0; + } + for (int l3 = 0; (l3 < 2); l3 = (l3 + 1)) { + fRec3[l3] = 0.0; + } + for (int l4 = 0; (l4 < 2); l4 = (l4 + 1)) { + fRec4[l4] = 0.0; + } + for (int l5 = 0; (l5 < 2); l5 = (l5 + 1)) { + fRec5[l5] = 0.0; + } + } + + virtual void init(int sample_rate) { + classInit(sample_rate); + instanceInit(sample_rate); + } + virtual void instanceInit(int sample_rate) { + instanceConstants(sample_rate); + instanceResetUserInterface(); + instanceClear(); + } + + virtual faustEqLshelf* clone() { + return new faustEqLshelf(); + } + + virtual int getSampleRate() { + return fSampleRate; + } + + virtual void buildUserInterface(UI* ui_interface) { + } + + virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { + FAUSTFLOAT* input0 = inputs[0]; + FAUSTFLOAT* output0 = outputs[0]; + double fSlow0 = (fSmoothEnable ? fConst1 : 0.0); + double fSlow1 = std::pow(10.0, (0.025000000000000001 * double(fPkShGain))); + double fSlow2 = (fConst2 * std::max(0.0, double(fCutoff))); + double fSlow3 = std::cos(fSlow2); + double fSlow4 = (fSlow3 * (fSlow1 + 1.0)); + double fSlow5 = (fSlow1 + -1.0); + double fSlow6 = (fSlow3 * fSlow5); + double fSlow7 = (faustEqLshelf_faustpower2_f(fSlow1) + 1.0); + double fSlow8 = faustEqLshelf_faustpower2_f(fSlow5); + double fSlow9 = ((std::sqrt(fSlow1) * std::sin(fSlow2)) / std::max(0.001, (1.0 / std::sqrt((((fSlow1 + (1.0 / fSlow1)) * ((1.0 / std::min(((fSlow7 / fSlow8) + -0.01), std::max(0.01, ((double(fBandwidth) * fSlow7) / fSlow8)))) + -1.0)) + 2.0))))); + double fSlow10 = (fSlow6 + fSlow9); + double fSlow11 = ((fSlow1 + fSlow10) + 1.0); + double fSlow12 = (1.0 - fSlow0); + double fSlow13 = (((0.0 - (2.0 * ((fSlow1 + fSlow4) + -1.0))) / fSlow11) * fSlow12); + double fSlow14 = ((((fSlow1 + fSlow6) + (1.0 - fSlow9)) / fSlow11) * fSlow12); + double fSlow15 = (((fSlow1 * ((fSlow1 + fSlow9) + (1.0 - fSlow6))) / fSlow11) * fSlow12); + double fSlow16 = ((2.0 * ((fSlow1 * (fSlow1 + (-1.0 - fSlow4))) / fSlow11)) * fSlow12); + double fSlow17 = (((fSlow1 * (fSlow1 + (1.0 - fSlow10))) / fSlow11) * fSlow12); + for (int i = 0; (i < count); i = (i + 1)) { + double fTemp0 = double(input0[i]); + fRec1[0] = ((fSlow0 * fRec1[1]) + fSlow13); + fRec2[0] = ((fSlow0 * fRec2[1]) + fSlow14); + fRec0[0] = (fTemp0 - ((fRec1[0] * fRec0[1]) + (fRec2[0] * fRec0[2]))); + fRec3[0] = ((fSlow0 * fRec3[1]) + fSlow15); + fRec4[0] = ((fSlow0 * fRec4[1]) + fSlow16); + fRec5[0] = ((fSlow0 * fRec5[1]) + fSlow17); + output0[i] = FAUSTFLOAT((((fRec0[0] * fRec3[0]) + (fRec4[0] * fRec0[1])) + (fRec5[0] * fRec0[2]))); + fRec1[1] = fRec1[0]; + fRec2[1] = fRec2[0]; + fRec0[2] = fRec0[1]; + fRec0[1] = fRec0[0]; + fRec3[1] = fRec3[0]; + fRec4[1] = fRec4[0]; + fRec5[1] = fRec5[0]; + } + } + +}; + +#endif diff --git a/src/sfizz/gen/filters/sfzEq.cxx b/src/sfizz/gen/filters/sfzEqPeak.cxx similarity index 95% rename from src/sfizz/gen/filters/sfzEq.cxx rename to src/sfizz/gen/filters/sfzEqPeak.cxx index c0de8618..5eb2f7f2 100644 --- a/src/sfizz/gen/filters/sfzEq.cxx +++ b/src/sfizz/gen/filters/sfzEqPeak.cxx @@ -6,8 +6,8 @@ Code generated with Faust 2.20.2 (https://faust.grame.fr) Compilation options: -lang cpp -inpl -double -ftz 0 ------------------------------------------------------------ */ -#ifndef __faustEq_H__ -#define __faustEq_H__ +#ifndef __faustEqPeak_H__ +#define __faustEqPeak_H__ #ifndef FAUSTFLOAT #define FAUSTFLOAT float @@ -20,7 +20,7 @@ Compilation options: -lang cpp -inpl -double -ftz 0 #ifndef FAUSTCLASS -#define FAUSTCLASS faustEq +#define FAUSTCLASS faustEqPeak #endif #ifdef __APPLE__ @@ -28,7 +28,7 @@ Compilation options: -lang cpp -inpl -double -ftz 0 #define exp10 __exp10 #endif -class faustEq : public sfzFilterDsp { +class faustEqPeak : public sfzFilterDsp { public: @@ -131,8 +131,8 @@ class faustEq : public sfzFilterDsp { instanceClear(); } - virtual faustEq* clone() { - return new faustEq(); + virtual faustEqPeak* clone() { + return new faustEqPeak(); } virtual int getSampleRate() { From 21ed6f9ed3c3a64235f1ef45e42262fe772b6c2f Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Wed, 11 Mar 2020 20:17:44 +0100 Subject: [PATCH 2/9] Allow the EQ demo to work with the filter update --- tests/DemoFilters.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/DemoFilters.cpp b/tests/DemoFilters.cpp index 622a7daa..3a59ea7e 100644 --- a/tests/DemoFilters.cpp +++ b/tests/DemoFilters.cpp @@ -117,6 +117,7 @@ bool DemoApp::initSound() fFilter.setChannels(2); fFilterEq.init(sampleRate); + fFilterEq.setType(sfz::kEqPeak); // TODO: make a chooser of EQ type fFilterEq.setChannels(2); fTempCutoff.reset(new float[bufferSize]); From 344e318b19dc4b1e688ac95fe9db4a3b9c071cd8 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Thu, 12 Mar 2020 14:03:33 +0100 Subject: [PATCH 3/9] Add some functions to lookup filter type. Add the bpk_2p alias. --- src/sfizz/Region.cpp | 47 ++++++++++++----------------------------- src/sfizz/SfzFilter.cpp | 47 +++++++++++++++++++++++++++++++++++++++++ src/sfizz/SfzFilter.h | 12 +++++++++++ 3 files changed, 73 insertions(+), 33 deletions(-) diff --git a/src/sfizz/Region.cpp b/src/sfizz/Region.cpp index 35daf0a6..8dc962b4 100644 --- a/src/sfizz/Region.cpp +++ b/src/sfizz/Region.cpp @@ -498,32 +498,13 @@ bool sfz::Region::parseOpcode(const Opcode& opcode) if (!extendIfNecessary(filters, filterIndex + 1, Default::numFilters)) return false; - switch (hash(opcode.value)) { - case hash("lpf_1p"): filters[filterIndex].type = FilterType::kFilterLpf1p; break; - case hash("hpf_1p"): filters[filterIndex].type = FilterType::kFilterHpf1p; break; - case hash("lpf_2p"): filters[filterIndex].type = FilterType::kFilterLpf2p; break; - case hash("hpf_2p"): filters[filterIndex].type = FilterType::kFilterHpf2p; break; - case hash("bpf_2p"): filters[filterIndex].type = FilterType::kFilterBpf2p; break; - case hash("brf_2p"): filters[filterIndex].type = FilterType::kFilterBrf2p; break; - case hash("bpf_1p"): filters[filterIndex].type = FilterType::kFilterBpf1p; break; - case hash("brf_1p"): filters[filterIndex].type = FilterType::kFilterBrf1p; break; - case hash("apf_1p"): filters[filterIndex].type = FilterType::kFilterApf1p; break; - case hash("lpf_2p_sv"): filters[filterIndex].type = FilterType::kFilterLpf2pSv; break; - case hash("hpf_2p_sv"): filters[filterIndex].type = FilterType::kFilterHpf2pSv; break; - case hash("bpf_2p_sv"): filters[filterIndex].type = FilterType::kFilterBpf2pSv; break; - case hash("brf_2p_sv"): filters[filterIndex].type = FilterType::kFilterBrf2pSv; break; - case hash("lpf_4p"): filters[filterIndex].type = FilterType::kFilterLpf4p; break; - case hash("hpf_4p"): filters[filterIndex].type = FilterType::kFilterHpf4p; break; - case hash("lpf_6p"): filters[filterIndex].type = FilterType::kFilterLpf6p; break; - case hash("hpf_6p"): filters[filterIndex].type = FilterType::kFilterHpf6p; break; - case hash("pink"): filters[filterIndex].type = FilterType::kFilterPink; break; - case hash("lsh"): filters[filterIndex].type = FilterType::kFilterLsh; break; - case hash("hsh"): filters[filterIndex].type = FilterType::kFilterHsh; break; - case hash("pkf_2p"): [[fallthrough]]; - case hash("peq"): filters[filterIndex].type = FilterType::kFilterPeq; break; - default: - filters[filterIndex].type = FilterType::kFilterNone; - DBG("Unknown filter type: " << std::string(opcode.value)); + absl::optional ftype = Filter::typeFromName(opcode.value); + + if (ftype) + filters[filterIndex].type = *ftype; + else { + filters[filterIndex].type = FilterType::kFilterNone; + DBG("Unknown filter type: " << std::string(opcode.value)); } } break; @@ -629,13 +610,13 @@ bool sfz::Region::parseOpcode(const Opcode& opcode) if (!extendIfNecessary(equalizers, eqNumber, Default::numEQs)) return false; - switch (hash(opcode.value)) { - case hash("peak"): equalizers[eqNumber - 1].type = EqType::kEqPeak; break; - case hash("lshelf"): equalizers[eqNumber - 1].type = EqType::kEqLowShelf; break; - case hash("hshelf"): equalizers[eqNumber - 1].type = EqType::kEqHighShelf; break; - default: - equalizers[eqNumber - 1].type = EqType::kEqNone; - DBG("Unknown EQ type: " << std::string(opcode.value)); + absl::optional ftype = FilterEq::typeFromName(opcode.value); + + if (ftype) + equalizers[eqNumber - 1].type = *ftype; + else { + equalizers[eqNumber - 1].type = EqType::kEqNone; + DBG("Unknown EQ type: " << std::string(opcode.value)); } } break; diff --git a/src/sfizz/SfzFilter.cpp b/src/sfizz/SfzFilter.cpp index fa7d354c..a172c68b 100644 --- a/src/sfizz/SfzFilter.cpp +++ b/src/sfizz/SfzFilter.cpp @@ -7,6 +7,7 @@ #include "Config.h" #include "SfzFilter.h" #include "SfzFilterImpls.cxx" +#include "StringViewHelpers.h" #include #include "SIMDHelpers.h" #include "Debug.h" @@ -203,6 +204,39 @@ void Filter::setType(FilterType type) } } +absl::optional Filter::typeFromName(absl::string_view name) +{ + absl::optional ftype; + + switch (hash(name)) { + case hash("lpf_1p"): ftype = kFilterLpf1p; break; + case hash("hpf_1p"): ftype = kFilterHpf1p; break; + case hash("lpf_2p"): ftype = kFilterLpf2p; break; + case hash("hpf_2p"): ftype = kFilterHpf2p; break; + case hash("bpf_2p"): ftype = kFilterBpf2p; break; + case hash("brf_2p"): ftype = kFilterBrf2p; break; + case hash("bpf_1p"): ftype = kFilterBpf1p; break; + case hash("brf_1p"): ftype = kFilterBrf1p; break; + case hash("apf_1p"): ftype = kFilterApf1p; break; + case hash("lpf_2p_sv"): ftype = kFilterLpf2pSv; break; + case hash("hpf_2p_sv"): ftype = kFilterHpf2pSv; break; + case hash("bpf_2p_sv"): ftype = kFilterBpf2pSv; break; + case hash("brf_2p_sv"): ftype = kFilterBrf2pSv; break; + case hash("lpf_4p"): ftype = kFilterLpf4p; break; + case hash("hpf_4p"): ftype = kFilterHpf4p; break; + case hash("lpf_6p"): ftype = kFilterLpf6p; break; + case hash("hpf_6p"): ftype = kFilterHpf6p; break; + case hash("pink"): ftype = kFilterPink; break; + case hash("lsh"): ftype = kFilterLsh; break; + case hash("hsh"): ftype = kFilterHsh; break; + case hash("bpk_2p"): [[fallthrough]]; + case hash("pkf_2p"): [[fallthrough]]; + case hash("peq"): ftype = kFilterPeq; break; + } + + return ftype; +} + sfzFilterDsp *Filter::Impl::getDsp(unsigned channels, FilterType type) { switch (idDsp(channels, type)) { @@ -410,6 +444,19 @@ void FilterEq::setType(EqType type) } } +absl::optional FilterEq::typeFromName(absl::string_view name) +{ + absl::optional ftype; + + switch (hash(name)) { + case hash("peak"): ftype = kEqPeak; break; + case hash("lshelf"): ftype = kEqLowShelf; break; + case hash("hshelf"): ftype = kEqHighShelf; break; + } + + return ftype; +} + sfzFilterDsp *FilterEq::Impl::getDsp(unsigned channels, EqType type) { switch (idDsp(channels, type)) { diff --git a/src/sfizz/SfzFilter.h b/src/sfizz/SfzFilter.h index ec6a8191..62cba612 100644 --- a/src/sfizz/SfzFilter.h +++ b/src/sfizz/SfzFilter.h @@ -5,6 +5,8 @@ // If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz #pragma once +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" #include namespace sfz { @@ -82,6 +84,11 @@ public: */ void setType(FilterType type); + /** + Get the filter type associated with the given name. + */ + static absl::optional typeFromName(absl::string_view name); + private: struct Impl; std::unique_ptr P; @@ -187,6 +194,11 @@ public: */ void setType(EqType type); + /** + Get the filter type associated with the given name. + */ + static absl::optional typeFromName(absl::string_view name); + private: struct Impl; std::unique_ptr P; From bfbbc6085b4a4cb2ee31f357c26570d9521e04d7 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Thu, 12 Mar 2020 14:27:39 +0100 Subject: [PATCH 4/9] Add the filter effect --- src/CMakeLists.txt | 1 + src/sfizz/Effects.cpp | 2 + src/sfizz/effects/Filter.cpp | 101 +++++++++++++++++++++++++++++++++++ src/sfizz/effects/Filter.h | 55 +++++++++++++++++++ 4 files changed, 159 insertions(+) create mode 100644 src/sfizz/effects/Filter.cpp create mode 100644 src/sfizz/effects/Filter.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5b22a2b2..6113c8b0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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) diff --git a/src/sfizz/Effects.cpp b/src/sfizz/Effects.cpp index 512f2b5e..78159d4e 100644 --- a/src/sfizz/Effects.cpp +++ b/src/sfizz/Effects.cpp @@ -10,6 +10,7 @@ #include "SIMDHelpers.h" #include "Config.h" #include "effects/Nothing.h" +#include "effects/Filter.h" #include "effects/Lofi.h" #include @@ -18,6 +19,7 @@ namespace sfz { void EffectFactory::registerStandardEffectTypes() { // TODO + registerEffectType("filter", fx::Filter::makeInstance); registerEffectType("lofi", fx::Lofi::makeInstance); } diff --git a/src/sfizz/effects/Filter.cpp b/src/sfizz/effects/Filter.cpp new file mode 100644 index 00000000..1303132e --- /dev/null +++ b/src/sfizz/effects/Filter.cpp @@ -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 cutoff = _tempBuffer.getSpan(0).first(nframes); + absl::Span q = _tempBuffer.getSpan(1).first(nframes); + absl::Span 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 Filter::makeInstance(absl::Span 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 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(desc); + } + +} // namespace fx +} // namespace sfz diff --git a/src/sfizz/effects/Filter.h b/src/sfizz/effects/Filter.h new file mode 100644 index 00000000..c3265667 --- /dev/null +++ b/src/sfizz/effects/Filter.h @@ -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 block. + */ + static std::unique_ptr makeInstance(absl::Span members); + + private: + sfz::Filter _filter; + FilterDescription _desc; + AudioBuffer _tempBuffer { 3, config::defaultSamplesPerBlock }; + }; + +} // namespace fx +} // namespace sfz From 43262395c9bd7edb2585c042bc74dd385e83bb99 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Thu, 12 Mar 2020 14:49:31 +0100 Subject: [PATCH 5/9] Add the EQ effect --- src/CMakeLists.txt | 1 + src/sfizz/Effects.cpp | 2 + src/sfizz/effects/Eq.cpp | 98 ++++++++++++++++++++++++++++++++++++++++ src/sfizz/effects/Eq.h | 55 ++++++++++++++++++++++ 4 files changed, 156 insertions(+) create mode 100644 src/sfizz/effects/Eq.cpp create mode 100644 src/sfizz/effects/Eq.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6113c8b0..14d469f6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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) diff --git a/src/sfizz/Effects.cpp b/src/sfizz/Effects.cpp index 78159d4e..71494d1d 100644 --- a/src/sfizz/Effects.cpp +++ b/src/sfizz/Effects.cpp @@ -11,6 +11,7 @@ #include "Config.h" #include "effects/Nothing.h" #include "effects/Filter.h" +#include "effects/Eq.h" #include "effects/Lofi.h" #include @@ -20,6 +21,7 @@ void EffectFactory::registerStandardEffectTypes() { // TODO registerEffectType("filter", fx::Filter::makeInstance); + registerEffectType("eq", fx::Eq::makeInstance); registerEffectType("lofi", fx::Lofi::makeInstance); } diff --git a/src/sfizz/effects/Eq.cpp b/src/sfizz/effects/Eq.cpp new file mode 100644 index 00000000..2e4ad052 --- /dev/null +++ b/src/sfizz/effects/Eq.cpp @@ -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 cutoff = _tempBuffer.getSpan(0).first(nframes); + absl::Span bw = _tempBuffer.getSpan(1).first(nframes); + absl::Span 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 Eq::makeInstance(absl::Span 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 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(desc); + } + +} // namespace fx +} // namespace sfz diff --git a/src/sfizz/effects/Eq.h b/src/sfizz/effects/Eq.h new file mode 100644 index 00000000..0c94cc9a --- /dev/null +++ b/src/sfizz/effects/Eq.h @@ -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 block. + */ + static std::unique_ptr makeInstance(absl::Span members); + + private: + sfz::FilterEq _filter; + EQDescription _desc; + AudioBuffer _tempBuffer { 3, config::defaultSamplesPerBlock }; + }; + +} // namespace fx +} // namespace sfz From 74bb98c957039ee4507c2a3fd22828ce99d3be8c Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Thu, 12 Mar 2020 16:00:25 +0100 Subject: [PATCH 6/9] Fix various errors --- src/sfizz/effects/Eq.cpp | 3 +-- src/sfizz/effects/Eq.h | 2 +- src/sfizz/effects/Filter.cpp | 3 +-- src/sfizz/effects/Filter.h | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/sfizz/effects/Eq.cpp b/src/sfizz/effects/Eq.cpp index 2e4ad052..8c1188c5 100644 --- a/src/sfizz/effects/Eq.cpp +++ b/src/sfizz/effects/Eq.cpp @@ -36,7 +36,6 @@ namespace fx { void Eq::setSampleRate(double sampleRate) { _filter.init(sampleRate); - _filter.clear(); } void Eq::setSamplesPerBlock(int samplesPerBlock) @@ -67,7 +66,7 @@ namespace fx { EQDescription desc; for (const Opcode& opc : members) { - switch (hash(opc.value)) { + switch (opc.lettersOnlyHash) { case hash("eq_freq"): setValueFromOpcode(opc, desc.frequency, Default::eqFrequencyRange); break; diff --git a/src/sfizz/effects/Eq.h b/src/sfizz/effects/Eq.h index 0c94cc9a..7f1f2b63 100644 --- a/src/sfizz/effects/Eq.h +++ b/src/sfizz/effects/Eq.h @@ -48,7 +48,7 @@ namespace fx { private: sfz::FilterEq _filter; EQDescription _desc; - AudioBuffer _tempBuffer { 3, config::defaultSamplesPerBlock }; + AudioBuffer _tempBuffer { 3, config::defaultSamplesPerBlock }; }; } // namespace fx diff --git a/src/sfizz/effects/Filter.cpp b/src/sfizz/effects/Filter.cpp index 1303132e..42ee5c4f 100644 --- a/src/sfizz/effects/Filter.cpp +++ b/src/sfizz/effects/Filter.cpp @@ -38,7 +38,6 @@ namespace fx { void Filter::setSampleRate(double sampleRate) { _filter.init(sampleRate); - _filter.clear(); } void Filter::setSamplesPerBlock(int samplesPerBlock) @@ -69,7 +68,7 @@ namespace fx { FilterDescription desc; for (const Opcode& opc : members) { - switch (hash(opc.value)) { + switch (opc.lettersOnlyHash) { case hash("filter_cutoff"): setValueFromOpcode(opc, desc.cutoff, Default::filterCutoffRange); break; diff --git a/src/sfizz/effects/Filter.h b/src/sfizz/effects/Filter.h index c3265667..51546041 100644 --- a/src/sfizz/effects/Filter.h +++ b/src/sfizz/effects/Filter.h @@ -48,7 +48,7 @@ namespace fx { private: sfz::Filter _filter; FilterDescription _desc; - AudioBuffer _tempBuffer { 3, config::defaultSamplesPerBlock }; + AudioBuffer _tempBuffer { 3, config::defaultSamplesPerBlock }; }; } // namespace fx From 9dbfa706735a1a0fb7e837a3bef1afd6f61b591d Mon Sep 17 00:00:00 2001 From: Paul Fd Date: Thu, 12 Mar 2020 21:51:04 +0100 Subject: [PATCH 7/9] Wrong variable name in debug mode --- src/sfizz/effects/Eq.cpp | 2 +- src/sfizz/effects/Filter.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sfizz/effects/Eq.cpp b/src/sfizz/effects/Eq.cpp index 8c1188c5..90c5e032 100644 --- a/src/sfizz/effects/Eq.cpp +++ b/src/sfizz/effects/Eq.cpp @@ -83,7 +83,7 @@ namespace fx { desc.type = *ftype; else { desc.type = EqType::kEqNone; - DBG("Unknown EQ type: " << std::string(opcode.value)); + DBG("Unknown EQ type: " << std::string(opc.value)); } break; } diff --git a/src/sfizz/effects/Filter.cpp b/src/sfizz/effects/Filter.cpp index 42ee5c4f..a3783c9b 100644 --- a/src/sfizz/effects/Filter.cpp +++ b/src/sfizz/effects/Filter.cpp @@ -82,7 +82,7 @@ namespace fx { desc.type = *ftype; else { desc.type = FilterType::kFilterNone; - DBG("Unknown filter type: " << std::string(opcode.value)); + DBG("Unknown filter type: " << std::string(opc.value)); } break; } From 1ba834a8923ed1288392c2e603fed87d9cc71181 Mon Sep 17 00:00:00 2001 From: Paul Fd Date: Thu, 12 Mar 2020 21:51:17 +0100 Subject: [PATCH 8/9] Add tests for the new eq parameters --- tests/RegionT.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/RegionT.cpp b/tests/RegionT.cpp index 65bf133f..c96f34ae 100644 --- a/tests/RegionT.cpp +++ b/tests/RegionT.cpp @@ -1220,6 +1220,12 @@ TEST_CASE("[Region] Parsing opcodes") REQUIRE(region.filters[0].type == sfz::FilterType::kFilterHsh); region.parseOpcode({ "fil_type", "peq" }); REQUIRE(region.filters[0].type == sfz::FilterType::kFilterPeq); + region.parseOpcode({ "fil_type", "lpf_1p" }); + region.parseOpcode({ "fil_type", "pkf_2p" }); + REQUIRE(region.filters[0].type == sfz::FilterType::kFilterPeq); + region.parseOpcode({ "fil_type", "lpf_1p" }); + region.parseOpcode({ "fil_type", "bpk_2p" }); + REQUIRE(region.filters[0].type == sfz::FilterType::kFilterPeq); region.parseOpcode({ "fil_type", "unknown" }); REQUIRE(region.filters[0].type == sfz::FilterType::kFilterNone); } @@ -1232,6 +1238,7 @@ TEST_CASE("[Region] Parsing opcodes") REQUIRE(region.equalizers.size() == 1); REQUIRE(region.equalizers[0].gain == 6.0f); // Check defaults + REQUIRE(region.equalizers[0].type == sfz::EqType::kEqPeak); REQUIRE(region.equalizers[0].bandwidth == 1.0f); REQUIRE(region.equalizers[0].frequency == 0.0f); REQUIRE(region.equalizers[0].vel2frequency == 0); @@ -1244,6 +1251,7 @@ TEST_CASE("[Region] Parsing opcodes") REQUIRE(region.equalizers.size() == 2); REQUIRE(region.equalizers[1].gain == -96.0f); // Check defaults + REQUIRE(region.equalizers[1].type == sfz::EqType::kEqPeak); REQUIRE(region.equalizers[1].bandwidth == 1.0f); REQUIRE(region.equalizers[1].frequency == 0.0f); REQUIRE(region.equalizers[1].vel2frequency == 0); @@ -1255,6 +1263,7 @@ TEST_CASE("[Region] Parsing opcodes") region.parseOpcode({ "eq4_gain", "500" }); REQUIRE(region.equalizers.size() == 4); REQUIRE(region.equalizers[2].gain == 0.0f); + REQUIRE(region.equalizers[3].type == sfz::EqType::kEqPeak); REQUIRE(region.equalizers[3].gain == 96.0f); // Check defaults REQUIRE(region.equalizers[2].bandwidth == 1.0f); @@ -1273,6 +1282,18 @@ TEST_CASE("[Region] Parsing opcodes") REQUIRE(region.equalizers[3].gainCC.empty()); } + SECTION("EQ types") + { + region.parseOpcode({ "eq1_type", "hshelf" }); + REQUIRE(region.equalizers[0].type == sfz::EqType::kEqHighShelf); + region.parseOpcode({ "eq1_type", "somethingsomething" }); + REQUIRE(region.equalizers[0].type == sfz::EqType::kEqNone); + region.parseOpcode({ "eq1_type", "lshelf" }); + REQUIRE(region.equalizers[0].type == sfz::EqType::kEqLowShelf); + region.parseOpcode({ "eq1_type", "peak" }); + REQUIRE(region.equalizers[0].type == sfz::EqType::kEqPeak); + } + SECTION("EQ parameter dispatch") { region.parseOpcode({ "eq3_bw", "2" }); @@ -1282,6 +1303,8 @@ TEST_CASE("[Region] Parsing opcodes") REQUIRE(region.equalizers[0].gain == -25.0f); region.parseOpcode({ "eq2_freq", "300" }); REQUIRE(region.equalizers[1].frequency == 300.0f); + region.parseOpcode({ "eq3_type", "lshelf" }); + REQUIRE(region.equalizers[2].type == sfz::EqType::kEqLowShelf); region.parseOpcode({ "eq3_vel2gain", "10" }); REQUIRE(region.equalizers[2].vel2gain == 10.0f); region.parseOpcode({ "eq1_vel2freq", "100" }); @@ -1297,6 +1320,8 @@ TEST_CASE("[Region] Parsing opcodes") REQUIRE(region.equalizers[2].frequencyCC[15] == 10.0f); region.parseOpcode({ "eq3_freq_oncc15", "20" }); REQUIRE(region.equalizers[2].frequencyCC[15] == 20.0f); + region.parseOpcode({ "eq1_type", "hshelf" }); + REQUIRE(region.equalizers[0].type == sfz::EqType::kEqHighShelf); region.parseOpcode({ "eq2_gaincc123", "2" }); REQUIRE(region.equalizers[1].gainCC.contains(123)); REQUIRE(region.equalizers[1].gainCC[123] == 2.0f); From 98b44d70979627794ff9f7aa0323bf69809c15a7 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Thu, 12 Mar 2020 22:58:50 +0100 Subject: [PATCH 9/9] Prepare the coeffs initially in filter-based effects --- src/sfizz/effects/Eq.cpp | 7 +++++++ src/sfizz/effects/Eq.h | 3 +++ src/sfizz/effects/Filter.cpp | 7 +++++++ src/sfizz/effects/Filter.h | 3 +++ 4 files changed, 20 insertions(+) diff --git a/src/sfizz/effects/Eq.cpp b/src/sfizz/effects/Eq.cpp index 90c5e032..a61f77e7 100644 --- a/src/sfizz/effects/Eq.cpp +++ b/src/sfizz/effects/Eq.cpp @@ -36,6 +36,7 @@ namespace fx { void Eq::setSampleRate(double sampleRate) { _filter.init(sampleRate); + prepareFilter(); } void Eq::setSamplesPerBlock(int samplesPerBlock) @@ -46,6 +47,7 @@ namespace fx { void Eq::clear() { _filter.clear(); + prepareFilter(); } void Eq::process(const float* const inputs[], float* const outputs[], unsigned nframes) @@ -93,5 +95,10 @@ namespace fx { return absl::make_unique(desc); } + void Eq::prepareFilter() + { + _filter.prepare(_desc.frequency, _desc.bandwidth, _desc.gain); + } + } // namespace fx } // namespace sfz diff --git a/src/sfizz/effects/Eq.h b/src/sfizz/effects/Eq.h index 7f1f2b63..ea6a5976 100644 --- a/src/sfizz/effects/Eq.h +++ b/src/sfizz/effects/Eq.h @@ -45,6 +45,9 @@ namespace fx { */ static std::unique_ptr makeInstance(absl::Span members); + private: + void prepareFilter(); + private: sfz::FilterEq _filter; EQDescription _desc; diff --git a/src/sfizz/effects/Filter.cpp b/src/sfizz/effects/Filter.cpp index a3783c9b..8b118ee0 100644 --- a/src/sfizz/effects/Filter.cpp +++ b/src/sfizz/effects/Filter.cpp @@ -38,6 +38,7 @@ namespace fx { void Filter::setSampleRate(double sampleRate) { _filter.init(sampleRate); + prepareFilter(); } void Filter::setSamplesPerBlock(int samplesPerBlock) @@ -48,6 +49,7 @@ namespace fx { void Filter::clear() { _filter.clear(); + prepareFilter(); } void Filter::process(const float* const inputs[], float* const outputs[], unsigned nframes) @@ -96,5 +98,10 @@ namespace fx { return absl::make_unique(desc); } + void Filter::prepareFilter() + { + _filter.prepare(_desc.cutoff, _desc.resonance, _desc.gain); + } + } // namespace fx } // namespace sfz diff --git a/src/sfizz/effects/Filter.h b/src/sfizz/effects/Filter.h index 51546041..9e91f798 100644 --- a/src/sfizz/effects/Filter.h +++ b/src/sfizz/effects/Filter.h @@ -45,6 +45,9 @@ namespace fx { */ static std::unique_ptr makeInstance(absl::Span members); + private: + void prepareFilter(); + private: sfz::Filter _filter; FilterDescription _desc;