1 /************************** BEGIN wasm-dsp-imp.h **************************/ 2 /************************************************************************ 3 FAUST Architecture File 4 Copyright (C) 2020 GRAME, Centre National de Creation Musicale 5 --------------------------------------------------------------------- 6 This Architecture section is free software; you can redistribute it 7 and/or modify it under the terms of the GNU General Public License 8 as published by the Free Software Foundation; either version 3 of 9 the License, or (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; If not, see <http://www.gnu.org/licenses/>. 18 19 EXCEPTION : As a special exception, you may create a larger work 20 that contains this FAUST architecture section and distribute 21 that work under terms of your choice, so long as this FAUST 22 architecture section is not modified. 23 ************************************************************************/ 24 25 #ifndef wasm_dsp_imp_H 26 #define wasm_dsp_imp_H 27 28 #include <string> 29 #include <vector> 30 #include <assert.h> 31 32 #include "faust/dsp/dsp.h" 33 #include "faust/gui/meta.h" 34 #include "faust/gui/JSONUIDecoder.h" 35 36 // Generic wasm_dsp_factory class that keeps the JSON decoder. 37 38 class wasm_dsp_factory_imp : public dsp_factory { 39 40 public: 41 wasm_dsp_factory_imp()42 wasm_dsp_factory_imp():fDecoder(nullptr) {} ~wasm_dsp_factory_imp()43 virtual ~wasm_dsp_factory_imp() 44 { 45 delete fDecoder; 46 } 47 48 JSONUIDecoderBase* fDecoder; 49 getName()50 std::string getName() { return fDecoder->getName(); } 51 getSHAKey()52 virtual std::string getSHAKey() { return ""; } 53 getDSPCode()54 virtual std::string getDSPCode() { return ""; } 55 getCompileOptions()56 std::string getCompileOptions() { return fDecoder->getCompileOptions(); } 57 getLibraryList()58 std::vector<std::string> getLibraryList() { return fDecoder->getLibraryList(); } 59 getIncludePathnames()60 std::vector<std::string> getIncludePathnames() { return fDecoder->getIncludePathnames(); } 61 createDSPInstance()62 virtual dsp* createDSPInstance() {} 63 setMemoryManager(dsp_memory_manager * manager)64 virtual void setMemoryManager(dsp_memory_manager* manager) {} 65 getMemoryManager()66 virtual dsp_memory_manager* getMemoryManager() { return nullptr; } 67 }; 68 69 // Generic wasm_dsp class that creates and use the JSON decoder, and manage DSP and audio memory. 70 71 class wasm_dsp_imp : public dsp { 72 73 protected: 74 75 wasm_dsp_factory_imp* fFactory; 76 77 char* fMemory; // Wasm memory 78 79 int fWasmInputs; // Index in wasm memory 80 int fWasmOutputs; // Index in wasm memory 81 82 FAUSTFLOAT** fInputs; // Wasm memory mapped to audio pointers 83 FAUSTFLOAT** fOutputs; // Wasm memory mapped to audio pointers 84 85 // Assuming fFactory and fMemory are set initDecoder()86 void initDecoder() 87 { 88 assert(fFactory); 89 assert(fMemory); 90 91 if (!fFactory->fDecoder) { 92 std::string json = std::string(fMemory); 93 std::cout << "JSON " << json << std::endl; 94 fFactory->fDecoder = createJSONUIDecoder(json); 95 } 96 97 std::cout << "Libfaust version: " << fFactory->fDecoder->getLibVersion() << std::endl; 98 std::cout << "Compilation options: " << fFactory->fDecoder->getCompileOptions() << std::endl; 99 100 int ptr_size = sizeof(FAUSTFLOAT*); 101 int sample_size = sizeof(FAUSTFLOAT); 102 int buffer_size = 4096; // Max 103 104 fInputs = new FAUSTFLOAT*[fFactory->fDecoder->getNumInputs()]; 105 fOutputs = new FAUSTFLOAT*[fFactory->fDecoder->getNumOutputs()]; 106 107 // DSP is placed first with index 0. Audio buffer start at the end of DSP 108 int audio_heap_ptr = fFactory->fDecoder->getDSPSize(); 109 110 // Setup pointers offset 111 int audio_heap_ptr_inputs = audio_heap_ptr; 112 int audio_heap_ptr_outputs = audio_heap_ptr_inputs + (fFactory->fDecoder->getNumInputs() * ptr_size); 113 114 // Setup buffer offset 115 int audio_heap_inputs = audio_heap_ptr_outputs + (fFactory->fDecoder->getNumOutputs() * ptr_size); 116 int audio_heap_outputs = audio_heap_inputs + (fFactory->fDecoder->getNumInputs() * buffer_size * sample_size); 117 118 if (fFactory->fDecoder->getNumInputs() > 0) { 119 120 fWasmInputs = audio_heap_ptr_inputs; 121 int* HEAP32 = reinterpret_cast<int*>(fMemory + audio_heap_ptr_inputs); 122 FAUSTFLOAT* HEAPF32 = reinterpret_cast<FAUSTFLOAT*>(fMemory + audio_heap_inputs); 123 124 for (int i = 0; i < fFactory->fDecoder->getNumInputs(); i++) { 125 // Setup input buffer indexes for wasm side 126 HEAP32[i] = audio_heap_inputs + (buffer_size * sample_size * i); 127 // Setup input buffer pointers for runtime side 128 fInputs[i] = HEAPF32 + (buffer_size * i); 129 } 130 } 131 132 if (fFactory->fDecoder->getNumOutputs() > 0) { 133 134 fWasmOutputs = audio_heap_ptr_outputs; 135 int* HEAP32 = reinterpret_cast<int*>(fMemory + audio_heap_ptr_outputs); 136 FAUSTFLOAT* HEAPF32 = reinterpret_cast<FAUSTFLOAT*>(fMemory + audio_heap_outputs); 137 138 for (int i = 0; i < fFactory->fDecoder->getNumOutputs(); i++) { 139 // Setup output buffer indexes for wasm side 140 HEAP32[i] = audio_heap_outputs + (buffer_size * sample_size * i); 141 // Setup output buffer pointers for runtime side 142 fOutputs[i] = HEAPF32 + (buffer_size * i); 143 } 144 } 145 } 146 147 public: 148 149 wasm_dsp_imp(wasm_dsp_factory_imp* factory, char* memory = nullptr): fFactory(factory)150 fFactory(factory), 151 fMemory(memory), 152 fInputs(nullptr), 153 fOutputs(nullptr), 154 fWasmInputs(0), 155 fWasmOutputs(0) 156 {} 157 ~wasm_dsp_imp()158 virtual ~wasm_dsp_imp() 159 { 160 delete [] fInputs; 161 delete [] fOutputs; 162 } 163 getNumInputs()164 virtual int getNumInputs() { return -1; } getNumOutputs()165 virtual int getNumOutputs() { return -1; ; } buildUserInterface(UI * ui_interface)166 virtual void buildUserInterface(UI* ui_interface) 167 { 168 fFactory->fDecoder->buildUserInterface(ui_interface, fMemory); 169 } getSampleRate()170 virtual int getSampleRate() { return -1; } init(int sample_rate)171 virtual void init(int sample_rate) {} instanceInit(int sample_rate)172 virtual void instanceInit(int sample_rate) {} instanceConstants(int sample_rate)173 virtual void instanceConstants(int sample_rate) {} instanceResetUserInterface()174 virtual void instanceResetUserInterface() {} instanceClear()175 virtual void instanceClear() {} clone()176 virtual wasm_dsp_imp* clone() { return nullptr; } metadata(Meta * m)177 virtual void metadata(Meta* m) 178 { 179 fFactory->fDecoder->metadata(m); 180 } 181 // Beware: subclasses usually have to overload the two 'compute' methods compute(int count,FAUSTFLOAT ** inputs,FAUSTFLOAT ** outputs)182 virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) {} compute(double date_usec,int count,FAUSTFLOAT ** inputs,FAUSTFLOAT ** outputs)183 virtual void compute(double date_usec, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) {} 184 }; 185 186 #endif 187 /************************** END wasm-dsp-imp.h **************************/ 188