Skip to content

Commit

Permalink
latest box api
Browse files Browse the repository at this point in the history
  • Loading branch information
DBraun committed Sep 11, 2022
1 parent f7638fb commit afd4989
Show file tree
Hide file tree
Showing 8 changed files with 230 additions and 151 deletions.
68 changes: 61 additions & 7 deletions Source/FaustBoxAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -1113,8 +1113,8 @@ inline void create_bindings_for_faust_box(py::module &faust_module) {
[](BoxWrapper &b) {
double r;
bool res = isBoxReal(b, &r);
return py::make_tuple<py::return_value_policy::take_ownership>(
res, r);
return py::make_tuple<py::return_value_policy::take_ownership>(res,
r);
},
arg("box"))

Expand Down Expand Up @@ -1238,11 +1238,65 @@ inline void create_bindings_for_faust_box(py::module &faust_module) {
"getBoxType",
[](BoxWrapper s1) {
int inputs, outputs;
bool result = getBoxType(s1, &inputs, &outputs);
return py::make_tuple(result, inputs, outputs);
try {
bool result = getBoxType(s1, &inputs, &outputs);
return py::make_tuple(result, inputs, outputs);
} catch (std::exception &e) {
throw std::runtime_error(e.what());
}
},
arg("box"),
"Return a tuple of (whether the type is valid, number of inputs, "
"number of outputs) of a box.",
returnPolicy);
"Return a size-3 tuple of (whether the type is valid, number of "
"inputs, number of outputs) of a box.",
returnPolicy)

.def(
"boxToSource",
[](BoxWrapper &box, std::string &lang, std::string &class_name,
std::optional<std::vector<std::string>> in_argv) {
auto pathToFaustLibraries = getPathToFaustLibraries();

if (pathToFaustLibraries == "") {
throw std::runtime_error("Unable to load Faust Libraries.");
}

int argc = 0;
const char **argv = new const char *[256];

argv[argc++] = "-I";
argv[argc++] = pathToFaustLibraries.c_str();

argv[argc++] = "-cn";
argv[argc++] = class_name.c_str();

// if (m_faustLibrariesPath != "") {
// argv[argc++] = "-I";
// argv[argc++] = m_faustLibrariesPath.c_str();
// }

if (in_argv.has_value()) {
for (auto v : *in_argv) {
argv[argc++] = v.c_str();
}
}

std::string error_msg;

std::string source_code =
createSourceFromBoxes("test", box, lang, argc, argv, error_msg);

for (int i = 0; i < argc; i++) {
argv[i] = NULL;
}
delete[] argv;
argv = nullptr;

return py::make_tuple(source_code, error_msg);
},
arg("box"), arg("language"), arg("class_name"),
arg("argv") = py::none(),
"Turn a box into source code in a target language such as C++ "
"(\"cpp\").")

;
}
186 changes: 67 additions & 119 deletions Source/FaustProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -721,58 +721,6 @@ std::tuple<BoxWrapper, int, int> FaustProcessor::dspToBox(
return std::tuple<BoxWrapper, int, int>(BoxWrapper(box), inputs, outputs);
}

std::string FaustProcessor::compileBoxCPP(
BoxWrapper& box, std::optional<std::vector<std::string>> in_argv) {
auto pathToFaustLibraries = getPathToFaustLibraries();

if (pathToFaustLibraries == "") {
throw std::runtime_error(
"FaustProcessor::compile(): Error for path for faust libraries: " +
pathToFaustLibraries);
}

int argc = 0;
const char** argv = new const char*[256];

argv[argc++] = "-I";
argv[argc++] = pathToFaustLibraries.c_str();

if (m_faustLibrariesPath != "") {
argv[argc++] = "-I";
argv[argc++] = m_faustLibrariesPath.c_str();
}

if (in_argv.has_value()) {
for (auto v : *in_argv) {
argv[argc++] = v.c_str();
}
}

std::string error_msg;

dsp_factory_base* factory =
createCPPDSPFactoryFromBoxes("test", box, argc, argv, error_msg);

for (int i = 0; i < argc; i++) {
argv[i] = NULL;
}
delete[] argv;
argv = nullptr;

if (factory) {
// Print the C++ class
seqbuf seq;
std::ostream os(&seq);
factory->write(&os);
delete (factory);
auto s = seq.get_sequence();
return std::string(s.begin(), s.end());
} else {
throw std::runtime_error(error_msg);
}
return std::string("");
}

