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;
+
+};