/** * Extract Presets from realtime data */ #include "../Params/PresetsStore.h" #include "../Misc/Master.h" #include "../Misc/Util.h" #include "../Misc/Allocator.h" #include "../Effects/EffectMgr.h" #include "../Synth/OscilGen.h" #include "../Synth/Resonance.h" #include "../Params/ADnoteParameters.h" #include "../Params/EnvelopeParams.h" #include "../Params/FilterParams.h" #include "../Params/LFOParams.h" #include "../Params/PADnoteParameters.h" #include "../Params/Presets.h" #include "../Params/PresetsArray.h" #include "../Params/SUBnoteParameters.h" #include "../Misc/MiddleWare.h" #include "PresetExtractor.h" #include #include #include using std::string; static void dummy(const char *, rtosc::RtData&) {} const rtosc::Ports real_preset_ports = { {"scan-for-presets:", 0, 0, [](const char *, rtosc::RtData &d) { MiddleWare &mw = *(MiddleWare*)d.obj; assert(d.obj); mw.getPresetsStore().scanforpresets(); auto &pre = mw.getPresetsStore().presets; d.reply(d.loc, "i", pre.size()); for(unsigned i=0; i T capture(Master *m, std::string url); template <> std::string capture(Master *m, std::string url) { Capture c(m); char query[1024]; rtosc_message(query, 1024, url.c_str(), ""); Master::ports.dispatch(query+1,c); if(rtosc_message_length(c.msgbuf, sizeof(c.msgbuf))) { if(rtosc_type(c.msgbuf, 0) == 's') return rtosc_argument(c.msgbuf,0).s; } return ""; } template <> void *capture(Master *m, std::string url) { Capture c(m); char query[1024]; rtosc_message(query, 1024, url.c_str(), ""); Master::ports.dispatch(query+1,c); if(rtosc_message_length(c.msgbuf, sizeof(c.msgbuf))) { if(rtosc_type(c.msgbuf, 0) == 'b' && rtosc_argument(c.msgbuf, 0).b.len == sizeof(void*)) return *(void**)rtosc_argument(c.msgbuf,0).b.data; } return NULL; } template std::string doCopy(MiddleWare &mw, string url, string name) { XMLwrapper xml; mw.doReadOnlyOp([&xml, url, name, &mw](){ Master *m = mw.spawnMaster(); //Get the pointer //printf("capture at <%s>\n", (url+"self").c_str()); T *t = (T*)capture(m, url+"self"); assert(t); //Extract Via mxml //t->add2XML(&xml); t->copy(mw.getPresetsStore(), name.empty()? NULL:name.c_str()); }); return "";//xml.getXMLdata(); } template void doPaste(MiddleWare &mw, string url, string type, XMLwrapper &xml, Ts&&... args) { //Generate a new object T *t = new T(std::forward(args)...); //Old workaround for LFO parameters if(strstr(type.c_str(), "Plfo")) type = "Plfo"; if(xml.enterbranch(type) == 0) return; t->getfromXML(xml); //Send the pointer string path = url+"paste"; char buffer[1024]; rtosc_message(buffer, 1024, path.c_str(), "b", sizeof(void*), &t); if(!Master::ports.apropos(path.c_str())) fprintf(stderr, "Warning: Missing Paste URL: '%s'\n", path.c_str()); //printf("Sending info to '%s'\n", buffer); mw.transmitMsg(buffer); //Let the pointer be reclaimed later } template std::string doArrayCopy(MiddleWare &mw, int field, string url, string name) { XMLwrapper xml; //printf("Getting info from '%s'<%d>\n", url.c_str(), field); mw.doReadOnlyOp([&xml, url, field, name, &mw](){ Master *m = mw.spawnMaster(); //Get the pointer T *t = (T*)capture(m, url+"self"); //Extract Via mxml t->copy(mw.getPresetsStore(), field, name.empty()?NULL:name.c_str()); }); return "";//xml.getXMLdata(); } template void doArrayPaste(MiddleWare &mw, int field, string url, string type, XMLwrapper &xml, Ts&&... args) { //Generate a new object T *t = new T(std::forward(args)...); if(xml.enterbranch(type+"n") == 0) { delete t; return; } t->defaults(field); t->getfromXMLsection(xml, field); xml.exitbranch(); //Send the pointer string path = url+"paste-array"; char buffer[1024]; rtosc_message(buffer, 1024, path.c_str(), "bi", sizeof(void*), &t, field); if(!Master::ports.apropos(path.c_str())) fprintf(stderr, "Warning: Missing Paste URL: '%s'\n", path.c_str()); //printf("Sending info to '%s'<%d>\n", buffer, field); mw.transmitMsg(buffer); //Let the pointer be reclaimed later } /* * Dispatch to class specific operators * * Oscilgen and PADnoteParameters have mixed RT/non-RT parameters and require * extra handling. * See MiddleWare.cpp for these specifics */ void doClassPaste(std::string type, std::string type_, MiddleWare &mw, string url, XMLwrapper &data) { //printf("Class Paste\n"); if(type == "EnvelopeParams") doPaste(mw, url, type_, data); else if(type == "LFOParams") doPaste(mw, url, type_, data); else if(type == "FilterParams") doPaste(mw, url, type_, data); else if(type == "ADnoteParameters") doPaste(mw, url, type_, data, mw.getSynth(), (FFTwrapper*)NULL); else if(type == "PADnoteParameters") doPaste(mw, url, type_, data, mw.getSynth(), (FFTwrapper*)NULL); else if(type == "SUBnoteParameters") doPaste(mw, url, type_, data); else if(type == "OscilGen") doPaste(mw, url, type_, data, mw.getSynth(), (FFTwrapper*)NULL, (Resonance*)NULL); else if(type == "Resonance") doPaste(mw, url, type_, data); else if(type == "EffectMgr") doPaste(mw, url, type_, data, DummyAlloc, mw.getSynth(), false); else { fprintf(stderr, "Warning: Unknown type<%s> from url<%s>\n", type.c_str(), url.c_str()); } } std::string doClassCopy(std::string type, MiddleWare &mw, string url, string name) { //printf("doClassCopy(%p)\n", mw.spawnMaster()->uToB); if(type == "EnvelopeParams") return doCopy(mw, url, name); else if(type == "LFOParams") return doCopy(mw, url, name); else if(type == "FilterParams") return doCopy(mw, url, name); else if(type == "ADnoteParameters") return doCopy(mw, url, name); else if(type == "PADnoteParameters") return doCopy(mw, url, name); else if(type == "SUBnoteParameters") return doCopy(mw, url, name); else if(type == "OscilGen") return doCopy(mw, url, name); else if(type == "Resonance") return doCopy(mw, url, name); else if(type == "EffectMgr") doCopy(mw, url, name); return "UNDEF"; } void doClassArrayPaste(std::string type, std::string type_, int field, MiddleWare &mw, string url, XMLwrapper &data) { if(type == "FilterParams") doArrayPaste(mw, field, url, type_, data); else if(type == "ADnoteParameters") doArrayPaste(mw, field, url, type_, data, mw.getSynth(), (FFTwrapper*)NULL); } std::string doClassArrayCopy(std::string type, int field, MiddleWare &mw, string url, string name) { if(type == "FilterParams") return doArrayCopy(mw, field, url, name); else if(type == "ADnoteParameters") return doArrayCopy(mw, field, url, name); return "UNDEF"; } //This is an abuse of the readonly op, but one that might look reasonable from a //user perspective... std::string getUrlPresetType(std::string url, MiddleWare &mw) { std::string result; mw.doReadOnlyOp([url, &result, &mw](){ Master *m = mw.spawnMaster(); //Get the pointer result = capture(m, url+"preset-type"); }); //printf("preset type = %s\n", result.c_str()); return result; } std::string getUrlType(std::string url) { assert(!url.empty()); //printf("Searching for '%s'\n", (url+"self").c_str()); auto self = Master::ports.apropos((url+"self").c_str()); if(!self) fprintf(stderr, "Warning: URL Metadata Not Found For '%s'\n", url.c_str()); if(self) return self->meta()["class"]; else return ""; } /***************************************************************************** * API Stubs * *****************************************************************************/ #if 0 Clipboard clipboardCopy(MiddleWare &mw, string url) { //Identify The Self Type of the Object string type = getUrlType(url); printf("Copying a '%s' object", type.c_str()); //Copy The Object string data = doClassCopy(type, mw, url); printf("Object Information '%s'\n", data.c_str()); return {type, data}; } void clipBoardPaste(const char *url, Clipboard clip) { (void) url; (void) clip; } #endif void presetCopy(MiddleWare &mw, std::string url, std::string name) { (void) name; doClassCopy(getUrlType(url), mw, url, name); //printf("PresetCopy()\n"); } void presetPaste(MiddleWare &mw, std::string url, std::string name) { (void) name; //printf("PresetPaste()\n"); string data = ""; XMLwrapper xml; if(name.empty()) { data = mw.getPresetsStore().clipboard.data; if(data.length() < 20) return; if(!xml.putXMLdata(data.c_str())) return; } else { if(xml.loadXMLfile(name)) return; } doClassPaste(getUrlType(url), getUrlPresetType(url, mw), mw, url, xml); } void presetCopyArray(MiddleWare &mw, std::string url, int field, std::string name) { (void) name; //printf("PresetArrayCopy()\n"); doClassArrayCopy(getUrlType(url), field, mw, url, name); } void presetPasteArray(MiddleWare &mw, std::string url, int field, std::string name) { (void) name; //printf("PresetArrayPaste()\n"); string data = ""; XMLwrapper xml; if(name.empty()) { data = mw.getPresetsStore().clipboard.data; if(data.length() < 20) return; if(!xml.putXMLdata(data.c_str())) return; } else { if(xml.loadXMLfile(name)) return; } //printf("Performing Paste...\n"); doClassArrayPaste(getUrlType(url), getUrlPresetType(url, mw), field, mw, url, xml); } #if 0 void presetPaste(std::string url, int) { printf("PresetPaste()\n"); doClassPaste(getUrlType(url), *middlewarepointer, url, presetsstore.clipboard.data); } #endif void presetDelete(int) { printf("PresetDelete()\n"); } void presetRescan() { printf("PresetRescan()\n"); } std::string presetClipboardType() { printf("PresetClipboardType()\n"); return "dummy"; } bool presetCheckClipboardType() { printf("PresetCheckClipboardType()\n"); return true; }