1 /************************************************************************
2 ************************************************************************
3 FAUST compiler
4 Copyright (C) 2003-2014 GRAME, Centre National de Creation Musicale
5 ---------------------------------------------------------------------
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (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, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 ************************************************************************
20 ************************************************************************/
21
22 #ifdef WIN32
23 #pragma warning(disable : 4251 4275 4800)
24 #endif
25
26 #include "wasm_dynamic_dsp_aux.hh"
27 #include "Text.hh"
28 #include "compatibility.hh"
29
30 #ifdef WIN32
31 #define strdup _strdup
32 #endif
33
34 #ifdef EMCC
35 #include <emscripten.h>
36 #include <emscripten/bind.h>
37 using namespace emscripten;
38 #endif
39
createWasmDSPFactoryFromString2(const string & name_app,const string & dsp_content,const vector<string> & argv,bool internal_memory)40 wasm_dsp_factory* wasm_dynamic_dsp_factory::createWasmDSPFactoryFromString2(const string& name_app,
41 const string& dsp_content,
42 const vector<string>& argv,
43 bool internal_memory)
44 {
45 int argc1 = 0;
46 const char* argv1[64];
47 for (size_t i = 0; i < argv.size(); i++) {
48 argv1[argc1++] = argv[i].c_str();
49 }
50 argv1[argc1] = nullptr; // NULL terminated argv
51
52 return createWasmDSPFactoryFromString(name_app, dsp_content, argc1, argv1,
53 wasm_dsp_factory::gErrorMessage, internal_memory);
54 }
55
generateWasmFromString2(const std::string & name_app,const std::string & dsp_content,const std::vector<std::string> & argv,bool internal_memory)56 std::string wasm_dynamic_dsp_factory::generateWasmFromString2(const std::string& name_app,
57 const std::string& dsp_content,
58 const std::vector<std::string>& argv,
59 bool internal_memory)
60 {
61 int argc1 = 0;
62 const char* argv1[64];
63 for (size_t i = 0; i < argv.size(); i++) {
64 argv1[argc1++] = argv[i].c_str();
65 }
66 argv1[argc1] = nullptr; // NULL terminated argv
67
68 return generateWasmFromString(name_app, dsp_content, argc1, argv1,wasm_dsp_factory::gErrorMessage, internal_memory);
69 }
70
71 // C++ API
72
createWasmDSPFactoryFromFile(const string & filename,int argc,const char * argv[],string & error_msg,bool internal_memory)73 EXPORT wasm_dsp_factory* createWasmDSPFactoryFromFile(const string& filename, int argc, const char* argv[],
74 string& error_msg, bool internal_memory)
75 {
76 string base = basename((char*)filename.c_str());
77 size_t pos = filename.find(".dsp");
78
79 if (pos != string::npos) {
80 return createWasmDSPFactoryFromString(base.substr(0, pos), pathToContent(filename), argc, argv, error_msg,
81 internal_memory);
82 } else {
83 error_msg = "ERROR : file extension is not the one expected (.dsp expected)\n";
84 return nullptr;
85 }
86 }
87
createWasmDSPFactoryFromString(const string & name_app,const string & dsp_content,int argc,const char * argv[],string & error_msg,bool internal_memory)88 EXPORT wasm_dsp_factory* createWasmDSPFactoryFromString(const string& name_app, const string& dsp_content, int argc,
89 const char* argv[], string& error_msg, bool internal_memory)
90 {
91 string expanded_dsp_content, sha_key;
92
93 if ((expanded_dsp_content = sha1FromDSP(name_app, dsp_content, argc, argv, sha_key)) == "") {
94 return nullptr;
95 } else {
96 int argc1 = 0;
97 const char* argv1[64];
98 argv1[argc1++] = "faust";
99 argv1[argc1++] = "-lang";
100 // argv1[argc1++] = (internal_memory) ? "wasm-i" : "wasm-e";
101 argv1[argc1++] = (internal_memory) ? "wasm-ib" : "wasm-eb";
102 argv1[argc1++] = "-o";
103 argv1[argc1++] = "binary";
104 // Copy argument
105 for (int i = 0; i < argc; i++) {
106 argv1[argc1++] = argv[i];
107 }
108 argv1[argc1] = nullptr; // NULL terminated argv
109
110 dsp_factory_base* dsp_factory_aux = createFactory(name_app.c_str(), dsp_content.c_str(), argc1, argv1, error_msg, true);
111 if (dsp_factory_aux) {
112 dsp_factory_aux->setName(name_app);
113 wasm_dsp_factory* factory = new wasm_dsp_factory(dsp_factory_aux);
114 wasm_dsp_factory::gWasmFactoryTable.setFactory(factory);
115 factory->setSHAKey(sha_key);
116 factory->setDSPCode(expanded_dsp_content);
117 return factory;
118 } else {
119 return nullptr;
120 }
121 }
122 }
123
createWasmDSPFactoryFromSignals(const std::string & name_app,tvec signals,int argc,const char * argv[],std::string & error_msg,bool internal_memory)124 EXPORT wasm_dsp_factory* createWasmDSPFactoryFromSignals(const std::string& name_app, tvec signals,
125 int argc, const char* argv[], std::string& error_msg,
126 bool internal_memory)
127 {
128 int argc1 = 0;
129 const char* argv1[64];
130 argv1[argc1++] = "faust";
131 argv1[argc1++] = "-lang";
132 // argv1[argc1++] = (internal_memory) ? "wasm-i" : "wasm-e";
133 argv1[argc1++] = (internal_memory) ? "wasm-ib" : "wasm-eb";
134 argv1[argc1++] = "-o";
135 argv1[argc1++] = "binary";
136 // Copy argument
137 for (int i = 0; i < argc; i++) {
138 argv1[argc1++] = argv[i];
139 }
140 argv1[argc1] = nullptr; // NULL terminated argv
141
142 dsp_factory_base* dsp_factory_aux = createFactory(name_app.c_str(), signals, argc1, argv1, error_msg);
143 if (dsp_factory_aux) {
144 dsp_factory_aux->setName(name_app);
145 wasm_dsp_factory* factory = new wasm_dsp_factory(dsp_factory_aux);
146 wasm_dsp_factory::gWasmFactoryTable.setFactory(factory);
147 return factory;
148 } else {
149 return nullptr;
150 }
151 }
152
generateWasmFromString(const string & name_app,const string & dsp_content,int argc,const char * argv[],string & error_msg,bool internal_memory)153 EXPORT std::string generateWasmFromString(const string& name_app, const string& dsp_content, int argc,
154 const char* argv[], string& error_msg, bool internal_memory)
155 {
156 int argc1 = 0;
157 const char* argv1[64];
158 argv1[argc1++] = "faust";
159 argv1[argc1++] = "-lang";
160 // argv1[argc1++] = (internal_memory) ? "wasm-i" : "wasm-e";
161 argv1[argc1++] = (internal_memory) ? "wasm-ib" : "wasm-eb";
162 argv1[argc1++] = "-o";
163 argv1[argc1++] = "binary";
164 for (int i = 0; i < argc; i++) {
165 argv1[argc1++] = argv[i];
166 }
167 argv1[argc1] = nullptr; // NULL terminated argv
168
169 dsp_factory_base* dsp_factory_aux = createFactory(name_app.c_str(), dsp_content.c_str(), argc1, argv1, error_msg, true);
170 return (dsp_factory_aux) ? dsp_factory_aux->getBinaryCode() : "";
171 }
172
173 #ifdef __cplusplus
174 extern "C" {
175 #endif
176
deleteAllWasmCDSPFactories()177 EXPORT void deleteAllWasmCDSPFactories()
178 {
179 deleteAllWasmDSPFactories();
180 }
181
createWasmCDSPFactoryFromFile2(const char * filename,int argc,const char * argv[],char * error_msg,bool internal_memory)182 EXPORT wasm_dsp_factory* createWasmCDSPFactoryFromFile2(const char* filename, int argc, const char* argv[],
183 char* error_msg, bool internal_memory)
184 {
185 string error_msg_aux;
186 wasm_dsp_factory* factory = createWasmDSPFactoryFromFile(filename, argc, argv, error_msg_aux, internal_memory);
187 strncpy(error_msg, error_msg_aux.c_str(), 4096);
188 return factory;
189 }
190
createWasmCDSPFactoryFromString2(const char * name_app,const char * dsp_content,int argc,const char * argv[],char * error_msg,bool internal_memory)191 EXPORT wasm_dsp_factory* createWasmCDSPFactoryFromString2(const char* name_app, const char* dsp_content, int argc,
192 const char* argv[], char* error_msg, bool internal_memory)
193 {
194 string error_msg_aux;
195 wasm_dsp_factory* factory =
196 createWasmDSPFactoryFromString(name_app, dsp_content, argc, argv, error_msg_aux, internal_memory);
197 strncpy(error_msg, error_msg_aux.c_str(), 4096);
198 return factory;
199 }
200
createWasmCDSPFactoryFromSignals2(const char * name_app,tvec signals,int argc,const char * argv[],char * error_msg,bool internal_memory)201 EXPORT wasm_dsp_factory* createWasmCDSPFactoryFromSignals2(const char* name_app, tvec signals,
202 int argc, const char* argv[], char* error_msg,
203 bool internal_memory)
204 {
205 string error_msg_aux;
206 wasm_dsp_factory* factory =
207 createWasmDSPFactoryFromSignals(name_app, signals, argc, argv, error_msg_aux, internal_memory);
208 strncpy(error_msg, error_msg_aux.c_str(), 4096);
209 return factory;
210 }
211
createWasmCDSPFactoryAux(wasm_dsp_factory * factory,const string & error_msg_aux,char * error_msg)212 static WasmModule* createWasmCDSPFactoryAux(wasm_dsp_factory* factory, const string& error_msg_aux, char* error_msg)
213 {
214 strncpy(error_msg, error_msg_aux.c_str(), 4096);
215 if (factory) {
216 WasmModule* res = static_cast<WasmModule*>(calloc(1, sizeof(WasmModule)));
217
218 // 'Binary' string, so directly copy its raw content
219 string code = factory->getBinaryCode();
220 res->fWASMCodeSize = (int)code.size();
221 res->fWASMCode = (char*)malloc(res->fWASMCodeSize);
222 memcpy(res->fWASMCode, code.c_str(), res->fWASMCodeSize);
223
224 stringstream dst2;
225 factory->writeHelper(&dst2, false, false);
226 res->fJSHelpers = strdup(flatten(dst2.str()).c_str());
227
228 return res;
229 // And keep factory...
230 } else {
231 return nullptr;
232 }
233 }
234
createWasmCDSPFactoryFromFile(const char * filename,int argc,const char * argv[],char * error_msg,bool internal_memory)235 EXPORT WasmModule* createWasmCDSPFactoryFromFile(const char* filename, int argc, const char* argv[], char* error_msg,
236 bool internal_memory)
237 {
238 string error_msg_aux;
239 wasm_dsp_factory* factory = createWasmDSPFactoryFromFile(filename, argc, argv, error_msg_aux, internal_memory);
240 return createWasmCDSPFactoryAux(factory, error_msg_aux, error_msg);
241 }
242
createWasmCDSPFactoryFromString(const char * name_app,const char * dsp_content,int argc,const char * argv[],char * error_msg,bool internal_memory)243 EXPORT WasmModule* createWasmCDSPFactoryFromString(const char* name_app, const char* dsp_content, int argc,
244 const char* argv[], char* error_msg, bool internal_memory)
245 {
246 string error_msg_aux;
247 wasm_dsp_factory* factory =
248 createWasmDSPFactoryFromString(name_app, dsp_content, argc, argv, error_msg_aux, internal_memory);
249 return createWasmCDSPFactoryAux(factory, error_msg_aux, error_msg);
250 }
251
getWasmCModule(WasmModule * module)252 EXPORT const char* getWasmCModule(WasmModule* module)
253 {
254 return module->fWASMCode;
255 }
256
getWasmCModuleSize(WasmModule * module)257 EXPORT int getWasmCModuleSize(WasmModule* module)
258 {
259 return module->fWASMCodeSize;
260 }
261
getWasmCHelpers(WasmModule * module)262 EXPORT const char* getWasmCHelpers(WasmModule* module)
263 {
264 return module->fJSHelpers;
265 }
266
freeWasmCModule(WasmModule * module)267 EXPORT void freeWasmCModule(WasmModule* module)
268 {
269 free((void*)module->fWASMCode);
270 free((void*)module->fJSHelpers);
271 free(module);
272 }
273
274 #ifdef __cplusplus
275 }
276 #endif
277
278 #ifdef EMCC
279
makeStringVector()280 vector<string> makeStringVector()
281 {
282 return vector<string>();
283 }
284
EMSCRIPTEN_BINDINGS(CLASS_wasm_dynamic_dsp_factory)285 EMSCRIPTEN_BINDINGS(CLASS_wasm_dynamic_dsp_factory)
286 {
287 emscripten::function("makeStringVector", &makeStringVector);
288 register_vector<string>("vector<string>");
289 class_<wasm_dynamic_dsp_factory>("wasm_dynamic_dsp_factory")
290 .constructor()
291 .class_function("createWasmDSPFactoryFromString2", &wasm_dynamic_dsp_factory::createWasmDSPFactoryFromString2,
292 allow_raw_pointers())
293 .class_function("generateWasmFromString2", &wasm_dynamic_dsp_factory::createWasmDSPFactoryFromString2,
294 allow_raw_pointers());
295 }
296
297 #endif
298