You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
3.6KB

  1. #include "ScriptEngine.hpp"
  2. #include <faust/dsp/llvm-dsp.h>
  3. #include <iostream>
  4. #define kBufferSize 64
  5. class FaustEngine : public ScriptEngine {
  6. public:
  7. FaustEngine():fDSPFactory(nullptr), fDSP(nullptr), fInputs(nullptr), fOutputs(nullptr)
  8. {}
  9. ~FaustEngine()
  10. {
  11. delete [] fInputs;
  12. delete [] fOutputs;
  13. delete fDSP;
  14. deleteDSPFactory(fDSPFactory);
  15. }
  16. std::string getEngineName() override
  17. {
  18. return "Faust";
  19. }
  20. int run(const std::string& path, const std::string& script) override
  21. {
  22. std::string filename = path.substr(path.find_last_of("/"));
  23. #if defined ARCH_MAC
  24. std::string tempDir = "/private/var/tmp/";
  25. #else
  26. std::string tempDir = "";
  27. #endif
  28. std::string error_msg;
  29. // Try to load the machine code cache
  30. fDSPFactory = readDSPFactoryFromMachineFile(tempDir + filename, "", error_msg);
  31. if (!fDSPFactory) {
  32. // Otherwise recompile the DSP
  33. fDSPFactory = createDSPFactoryFromString("FaustDSP", script, 0, NULL, "", error_msg, -1);
  34. if (!fDSPFactory) {
  35. display("ERROR: cannot create Faust factory !");
  36. return -1;
  37. } else {
  38. // And save the cache
  39. display("Compiling factory finished");
  40. writeDSPFactoryToMachineFile(fDSPFactory, tempDir + filename, "");
  41. }
  42. }
  43. // Create DSP
  44. fDSP = fDSPFactory->createDSPInstance();
  45. if (!fDSP) {
  46. display("ERROR: cannot create Faust instance !");
  47. return -1;
  48. } else {
  49. display("Created DSP");
  50. }
  51. // Prepare inputs/outputs
  52. if (fDSP->getNumInputs() > 6) {
  53. display("ERROR: DSP has " + std::to_string(fDSP->getNumInputs()) + " inputs !");
  54. return -1;
  55. }
  56. if (fDSP->getNumOutputs() > 6) {
  57. display("ERROR: DSP has " + std::to_string(fDSP->getNumInputs()) + " outputs !");
  58. return -1;
  59. }
  60. setFrameDivider(1);
  61. setBufferSize(kBufferSize);
  62. // Prepare buffers for process
  63. ProcessBlock* block = getProcessBlock();
  64. fInputs = new FAUSTFLOAT*[fDSP->getNumInputs()];
  65. for (int chan = 0; chan < fDSP->getNumInputs(); chan++) {
  66. fInputs[chan] = block->inputs[chan];
  67. }
  68. fOutputs = new FAUSTFLOAT*[fDSP->getNumOutputs()];
  69. for (int chan = 0; chan < fDSP->getNumOutputs(); chan++) {
  70. fOutputs[chan] = block->outputs[chan];
  71. }
  72. // Init DSP with default SR
  73. fDSP->init(44100);
  74. return 0;
  75. }
  76. int process() override
  77. {
  78. // Possibly update SR
  79. if (getProcessBlock()->sampleRate != fDSP->getSampleRate()) {
  80. fDSP->init(getProcessBlock()->sampleRate);
  81. }
  82. fDSP->compute(kBufferSize, fInputs, fOutputs);
  83. return 0;
  84. }
  85. private:
  86. llvm_dsp_factory* fDSPFactory;
  87. llvm_dsp* fDSP;
  88. FAUSTFLOAT** fInputs;
  89. FAUSTFLOAT** fOutputs;
  90. };
  91. __attribute__((constructor(1000)))
  92. static void constructor() {
  93. addScriptEngine<FaustEngine>("dsp");
  94. }