diff --git a/architecture/faust/dsp/libfaust-signal.h b/architecture/faust/dsp/libfaust-signal.h index d8018afe98..4b777d90b0 100644 --- a/architecture/faust/dsp/libfaust-signal.h +++ b/architecture/faust/dsp/libfaust-signal.h @@ -473,6 +473,13 @@ LIBFAUST_API Signal sigAtan2(Signal x, Signal y); */ LIBFAUST_API Signal sigSelf(); +/** + * Create a recursive signal inside the sigRecursion expression, without the one sample delay. + * + * @return the recursive signal. + */ +LIBFAUST_API Signal sigSelfZero(); + /** * Create a recursive signal. Use sigSelf() to refer to the * recursive signal inside the sigRecursion expression. @@ -492,6 +499,15 @@ LIBFAUST_API Signal sigRecursion(Signal s); */ LIBFAUST_API Signal sigSelfN(int id); +/** + * Create a recursive signal inside the sigRecursionN expression, without the one sample delay. + * + * @param id - the recursive signal index (starting from 0, up to the number of outputs signals in the recursive block) + * + * @return the recursive signal. + */ +LIBFAUST_API Signal sigSelfZeroN(int id); + /** * Create a recursive block of signals. Use sigSelfN() to refer to the * recursive signal inside the sigRecursionN expression. diff --git a/architecture/max-msp/py2max b/architecture/max-msp/py2max index 3d8cc3c476..f7e2aac53e 160000 --- a/architecture/max-msp/py2max +++ b/architecture/max-msp/py2max @@ -1 +1 @@ -Subproject commit 3d8cc3c476fec7a9700cd40c99a3e8efd2ee5046 +Subproject commit f7e2aac53e462f03e499d41842920cea0aa13c5c diff --git a/compiler/box_signal_api.cpp b/compiler/box_signal_api.cpp index 4072dd5845..dbaa8f2487 100644 --- a/compiler/box_signal_api.cpp +++ b/compiler/box_signal_api.cpp @@ -211,6 +211,11 @@ LIBFAUST_API Tree sigSelf() return sigDelay1(sigProj(0, ref(1))); } +LIBFAUST_API Tree sigSelfZero() +{ + return sigDelay0(sigProj(0, ref(1))); +} + LIBFAUST_API Tree sigRecursion(Tree s) { return sigDelay0(sigProj(0, rec(cons(s, gGlobal->nil)))); @@ -222,6 +227,11 @@ LIBFAUST_API Tree sigSelfN(int i) return sigDelay1(sigProj(i, ref(1))); } +LIBFAUST_API Tree sigSelfZeroN(int i) +{ + return sigDelay0(sigProj(i, ref(1))); +} + LIBFAUST_API tvec sigRecursionN(const tvec& ins) { Tree out = rec(listConvert(ins)); diff --git a/tools/benchmark/Makefile b/tools/benchmark/Makefile index 525c56804a..ff4c0b0208 100644 --- a/tools/benchmark/Makefile +++ b/tools/benchmark/Makefile @@ -100,6 +100,9 @@ interp-tracer: interp-tracer.cpp $(LIB)/libfaust.a signal-tester: signal-tester.cpp $(LIB)/libfaust.a $(CXX) $(COMPILEOPT) $(ARCHS) signal-tester.cpp -L $(LIB_FLAGS) $(LIBS) -I $(INC) $(LLVM) `pkg-config --cflags --libs jack gtk+-2.0` $(STRIP) -lz -lncurses -lpthread -o $@ +ciaramella: ciaramella.cpp $(LIB)/libfaust.a + $(CXX) $(COMPILEOPT) ciaramella.cpp -L/opt/local/lib $(LIBS) -I $(INC) $(LLVM) `pkg-config --cflags --libs jack gtk+-2.0` $(STRIP) -lz -lncurses -lpthread -o $@ + signal-tester-c: signal-tester.c $(LIB)/libfaust.a $(CXX) $(COMPILEOPT1) $(ARCHS) signal-tester.c -L $(LIB_FLAGS) $(LIBS) -I $(INC) $(LLVM) $(STRIP) -lz -lncurses -lpthread -o signal-tester-c diff --git a/tools/benchmark/ciaramella.cpp b/tools/benchmark/ciaramella.cpp new file mode 100644 index 0000000000..9a7262094e --- /dev/null +++ b/tools/benchmark/ciaramella.cpp @@ -0,0 +1,848 @@ +/************************************************************************ + FAUST Architecture File + Copyright (C) 2021 GRAME, Centre National de Creation Musicale + --------------------------------------------------------------------- + This Architecture section is free software; you can redistribute it + and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 3 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; If not, see . + + EXCEPTION : As a special exception, you may create a larger work + that contains this FAUST architecture section and distribute + that work under terms of your choice, so long as this FAUST + architecture section is not modified. + + ************************************************************************/ + +#include +#include +#include +#include + +#include "faust/dsp/libfaust-signal.h" +#include "faust/dsp/llvm-dsp.h" +#include "faust/dsp/dsp-combiner.h" +#include "faust/audio/dummy-audio.h" +#include "faust/misc.h" + +// Ciaramella C++ code +#include "generated-code/lp_filter.cpp" +#include "generated-code/lp_filter2.cpp" +#include "generated-code/lp_filter3.cpp" +#include "generated-code/lowshelffilter.cpp" +#include "generated-code/diode_clipper.cpp" + +// Faust C++ code +#include "generated-code/lp_filter2_faust.cpp" + +#define SAMPLE_RATE 44100 + +#define CUTOFF 0.8 +#define VOL 0.9 +#define GAIN 0.5 + +// Base Faust ciaramella adapter class +struct ciaramella_dsp : public dsp { + + ciaramella_dsp() + {} + + virtual int getNumInputs() { return -1; } + virtual int getNumOutputs() { return -1; } + + virtual void init(int sample_rate) + {} + + virtual void instanceInit(int sample_rate) + {} + virtual void instanceConstants(int sample_rate) + {} + + virtual void instanceResetUserInterface() + {} + + virtual void instanceClear() + {} + + virtual dsp* clone() { return new ciaramella_dsp(); } + + virtual void metadata(Meta* m) {} + + virtual void buildUserInterface(UI* ui_interface) + {} + + virtual int getSampleRate() { return SAMPLE_RATE; } + + virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) + {} +}; + +// Faust adapter for lp_filter +struct ciaramella_lp_dsp : public ciaramella_dsp { + + lp_filter fFilter; + + ciaramella_lp_dsp() + {} + + int getNumInputs() { return 1; } + int getNumOutputs() { return 1; } + + void init(int sample_rate) + { + fFilter.setSampleRate(sample_rate); + fFilter.reset(); + fFilter.setcutoff(CUTOFF); + } + + dsp* clone() { return new ciaramella_lp_dsp(); } + + void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) + { + fFilter.process(inputs[0], outputs[0], count); + } +}; + +// Faust adapter for lp_filter2 +struct ciaramella_lp2_dsp : public ciaramella_dsp { + + lp_filter2 fFilter; + + ciaramella_lp2_dsp() + {} + + int getNumInputs() { return 1; } + int getNumOutputs() { return 1; } + + void init(int sample_rate) + { + fFilter.setSampleRate(sample_rate); + fFilter.reset(); + fFilter.setcutoff(CUTOFF); + } + + dsp* clone() { return new ciaramella_lp2_dsp(); } + + void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) + { + fFilter.process(inputs[0], outputs[0], count); + } +}; + +// Faust adapter for lp_filter3 +struct ciaramella_lp3_dsp : public ciaramella_dsp { + + lp_filter3 fFilter; + + ciaramella_lp3_dsp() + {} + + int getNumInputs() { return 1; } + int getNumOutputs() { return 1; } + + void init(int sample_rate) + { + fFilter.setSampleRate(sample_rate); + fFilter.reset(); + fFilter.setcutoff(CUTOFF); + fFilter.setvol(VOL); + } + + dsp* clone() { return new ciaramella_lp3_dsp(); } + + void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) + { + fFilter.process(inputs[0], outputs[0], count); + } +}; + +// Faust adapter for lowshelffilter +struct ciaramella_lowshelffilter_dsp : public ciaramella_dsp { + + lowshelffilter fFilter; + + ciaramella_lowshelffilter_dsp() + {} + + int getNumInputs() { return 1; } + int getNumOutputs() { return 1; } + + void init(int sample_rate) + { + fFilter.setSampleRate(sample_rate); + fFilter.reset(); + fFilter.setgain(GAIN); + } + + dsp* clone() { return new ciaramella_lowshelffilter_dsp(); } + + void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) + { + fFilter.process(inputs[0], outputs[0], count); + } +}; + +// Faust adapter for diode_clipper +struct ciaramella_diode_clipper_dsp : public ciaramella_dsp { + + diode_clipper fDiode; + + ciaramella_diode_clipper_dsp() + {} + + int getNumInputs() { return 1; } + int getNumOutputs() { return 1; } + + void init(int sample_rate) + { + fDiode.setSampleRate(sample_rate); + fDiode.reset(); + } + + dsp* clone() { return new ciaramella_diode_clipper_dsp(); } + + void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) + { + fDiode.process(inputs[0], outputs[0], count); + } +}; + +using namespace std; + +#define COMPILER(exp) \ +{ \ + createLibContext(); \ + exp \ + destroyLibContext(); \ +} \ + +static tvec concat(tvec v1, tvec v2) +{ + v1.insert(v1.end(), v2.begin(), v2.end()); + return v1; +} + +static void compile(const string& name_app, tvec signals, int argc = 0, const char* argv[] = nullptr) +{ + string error_msg, source = createSourceFromSignals(name_app, signals, "cpp", argc, argv, error_msg); + if (source != "") { + cout << source; + } else { + cerr << error_msg; + } +} +/** + * Return the current runtime sample rate. + * + * Reproduce the 'SR' definition in platform.lib: SR = fconstant(int fSamplingFreq, ); + * + * @return the current runtime sample rate. + */ +inline Signal fs() +{ + return sigFConst(SType::kSInt, "fSamplingFreq", ""); +} + +/** + * Return the current runtime buffer size. + * + * Reproduce the 'BS' definition in platform.lib: BS = fvariable(int count, ); + * + * @return the current runtime buffer size. + */ +inline Signal BS() +{ + return sigFVar(SType::kSInt, "count", ""); +} + +// WDF based filters + +// Create the PI constant +inline Signal pi() +{ + return sigReal(3.141592653589793); +} + +// Faust and ciamarella DSP tester: send a same noise test signal in both DSPs. + +typedef Signal (*signal_builder)(); + +static void filter_tester(signal_builder faust_dsp, dsp* ciaramella_dsp) +{ + // Create a noise test signal + string error_msg; + llvm_dsp_factory* noise_factory = createDSPFactoryFromString("FaustDSP", + "import(\"stdfaust.lib\"); process = no.noise;", + 0, NULL, "", + error_msg, -1); + assert(noise_factory); + + dsp* noise_dsp = noise_factory->createDSPInstance(); + assert(noise_dsp); + + createLibContext(); + { + // Create the filter using the signal API + tvec signals = { faust_dsp() }; + + // Compile the filter + llvm_dsp_factory* filter_factory = createDSPFactoryFromSignals("FaustDSP", signals, 0, nullptr, "", error_msg); + assert(filter_factory); + + // Instantiate the Faust filter + dsp* filter_dsp = filter_factory->createDSPInstance(); + assert(filter_dsp); + + // Create the parallelizer with both filters + dsp* parallel_dsp = createDSPParallelizer(ciaramella_dsp, filter_dsp, error_msg); + + // Split the noise test signal in both filters + dsp* splitter = createDSPSplitter(noise_dsp, parallel_dsp, error_msg); + + // Render the audio + dummyaudio audio(SAMPLE_RATE, 128, 1, 128); + audio.init("Test", splitter); + + // Audio real-time processing + audio.start(); + audio.stop(); + + delete filter_dsp; + deleteDSPFactory(filter_factory); + } + destroyLibContext(); + + delete noise_dsp; + deleteDSPFactory(noise_factory); +} + +static void filter_tester2(dsp* faust_dsp, dsp* ciaramella_dsp) +{ + // Create a noise test signal + string error_msg; + llvm_dsp_factory* noise_factory = createDSPFactoryFromString("FaustDSP", + "import(\"stdfaust.lib\"); process = no.noise;", + 0, NULL, "", + error_msg, -1); + assert(noise_factory); + + dsp* noise_dsp = noise_factory->createDSPInstance(); + assert(noise_dsp); + + // Create the parallelizer with both filters + dsp* parallel_dsp = createDSPParallelizer(ciaramella_dsp, faust_dsp, error_msg); + + // Split the noise test signal in both filters + dsp* splitter = createDSPSplitter(noise_dsp, parallel_dsp, error_msg); + + // Render the audio + dummyaudio audio(SAMPLE_RATE, 128, 1, 128); + audio.init("Test", splitter); + + // Audio real-time processing + audio.start(); + audio.stop(); + + delete noise_dsp; + deleteDSPFactory(noise_factory); +} + +/* +b, R0 = wdf_resistor(a, R) { + b = 0 + R0 = R +} +*/ +static tvec wdf_resistor(Signal a, Signal R) +{ + return { sigReal(0.0), R }; +} + +/* +b, R0 = wdf_capacitor(a, C) { + b = delay1(a) + R0 = 0.5 / (C * fs) +} +*/ +static tvec wdf_capacitor(Signal a, Signal C) +{ + return { sigDelay1(a), sigDiv(sigReal(0.5), sigMul(C, fs())) }; +} + +/* +b = wdf_voltage_source_root(a, E) { + b = 2 * E - a +} +*/ +static Signal wdf_voltage_source_root(Signal a, Signal E) +{ + return sigSub(sigMul(sigReal(2), E), a); +} + +/* +bu, bl, br, R0 = wdf_3port_series(au, al, ar, Rl, Rr) { + bl = al - Rl / (Rl + Rr) * (al + ar + au) + br = ar - Rr / (Rl + Rr) * (al + ar + au) + bu = -(al + ar) + R0 = Rl + Rr +} +*/ +static tvec wdf_3port_series(Signal au, Signal al, Signal ar, Signal Rl, Signal Rr) +{ + Signal bl = sigSub(al, sigMul(sigDiv(Rl, sigAdd(Rl, Rr)), sigAdd(sigAdd(al, ar), au))); + Signal br = sigSub(ar, sigMul(sigDiv(Rr, sigAdd(Rl, Rr)), sigAdd(sigAdd(al, ar), au))); + Signal bu = sigSub(sigReal(0.0), sigAdd(al, ar)); + Signal R0 = sigAdd(Rl, Rr); + return { bu, bl, br, R0 }; +} + +/* +bu, bl, br, R0 = wdf_3port_parallel(au, al, ar, Rl, Rr) { + # Naive implementation + bl = (dl - 1) * al + dr * ar + au + br = dl * al + (dr - 1) * ar + au + bu = dl * al + dr * ar + + R0 = (Rl * Rr) / (Rl + Rr) + Gu = 1.0 / R0 + Gl = 1.0 / Rl + Gr = 1.0 / Rr + dl = 2.0 * Gl / (Gu + Gl + Gr) + dr = 1.0 - dl +} +*/ +static tvec wdf_3port_parallel(Signal au, Signal al, Signal ar, Signal Rl, Signal Rr) +{ + Signal R0 = sigDiv(sigMul(Rl, Rr), sigAdd(Rl, Rr)); + Signal Gu = sigDiv(sigReal(1.), R0); + Signal Gl = sigDiv(sigReal(1.), Rl); + Signal Gr = sigDiv(sigReal(1.), Rr); + Signal dl = sigDiv(sigMul(sigReal(2.), Gl), sigAdd(sigAdd(Gu, Gl), Gr)); + Signal dr = sigSub(sigReal(1.), dl); + + Signal bl = sigAdd(sigAdd(sigMul(sigSub(dl, sigReal(1.)), al), sigMul(dr, ar)), au); + Signal br = sigAdd(sigAdd(sigMul(dl, al), sigMul(sigSub(dr, sigReal(1.)), ar)), au); + Signal bu = sigAdd(sigMul(dl, al), sigMul(dr, ar)); + + return { bu, bl, br, R0 }; +} + +/* +y = lp_filter(x, cutoff) { + fc = (0.1 + 0.3 * cutoff) * fs + C = 1e-6 + R = 1 / (2 * pi * fc * C) + + bR, RR = wdf_resistor(aR, R) + bC, RC = wdf_capacitor(aC, C) + bV = wdf_voltage_source_root(aV, x) + aV, aR, aC, Rp = wdf_3port_series(bV, bR, bC, RR, RC) + @aC = 0 + + y = 0.5 * (aC + bC) +} +*/ +static Signal lp_filter(Signal x, Signal cutoff) +{ + Signal fc = sigMul(sigAdd(sigReal(0.1), sigMul(sigReal(0.3), cutoff)), fs()); + Signal C = sigReal(1e-6); + Signal R = sigDiv(sigReal(1.0), sigMul(sigMul(sigMul(sigReal(2.0), pi()), fc), C)); + + // Recursive signals + Signal bR = sigSelfZeroN(0); + Signal RR = sigSelfZeroN(1); + Signal bC = sigSelfZeroN(2); + Signal RC = sigSelfZeroN(3); + + Signal aV = sigSelfZeroN(4); + Signal aR = sigSelfZeroN(5); + Signal aC = sigSelfZeroN(6); + Signal Rp = sigSelfZeroN(7); + + // bR, RR = wdf_resistor(aR, R); + tvec res1 = wdf_resistor(aR, R); + + // bC, RC = wdf_capacitor(aC, C); + tvec res2 = wdf_capacitor(aC, C); + + // bV = wdf_voltage_source_root(aV, x); + Signal bV = wdf_voltage_source_root(aV, x); + + // aV, aR, aC, Rp = wdf_3port_series(bV, bR, bC, RR, RC); + // Recursion is build here to access aV, aR, aC signals + tvec res3 = wdf_3port_series(bV, bR, bC, RR, RC); + + // Create recursion + tvec ins = concat(concat(res1, res2), res3); + tvec outs = sigRecursionN(ins); + + // bC recursive signal explicitly taken again here + // y = 0.5 * (aC + bC) + aC = outs[6]; + bC = outs[2]; + + return sigMul(sigReal(0.5), sigAdd(aC, bC)); +} + +/* +y = lp_filter3 (x, cutoff, vol) { + y = lp_filter(lp_filter(lp_filter(x, cutoff), cutoff), cutoff) * vol +} +*/ +static Signal lp_filter3(Signal x, Signal cutoff, Signal vol) +{ + return sigMul(lp_filter(lp_filter(lp_filter(x, cutoff), cutoff), cutoff), vol); +} + +/* + y = lp_filter2(x, cutoff) { + # component values + fc = (0.01 + 0.3 * cutoff) * fs + C = 1e-6 + R = 1 / (2 * pi * fc * C) + + # input + bV = wdf_voltage_source_root(aV, x) + + # filter 1 + bR1, RR1 = wdf_resistor(aR1, R) + bC1, RC1 = wdf_capacitor(aC1, C) + @aC1 = 0 + + # filter 2 + bR2, RR2 = wdf_resistor(aR2, R) + bC2, RC2 = wdf_capacitor(aC2, C) + @aC2 = 0 + + # connections + aP1, aR2, aC2, Rp2 = wdf_3port_series(bP1, bR2, bC2, RR2, RC2) + aS1, bP1, aC1, Rp1 = wdf_3port_parallel(bS1, aP1, bC1, Rp2, RC1) + aV, aR1, bS1, Rp0 = wdf_3port_series(bV, bR1, aS1, RR1, Rp1) + + # output + y = 0.5 * (aC2 + bC2) +} +*/ + +static Signal lp_filter2(Signal x, Signal cutoff) +{ + // component values + // fc = (0.01 + 0.3 * cutoff) * fs + // C = 1e-6 + // R = 1 / (2 * pi * fc * C) + + Signal fc = sigMul(sigAdd(sigReal(0.01), sigMul(sigReal(0.3), cutoff)), fs()); + Signal C = sigReal(1e-6); + Signal R = sigDiv(sigReal(1.0), sigMul(sigMul(sigMul(sigReal(2.0), pi()), fc), C)); + + // Recursive signals + Signal aP1 = sigSelfZeroN(0); + Signal aR2 = sigSelfZeroN(1); + Signal aC2 = sigSelfZeroN(2); + Signal Rp2 = sigSelfZeroN(3); + + Signal aS1 = sigSelfZeroN(4); + Signal bP1 = sigSelfZeroN(5); + Signal aC1 = sigSelfZeroN(6); + Signal Rp1 = sigSelfZeroN(7); + + Signal aV = sigSelfZeroN(8); + Signal aR1 = sigSelfZeroN(9); + Signal bS1 = sigSelfZeroN(10); + Signal Rp0 = sigSelfZeroN(11); + + // Input + Signal bV = wdf_voltage_source_root(aV, x); + //tvec res0 = { wdf_voltage_source_root(aV, x) }; + + // filter 1 + // bR1, RR1 = wdf_resistor(aR1, R) + // bC1, RC1 = wdf_capacitor(aC1, C) + tvec res1 = wdf_resistor(aR1, R); + tvec res2 = wdf_capacitor(aC1, C); + + // filter 2 + // bR2, RR2 = wdf_resistor(aR2, R) + // bC2, RC2 = wdf_capacitor(aC2, C) + tvec res3 = wdf_resistor(aR2, R); + tvec res4 = wdf_capacitor(aC2, C); + + // connections + // aP1, aR2, aC2, Rp2 = wdf_3port_series(bP1, bR2, bC2, RR2, RC2) + // aS1, bP1, aC1, Rp1 = wdf_3port_parallel(bS1, aP1, bC1, Rp2, RC1) + // aV, aR1, bS1, Rp0 = wdf_3port_series(bV, bR1, aS1, RR1, Rp1) + tvec res5 = wdf_3port_series(bP1, res3[0], res4[0], res3[1], res4[1]); + tvec res6 = wdf_3port_parallel(bS1, aP1, res2[0], Rp2, res2[1]); + tvec res7 = wdf_3port_series(bV, res1[0], aS1, res1[1], Rp1); + + // Create recursion + tvec ins = concat(concat(res5, res6), res7); + tvec outs = sigRecursionN(ins); + + // output + // y = 0.5 * (aC2 + bC2); + aC2 = outs[2]; + Signal bC2 = wdf_capacitor(aC2, C)[0]; + return sigMul(sigReal(0.5), sigAdd(aC2, bC2)); +} + +/* + y = lowshelffilter(x, gain) { + K = gain + f0 = 200 + z = (pi*f0)/fs + + a = (z - 1) / (z + 1) + + u = ((K - 1 ) / 2) * (a * x + delay1(x)) - a * delay1(u) + @u = 0 + + y = ((K + 1) / 2) * x + u + } + */ +static Signal lowshelffilter(Signal x, Signal gain) +{ + Signal K = gain; + Signal f0 = sigReal(200.); + Signal z = sigDiv(sigMul(pi(), f0), fs()); + + Signal a = sigDiv(sigSub(z, sigReal(1.)), sigAdd(z, sigReal(1.))); + + Signal n_u = sigRecursion(sigSub(sigMul(sigDiv(sigSub(K, sigReal(1.)), sigReal(2.)), + sigAdd(sigMul(a, x), sigDelay1(x))), sigMul(a, sigDelay1(sigSelfZero())))); + + Signal y = sigAdd(sigMul(sigDiv(sigAdd(K, sigReal(1.)), sigReal(2.)), x), n_u); + return y; +} + +/* +y = diode_clipper (x) { + Is = 1e-16 + VT = 0.026 + R = 2.2e3 + C = 0.01e-6 + + k1 = 1.0 / (R * C) + k4 = 1.0 / VT + + B0 = 2 * fs + B1 = -B0 + A1 = 1 + + k2 = (C * R) / (B0 * C * R + 1.0) + k3 = (Is * R) / (B0 * C * R + 1.0) + k5 = log((Is * R) / ((B0 * C * R + 1.0) * VT)) + k6 = B1 - A1 * B0 + + p_z1 = delay1(p) + q = k1 * x - p_z1 + r = sign(q) + w = k2 * q + k3 * r + y = w - VT * r * omega(k4 * r * w + k5) + p = k6 * x - A1 * p_z1 + + @p = 0 + } +*/ + +static Signal sign(Signal x) +{ + return sigSelect2(sigLT(x, sigReal(0.)), sigSelect2(sigGT(x, sigReal(0.)), sigReal(0.), sigReal(1.)), sigReal(-1.)); +} +static Signal omega(Signal x) { return sigMax(sigReal(0.), x); } + +static Signal diode_clipper(Signal x) +{ + Signal Is = sigReal(1e-16); + Signal VT = sigReal(0.026); + Signal R = sigReal(2.2e3); + Signal C = sigReal(0.01e-6); + + Signal k1 = sigDiv(sigReal(1.), sigMul(R, C)); + Signal k4 = sigDiv(sigReal(1.), VT); + + Signal B0 = sigMul(sigReal(2.), fs()); + Signal B1 = sigSub(sigReal(0.), B0); + Signal A1 = sigReal(1.); + + Signal k2 = sigDiv(sigMul(C, R), sigAdd(sigMul(sigMul(B0, C), R), sigReal(1.))); + Signal k3 = sigDiv(sigMul(Is, R), sigAdd(sigMul(sigMul(B0, C), R), sigReal(1.))); + Signal k5 = sigLog(sigDiv(sigMul(Is, R), sigMul(sigAdd(sigMul(sigMul(B0, C), R), sigReal(1.)), VT))); + Signal k6 = sigSub(B1, sigMul(A1, B0)); + + // Recursive signal + Signal p = sigSelfZeroN(0); + + Signal p_z1 = sigDelay1(p); + Signal q = sigSub(sigMul(k1, x), p_z1); + Signal r = sign(q); + Signal w = sigAdd(sigMul(k2, q), sigMul(k3, r)); + Signal y = sigSub(w, sigMul(sigMul(VT, r), omega(sigAdd(sigMul(sigMul(k4, r), w), k5)))); + tvec outs = sigRecursionN({sigSub(sigMul(k6, x), sigMul(A1, p_z1)), y}); + + return outs[1]; +} + +// ======= +// Tests +// ======= + +static Signal lp_filter_builder() +{ + Signal in1 = sigInput(0); + Signal cutoff = sigVSlider("cutoff", sigReal(CUTOFF), sigReal(0), sigReal(1), sigReal(0.01)); + return lp_filter(in1, cutoff); +} + +// Generate the Faust C++ output +static void test1() +{ + createLibContext(); + { + tvec signals = { lp_filter_builder() }; + int argc = 2; + const char* argv[] = { "-cn", "lp_filter" }; + compile("test1", signals, argc, argv); + } + destroyLibContext(); +} + +// Compare the Faust and Ciaramella versions with a same noise test signal +static void test2() +{ + filter_tester(lp_filter_builder, new ciaramella_lp_dsp()); +} + +static Signal lp_filter3_builder() +{ + Signal in1 = sigInput(0); + Signal vol = sigVSlider("vol", sigReal(VOL), sigReal(0), sigReal(1), sigReal(0.01)); + Signal cutoff = sigVSlider("cutoff", sigReal(CUTOFF), sigReal(0), sigReal(1), sigReal(0.01)); + return lp_filter3(in1, cutoff, vol); +} + +// Generate the Faust C++ output +static void test3() +{ + createLibContext(); + { + tvec signals = { lp_filter3_builder() }; + int argc = 2; + const char* argv[] = { "-cn", "lp_filter3" }; + compile("test3", signals, argc, argv); + } + destroyLibContext(); +} + +// Compare the Faust and Ciaramella versions with a same noise test signal +static void test4() +{ + filter_tester(lp_filter3_builder, new ciaramella_lp3_dsp()); +} + +static Signal lowshelffilter_builder() +{ + Signal in1 = sigInput(0); + Signal gain = sigVSlider("gain", sigReal(GAIN), sigReal(0), sigReal(1), sigReal(0.01)); + return lowshelffilter(in1, gain); +} + +// Generate the Faust C++ output +static void test5() +{ + createLibContext(); + { + tvec signals = { lowshelffilter_builder() }; + int argc = 2; + const char* argv[] = { "-cn", "lowshelffilter" }; + compile("test5", signals, argc, argv); + } + destroyLibContext(); +} + +// Compare the Faust and Ciaramella versions with a same noise test signal +static void test6() +{ + filter_tester(lowshelffilter_builder, new ciaramella_lowshelffilter_dsp()); +} + +static Signal lp_filter2_builder() +{ + Signal in1 = sigInput(0); + Signal cutoff = sigVSlider("cutoff", sigReal(CUTOFF), sigReal(0), sigReal(1), sigReal(0.01)); + return lp_filter2(in1, cutoff); +} + +// Generate the Faust C++ output +static void test7() +{ + createLibContext(); + { + Signal in1 = sigInput(0); + Signal cutoff = sigVSlider("cutoff", sigReal(CUTOFF), sigReal(0), sigReal(1), sigReal(0.01)); + + tvec signals = { lp_filter2(in1, cutoff) }; + int argc = 2; + const char* argv[] = { "-cn", "lp_filter2_faust" }; + compile("test7", signals, argc, argv); + } + destroyLibContext(); +} + +// Compare the Faust and Ciaramella versions with a same noise test signal +// lp_filter2_faust is manually edited to correct variable dependencies +static void test8() +{ + filter_tester2(new lp_filter2_faust(), new ciaramella_lp2_dsp()); +} + +static Signal diode_clipper_builder() +{ + Signal in1 = sigInput(0); + return diode_clipper(in1); +} + +// Generate the Faust C++ output +static void test9() +{ + createLibContext(); + { + tvec signals = { diode_clipper_builder() }; + int argc = 2; + const char* argv[] = { "-cn", "diode_clipper" }; + compile("test9", signals, argc, argv); + } + destroyLibContext(); +} + +// Compare the Faust and Ciaramella versions with a same noise test signal +static void test10() +{ + filter_tester(diode_clipper_builder, new ciaramella_diode_clipper_dsp()); +} + +int main(int argc, char* argv[]) +{ + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + // Incorrect code generated + test7(); + // Test with manually edited to correct variable dependencies + test8(); + test9(); + test10(); + return 0; +} + diff --git a/tools/benchmark/generated-code/EQregaliaStereo.cpp b/tools/benchmark/generated-code/EQregaliaStereo.cpp new file mode 100644 index 0000000000..6a35a275ba --- /dev/null +++ b/tools/benchmark/generated-code/EQregaliaStereo.cpp @@ -0,0 +1,200 @@ +#include "EQregaliaStereo.h" + + +static const float EQregaliaStereo_extra_0 = (40.0f * 0.5f); +static const float EQregaliaStereo_extra_2 = (40.0f * 0.5f); +static const float EQregaliaStereo_extra_4 = (40.0f * 0.5f); +static const float EQregaliaStereo_extra_7 = (3.141592653589793f * 200.0f); +static const float EQregaliaStereo_extra_9 = (3.141592653589793f * 5000.0f); +static const float EQregaliaStereo_extra_11 = (3.141592653589793f * 1789.0f); +static const float EQregaliaStereo_extra_12 = (3.141592653589793f * 1789.0f); +static const float EQregaliaStereo_extra_13 = -(0.4643843937958486f); +static const float EQregaliaStereo_extra_14 = ((2.0f * 3.141592653589793f) * 1000.0f); +static const float EQregaliaStereo_extra_17 = (40.0f * 0.5f); +static const float EQregaliaStereo_extra_19 = (40.0f * 0.5f); +static const float EQregaliaStereo_extra_21 = (40.0f * 0.5f); +static const float EQregaliaStereo_extra_24 = (3.141592653589793f * 200.0f); +static const float EQregaliaStereo_extra_26 = (3.141592653589793f * 5000.0f); +static const float EQregaliaStereo_extra_28 = (3.141592653589793f * 1789.0f); +static const float EQregaliaStereo_extra_29 = (3.141592653589793f * 1789.0f); +static const float EQregaliaStereo_extra_30 = -(0.4643843937958486f); +static const float EQregaliaStereo_extra_31 = ((2.0f * 3.141592653589793f) * 1000.0f); +static const float gain_4_I = ((1 * 40.0f) - (40.0f * 0.5f)); +static const float gain_6_I = ((0 * 40.0f) - (40.0f * 0.5f)); +static const float gain_11_I = ((1 * 40.0f) - (40.0f * 0.5f)); +static const float gain_13_I = ((0 * 40.0f) - (40.0f * 0.5f)); + + +void EQregaliaStereo::reset() +{ + firstRun = 1; +} + +void EQregaliaStereo::setSampleRate(float sampleRate) +{ + fs = sampleRate; + const float z_3 = (EQregaliaStereo_extra_7 / fs); + a_3 = ((z_3 - 1.0f) / (z_3 + 1.0f)); + const float z_5 = (EQregaliaStereo_extra_9 / fs); + a_5 = ((z_5 - 1.0f) / (z_5 + 1.0f)); + a_7 = ((1.0f - (EQregaliaStereo_extra_11 / fs)) / (1.0f + (EQregaliaStereo_extra_12 / fs))); + const float z_7 = (EQregaliaStereo_extra_14 / fs); + const float b_7 = -(((((EQregaliaStereo_extra_13 * z_7) * z_7) - (0.01348369482970019f * z_7)) + 1.000898384794433f)); + EQregaliaStereo_extra_15 = (b_7 * (1.0f + a_7)); + EQregaliaStereo_extra_16 = (b_7 * (1.0f + a_7)); + const float z_10 = (EQregaliaStereo_extra_24 / fs); + a_10 = ((z_10 - 1.0f) / (z_10 + 1.0f)); + const float z_12 = (EQregaliaStereo_extra_26 / fs); + a_12 = ((z_12 - 1.0f) / (z_12 + 1.0f)); + a_14 = ((1.0f - (EQregaliaStereo_extra_28 / fs)) / (1.0f + (EQregaliaStereo_extra_29 / fs))); + const float z_14 = (EQregaliaStereo_extra_31 / fs); + const float b_14 = -(((((EQregaliaStereo_extra_30 * z_14) * z_14) - (0.01348369482970019f * z_14)) + 1.000898384794433f)); + EQregaliaStereo_extra_32 = (b_14 * (1.0f + a_14)); + EQregaliaStereo_extra_33 = (b_14 * (1.0f + a_14)); + +} + +void EQregaliaStereo::process(float *xL, float *xR, float *yL_out_, float *yR_out_, int nSamples) +{ + if (firstRun) { + low_CHANGED = 1; + high_CHANGED = 1; + peak_CHANGED = 1; + } + else { + low_CHANGED = low != low_z1; + high_CHANGED = high != high_z1; + peak_CHANGED = peak != peak_z1; + } + + if (peak_CHANGED) { + const float gain_8 = ((peak * 40.0f) - EQregaliaStereo_extra_0); + const float K_7 = (1.005216266655582f + (gain_8 * (0.1154462118686094f + (gain_8 * (0.006357962473527189f + (gain_8 * (0.0002473043497433871f + (gain_8 * (0.000009275409030059003f + (gain_8 * 2.061300092186973e-7f)))))))))); + EQregaliaStereo_extra_1 = ((1.0f + K_7) / 2.0f); + EQregaliaStereo_extra_10 = ((1.0f - K_7) / 2.0f); + const float gain_15 = ((peak * 40.0f) - EQregaliaStereo_extra_17); + const float K_14 = (1.005216266655582f + (gain_15 * (0.1154462118686094f + (gain_15 * (0.006357962473527189f + (gain_15 * (0.0002473043497433871f + (gain_15 * (0.000009275409030059003f + (gain_15 * 2.061300092186973e-7f)))))))))); + EQregaliaStereo_extra_18 = ((1.0f + K_14) / 2.0f); + EQregaliaStereo_extra_27 = ((1.0f - K_14) / 2.0f); + } + if (high_CHANGED) { + const float gain_6 = ((high * 40.0f) - EQregaliaStereo_extra_2); + const float K_5 = (1.005216266655582f + (gain_6 * (0.1154462118686094f + (gain_6 * (0.006357962473527189f + (gain_6 * (0.0002473043497433871f + (gain_6 * (0.000009275409030059003f + (gain_6 * 2.061300092186973e-7f)))))))))); + EQregaliaStereo_extra_3 = ((1.0f + K_5) / 2.0f); + EQregaliaStereo_extra_8 = ((1.0f - K_5) / 2.0f); + const float gain_13 = ((high * 40.0f) - EQregaliaStereo_extra_19); + const float K_12 = (1.005216266655582f + (gain_13 * (0.1154462118686094f + (gain_13 * (0.006357962473527189f + (gain_13 * (0.0002473043497433871f + (gain_13 * (0.000009275409030059003f + (gain_13 * 2.061300092186973e-7f)))))))))); + EQregaliaStereo_extra_20 = ((1.0f + K_12) / 2.0f); + EQregaliaStereo_extra_25 = ((1.0f - K_12) / 2.0f); + } + if (low_CHANGED) { + const float gain_4 = ((low * 40.0f) - EQregaliaStereo_extra_4); + const float K_3 = (1.005216266655582f + (gain_4 * (0.1154462118686094f + (gain_4 * (0.006357962473527189f + (gain_4 * (0.0002473043497433871f + (gain_4 * (0.000009275409030059003f + (gain_4 * 2.061300092186973e-7f)))))))))); + EQregaliaStereo_extra_5 = ((K_3 + 1.0f) / 2.0f); + EQregaliaStereo_extra_6 = ((K_3 - 1.0f) / 2.0f); + const float gain_11 = ((low * 40.0f) - EQregaliaStereo_extra_21); + const float K_10 = (1.005216266655582f + (gain_11 * (0.1154462118686094f + (gain_11 * (0.006357962473527189f + (gain_11 * (0.0002473043497433871f + (gain_11 * (0.000009275409030059003f + (gain_11 * 2.061300092186973e-7f)))))))))); + EQregaliaStereo_extra_22 = ((K_10 + 1.0f) / 2.0f); + EQregaliaStereo_extra_23 = ((K_10 - 1.0f) / 2.0f); + } + + low_CHANGED = 0; + high_CHANGED = 0; + peak_CHANGED = 0; + + if (firstRun) { + + _delayed_34 = 0; + _delayed_35 = 0.0f; + _delayed_36 = (((((1.005216266655582f + (gain_4_I * (0.1154462118686094f + (gain_4_I * (0.006357962473527189f + (gain_4_I * (0.0002473043497433871f + (gain_4_I * (0.000009275409030059003f + (gain_4_I * 2.061300092186973e-7f)))))))))) + 1.0f) / 2.0f) * 0) + 0.0f); + _delayed_37 = 0.0f; + _delayed_38 = ((((1.0f + (1.005216266655582f + (gain_6_I * (0.1154462118686094f + (gain_6_I * (0.006357962473527189f + (gain_6_I * (0.0002473043497433871f + (gain_6_I * (0.000009275409030059003f + (gain_6_I * 2.061300092186973e-7f))))))))))) / 2.0f) * (((((1.005216266655582f + (gain_4_I * (0.1154462118686094f + (gain_4_I * (0.006357962473527189f + (gain_4_I * (0.0002473043497433871f + (gain_4_I * (0.000009275409030059003f + (gain_4_I * 2.061300092186973e-7f)))))))))) + 1.0f) / 2.0f) * 0) + 0.0f)) + 0.0f); + _delayed_39 = ((((1.0f + (1.005216266655582f + (gain_6_I * (0.1154462118686094f + (gain_6_I * (0.006357962473527189f + (gain_6_I * (0.0002473043497433871f + (gain_6_I * (0.000009275409030059003f + (gain_6_I * 2.061300092186973e-7f))))))))))) / 2.0f) * (((((1.005216266655582f + (gain_4_I * (0.1154462118686094f + (gain_4_I * (0.006357962473527189f + (gain_4_I * (0.0002473043497433871f + (gain_4_I * (0.000009275409030059003f + (gain_4_I * 2.061300092186973e-7f)))))))))) + 1.0f) / 2.0f) * 0) + 0.0f)) + 0.0f); + _delayed_40 = ((((1.0f + (1.005216266655582f + (gain_6_I * (0.1154462118686094f + (gain_6_I * (0.006357962473527189f + (gain_6_I * (0.0002473043497433871f + (gain_6_I * (0.000009275409030059003f + (gain_6_I * 2.061300092186973e-7f))))))))))) / 2.0f) * (((((1.005216266655582f + (gain_4_I * (0.1154462118686094f + (gain_4_I * (0.006357962473527189f + (gain_4_I * (0.0002473043497433871f + (gain_4_I * (0.000009275409030059003f + (gain_4_I * 2.061300092186973e-7f)))))))))) + 1.0f) / 2.0f) * 0) + 0.0f)) + 0.0f); + _delayed_41 = 0.0f; + _delayed_42 = 0.0f; + _delayed_43 = 0.0f; + _delayed_44 = 0; + _delayed_45 = 0.0f; + _delayed_46 = (((((1.005216266655582f + (gain_11_I * (0.1154462118686094f + (gain_11_I * (0.006357962473527189f + (gain_11_I * (0.0002473043497433871f + (gain_11_I * (0.000009275409030059003f + (gain_11_I * 2.061300092186973e-7f)))))))))) + 1.0f) / 2.0f) * 0) + 0.0f); + _delayed_47 = 0.0f; + _delayed_48 = ((((1.0f + (1.005216266655582f + (gain_13_I * (0.1154462118686094f + (gain_13_I * (0.006357962473527189f + (gain_13_I * (0.0002473043497433871f + (gain_13_I * (0.000009275409030059003f + (gain_13_I * 2.061300092186973e-7f))))))))))) / 2.0f) * (((((1.005216266655582f + (gain_11_I * (0.1154462118686094f + (gain_11_I * (0.006357962473527189f + (gain_11_I * (0.0002473043497433871f + (gain_11_I * (0.000009275409030059003f + (gain_11_I * 2.061300092186973e-7f)))))))))) + 1.0f) / 2.0f) * 0) + 0.0f)) + 0.0f); + _delayed_49 = ((((1.0f + (1.005216266655582f + (gain_13_I * (0.1154462118686094f + (gain_13_I * (0.006357962473527189f + (gain_13_I * (0.0002473043497433871f + (gain_13_I * (0.000009275409030059003f + (gain_13_I * 2.061300092186973e-7f))))))))))) / 2.0f) * (((((1.005216266655582f + (gain_11_I * (0.1154462118686094f + (gain_11_I * (0.006357962473527189f + (gain_11_I * (0.0002473043497433871f + (gain_11_I * (0.000009275409030059003f + (gain_11_I * 2.061300092186973e-7f)))))))))) + 1.0f) / 2.0f) * 0) + 0.0f)) + 0.0f); + _delayed_50 = ((((1.0f + (1.005216266655582f + (gain_13_I * (0.1154462118686094f + (gain_13_I * (0.006357962473527189f + (gain_13_I * (0.0002473043497433871f + (gain_13_I * (0.000009275409030059003f + (gain_13_I * 2.061300092186973e-7f))))))))))) / 2.0f) * (((((1.005216266655582f + (gain_11_I * (0.1154462118686094f + (gain_11_I * (0.006357962473527189f + (gain_11_I * (0.0002473043497433871f + (gain_11_I * (0.000009275409030059003f + (gain_11_I * 2.061300092186973e-7f)))))))))) + 1.0f) / 2.0f) * 0) + 0.0f)) + 0.0f); + _delayed_51 = 0.0f; + _delayed_52 = 0.0f; + _delayed_53 = 0.0f; + } + + for (int i = 0; i < nSamples; i++) { + + const float x_3 = xL[i]; + const float u_3 = ((EQregaliaStereo_extra_6 * ((a_3 * x_3) + _delayed_34)) - (a_3 * _delayed_35)); + const float x_5 = ((EQregaliaStereo_extra_5 * x_3) + u_3); + const float u_5 = ((EQregaliaStereo_extra_8 * ((a_5 * x_5) + _delayed_36)) - (a_5 * _delayed_37)); + const float x_7 = ((EQregaliaStereo_extra_3 * x_5) + u_5); + const float u_7 = (((EQregaliaStereo_extra_10 * (((a_7 * x_7) + (EQregaliaStereo_extra_15 * _delayed_38)) + _delayed_40)) - (EQregaliaStereo_extra_16 * _delayed_41)) - (a_7 * _delayed_43)); + const float yL = ((EQregaliaStereo_extra_1 * x_7) + u_7); + const float x_10 = xR[i]; + const float u_10 = ((EQregaliaStereo_extra_23 * ((a_10 * x_10) + _delayed_44)) - (a_10 * _delayed_45)); + const float x_12 = ((EQregaliaStereo_extra_22 * x_10) + u_10); + const float u_12 = ((EQregaliaStereo_extra_25 * ((a_12 * x_12) + _delayed_46)) - (a_12 * _delayed_47)); + const float x_14 = ((EQregaliaStereo_extra_20 * x_12) + u_12); + const float u_14 = (((EQregaliaStereo_extra_27 * (((a_14 * x_14) + (EQregaliaStereo_extra_32 * _delayed_48)) + _delayed_50)) - (EQregaliaStereo_extra_33 * _delayed_51)) - (a_14 * _delayed_53)); + const float yR = ((EQregaliaStereo_extra_18 * x_14) + u_14); + + _delayed_34 = x_3; + _delayed_35 = u_3; + _delayed_36 = x_5; + _delayed_37 = u_5; + _delayed_38 = x_7; + _delayed_39 = x_7; + _delayed_40 = _delayed_39; + _delayed_41 = u_7; + _delayed_42 = u_7; + _delayed_43 = _delayed_42; + _delayed_44 = x_10; + _delayed_45 = u_10; + _delayed_46 = x_12; + _delayed_47 = u_12; + _delayed_48 = x_14; + _delayed_49 = x_14; + _delayed_50 = _delayed_49; + _delayed_51 = u_14; + _delayed_52 = u_14; + _delayed_53 = _delayed_52; + + + yL_out_[i] = yL; + yR_out_[i] = yR; + } + + + low_z1 = low; + high_z1 = high; + peak_z1 = peak; + firstRun = 0; +} + + +float EQregaliaStereo::getlow() { + return low; +} +void EQregaliaStereo::setlow(float value) { + low = value; +} + +float EQregaliaStereo::gethigh() { + return high; +} +void EQregaliaStereo::sethigh(float value) { + high = value; +} + +float EQregaliaStereo::getpeak() { + return peak; +} +void EQregaliaStereo::setpeak(float value) { + peak = value; +} + diff --git a/tools/benchmark/generated-code/EQregaliaStereo.h b/tools/benchmark/generated-code/EQregaliaStereo.h new file mode 100644 index 0000000000..aaba217690 --- /dev/null +++ b/tools/benchmark/generated-code/EQregaliaStereo.h @@ -0,0 +1,78 @@ +class EQregaliaStereo +{ +public: + void setSampleRate(float sampleRate); + void reset(); + void process(float *xL, float *xR, float *yL_out_, float *yR_out_, int nSamples); + + float getlow(); + void setlow(float value); + float gethigh(); + void sethigh(float value); + float getpeak(); + void setpeak(float value); + +private: + + + float EQregaliaStereo_extra_1 = 0.0f; + float EQregaliaStereo_extra_3 = 0.0f; + float EQregaliaStereo_extra_5 = 0.0f; + float EQregaliaStereo_extra_6 = 0.0f; + float a_3 = 0.0f; + float EQregaliaStereo_extra_8 = 0.0f; + float a_5 = 0.0f; + float EQregaliaStereo_extra_10 = 0.0f; + float a_7 = 0.0f; + float EQregaliaStereo_extra_15 = 0.0f; + float EQregaliaStereo_extra_16 = 0.0f; + float EQregaliaStereo_extra_18 = 0.0f; + float EQregaliaStereo_extra_20 = 0.0f; + float EQregaliaStereo_extra_22 = 0.0f; + float EQregaliaStereo_extra_23 = 0.0f; + float a_10 = 0.0f; + float EQregaliaStereo_extra_25 = 0.0f; + float a_12 = 0.0f; + float EQregaliaStereo_extra_27 = 0.0f; + float a_14 = 0.0f; + float EQregaliaStereo_extra_32 = 0.0f; + float EQregaliaStereo_extra_33 = 0.0f; + float _delayed_34 = 0.0f; + float _delayed_35 = 0.0f; + float _delayed_36 = 0.0f; + float _delayed_37 = 0.0f; + float _delayed_38 = 0.0f; + float _delayed_39 = 0.0f; + float _delayed_40 = 0.0f; + float _delayed_41 = 0.0f; + float _delayed_42 = 0.0f; + float _delayed_43 = 0.0f; + float _delayed_44 = 0.0f; + float _delayed_45 = 0.0f; + float _delayed_46 = 0.0f; + float _delayed_47 = 0.0f; + float _delayed_48 = 0.0f; + float _delayed_49 = 0.0f; + float _delayed_50 = 0.0f; + float _delayed_51 = 0.0f; + float _delayed_52 = 0.0f; + float _delayed_53 = 0.0f; + float low = 1.0f; + float high = 0.0f; + float peak = 0.0f; + + + float low_z1; + char low_CHANGED; + + float high_z1; + char high_CHANGED; + + float peak_z1; + char peak_CHANGED; + + + float fs; + char firstRun; + +}; diff --git a/tools/benchmark/generated-code/diode_clipper.cpp b/tools/benchmark/generated-code/diode_clipper.cpp new file mode 100644 index 0000000000..c13a9f6204 --- /dev/null +++ b/tools/benchmark/generated-code/diode_clipper.cpp @@ -0,0 +1,59 @@ +#include "diode_clipper.h" + + +static const float diode_clipper_extra_0 = (1e-8f * 2200.0f); +static const float k1 = (1.0f / (2200.0f * 1e-8f)); +static const float diode_clipper_extra_1 = (1e-16f * 2200.0f); +static const float k4 = (1.0f / 0.026f); +static const float diode_clipper_extra_2 = (1e-16f * 2200.0f); + + +void diode_clipper::reset() +{ + firstRun = 1; +} + +void diode_clipper::setSampleRate(float sampleRate) +{ + fs = sampleRate; + const float B0 = (2.0f * fs); + k2 = (diode_clipper_extra_0 / (((B0 * 1e-8f) * 2200.0f) + 1.0f)); + k3 = (diode_clipper_extra_1 / (((B0 * 1e-8f) * 2200.0f) + 1.0f)); + k5 = log((diode_clipper_extra_2 / ((((B0 * 1e-8f) * 2200.0f) + 1.0f) * 0.026f))); + k6 = (-(B0) - (1.0f * B0)); + +} + +void diode_clipper::process(float *x, float *y_out_, int nSamples) +{ + if (firstRun) { + } + else { + } + + + + if (firstRun) { + + _delayed_3 = 0.0f; + } + + for (int i = 0; i < nSamples; i++) { + + const float p_z1 = _delayed_3; + const float q = ((k1 * x[i]) - p_z1); + const float r = sign(q); + const float w = ((k2 * q) + (k3 * r)); + const float y = (w - ((0.026f * r) * omega((((k4 * r) * w) + k5)))); + + _delayed_3 = ((k6 * x[i]) - (1.0f * p_z1)); + + + y_out_[i] = y; + } + + + firstRun = 0; +} + + diff --git a/tools/benchmark/generated-code/diode_clipper.h b/tools/benchmark/generated-code/diode_clipper.h new file mode 100644 index 0000000000..3c201a8f70 --- /dev/null +++ b/tools/benchmark/generated-code/diode_clipper.h @@ -0,0 +1,29 @@ +#include + +// Dummy omega +float omega(float x) { return std::max(0.f, x); } +float sign(float x) { return (x < 0) ? -1 : ((x > 0) ? 1 : 0); } + +class diode_clipper +{ + public: + void setSampleRate(float sampleRate); + void reset(); + void process(float *x, float *y_out_, int nSamples); + + + private: + + + float k2 = 0.0f; + float k3 = 0.0f; + float k5 = 0.0f; + float k6 = 0.0f; + float _delayed_3 = 0.0f; + + + + float fs; + char firstRun; + +}; diff --git a/tools/benchmark/generated-code/lowshelffilter.cpp b/tools/benchmark/generated-code/lowshelffilter.cpp new file mode 100644 index 0000000000..13d9a358f5 --- /dev/null +++ b/tools/benchmark/generated-code/lowshelffilter.cpp @@ -0,0 +1,67 @@ +#include "lowshelffilter.h" + + +static const float lowshelffilter_extra_2 = (3.141592653589793f * 200.0f); + + +void lowshelffilter::reset() +{ + firstRun = 1; +} + +void lowshelffilter::setSampleRate(float sampleRate) +{ + fs = sampleRate; + const float z = (lowshelffilter_extra_2 / fs); + a = ((z - 1.0f) / (z + 1.0f)); + +} + +void lowshelffilter::process(float *x, float *y_out_, int nSamples) +{ + if (firstRun) { + gain_CHANGED = 1; + } + else { + gain_CHANGED = gain != gain_z1; + } + + if (gain_CHANGED) { + const float K = gain; + lowshelffilter_extra_0 = ((K + 1.0f) / 2.0f); + lowshelffilter_extra_1 = ((K - 1.0f) / 2.0f); + } + + gain_CHANGED = 0; + + if (firstRun) { + + _delayed_3 = 0; + _delayed_4 = 0.0f; + } + + for (int i = 0; i < nSamples; i++) { + + const float u = ((lowshelffilter_extra_1 * ((a * x[i]) + _delayed_3)) - (a * _delayed_4)); + const float y = ((lowshelffilter_extra_0 * x[i]) + u); + + _delayed_3 = x[i]; + _delayed_4 = u; + + + y_out_[i] = y; + } + + + gain_z1 = gain; + firstRun = 0; +} + + +float lowshelffilter::getgain() { + return gain; +} +void lowshelffilter::setgain(float value) { + gain = value; +} + diff --git a/tools/benchmark/generated-code/lowshelffilter.h b/tools/benchmark/generated-code/lowshelffilter.h new file mode 100644 index 0000000000..da95f4609e --- /dev/null +++ b/tools/benchmark/generated-code/lowshelffilter.h @@ -0,0 +1,29 @@ +class lowshelffilter +{ +public: + void setSampleRate(float sampleRate); + void reset(); + void process(float *x, float *y_out_, int nSamples); + + float getgain(); + void setgain(float value); + +private: + + + float lowshelffilter_extra_0 = 0.0f; + float lowshelffilter_extra_1 = 0.0f; + float a = 0.0f; + float _delayed_3 = 0.0f; + float _delayed_4 = 0.0f; + float gain = 0.0f; + + + float gain_z1; + char gain_CHANGED; + + + float fs; + char firstRun; + +}; diff --git a/tools/benchmark/generated-code/lp_filter.cpp b/tools/benchmark/generated-code/lp_filter.cpp new file mode 100644 index 0000000000..26ab62797c --- /dev/null +++ b/tools/benchmark/generated-code/lp_filter.cpp @@ -0,0 +1,65 @@ +#include "lp_filter.h" + + +static const float C_3 = 0.000001f; +static const float lp_filter_extra_0 = (2.0f * 3.141592653589793f); +static const float al_5 = 0.0f; + + +void lp_filter::reset() +{ + firstRun = 1; +} + +void lp_filter::setSampleRate(float sampleRate) +{ + fs = sampleRate; + Rr_5 = (0.5f / (C_3 * fs)); +} + +void lp_filter::process(float *x, float *y_out_, int nSamples) +{ + if (firstRun) { + cutoff_CHANGED = 1; + } + else { + cutoff_CHANGED = cutoff != cutoff_z1; + } + + if (cutoff_CHANGED) { + lp_filter_extra_1 = (Rr_5 / ((1.0f / ((lp_filter_extra_0 * ((0.1f + (0.3f * cutoff)) * fs)) * 0.000001f)) + Rr_5)); + } + + cutoff_CHANGED = 0; + + if (firstRun) { + + _delayed_2 = 0.0f; + } + + for (int i = 0; i < nSamples; i++) { + + const float bC = _delayed_2; + const float ar_5 = bC; + const float aC = (ar_5 - (lp_filter_extra_1 *(ar_5 + ((2.0f * x[i]) + ar_5)))); + const float y = (0.5f * (aC + bC)); + + _delayed_2 = aC; + + + y_out_[i] = y; + } + + + cutoff_z1 = cutoff; + firstRun = 0; +} + + +float lp_filter::getcutoff() { + return cutoff; +} +void lp_filter::setcutoff(float value) { + cutoff = value; +} + diff --git a/tools/benchmark/generated-code/lp_filter.h b/tools/benchmark/generated-code/lp_filter.h new file mode 100644 index 0000000000..ab1bced5e8 --- /dev/null +++ b/tools/benchmark/generated-code/lp_filter.h @@ -0,0 +1,27 @@ +class lp_filter +{ +public: + void setSampleRate(float sampleRate); + void reset(); + void process(float *x, float *y_out_, int nSamples); + + float getcutoff(); + void setcutoff(float value); + +private: + + + float Rr_5 = 0.0f; + float lp_filter_extra_1 = 0.0f; + float _delayed_2 = 0.0f; + float cutoff = 0.0f; + + + float cutoff_z1; + char cutoff_CHANGED; + + + float fs; + char firstRun; + +}; diff --git a/tools/benchmark/generated-code/lp_filter2.cpp b/tools/benchmark/generated-code/lp_filter2.cpp new file mode 100644 index 0000000000..e5bfe1fad3 --- /dev/null +++ b/tools/benchmark/generated-code/lp_filter2.cpp @@ -0,0 +1,87 @@ +#include "lp_filter2.h" + + +static const float C_6 = 0.000001f; +static const float lp_filter2_extra_0 = (2.0f * 3.141592653589793f); +static const float al_7 = 0.0f; +static const float C_4 = 0.000001f; +static const float al_9 = 0.0f; + + +void lp_filter2::reset() +{ + firstRun = 1; +} + +void lp_filter2::setSampleRate(float sampleRate) +{ + fs = sampleRate; + Rr_7 = (0.5f / (C_6 * fs)); + Rr_8 = (0.5f / (C_4 * fs)); + Gr_8 = (1.0f / Rr_8); + +} + +void lp_filter2::process(float *x, float *y_out_, int nSamples) +{ + if (firstRun) { + cutoff_CHANGED = 1; + } + else { + cutoff_CHANGED = cutoff != cutoff_z1; + } + + if (cutoff_CHANGED) { + const float R = (1.0f / ((lp_filter2_extra_0 * ((0.01f + (0.3f * cutoff)) * fs)) * 0.000001f)); + const float Rl_7 = R; + lp_filter2_extra_1 = (Rr_7 / (Rl_7 + Rr_7)); + const float Rl_8 = (Rl_7 + Rr_7); + const float Gl_8 = (1.0f / Rl_8); + const float R0_8 = ((Rl_8 * Rr_8) / (Rl_8 + Rr_8)); + dl_8 = ((2.0f * Gl_8) / (((1.0f / R0_8) + Gl_8) + Gr_8)); + lp_filter2_extra_2 = (dl_8 - 1.0f); + dr_8 = (1.0f - dl_8); + const float Rr_9 = R0_8; + lp_filter2_extra_3 = (Rr_9 / (R + Rr_9)); + lp_filter2_extra_5 = (dr_8 - 1.0f); + } + + cutoff_CHANGED = 0; + + if (firstRun) { + + _delayed_4 = 0.0f; + _delayed_6 = 0.0f; + } + + for (int i = 0; i < nSamples; i++) { + + const float bC2 = _delayed_4; + const float ar_7 = bC2; + const float al_8 = -((al_7 + ar_7)); + const float ar_8 = _delayed_6; + const float ar_9 = ((dl_8 * al_8) + (dr_8 * ar_8)); + const float au_8 = (ar_9 - (lp_filter2_extra_3 * ((al_9 + ar_9) + ((2.0f * x[i]) - -((al_9 + ar_9)))))); + const float aC2 = (ar_7 - (lp_filter2_extra_1 * ((al_7 + ar_7) + (((lp_filter2_extra_2 * al_8) + (dr_8 * ar_8)) + au_8)))); + const float y = (0.5f * (aC2 + bC2)); + + _delayed_4 = aC2; + _delayed_6 = (((dl_8 * al_8) + (lp_filter2_extra_5 * ar_8)) + au_8); + + + y_out_[i] = y; + } + + + cutoff_z1 = cutoff; + firstRun = 0; +} + + +float lp_filter2::getcutoff() { + return cutoff; +} +void lp_filter2::setcutoff(float value) { + cutoff = value; +} + diff --git a/tools/benchmark/generated-code/lp_filter2.h b/tools/benchmark/generated-code/lp_filter2.h new file mode 100644 index 0000000000..52b26ad609 --- /dev/null +++ b/tools/benchmark/generated-code/lp_filter2.h @@ -0,0 +1,35 @@ +class lp_filter2 +{ +public: + void setSampleRate(float sampleRate); + void reset(); + void process(float *x, float *y_out_, int nSamples); + + float getcutoff(); + void setcutoff(float value); + +private: + + + float Rr_7 = 0.0f; + float lp_filter2_extra_1 = 0.0f; + float Rr_8 = 0.0f; + float Gr_8 = 0.0f; + float dl_8 = 0.0f; + float lp_filter2_extra_2 = 0.0f; + float dr_8 = 0.0f; + float lp_filter2_extra_3 = 0.0f; + float _delayed_4 = 0.0f; + float lp_filter2_extra_5 = 0.0f; + float _delayed_6 = 0.0f; + float cutoff = 0.0f; + + + float cutoff_z1; + char cutoff_CHANGED; + + + float fs; + char firstRun; + +}; diff --git a/tools/benchmark/generated-code/lp_filter2_faust.cpp b/tools/benchmark/generated-code/lp_filter2_faust.cpp new file mode 100644 index 0000000000..cedf3a7265 --- /dev/null +++ b/tools/benchmark/generated-code/lp_filter2_faust.cpp @@ -0,0 +1,149 @@ +/* ------------------------------------------------------------ + name: "test7" + Code generated with Faust 2.66.10 (https://faust.grame.fr) + Compilation options: -lang cpp -ct 1 -cn lp_filter2_faust -es 1 -mcd 16 -single -ftz 0 + ------------------------------------------------------------ */ + +#ifndef __lp_filter2_faust_H__ +#define __lp_filter2_faust_H__ + +#ifndef FAUSTFLOAT +#define FAUSTFLOAT float +#endif + +#include +#include +#include +#include + +#ifndef FAUSTCLASS +#define FAUSTCLASS lp_filter2_faust +#endif + +#ifdef __APPLE__ +#define exp10f __exp10f +#define exp10 __exp10 +#endif + +#if defined(_WIN32) +#define RESTRICT __restrict +#else +#define RESTRICT __restrict__ +#endif + + +class lp_filter2_faust : public dsp { + + private: + + FAUSTFLOAT fVslider0; + float fRec1[2]; + int fSampleRate; + float fConst1; + float fConst2; + float fConst3; + float fRec5[2]; + float fConst4; + + public: + lp_filter2_faust() {} + + void metadata(Meta* m) { + m->declare("compile_options", "-lang cpp -ct 1 -cn lp_filter2_faust -es 1 -mcd 16 -single -ftz 0"); + m->declare("name", "test7"); + } + + virtual int getNumInputs() { + return 1; + } + virtual int getNumOutputs() { + return 1; + } + + static void classInit(int sample_rate) { + } + + virtual void instanceConstants(int sample_rate) { + fSampleRate = sample_rate; + float fConst0 = float(fSampleRate); + fConst1 = 1.0f / fConst0; + fConst2 = 2e-06f * fConst0; + fConst3 = 5e+05f / fConst0; + fConst4 = 159154.94f / fConst0; + } + + virtual void instanceResetUserInterface() { + fVslider0 = FAUSTFLOAT(0.8f); + } + + virtual void instanceClear() { + for (int l0 = 0; l0 < 2; l0 = l0 + 1) { + fRec1[l0] = 0.0f; + } + for (int l1 = 0; l1 < 2; l1 = l1 + 1) { + fRec5[l1] = 0.0f; + } + } + + virtual void init(int sample_rate) { + classInit(sample_rate); + instanceInit(sample_rate); + } + + virtual void instanceInit(int sample_rate) { + instanceConstants(sample_rate); + instanceResetUserInterface(); + instanceClear(); + } + + virtual lp_filter2_faust* clone() { + return new lp_filter2_faust(); + } + + virtual int getSampleRate() { + return fSampleRate; + } + + virtual void buildUserInterface(UI* ui_interface) { + ui_interface->openVerticalBox("test7"); + ui_interface->addVerticalSlider("cutoff", &fVslider0, FAUSTFLOAT(0.8f), FAUSTFLOAT(0.0f), FAUSTFLOAT(1.0f), FAUSTFLOAT(0.01f)); + ui_interface->closeBox(); + } + + // Manually edited to correct variable dependencies + virtual void compute(int count, FAUSTFLOAT** RESTRICT inputs, FAUSTFLOAT** RESTRICT outputs) { + FAUSTFLOAT* input0 = inputs[0]; + FAUSTFLOAT* output0 = outputs[0]; + float fSlow0 = 0.3f * float(fVslider0) + 0.01f; + float fSlow1 = 159154.94f / fSlow0 + 5e+05f; + float fSlow2 = 5e+05f / fSlow1; + float fSlow3 = fConst1 * fSlow1; + float fSlow4 = fConst4 / fSlow0; + for (int i0 = 0; i0 < count; i0 = i0 + 1) { + float fRec0 = -1.0f * fRec1[1]; + float fRec2 = fSlow3; + float fTemp1 = fConst3 + fRec2; + float fRec6 = fConst3 * (fRec2 / fTemp1); + float fTemp7 = fSlow4 + fRec6; + float fTemp2 = fRec2 * (fConst2 + (fConst2 * fTemp1 + 1.0f) / fRec2); + float fTemp3 = 2.0f * (fRec0 / fTemp2); + float fTemp4 = 2.0f / fTemp2; + float fTemp5 = (1.0f - fTemp4) * fRec5[1]; + float fRec3 = fTemp3 + fTemp5; + float fRec7 = -1.0f * fRec3; + float fTemp6 = 2.0f * float(input0[i0]) + fRec3 - fRec7; + float fRec8 = fRec3 - fRec6 * fTemp6 / fTemp7; + float fRec4 = fRec0 * (fTemp4 + -1.0f) + fRec8 + fTemp5; + float fTemp0 = fRec4 + fRec1[1]; + fRec1[0] = fRec1[1] - fSlow2 * fTemp0; + fRec5[0] = fRec5[1] * (0.0f - fTemp4) + fRec8 + fTemp3; + output0[i0] = FAUSTFLOAT(0.5f * (fRec1[0] + fRec1[1])); + fRec1[1] = fRec1[0]; + fRec5[1] = fRec5[0]; + } + } + +}; + +#endif + diff --git a/tools/benchmark/generated-code/lp_filter3.cpp b/tools/benchmark/generated-code/lp_filter3.cpp new file mode 100644 index 0000000000..df51c2032c --- /dev/null +++ b/tools/benchmark/generated-code/lp_filter3.cpp @@ -0,0 +1,97 @@ +#include "lp_filter3.h" + + +static const float al_C_4 = 0.000001f; +static const float lp_filter3_extra_0 = (2.0f * 3.141592653589793f); +static const float al_6 = 0.0f; +static const float C_9 = 0.000001f; +static const float lp_filter3_extra_2 = (2.0f * 3.141592653589793f); +static const float al_11 = 0.0f; +static const float C_14 = 0.000001f; +static const float lp_filter3_extra_4 = (2.0f * 3.141592653589793f); +static const float al_16 = 0.0f; + + +void lp_filter3::reset() +{ + firstRun = 1; +} + +void lp_filter3::setSampleRate(float sampleRate) +{ + fs = sampleRate; + Rr_6 = (0.5f / (al_C_4 * fs)); + Rr_11 = (0.5f / (C_9 * fs)); + Rr_16 = (0.5f / (C_14 * fs)); + +} + +void lp_filter3::process(float *x, float *y_out_, int nSamples) +{ + if (firstRun) { + cutoff_CHANGED = 1; + vol_CHANGED = 1; + } + else { + cutoff_CHANGED = cutoff != cutoff_z1; + vol_CHANGED = vol != vol_z1; + } + + if (cutoff_CHANGED) { + lp_filter3_extra_1 = (Rr_6 / ((1.0f / ((lp_filter3_extra_0 * ((0.1f + (0.3f * cutoff)) * fs)) * 0.000001f)) + Rr_6)); + lp_filter3_extra_3 = (Rr_11 / ((1.0f / ((lp_filter3_extra_2 * ((0.1f + (0.3f * cutoff)) * fs)) * 0.000001f)) + Rr_11)); + lp_filter3_extra_5 = (Rr_16 / ((1.0f / ((lp_filter3_extra_4 * ((0.1f + (0.3f * cutoff)) * fs)) * 0.000001f)) + Rr_16)); + } + + cutoff_CHANGED = 0; + vol_CHANGED = 0; + + if (firstRun) { + + _delayed_6 = 0.0f; + _delayed_7 = 0.0f; + _delayed_8 = 0.0f; + } + + for (int i = 0; i < nSamples; i++) { + + const float bC_2 = _delayed_6; + const float ar_6 = bC_2; + const float bC_7 = _delayed_7; + const float ar_11 = bC_7; + const float bC_12 = _delayed_8; + const float ar_16 = bC_12; + const float aC_12 = (ar_16 - (lp_filter3_extra_5 * ((al_16 + ar_16) + ((2.0f * x[i]) - -((al_16 + ar_16)))))); + const float aC_7 = (ar_11 - (lp_filter3_extra_3 * ((al_11 + ar_11) + ((2.0f * (0.5f * (aC_12 + bC_12))) - -((al_11 + ar_11)))))); + const float aC_2 = (ar_6 - (lp_filter3_extra_1 * ((al_6 + ar_6) + ((2.0f * (0.5f * (aC_7 + bC_7))) - -((al_6 + ar_6)))))); + const float y = ((0.5f * (aC_2 + bC_2)) * vol); + + _delayed_6 = aC_2; + _delayed_7 = aC_7; + _delayed_8 = aC_12; + + + y_out_[i] = y; + } + + + cutoff_z1 = cutoff; + vol_z1 = vol; + firstRun = 0; +} + + +float lp_filter3::getcutoff() { + return cutoff; +} +void lp_filter3::setcutoff(float value) { + cutoff = value; +} + +float lp_filter3::getvol() { + return vol; +} +void lp_filter3::setvol(float value) { + vol = value; +} + diff --git a/tools/benchmark/generated-code/lp_filter3.h b/tools/benchmark/generated-code/lp_filter3.h new file mode 100644 index 0000000000..fe32228568 --- /dev/null +++ b/tools/benchmark/generated-code/lp_filter3.h @@ -0,0 +1,39 @@ +class lp_filter3 +{ +public: + void setSampleRate(float sampleRate); + void reset(); + void process(float *x, float *y_out_, int nSamples); + + float getcutoff(); + void setcutoff(float value); + float getvol(); + void setvol(float value); + +private: + + + float Rr_6 = 0.0f; + float lp_filter3_extra_1 = 0.0f; + float Rr_11 = 0.0f; + float lp_filter3_extra_3 = 0.0f; + float Rr_16 = 0.0f; + float lp_filter3_extra_5 = 0.0f; + float _delayed_6 = 0.0f; + float _delayed_7 = 0.0f; + float _delayed_8 = 0.0f; + float cutoff = 0.0f; + float vol = 0.0f; + + + float cutoff_z1; + char cutoff_CHANGED; + + float vol_z1; + char vol_CHANGED; + + + float fs; + char firstRun; + +};