Browse Source

Code format.

faust
Stephane Letz 4 years ago
parent
commit
8b07400def
1 changed files with 290 additions and 288 deletions
  1. +290
    -288
      src/FaustEngine.cpp

+ 290
- 288
src/FaustEngine.cpp View File

@@ -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 <http://www.gnu.org/licenses/>.
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 <faust/dsp/libfaust.h>
#include <faust/gui/DecoratorUI.h>
@@ -45,9 +45,9 @@
#define kBufferSize 64

#ifdef INTERP
#include <faust/dsp/interpreter-dsp.h>
#include <faust/dsp/interpreter-dsp.h>
#else
#include <faust/dsp/llvm-dsp.h>
#include <faust/dsp/llvm-dsp.h>
#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<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 {
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 (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<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;
}
}
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<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 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<interpreter_dsp_factory*>(fDSPFactory));
deleteInterpreterDSPFactory(static_cast<interpreter_dsp_factory*>(fDSPFactory));
#else
deleteDSPFactory(static_cast<llvm_dsp_factory*>(fDSPFactory));
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 {
}
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<interpreter_dsp_factory*>(fDSPFactory), temp_cache);
writeInterpreterDSPFactoryToBitcodeFile(static_cast<interpreter_dsp_factory*>(fDSPFactory), temp_cache);
#else
writeDSPFactoryToMachineFile(static_cast<llvm_dsp_factory*>(fDSPFactory), temp_cache, "");
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;
}
}
}
// 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<FaustEngine>("dsp");
addScriptEngine<FaustEngine>("dsp");
}

Loading…
Cancel
Save