diff --git a/src/FaustEngine.cpp b/src/FaustEngine.cpp
index bfb002a..9a51d2d 100644
--- a/src/FaustEngine.cpp
+++ b/src/FaustEngine.cpp
@@ -6,15 +6,15 @@
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
@@ -32,7 +32,7 @@
#pragma GCC diagnostic push
#ifndef __clang__
- #pragma GCC diagnostic ignored "-Wsuggest-override"
+ #pragma GCC diagnostic ignored "-Wsuggest-override"
#endif
#include
#include
@@ -45,9 +45,9 @@
#define kBufferSize 64
#ifdef INTERP
- #include
+ #include
#else
- #include
+ #include
#endif
#pragma GCC diagnostic pop
@@ -55,322 +55,324 @@ extern rack::Plugin* pluginInstance;
// UI handler for switches, knobs and lights
struct RackUI : public GenericUI {
- typedef std::function updateFunction;
-
- std::vector fConverters;
- std::vector fUpdateFunIn;
- std::vector fUpdateFunOut;
-
- // For checkbox handling
- struct CheckBox {
- float fLastButton = 0.0f;
- };
- std::map fCheckBoxes;
-
- std::string fKey, fValue, fScale;
-
- int getIndex(const std::string& value) {
- try {
- int index = stoi(value);
- if (index >= 0 && index <= NUM_ROWS) {
- return index;
- }
- else {
- WARN("ERROR : incorrect '%d' value", index);
- return -1;
- }
- }
- catch (std::invalid_argument& e) {
- return -1;
- }
- }
-
- RackUI(): fScale("lin")
- {}
-
- virtual ~RackUI() {
- for (auto& it : fConverters)
- delete it;
- }
-
- void addButton(const char* label, FAUSTFLOAT* zone) override {
+ typedef std::function updateFunction;
+
+ std::vector fConverters;
+ std::vector fUpdateFunIn;
+ std::vector fUpdateFunOut;
+
+ // For checkbox handling
+ struct CheckBox {
+ float fLastButton = 0.0f;
+ };
+ std::map fCheckBoxes;
+
+ std::string fKey, fValue, fScale;
+
+ int getIndex(const std::string& value) {
+ try {
+ int index = stoi(value);
+ if (index >= 0 && index <= NUM_ROWS) {
+ return index;
+ }
+ else {
+ WARN("ERROR : incorrect '%d' value", index);
+ return -1;
+ }
+ }
+ catch (std::invalid_argument& e) {
+ return -1;
+ }
+ }
+
+ RackUI(): fScale("lin")
+ {}
+
+ virtual ~RackUI() {
+ for (auto& it : fConverters)
+ delete it;
+ }
+
+ void addButton(const char* label, FAUSTFLOAT* zone) override {
int index = getIndex(fValue);
if (index == -1) return;
- if (fKey == "switch") {
- fUpdateFunIn.push_back([ = ](ProcessBlock * block) {
- *zone = block->switches[index - 1];
+ if (fKey == "switch") {
+ fUpdateFunIn.push_back([ = ](ProcessBlock * block) {
+ *zone = block->switches[index - 1];
});
- }
- fKey = fValue = "";
- }
-
- void addCheckButton(const char* label, FAUSTFLOAT* zone) override {
- int index = getIndex(fValue);
+ }
+ fKey = fValue = "";
+ }
+
+ void addCheckButton(const char* label, FAUSTFLOAT* zone) override {
+ int index = getIndex(fValue);
if (index == -1) return;
- if (fKey == "switch") {
- // Add a checkbox
- fCheckBoxes[zone] = CheckBox();
- // Update function
- fUpdateFunIn.push_back([ = ](ProcessBlock * block) {
- float button = block->switches[index - 1];
- // Detect upfront
- if (button == 1.0 && (button != fCheckBoxes[zone].fLastButton)) {
- // Switch button state
- *zone = !*zone;
+ if (fKey == "switch") {
+ // Add a checkbox
+ fCheckBoxes[zone] = CheckBox();
+ // Update function
+ fUpdateFunIn.push_back([ = ](ProcessBlock * block) {
+ float button = block->switches[index - 1];
+ // Detect upfront
+ if (button == 1.0 && (button != fCheckBoxes[zone].fLastButton)) {
+ // Switch button state
+ *zone = !*zone;
}
- // Keep previous button state
- fCheckBoxes[zone].fLastButton = button;
- });
- }
- fKey = fValue = "";
- }
-
- void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) override {
- addNumEntry(label, zone, init, min, max, step);
- }
-
- void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) override {
- addNumEntry(label, zone, init, min, max, step);
- }
-
- void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) override {
- int index = getIndex(fValue);
- if (fKey == "knob") {
- ConverterZoneControl* converter;
- if (fScale == "log") {
- converter = new ConverterZoneControl(zone, new LogValueConverter(0., 1., min, max));
- }
- else if (fScale == "exp") {
- converter = new ConverterZoneControl(zone, new ExpValueConverter(0., 1., min, max));
- }
- else {
- converter = new ConverterZoneControl(zone, new LinearValueConverter(0., 1., min, max));
- }
- fUpdateFunIn.push_back([ = ](ProcessBlock * block) {
- converter->update(block->knobs[index - 1]);
- });
- fConverters.push_back(converter);
- }
- fScale = "lin";
- fKey = fValue = "";
- }
-
- void addBarGraph(FAUSTFLOAT* zone) {
+ // Keep previous button state
+ fCheckBoxes[zone].fLastButton = button;
+ });
+ }
+ fKey = fValue = "";
+ }
+
+ void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) override {
+ addNumEntry(label, zone, init, min, max, step);
+ }
+
+ void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) override {
+ addNumEntry(label, zone, init, min, max, step);
+ }
+
+ void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) override {
int index = getIndex(fValue);
if (index == -1) return;
- if ((fKey == "light_red")) {
- fUpdateFunOut.push_back([ = ](ProcessBlock * block) {
- block->lights[index - 1][0] = *zone;
- });
- }
- else if ((fKey == "light_green")) {
- fUpdateFunOut.push_back([ = ](ProcessBlock * block) {
- block->lights[index - 1][1] = *zone;
- });
- }
- else if ((fKey == "light_blue")) {
- fUpdateFunOut.push_back([ = ](ProcessBlock * block) {
- block->lights[index - 1][2] = *zone;
- });
- }
- else if ((fKey == "switchlight_red")) {
- fUpdateFunOut.push_back([ = ](ProcessBlock * block) {
- block->switchLights[index - 1][0] = *zone;
- });
- }
- else if ((fKey == "switchlight_green")) {
- fUpdateFunOut.push_back([ = ](ProcessBlock * block) {
- block->switchLights[index - 1][1] = *zone;
- });
- }
- else if ((fKey == "switchlight_blue")) {
- fUpdateFunOut.push_back([ = ](ProcessBlock * block) {
- block->switchLights[index - 1][2] = *zone;
- });
- }
- fKey = fValue = "";
- }
-
- void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) override {
- addBarGraph(zone);
- }
-
- void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) override {
- addBarGraph(zone);
- }
-
- void addSoundfile(const char* label, const char* soundpath, Soundfile** sf_zone) override {
- WARN("Faust Prototype : 'soundfile' primitive not yet supported");
- }
-
- void declare(FAUSTFLOAT* zone, const char* key, const char* val) override {
- static std::vector keys = {"switch", "knob", "light_red", "light_green", "light_blue", "switchlight_red", "switchlight_green", "switchlight_blue"};
- if (find(keys.begin(), keys.end(), key) != keys.end()) {
- fKey = key;
- fValue = val;
- }
- else if (std::string(key) == "scale") {
- fScale = val;
- }
- }
+ if (fKey == "knob") {
+ ConverterZoneControl* converter;
+ if (fScale == "log") {
+ converter = new ConverterZoneControl(zone, new LogValueConverter(0., 1., min, max));
+ }
+ else if (fScale == "exp") {
+ converter = new ConverterZoneControl(zone, new ExpValueConverter(0., 1., min, max));
+ }
+ else {
+ converter = new ConverterZoneControl(zone, new LinearValueConverter(0., 1., min, max));
+ }
+ fUpdateFunIn.push_back([ = ](ProcessBlock * block) {
+ converter->update(block->knobs[index - 1]);
+ });
+ fConverters.push_back(converter);
+ }
+ fScale = "lin";
+ fKey = fValue = "";
+ }
+
+ void addBarGraph(FAUSTFLOAT* zone) {
+ int index = getIndex(fValue);
+ if (index == -1) return;
+
+ if ((fKey == "light_red")) {
+ fUpdateFunOut.push_back([ = ](ProcessBlock * block) {
+ block->lights[index - 1][0] = *zone;
+ });
+ }
+ else if ((fKey == "light_green")) {
+ fUpdateFunOut.push_back([ = ](ProcessBlock * block) {
+ block->lights[index - 1][1] = *zone;
+ });
+ }
+ else if ((fKey == "light_blue")) {
+ fUpdateFunOut.push_back([ = ](ProcessBlock * block) {
+ block->lights[index - 1][2] = *zone;
+ });
+ }
+ else if ((fKey == "switchlight_red")) {
+ fUpdateFunOut.push_back([ = ](ProcessBlock * block) {
+ block->switchLights[index - 1][0] = *zone;
+ });
+ }
+ else if ((fKey == "switchlight_green")) {
+ fUpdateFunOut.push_back([ = ](ProcessBlock * block) {
+ block->switchLights[index - 1][1] = *zone;
+ });
+ }
+ else if ((fKey == "switchlight_blue")) {
+ fUpdateFunOut.push_back([ = ](ProcessBlock * block) {
+ block->switchLights[index - 1][2] = *zone;
+ });
+ }
+ fKey = fValue = "";
+ }
+
+ void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) override {
+ addBarGraph(zone);
+ }
+
+ void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) override {
+ addBarGraph(zone);
+ }
+
+ void addSoundfile(const char* label, const char* soundpath, Soundfile** sf_zone) override {
+ WARN("Faust Prototype : 'soundfile' primitive not yet supported");
+ }
+
+ void declare(FAUSTFLOAT* zone, const char* key, const char* val) override {
+ static std::vector keys = {"switch", "knob", "light_red", "light_green", "light_blue", "switchlight_red", "switchlight_green", "switchlight_blue"};
+ if (find(keys.begin(), keys.end(), key) != keys.end()) {
+ fKey = key;
+ fValue = val;
+ }
+ else if (std::string(key) == "scale") {
+ fScale = val;
+ }
+ }
};
// Faust engine using libfaust + LLVM or Interp backends
class FaustEngine : public ScriptEngine {
-
+
public:
-
- FaustEngine():
- fDSPFactory(nullptr),
- fDSP(nullptr),
- fInputs(nullptr),
- fOutputs(nullptr),
- fDSPLibraries(rack::asset::plugin(pluginInstance, "res/faust"))
- {}
-
- ~FaustEngine() {
- delete [] fInputs;
- delete [] fOutputs;
- delete fDSP;
+
+ FaustEngine():
+ fDSPFactory(nullptr),
+ fDSP(nullptr),
+ fInputs(nullptr),
+ fOutputs(nullptr),
+ fDSPLibraries(rack::asset::plugin(pluginInstance, "res/faust"))
+ {}
+
+ ~FaustEngine() {
+ delete [] fInputs;
+ delete [] fOutputs;
+ delete fDSP;
#ifdef INTERP
- deleteInterpreterDSPFactory(static_cast(fDSPFactory));
+ deleteInterpreterDSPFactory(static_cast(fDSPFactory));
#else
- deleteDSPFactory(static_cast(fDSPFactory));
+ deleteDSPFactory(static_cast(fDSPFactory));
#endif
- }
-
- std::string getEngineName() override {
- return "Faust";
- }
-
- int run(const std::string& path, const std::string& script) override {
+ }
+
+ std::string getEngineName() override {
+ return "Faust";
+ }
+
+ int run(const std::string& path, const std::string& script) override {
#if defined ARCH_LIN
- std::string temp_cache = "/var/tmp/VCV_" + generateSHA1(script);
+ std::string temp_cache = "/var/tmp/VCV_" + generateSHA1(script);
#elif defined ARCH_MAC
- std::string temp_cache = "/private/var/tmp/VCV_" + generateSHA1(script);
+ std::string temp_cache = "/private/var/tmp/VCV_" + generateSHA1(script);
#elif defined ARCH_WIN
- char buf[MAX_PATH + 1] = {0};
- GetTempPath(sizeof(buf), buf);
- std::string temp_cache = std::string(buf) + "/VCV_" + generateSHA1(script);
+ char buf[MAX_PATH + 1] = {0};
+ GetTempPath(sizeof(buf), buf);
+ std::string temp_cache = std::string(buf) + "/VCV_" + generateSHA1(script);
#endif
- std::string error_msg;
-
- // Try to load the machine code cache
+ std::string error_msg;
+
+ // Try to load the machine code cache
#ifdef INTERP
- fDSPFactory = readInterpreterDSPFactoryFromBitcodeFile(temp_cache, error_msg);
+ fDSPFactory = readInterpreterDSPFactoryFromBitcodeFile(temp_cache, error_msg);
#else
- fDSPFactory = readDSPFactoryFromMachineFile(temp_cache, "", error_msg);
+ fDSPFactory = readDSPFactoryFromMachineFile(temp_cache, "", error_msg);
#endif
-
- if (!fDSPFactory) {
- // Otherwise recompile the DSP
- int argc = 0;
- const char* argv[8];
- argv[argc++] = "-I";
- argv[argc++] = fDSPLibraries.c_str();
- argv[argc] = nullptr; // NULL terminated argv
-
+
+ if (!fDSPFactory) {
+ // Otherwise recompile the DSP
+ int argc = 0;
+ const char* argv[8];
+ argv[argc++] = "-I";
+ argv[argc++] = fDSPLibraries.c_str();
+ argv[argc] = nullptr; // NULL terminated argv
+
#ifdef INTERP
- fDSPFactory = createInterpreterDSPFactoryFromString("FaustDSP", script, argc, argv, error_msg);
+ fDSPFactory = createInterpreterDSPFactoryFromString("FaustDSP", script, argc, argv, error_msg);
#else
- fDSPFactory = createDSPFactoryFromString("FaustDSP", script, argc, argv, "", error_msg, -1);
+ fDSPFactory = createDSPFactoryFromString("FaustDSP", script, argc, argv, "", error_msg, -1);
#endif
- if (!fDSPFactory) {
- display("ERROR : cannot create factory !");
- WARN("Faust Prototype : %s", error_msg.c_str());
- return -1;
- }
- else {
- // And save the cache
- display("Compiling factory finished");
+ if (!fDSPFactory) {
+ display("ERROR : cannot create factory !");
+ WARN("Faust Prototype : %s", error_msg.c_str());
+ return -1;
+ }
+ else {
+ // And save the cache
+ display("Compiling factory finished");
#ifdef INTERP
- writeInterpreterDSPFactoryToBitcodeFile(static_cast(fDSPFactory), temp_cache);
+ writeInterpreterDSPFactoryToBitcodeFile(static_cast(fDSPFactory), temp_cache);
#else
- writeDSPFactoryToMachineFile(static_cast(fDSPFactory), temp_cache, "");
+ writeDSPFactoryToMachineFile(static_cast(fDSPFactory), temp_cache, "");
#endif
- }
- }
-
- // Create DSP
- fDSP = fDSPFactory->createDSPInstance();
- if (!fDSP) {
- display("ERROR: cannot create instance !");
- return -1;
- }
- else {
- display("Created DSP");
- }
-
- // Check inputs/outputs
- if (fDSP->getNumInputs() > NUM_ROWS) {
- display("ERROR: DSP has " + std::to_string(fDSP->getNumInputs()) + " inputs !");
- return -1;
- }
-
- if (fDSP->getNumOutputs() > NUM_ROWS) {
- display("ERROR: DSP has " + std::to_string(fDSP->getNumInputs()) + " outputs !");
- return -1;
- }
-
- // Prepare buffers for process
- ProcessBlock* block = getProcessBlock();
-
- fInputs = new FAUSTFLOAT*[fDSP->getNumInputs()];
- for (int chan = 0; chan < fDSP->getNumInputs(); chan++) {
- fInputs[chan] = block->inputs[chan];
- }
-
- fOutputs = new FAUSTFLOAT*[fDSP->getNumOutputs()];
- for (int chan = 0; chan < fDSP->getNumOutputs(); chan++) {
- fOutputs[chan] = block->outputs[chan];
- }
-
- // Setup UI
- fDSP->buildUserInterface(&fRackUI);
-
- setFrameDivider(1);
- setBufferSize(kBufferSize);
-
- // Init DSP with default SR
- fDSP->init(44100);
- return 0;
- }
-
- int process() override {
- ProcessBlock* block = getProcessBlock();
-
- // Possibly update SR
- if (block->sampleRate != fDSP->getSampleRate()) {
- fDSP->init(block->sampleRate);
- }
-
- // Update inputs controllers
- for (auto& it : fRackUI.fUpdateFunIn)
- it(block);
-
- // Compute samples
- fDSP->compute(block->bufferSize, fInputs, fOutputs);
-
- // Update output controllers
- for (auto& it : fRackUI.fUpdateFunOut)
- it(block);
-
- return 0;
- }
-
+ }
+ }
+
+ // Create DSP
+ fDSP = fDSPFactory->createDSPInstance();
+ if (!fDSP) {
+ display("ERROR: cannot create instance !");
+ return -1;
+ }
+ else {
+ display("Created DSP");
+ }
+
+ // Check inputs/outputs
+ if (fDSP->getNumInputs() > NUM_ROWS) {
+ display("ERROR: DSP has " + std::to_string(fDSP->getNumInputs()) + " inputs !");
+ return -1;
+ }
+
+ if (fDSP->getNumOutputs() > NUM_ROWS) {
+ display("ERROR: DSP has " + std::to_string(fDSP->getNumInputs()) + " outputs !");
+ return -1;
+ }
+
+ // Prepare buffers for process
+ ProcessBlock* block = getProcessBlock();
+
+ fInputs = new FAUSTFLOAT*[fDSP->getNumInputs()];
+ for (int chan = 0; chan < fDSP->getNumInputs(); chan++) {
+ fInputs[chan] = block->inputs[chan];
+ }
+
+ fOutputs = new FAUSTFLOAT*[fDSP->getNumOutputs()];
+ for (int chan = 0; chan < fDSP->getNumOutputs(); chan++) {
+ fOutputs[chan] = block->outputs[chan];
+ }
+
+ // Setup UI
+ fDSP->buildUserInterface(&fRackUI);
+
+ setFrameDivider(1);
+ setBufferSize(kBufferSize);
+
+ // Init DSP with default SR
+ fDSP->init(44100);
+ return 0;
+ }
+
+ int process() override {
+ ProcessBlock* block = getProcessBlock();
+
+ // Possibly update SR
+ if (block->sampleRate != fDSP->getSampleRate()) {
+ fDSP->init(block->sampleRate);
+ }
+
+ // Update inputs controllers
+ for (auto& it : fRackUI.fUpdateFunIn)
+ it(block);
+
+ // Compute samples
+ fDSP->compute(block->bufferSize, fInputs, fOutputs);
+
+ // Update output controllers
+ for (auto& it : fRackUI.fUpdateFunOut)
+ it(block);
+
+ return 0;
+ }
+
private:
- dsp_factory* fDSPFactory;
- dsp* fDSP;
- FAUSTFLOAT** fInputs;
- FAUSTFLOAT** fOutputs;
- RackUI fRackUI;
- std::string fDSPLibraries;
+ dsp_factory* fDSPFactory;
+ dsp* fDSP;
+ FAUSTFLOAT** fInputs;
+ FAUSTFLOAT** fOutputs;
+ RackUI fRackUI;
+ std::string fDSPLibraries;
};
__attribute__((constructor(1000)))
static void constructor() {
- addScriptEngine("dsp");
+ addScriptEngine("dsp");
}