bool FaustProcessor::setDSPFile(const std::string& path) {
m_compileState = kNotCompiled;

Expand Down Expand Up @@ -1079,6 +1027,72 @@ void FaustProcessor::saveMIDI(std::string& savePath) {
file.writeTo(stream);
}

using myaudiotype =
py::array_t<float, py::array::c_style | py::array::forcecast>;

void FaustProcessor::setSoundfiles(py::dict d) {
m_compileState = kNotCompiled;

m_SoundfileMap.clear();

for (auto&& [potentialString, potentialListOfAudio] : d) {
if (!py::isinstance<py::str>(potentialString)) {
throw std::runtime_error(
"Error with FaustProcessor::setSoundfiles. Something was wrong with "
"the keys of the dictionary.");
return;
}

auto soundfileName = potentialString.cast<std::string>();

if (!py::isinstance<py::list>(potentialListOfAudio)) {
// todo: if it's audio, it's ok. Just use it.
throw std::runtime_error(
"Error with FaustProcessor::setSoundfiles. The values of the "
"dictionary must be lists of audio data.");
return;
}

py::list listOfAudio = potentialListOfAudio.cast<py::list>();

for (py::handle potentialAudio : listOfAudio) {
// if (py::isinstance<myaudiotype>(potentialAudio)) {

// todo: safer casting?
auto audioData = potentialAudio.cast<myaudiotype>();

float* input_ptr = (float*)audioData.data();

AudioSampleBuffer buffer;

buffer.setSize((int)audioData.shape(0), (int)audioData.shape(1));

for (int y = 0; y < audioData.shape(1); y++) {
for (int x = 0; x < audioData.shape(0); x++) {
buffer.setSample(x, y, input_ptr[x * audioData.shape(1) + y]);
}
}

m_SoundfileMap[soundfileName].push_back(buffer);

//}
// else {
// std::cerr << "key's value's list didn't contain audio data." <<
// std::endl;
//}
}
}
}

double FaustProcessor::getReleaseLength() { return m_releaseLengthSec; }

void FaustProcessor::setReleaseLength(double sec) {
m_releaseLengthSec = sec;
if (m_dsp_poly) {
m_dsp_poly->setReleaseLength(m_releaseLengthSec);
}
}

#ifdef WIN32

#include <assert.h>
Expand Down Expand Up @@ -1131,7 +1145,7 @@ const char* getMyDLLPath(void) {
}
#endif

std::string FaustProcessor::getPathToFaustLibraries() {
std::string getPathToFaustLibraries() {
// Get the path to the directory containing basics.lib, stdfaust.lib etc.

try {
Expand Down Expand Up @@ -1164,70 +1178,4 @@ std::string FaustProcessor::getPathToFaustLibraries() {
}
}

using myaudiotype =
py::array_t<float, py::array::c_style | py::array::forcecast>;

void FaustProcessor::setSoundfiles(py::dict d) {
m_compileState = kNotCompiled;

m_SoundfileMap.clear();

for (auto&& [potentialString, potentialListOfAudio] : d) {
if (!py::isinstance<py::str>(potentialString)) {
throw std::runtime_error(
"Error with FaustProcessor::setSoundfiles. Something was wrong with "
"the keys of the dictionary.");
return;
}

auto soundfileName = potentialString.cast<std::string>();

if (!py::isinstance<py::list>(potentialListOfAudio)) {
// todo: if it's audio, it's ok. Just use it.
throw std::runtime_error(
"Error with FaustProcessor::setSoundfiles. The values of the "
"dictionary must be lists of audio data.");
return;
}

py::list listOfAudio = potentialListOfAudio.cast<py::list>();

for (py::handle potentialAudio : listOfAudio) {
// if (py::isinstance<myaudiotype>(potentialAudio)) {

// todo: safer casting?
auto audioData = potentialAudio.cast<myaudiotype>();

float* input_ptr = (float*)audioData.data();

AudioSampleBuffer buffer;

buffer.setSize((int)audioData.shape(0), (int)audioData.shape(1));

for (int y = 0; y < audioData.shape(1); y++) {
for (int x = 0; x < audioData.shape(0); x++) {
buffer.setSample(x, y, input_ptr[x * audioData.shape(1) + y]);
}
}

m_SoundfileMap[soundfileName].push_back(buffer);

//}
// else {
// std::cerr << "key's value's list didn't contain audio data." <<
// std::endl;
//}
}
}
}

double FaustProcessor::getReleaseLength() { return m_releaseLengthSec; }

void FaustProcessor::setReleaseLength(double sec) {
m_releaseLengthSec = sec;
if (m_dsp_poly) {
m_dsp_poly->setReleaseLength(m_releaseLengthSec);
}
}

#endif
10 changes: 3 additions & 7 deletions Source/FaustProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
#include "generator/libfaust.h"
#include "tree.hh"


std::string getPathToFaustLibraries();

class MySoundUI : public SoundUI {
public:
void addSoundfile(const char *label, const char *filename,
Expand Down Expand Up @@ -242,8 +245,6 @@ class FaustProcessor : public ProcessorBase {
private:
double mySampleRate;

std::string getPathToFaustLibraries();

enum CompileState { kNotCompiled, kMono, kPoly, kSignalMono, kSignalPoly };

CompileState m_compileState;
Expand Down Expand Up @@ -313,9 +314,6 @@ class FaustProcessor : public ProcessorBase {
std::optional<std::vector<std::string>> in_argv);

std::tuple<BoxWrapper, int, int> dspToBox(const std::string &dsp_content);

std::string compileBoxCPP(BoxWrapper &box,
std::optional<std::vector<std::string>> in_argv);
};

inline void create_bindings_for_faust_processor(py::module &m) {
Expand Down Expand Up @@ -475,8 +473,6 @@ Note that note-ons and note-offs are counted separately.")
arg("signals"), arg("argv") = py::none(), returnPolicy)
.def("compile_box", &FaustProcessor::compileBox, arg("name"), arg("box"),
arg("argv") = py::none(), returnPolicy)
.def("compile_box_cpp", &FaustProcessor::compileBoxCPP, arg("box"),
arg("argv") = py::none(), "Print C++ code of a box.", returnPolicy)
.def("dsp_to_box", &FaustProcessor::dspToBox, arg("dsp_code"),
"Convert Faust DSP code to a tuple containing a Box, number of "
"inputs, and outputs.",
Expand Down

0 comments on commit afd4989

Please sign in to comment.