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