Browse Source

Autoformat FaustEngine.cpp.

Add `override` to overridden methods. Ignore override warning in Faust headers.
Remove `using namespace std`, add `std::` to required identifiers.
Move /res/faust to /fause_libraries.
Install Faust to dep instead of using build directory.
faust
Andrew Belt 4 years ago
parent
commit
8b867499dd
4 changed files with 338 additions and 324 deletions
  1. +1
    -0
      .gitignore
  2. +12
    -13
      Makefile
  3. +0
    -0
      faust_libraries/rack.lib
  4. +325
    -311
      src/FaustEngine.cpp

+ 1
- 0
.gitignore View File

@@ -5,3 +5,4 @@
/plugin.dylib /plugin.dylib
/plugin.dll /plugin.dll
.DS_Store .DS_Store
/faust_libraries

+ 12
- 13
Makefile View File

@@ -4,7 +4,7 @@ FLAGS += -Idep/include
CFLAGS += CFLAGS +=
CXXFLAGS += CXXFLAGS +=


LDFLAGS +=
LDFLAGS +=
SOURCES += src/Prototype.cpp SOURCES += src/Prototype.cpp


DISTRIBUTABLES += res examples DISTRIBUTABLES += res examples
@@ -13,12 +13,12 @@ DISTRIBUTABLES += $(wildcard LICENSE*)
include $(RACK_DIR)/arch.mk include $(RACK_DIR)/arch.mk


DUKTAPE ?= 0 DUKTAPE ?= 0
QUICKJS ?= 0
LUAJIT ?= 0
QUICKJS ?= 1
LUAJIT ?= 1
PYTHON ?= 0 PYTHON ?= 0
SUPERCOLLIDER ?= 0 SUPERCOLLIDER ?= 0
VULT ?= 0
LIBPD ?= 0
VULT ?= 1
LIBPD ?= 1
FAUST ?= 1 FAUST ?= 1


# Vult depends on both LuaJIT and QuickJS # Vult depends on both LuaJIT and QuickJS
@@ -223,7 +223,7 @@ FLAGS += -Idep/include/libpd -DHAVE_LIBDL
ifdef ARCH_WIN ifdef ARCH_WIN
# the PD_INTERNAL leaves the function declarations for libpd unchanged # the PD_INTERNAL leaves the function declarations for libpd unchanged
# not specifying that flag would enable the "EXTERN __declspec(dllexport) extern" macro # not specifying that flag would enable the "EXTERN __declspec(dllexport) extern" macro
# which throughs a linker error. I guess this macro should only be used for the windows
# which throughs a linker error. I guess this macro should only be used for the windows
# specific .dll dynamic linking format. # specific .dll dynamic linking format.
# The corresponding #define resides in "m_pd.h" inside pure data sources # The corresponding #define resides in "m_pd.h" inside pure data sources
FLAGS += -DPD_INTERNAL FLAGS += -DPD_INTERNAL
@@ -250,15 +250,13 @@ endif


# Faust # Faust
ifeq ($(FAUST), 1) ifeq ($(FAUST), 1)
libfaust := dep/faust/build/lib/libfaust.a
libfaust := dep/lib/libfaust.a
SOURCES += src/FaustEngine.cpp SOURCES += src/FaustEngine.cpp
OBJECTS += $(libfaust) OBJECTS += $(libfaust)
DEPS += $(libfaust) DEPS += $(libfaust)
FLAGS += -Idep/faust/architecture
FLAGS += -DINTERP FLAGS += -DINTERP
LDFLAGS += dep/faust/build/lib/libfaust.a


# Test using LLVM
# Test using LLVM
#LDFLAGS += -L/usr/local/lib -lfaust #LDFLAGS += -L/usr/local/lib -lfaust


# Test using MIR # Test using MIR
@@ -266,10 +264,11 @@ LDFLAGS += dep/faust/build/lib/libfaust.a


