Audio plugin host https://kx.studio/carla
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.

482 lines
15KB

  1. /**
  2. * Extract Presets from realtime data
  3. */
  4. #include "../Params/PresetsStore.h"
  5. #include "../Misc/Master.h"
  6. #include "../Misc/Util.h"
  7. #include "../Misc/Allocator.h"
  8. #include "../Effects/EffectMgr.h"
  9. #include "../Synth/OscilGen.h"
  10. #include "../Synth/Resonance.h"
  11. #include "../Params/ADnoteParameters.h"
  12. #include "../Params/EnvelopeParams.h"
  13. #include "../Params/FilterParams.h"
  14. #include "../Params/LFOParams.h"
  15. #include "../Params/PADnoteParameters.h"
  16. #include "../Params/Presets.h"
  17. #include "../Params/PresetsArray.h"
  18. #include "../Params/SUBnoteParameters.h"
  19. #include "../Misc/MiddleWare.h"
  20. #include "PresetExtractor.h"
  21. #include <rtosc/ports.h>
  22. #include <rtosc/port-sugar.h>
  23. #include <string>
  24. using std::string;
  25. static void dummy(const char *, rtosc::RtData&) {}
  26. const rtosc::Ports real_preset_ports =
  27. {
  28. {"scan-for-presets:", 0, 0,
  29. [](const char *msg, rtosc::RtData &d) {
  30. MiddleWare &mw = *(MiddleWare*)d.obj;
  31. mw.getPresetsStore().scanforpresets();
  32. auto &pre = mw.getPresetsStore().presets;
  33. d.reply(d.loc, "i", pre.size());
  34. for(unsigned i=0; i<pre.size();++i)
  35. d.reply(d.loc, "isss", i,
  36. pre[i].file.c_str(),
  37. pre[i].name.c_str(),
  38. pre[i].type.c_str());
  39. }},
  40. {"copy:s:ss:si:ssi", 0, 0,
  41. [](const char *msg, rtosc::RtData &d) {
  42. MiddleWare &mw = *(MiddleWare*)d.obj;
  43. std::string args = rtosc_argument_string(msg);
  44. d.reply(d.loc, "s", "clipboard copy...");
  45. printf("\nClipboard Copy...\n");
  46. if(args == "s")
  47. presetCopy(mw, rtosc_argument(msg, 0).s, "");
  48. else if(args == "ss")
  49. presetCopy(mw, rtosc_argument(msg, 0).s,
  50. rtosc_argument(msg, 1).s);
  51. else if(args == "si")
  52. presetCopyArray(mw, rtosc_argument(msg, 0).s,
  53. rtosc_argument(msg, 1).i, "");
  54. else if(args == "ssi")
  55. presetCopyArray(mw, rtosc_argument(msg, 0).s,
  56. rtosc_argument(msg, 2).i, rtosc_argument(msg, 1).s);
  57. else
  58. assert(false && "bad arguments");
  59. }},
  60. {"paste:s:ss:si:ssi", 0, 0,
  61. [](const char *msg, rtosc::RtData &d) {
  62. MiddleWare &mw = *(MiddleWare*)d.obj;
  63. std::string args = rtosc_argument_string(msg);
  64. d.reply(d.loc, "s", "clipboard paste...");
  65. printf("\nClipboard Paste...\n");
  66. if(args == "s")
  67. presetPaste(mw, rtosc_argument(msg, 0).s, "");
  68. else if(args == "ss")
  69. presetPaste(mw, rtosc_argument(msg, 0).s,
  70. rtosc_argument(msg, 1).s);
  71. else if(args == "si")
  72. presetPasteArray(mw, rtosc_argument(msg, 0).s,
  73. rtosc_argument(msg, 1).i, "");
  74. else if(args == "ssi")
  75. presetPasteArray(mw, rtosc_argument(msg, 0).s,
  76. rtosc_argument(msg, 2).i, rtosc_argument(msg, 1).s);
  77. else
  78. assert(false && "bad arguments");
  79. }},
  80. {"clipboard-type:", 0, 0,
  81. [](const char *msg, rtosc::RtData &d) {
  82. const MiddleWare &mw = *(MiddleWare*)d.obj;
  83. d.reply(d.loc, "s", mw.getPresetsStore().clipboard.type.c_str());
  84. }},
  85. {"delete:s", 0, 0,
  86. [](const char *msg, rtosc::RtData &d) {
  87. MiddleWare &mw = *(MiddleWare*)d.obj;
  88. mw.getPresetsStore().deletepreset(rtosc_argument(msg,0).s);
  89. }},
  90. };
  91. const rtosc::Ports preset_ports
  92. {
  93. {"scan-for-presets:", rDoc("Scan For Presets"), 0, dummy},
  94. {"copy:s:ss:si:ssi", rDoc("Copy <s> URL to <s> Name/Clipboard from subfield <i>"), 0, dummy},
  95. {"paste:s:ss:si:ssi", rDoc("Paste <s> URL to <s> File-Name/Clipboard from subfield <i>"), 0, dummy},
  96. {"clipboard-type:", rDoc("Type Stored In Clipboard"), 0, dummy},
  97. {"delete:s", rDoc("Delete the given preset file"), 0, dummy},
  98. };
  99. //Relevant types to keep in mind
  100. //Effects/EffectMgr.cpp: setpresettype("Peffect");
  101. //Params/ADnoteParameters.cpp: setpresettype("Padsynth");
  102. //Params/EnvelopeParams.cpp: //setpresettype("Penvamplitude");
  103. //Params/EnvelopeParams.cpp: //setpresettype("Penvamplitude");
  104. //Params/EnvelopeParams.cpp: //setpresettype("Penvfrequency");
  105. //Params/EnvelopeParams.cpp: //setpresettype("Penvfilter");
  106. //Params/EnvelopeParams.cpp: //setpresettype("Penvbandwidth");
  107. //Params/FilterParams.cpp: //setpresettype("Pfilter");
  108. //Params/LFOParams.cpp: // setpresettype("Plfofrequency");
  109. //Params/LFOParams.cpp: // setpresettype("Plfoamplitude");
  110. //Params/LFOParams.cpp: // setpresettype("Plfofilter");
  111. //Params/PADnoteParameters.cpp: setpresettype("Ppadsynth");
  112. //Params/SUBnoteParameters.cpp: setpresettype("Psubsynth");
  113. //Synth/OscilGen.cpp: setpresettype("Poscilgen");
  114. //Synth/Resonance.cpp: setpresettype("Presonance");
  115. //Translate newer symbols to old preset types
  116. std::vector<string> translate_preset_types(std::string metatype)
  117. {
  118. std::vector<string> results;
  119. return results;
  120. }
  121. /*****************************************************************************
  122. * Implementation Methods *
  123. *****************************************************************************/
  124. class Capture:public rtosc::RtData
  125. {
  126. public:
  127. Capture(void *obj_)
  128. {
  129. matches = 0;
  130. memset(locbuf, 0, sizeof(locbuf));
  131. loc = locbuf;
  132. loc_size = sizeof(locbuf);
  133. obj = obj_;
  134. }
  135. virtual void reply(const char *path, const char *args, ...)
  136. {
  137. printf("reply(%p)(%s)(%s)...\n", msgbuf, path, args);
  138. //printf("size is %d\n", sizeof(msgbuf));
  139. va_list va;
  140. va_start(va,args);
  141. char *buffer = msgbuf;
  142. rtosc_vmessage(buffer,sizeof(msgbuf),path,args,va);
  143. va_end(va);
  144. }
  145. char msgbuf[1024];
  146. char locbuf[1024];
  147. };
  148. template <class T>
  149. T capture(Master *m, std::string url);
  150. template <>
  151. std::string capture(Master *m, std::string url)
  152. {
  153. Capture c(m);
  154. char query[1024];
  155. rtosc_message(query, 1024, url.c_str(), "");
  156. Master::ports.dispatch(query+1,c);
  157. if(rtosc_message_length(c.msgbuf, sizeof(c.msgbuf))) {
  158. if(rtosc_type(c.msgbuf, 0) == 's')
  159. return rtosc_argument(c.msgbuf,0).s;
  160. }
  161. return "";
  162. }
  163. template <>
  164. void *capture(Master *m, std::string url)
  165. {
  166. Capture c(m);
  167. char query[1024];
  168. rtosc_message(query, 1024, url.c_str(), "");
  169. Master::ports.dispatch(query+1,c);
  170. if(rtosc_message_length(c.msgbuf, sizeof(c.msgbuf))) {
  171. if(rtosc_type(c.msgbuf, 0) == 'b' &&
  172. rtosc_argument(c.msgbuf, 0).b.len == sizeof(void*))
  173. return *(void**)rtosc_argument(c.msgbuf,0).b.data;
  174. }
  175. return NULL;
  176. }
  177. template<class T>
  178. std::string doCopy(MiddleWare &mw, string url, string name)
  179. {
  180. XMLwrapper xml;
  181. mw.doReadOnlyOp([&xml, url, name, &mw](){
  182. Master *m = mw.spawnMaster();
  183. //Get the pointer
  184. T *t = (T*)capture<void*>(m, url+"self");
  185. //Extract Via mxml
  186. //t->add2XML(&xml);
  187. t->copy(mw.getPresetsStore(), name.empty()? NULL:name.c_str());
  188. });
  189. return "";//xml.getXMLdata();
  190. }
  191. template<class T, typename... Ts>
  192. void doPaste(MiddleWare &mw, string url, string type, XMLwrapper &xml, Ts&&... args)
  193. {
  194. //Generate a new object
  195. T *t = new T(std::forward<Ts>(args)...);
  196. if(xml.enterbranch(type) == 0)
  197. return;
  198. t->getfromXML(&xml);
  199. //Send the pointer
  200. string path = url+"paste";
  201. char buffer[1024];
  202. rtosc_message(buffer, 1024, path.c_str(), "b", sizeof(void*), &t);
  203. if(!Master::ports.apropos(path.c_str()))
  204. fprintf(stderr, "Warning: Missing Paste URL: '%s'\n", path.c_str());
  205. printf("Sending info to '%s'\n", buffer);
  206. mw.transmitMsg(buffer);
  207. //Let the pointer be reclaimed later
  208. }
  209. template<class T>
  210. std::string doArrayCopy(MiddleWare &mw, int field, string url, string name)
  211. {
  212. XMLwrapper xml;
  213. printf("Getting info from '%s'<%d>\n", url.c_str(), field);
  214. mw.doReadOnlyOp([&xml, url, field, name, &mw](){
  215. Master *m = mw.spawnMaster();
  216. //Get the pointer
  217. T *t = (T*)capture<void*>(m, url+"self");
  218. //Extract Via mxml
  219. t->copy(mw.getPresetsStore(), field, name.empty()?NULL:name.c_str());
  220. });
  221. return "";//xml.getXMLdata();
  222. }
  223. template<class T, typename... Ts>
  224. void doArrayPaste(MiddleWare &mw, int field, string url, string type,
  225. XMLwrapper &xml, Ts&&... args)
  226. {
  227. //Generate a new object
  228. T *t = new T(std::forward<Ts>(args)...);
  229. if(xml.enterbranch(type+"n") == 0) {
  230. delete t;
  231. return;
  232. }
  233. t->defaults(field);
  234. t->getfromXMLsection(&xml, field);
  235. xml.exitbranch();
  236. //Send the pointer
  237. string path = url+"paste-array";
  238. char buffer[1024];
  239. rtosc_message(buffer, 1024, path.c_str(), "bi", sizeof(void*), &t, field);
  240. if(!Master::ports.apropos(path.c_str()))
  241. fprintf(stderr, "Warning: Missing Paste URL: '%s'\n", path.c_str());
  242. printf("Sending info to '%s'<%d>\n", buffer, field);
  243. mw.transmitMsg(buffer);
  244. //Let the pointer be reclaimed later
  245. }
  246. /*
  247. * Dispatch to class specific operators
  248. *
  249. * Oscilgen and PADnoteParameters have mixed RT/non-RT parameters and require
  250. * extra handling.
  251. * See MiddleWare.cpp for these specifics
  252. */
  253. void doClassPaste(std::string type, std::string type_, MiddleWare &mw, string url, XMLwrapper &data)
  254. {
  255. printf("Class Paste\n");
  256. if(type == "EnvelopeParams")
  257. doPaste<EnvelopeParams>(mw, url, type_, data);
  258. else if(type == "LFOParams")
  259. doPaste<LFOParams>(mw, url, type_, data);
  260. else if(type == "FilterParams")
  261. doPaste<FilterParams>(mw, url, type_, data);
  262. else if(type == "ADnoteParameters")
  263. doPaste<ADnoteParameters>(mw, url, type_, data, mw.getSynth(), (FFTwrapper*)NULL);
  264. else if(type == "PADnoteParameters")
  265. doPaste<PADnoteParameters>(mw, url, type_, data, mw.getSynth(), (FFTwrapper*)NULL);
  266. else if(type == "SUBnoteParameters")
  267. doPaste<SUBnoteParameters>(mw, url, type_, data);
  268. else if(type == "OscilGen")
  269. doPaste<OscilGen>(mw, url, type_, data, mw.getSynth(), (FFTwrapper*)NULL, (Resonance*)NULL);
  270. else if(type == "Resonance")
  271. doPaste<Resonance>(mw, url, type_, data);
  272. else if(type == "EffectMgr")
  273. doPaste<EffectMgr>(mw, url, type_, data, DummyAlloc, mw.getSynth(), false);
  274. else {
  275. fprintf(stderr, "Warning: Unknown type<%s> from url<%s>\n", type.c_str(), url.c_str());
  276. }
  277. }
  278. std::string doClassCopy(std::string type, MiddleWare &mw, string url, string name)
  279. {
  280. if(type == "EnvelopeParams")
  281. return doCopy<EnvelopeParams>(mw, url, name);
  282. else if(type == "LFOParams")
  283. return doCopy<LFOParams>(mw, url, name);
  284. else if(type == "FilterParams")
  285. return doCopy<FilterParams>(mw, url, name);
  286. else if(type == "ADnoteParameters")
  287. return doCopy<ADnoteParameters>(mw, url, name);
  288. else if(type == "PADnoteParameters")
  289. return doCopy<PADnoteParameters>(mw, url, name);
  290. else if(type == "SUBnoteParameters")
  291. return doCopy<SUBnoteParameters>(mw, url, name);
  292. else if(type == "OscilGen")
  293. return doCopy<OscilGen>(mw, url, name);
  294. else if(type == "Resonance")
  295. return doCopy<Resonance>(mw, url, name);
  296. else if(type == "EffectMgr")
  297. doCopy<EffectMgr>(mw, url, name);
  298. return "UNDEF";
  299. }
  300. void doClassArrayPaste(std::string type, std::string type_, int field, MiddleWare &mw, string url,
  301. XMLwrapper &data)
  302. {
  303. if(type == "FilterParams")
  304. doArrayPaste<FilterParams>(mw, field, url, type_, data);
  305. else if(type == "ADnoteParameters")
  306. doArrayPaste<ADnoteParameters>(mw, field, url, type_, data, mw.getSynth(), (FFTwrapper*)NULL);
  307. }
  308. std::string doClassArrayCopy(std::string type, int field, MiddleWare &mw, string url, string name)
  309. {
  310. if(type == "FilterParams")
  311. return doArrayCopy<FilterParams>(mw, field, url, name);
  312. else if(type == "ADnoteParameters")
  313. return doArrayCopy<ADnoteParameters>(mw, field, url, name);
  314. return "UNDEF";
  315. }
  316. //This is an abuse of the readonly op, but one that might look reasonable from a
  317. //user perspective...
  318. std::string getUrlPresetType(std::string url, MiddleWare &mw)
  319. {
  320. std::string result;
  321. mw.doReadOnlyOp([url, &result, &mw](){
  322. Master *m = mw.spawnMaster();
  323. //Get the pointer
  324. result = capture<std::string>(m, url+"preset-type");
  325. });
  326. printf("preset type = %s\n", result.c_str());
  327. return result;
  328. }
  329. std::string getUrlType(std::string url)
  330. {
  331. assert(!url.empty());
  332. printf("Searching for '%s'\n", (url+"self").c_str());
  333. auto self = Master::ports.apropos((url+"self").c_str());
  334. if(!self)
  335. fprintf(stderr, "Warning: URL Metadata Not Found For '%s'\n", url.c_str());
  336. if(self)
  337. return self->meta()["class"];
  338. else
  339. return "";
  340. }
  341. /*****************************************************************************
  342. * API Stubs *
  343. *****************************************************************************/
  344. #if 0
  345. Clipboard clipboardCopy(MiddleWare &mw, string url)
  346. {
  347. //Identify The Self Type of the Object
  348. string type = getUrlType(url);
  349. printf("Copying a '%s' object", type.c_str());
  350. //Copy The Object
  351. string data = doClassCopy(type, mw, url);
  352. printf("Object Information '%s'\n", data.c_str());
  353. return {type, data};
  354. }
  355. void clipBoardPaste(const char *url, Clipboard clip)
  356. {
  357. (void) url;
  358. (void) clip;
  359. }
  360. #endif
  361. void presetCopy(MiddleWare &mw, std::string url, std::string name)
  362. {
  363. (void) name;
  364. doClassCopy(getUrlType(url), mw, url, name);
  365. printf("PresetCopy()\n");
  366. }
  367. void presetPaste(MiddleWare &mw, std::string url, std::string name)
  368. {
  369. (void) name;
  370. printf("PresetPaste()\n");
  371. string data = "";
  372. XMLwrapper xml;
  373. if(name.empty()) {
  374. data = mw.getPresetsStore().clipboard.data;
  375. if(data.length() < 20)
  376. return;
  377. if(!xml.putXMLdata(data.c_str()))
  378. return;
  379. } else {
  380. if(xml.loadXMLfile(name))
  381. return;
  382. }
  383. doClassPaste(getUrlType(url), getUrlPresetType(url, mw), mw, url, xml);
  384. }
  385. void presetCopyArray(MiddleWare &mw, std::string url, int field, std::string name)
  386. {
  387. (void) name;
  388. printf("PresetArrayCopy()\n");
  389. doClassArrayCopy(getUrlType(url), field, mw, url, name);
  390. }
  391. void presetPasteArray(MiddleWare &mw, std::string url, int field, std::string name)
  392. {
  393. (void) name;
  394. printf("PresetArrayPaste()\n");
  395. string data = "";
  396. XMLwrapper xml;
  397. if(name.empty()) {
  398. data = mw.getPresetsStore().clipboard.data;
  399. if(data.length() < 20)
  400. return;
  401. if(!xml.putXMLdata(data.c_str()))
  402. return;
  403. } else {
  404. if(xml.loadXMLfile(name))
  405. return;
  406. }
  407. printf("Performing Paste...\n");
  408. doClassArrayPaste(getUrlType(url), getUrlPresetType(url, mw), field, mw, url, xml);
  409. }
  410. #if 0
  411. void presetPaste(std::string url, int)
  412. {
  413. printf("PresetPaste()\n");
  414. doClassPaste(getUrlType(url), *middlewarepointer, url, presetsstore.clipboard.data);
  415. }
  416. #endif
  417. void presetDelete(int)
  418. {
  419. printf("PresetDelete()\n");
  420. }
  421. void presetRescan()
  422. {
  423. printf("PresetRescan()\n");
  424. }
  425. std::string presetClipboardType()
  426. {
  427. printf("PresetClipboardType()\n");
  428. return "dummy";
  429. }
  430. bool presetCheckClipboardType()
  431. {
  432. printf("PresetCheckClipboardType()\n");
  433. return true;
  434. }