$(libfaust): $(libfaust):
cd dep && git clone "https://github.com/grame-cncm/faust.git" --recursive cd dep && git clone "https://github.com/grame-cncm/faust.git" --recursive
cd dep/faust && git checkout 1dfc452a8250f3123b5100edf8c882e1cea407a1 && cp -rf libraries/* ../../res/faust
cd dep/faust && make -C build cmake BACKENDS=interp.cmake TARGETS=interp.cmake && make -C build
cd dep/faust && git checkout 1dfc452a8250f3123b5100edf8c882e1cea407a1
cd dep/faust/build && make cmake BACKENDS=interp.cmake TARGETS=interp.cmake
cd dep/faust/build && make install PREFIX="$(DEP_PATH)"
cp -rf dep/faust/libraries/* faust_libraries/


endif endif


include $(RACK_DIR)/plugin.mk include $(RACK_DIR)/plugin.mk


res/faust/rack.lib → faust_libraries/rack.lib View File


+ 325
- 311
src/FaustEngine.cpp View File

@@ -6,15 +6,15 @@
and/or modify it under the terms of the GNU General Public License and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 3 of as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version. the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; If not, see <http://www.gnu.org/licenses/>. along with this program; If not, see <http://www.gnu.org/licenses/>.
EXCEPTION : As a special exception, you may create a larger work EXCEPTION : As a special exception, you may create a larger work
that contains this FAUST architecture section and distribute that contains this FAUST architecture section and distribute
that work under terms of your choice, so long as this FAUST that work under terms of your choice, so long as this FAUST
@@ -23,10 +23,6 @@


#include "ScriptEngine.hpp" #include "ScriptEngine.hpp"


#include <faust/dsp/libfaust.h>
#include <faust/gui/DecoratorUI.h>
#include <faust/gui/ValueConverter.h>

#include <iostream> #include <iostream>
#include <memory> #include <memory>
#include <map> #include <map>
@@ -34,326 +30,344 @@
#include <algorithm> #include <algorithm>
#include <functional> #include <functional>


using namespace std;
#pragma GCC diagnostic push
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wsuggest-override"
#endif
#include <faust/dsp/libfaust.h>
#include <faust/gui/DecoratorUI.h>
#include <faust/gui/ValueConverter.h>


#define kBufferSize 64 #define kBufferSize 64


#ifdef INTERP #ifdef INTERP
#include <faust/dsp/interpreter-dsp.h>
#include <faust/dsp/interpreter-dsp.h>
#else #else
#include <faust/dsp/llvm-dsp.h>
#include <faust/dsp/llvm-dsp.h>
#endif #endif
#pragma GCC diagnostic pop


extern rack::Plugin* pluginInstance; extern rack::Plugin* pluginInstance;


// UI handler for switches, knobs and lights // UI handler for switches, knobs and lights
struct RackUI : public GenericUI
{
typedef function<void(ProcessBlock* block)> updateFunction;
vector<ConverterZoneControl*> fConverters;
vector<updateFunction> fUpdateFunIn;
vector<updateFunction> fUpdateFunOut;
// For checkbox handling
struct CheckBox { float fLastButton = 0.0f; };
map <FAUSTFLOAT*, CheckBox> fCheckBoxes;
string fKey, fValue, fScale;
int getIndex(const string& value)
{
try {
int index = stoi(value);
if (index >= 0 && index <= NUM_ROWS) {
return index;
} else {
cerr << "ERROR : incorrect '" << index << "' value !\n";
return -1;
}
} catch (invalid_argument& e) {
return -1;
}
}
RackUI():fScale("lin")
{}
virtual ~RackUI()
{
for (auto& it : fConverters) delete it;
}
void addButton(const char* label, FAUSTFLOAT* zone)
{
int index = getIndex(fValue);
if (fKey == "switch" && (index != -1)) {
fUpdateFunIn.push_back([=] (ProcessBlock* block)
{
*zone = block->switches[index-1];
// And set the color to red when ON
block->switchLights[index-1][0] = *zone;
});
}
fKey = fValue = "";
}
void addCheckButton(const char* label, FAUSTFLOAT* zone)
{
int index = getIndex(fValue);
if (fKey == "switch" && (index != -1)) {
// 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;
// And set the color to white when ON
block->switchLights[index-1][0] = *zone;
block->switchLights[index-1][1] = *zone;
block->switchLights[index-1][2] = *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)
{
addNumEntry(label, zone, init, min, max, step);
}
void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
{
addNumEntry(label, zone, init, min, max, step);
}
void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
{
int index = getIndex(fValue);
if (fKey == "knob" && (index != -1)) {
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 ((fKey == "light_red") && (index != -1)) {
fUpdateFunOut.push_back([=] (ProcessBlock* block) { block->lights[index-1][0] = *zone; });
} else if ((fKey == "light_green") && (index != -1)) {
fUpdateFunOut.push_back([=] (ProcessBlock* block) { block->lights[index-1][1] = *zone; });
} else if ((fKey == "light_blue") && (index != -1)) {
fUpdateFunOut.push_back([=] (ProcessBlock* block) { block->lights[index-1][2] = *zone; });
} else if ((fKey == "switchlight_red") && (index != -1)) {
fUpdateFunOut.push_back([=] (ProcessBlock* block) { block->switchLights[index-1][0] = *zone; });
} else if ((fKey == "switchlight_green") && (index != -1)) {
fUpdateFunOut.push_back([=] (ProcessBlock* block) { block->switchLights[index-1][1] = *zone; });
} else if ((fKey == "switchlight_blue") && (index != -1)) {
fUpdateFunOut.push_back([=] (ProcessBlock* block) { block->switchLights[index-1][2] = *zone; });
}
fKey = fValue = "";
}
void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
{
addBarGraph(zone);
}
void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
{
addBarGraph(zone);
}
void addSoundfile(const char* label, const char* soundpath, Soundfile** sf_zone)
{
WARN("Faust Prototype : 'soundfile' primitive not yet supported", "");
}
void declare(FAUSTFLOAT* zone, const char* key, const char* val)
{
static vector<string> 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 (string(key) == "scale") {
fScale = val;
}
}
struct RackUI : public GenericUI {
typedef std::function<void(ProcessBlock* block)> updateFunction;

std::vector<ConverterZoneControl*> fConverters;
std::vector<updateFunction> fUpdateFunIn;
std::vector<updateFunction> fUpdateFunOut;

// For checkbox handling
struct CheckBox {
float fLastButton = 0.0f;
};
std::map <FAUSTFLOAT*, CheckBox> 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 (fKey == "switch" && (index != -1)) {
fUpdateFunIn.push_back([ = ](ProcessBlock * block) {
*zone = block->switches[index - 1];

// And set the color to red when ON
block->switchLights[index - 1][0] = *zone;
});
}
fKey = fValue = "";
}

void addCheckButton(const char* label, FAUSTFLOAT* zone) override {
int index = getIndex(fValue);
if (fKey == "switch" && (index != -1)) {
// 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;
// And set the color to white when ON
block->switchLights[index - 1][0] = *zone;
block->switchLights[index - 1][1] = *zone;
block->switchLights[index - 1][2] = *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" && (index != -1)) {
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 ((fKey == "light_red") && (index != -1)) {
fUpdateFunOut.push_back([ = ](ProcessBlock * block) {
block->lights[index - 1][0] = *zone;
});
}
else if ((fKey == "light_green") && (index != -1)) {
fUpdateFunOut.push_back([ = ](ProcessBlock * block) {
block->lights[index - 1][1] = *zone;
});
}
else if ((fKey == "light_blue") && (index != -1)) {
fUpdateFunOut.push_back([ = ](ProcessBlock * block) {
block->lights[index - 1][2] = *zone;
});
}
else if ((fKey == "switchlight_red") && (index != -1)) {
fUpdateFunOut.push_back([ = ](ProcessBlock * block) {
block->switchLights[index - 1][0] = *zone;
});
}
else if ((fKey == "switchlight_green") && (index != -1)) {
fUpdateFunOut.push_back([ = ](ProcessBlock * block) {
block->switchLights[index - 1][1] = *zone;
});
}
else if ((fKey == "switchlight_blue") && (index != -1)) {
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<std::string> 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 // Faust engine using libfaust/LLVM
class FaustEngine : public ScriptEngine { 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;
#ifdef INTERP
deleteInterpreterDSPFactory(static_cast<interpreter_dsp_factory*>(fDSPFactory));
#else
deleteDSPFactory(static_cast<llvm_dsp_factory*>(fDSPFactory));
#endif
}
string getEngineName() override
{
return "Faust";
}
int run(const string& path, const string& script) override
{
#if defined ARCH_LIN
string temp_cache = "/var/tmp/VCV_" + generateSHA1(script);
#elif defined ARCH_MAC
string temp_cache = "/private/var/tmp/VCV_" + generateSHA1(script);
#elif defined ARCH_WIN
char buf[MAX_PATH+1] = {0};
GetTempPath(sizeof(buf), buf);
string temp_cache = string(buf) + "/VCV_" + generateSHA1(script);
#endif
string error_msg;
// Try to load the machine code cache
#ifdef INTERP
fDSPFactory = readInterpreterDSPFactoryFromBitcodeFile(temp_cache, error_msg);
#else
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
#ifdef INTERP
fDSPFactory = createInterpreterDSPFactoryFromString("FaustDSP", script, argc, argv, error_msg);
#else
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");
#ifdef INTERP
writeInterpreterDSPFactoryToBitcodeFile(static_cast<interpreter_dsp_factory*>(fDSPFactory), temp_cache);
#else
writeDSPFactoryToMachineFile(static_cast<llvm_dsp_factory*>(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 " + to_string(fDSP->getNumInputs()) + " inputs !");
return -1;
}
if (fDSP->getNumOutputs() > NUM_ROWS) {
display("ERROR: DSP has " + 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;
string fDSPLibraries;
public:
FaustEngine():
fDSPFactory(nullptr),
fDSP(nullptr),
fInputs(nullptr),
fOutputs(nullptr),
fDSPLibraries(rack::asset::plugin(pluginInstance, "faust_libraries"))
{}
~FaustEngine() {
delete [] fInputs;
delete [] fOutputs;
delete fDSP;
#ifdef INTERP
deleteInterpreterDSPFactory(static_cast<interpreter_dsp_factory*>(fDSPFactory));
#else
deleteDSPFactory(static_cast<llvm_dsp_factory*>(fDSPFactory));
#endif
}
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);
#elif defined ARCH_MAC
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);
#endif
std::string error_msg;
// Try to load the machine code cache
#ifdef INTERP
fDSPFactory = readInterpreterDSPFactoryFromBitcodeFile(temp_cache, error_msg);
#else
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
#ifdef INTERP
fDSPFactory = createInterpreterDSPFactoryFromString("FaustDSP", script, argc, argv, error_msg);
#else
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");
#ifdef INTERP
writeInterpreterDSPFactoryToBitcodeFile(static_cast<interpreter_dsp_factory*>(fDSPFactory), temp_cache);
#else
writeDSPFactoryToMachineFile(static_cast<llvm_dsp_factory*>(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;
}
private:
dsp_factory* fDSPFactory;
dsp* fDSP;
FAUSTFLOAT** fInputs;
FAUSTFLOAT** fOutputs;
RackUI fRackUI;
std::string fDSPLibraries;
}; };


__attribute__((constructor(1000))) __attribute__((constructor(1000)))
static void constructor() { static void constructor() {
addScriptEngine<FaustEngine>("dsp");
addScriptEngine<FaustEngine>("dsp");
} }

Loading…
Cancel
Save