zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

commit 6ef10803b04aa1e3c4745630845fa51913f9f522
parent a40a1cd827d51aa3eee61b1111c114b9ee17efab
Author: fundamental <mark.d.mccurry@gmail.com>
Date:   Wed,  6 May 2015 18:17:15 -0400

Get Copy/Paste Generally Working

Get Backend/OSC layer Copy/Paste with clipboard only functional

Diffstat:
Msrc/Misc/Master.cpp | 5+++++
Msrc/Misc/MiddleWare.cpp | 13+++++++++++--
Msrc/Misc/PresetExtractor.cpp | 245++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Msrc/Misc/PresetExtractor.h | 8++++----
Msrc/Misc/Util.h | 6++----
Msrc/Params/ADnoteParameters.h | 7+++----
Msrc/Params/EnvelopeParams.cpp | 1-
Msrc/Params/FilterParams.cpp | 1-
Msrc/Params/FilterParams.h | 4+++-
Msrc/Params/LFOParams.cpp | 1-
Msrc/Params/PresetsArray.cpp | 13+++++--------
Msrc/Params/PresetsArray.h | 4++--
Msrc/Params/PresetsStore.h | 1-
Msrc/UI/Connection.cpp | 8++++++--
Msrc/main.cpp | 1-
15 files changed, 216 insertions(+), 102 deletions(-)

diff --git a/src/Misc/Master.cpp b/src/Misc/Master.cpp @@ -213,6 +213,11 @@ static const Ports master_ports = { //Master &m = *(Master*)d.obj; d.reply("/samplerate", "f", synth->samplerate_f); }}, + {"oscilsize:", rDoc("Synthesizer Global Oscillator Size"), 0, [](const char *, RtData &d) { + //Master &m = *(Master*)d.obj; + d.reply("/oscilsize", "f", synth->oscilsize_f); + d.reply("/oscilsize", "i", synth->oscilsize); + }}, {"undo_pause",0,0,[](const char *, rtosc::RtData &d) {d.reply("/undo_pause", "");}}, {"undo_resume",0,0,[](const char *, rtosc::RtData &d) diff --git a/src/Misc/MiddleWare.cpp b/src/Misc/MiddleWare.cpp @@ -130,7 +130,7 @@ static int handler_function(const char *path, const char *types, lo_arg **argv, lo_message_serialise(msg, path, buffer, &size); if(!strcmp(buffer, "/path-search") && !strcmp("ss", rtosc_argument_string(buffer))) { path_search(buffer, mw->activeUrl().c_str()); - } else if(buffer[0]=='/') + } else if(buffer[0]=='/' && rindex(buffer, '/')[1]) mw->transmitMsg(buffer); return 0; @@ -421,6 +421,7 @@ struct ParamStore class MiddleWareImpl { static constexpr const char* tmp_nam_prefix = "/tmp/zynaddsubfx_"; + MiddleWare *parent; //! returns file name to where UDP port is saved std::string get_tmp_nam() const @@ -709,13 +710,20 @@ public: { char buffer[1024]; memset(buffer, 0, sizeof(buffer)); - DummyDataObj d(buffer, 1024, (void*)&presetsstore, this, uToB); + DummyDataObj d(buffer, 1024, (void*)parent, this, uToB); strcpy(buffer, "/presets/"); //012345678 ///presets/ real_preset_ports.dispatch(msg+9, d); printf("Something <%s>\n", msg+9); + if(strstr(msg, "paste") && rtosc_argument_string(msg)[0] == 's') { + char buffer[1024]; + rtosc_message(buffer, 1024, "/damage", "s", + rtosc_argument(msg, 0).s); + GUI::raiseUi(ui, buffer); + } + if(!d.matches) { fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 1, 7 + 30, 0 + 40); @@ -794,6 +802,7 @@ public: }; MiddleWareImpl::MiddleWareImpl(MiddleWare *mw, int prefered_port) + :parent(mw) { bToU = new rtosc::ThreadLink(4096*2,1024); uToB = new rtosc::ThreadLink(4096*2,1024); diff --git a/src/Misc/PresetExtractor.cpp b/src/Misc/PresetExtractor.cpp @@ -41,48 +41,60 @@ const rtosc::Ports real_preset_ports = pre[i].type.c_str()); }}, - {"copy:s", 0, 0, + {"copy:s:ss:si:ssi", 0, 0, [](const char *msg, rtosc::RtData &d) { - presetCopy(rtosc_argument(msg, 0).s, ""); + MiddleWare &mw = *(MiddleWare*)d.obj; + std::string args = rtosc_argument_string(msg); d.reply(d.loc, "s", "clipboard copy..."); + printf("\nClipboard Copy...\n"); + if(args == "s") + presetCopy(mw, rtosc_argument(msg, 0).s, ""); + else if(args == "ss") + presetCopy(mw, rtosc_argument(msg, 0).s, + rtosc_argument(msg, 1).s); + else if(args == "si") + presetCopyArray(mw, rtosc_argument(msg, 0).s, + rtosc_argument(msg, 1).i, ""); + else if(args == "ssi") + presetCopyArray(mw, rtosc_argument(msg, 0).s, + rtosc_argument(msg, 2).i, rtosc_argument(msg, 1).s); + else + assert(false && "bad arguments"); }}, - {"paste:s", 0, 0, + {"paste:s:ss:si:ssi", 0, 0, [](const char *msg, rtosc::RtData &d) { - presetPaste(rtosc_argument(msg, 0).s, ""); + MiddleWare &mw = *(MiddleWare*)d.obj; + std::string args = rtosc_argument_string(msg); d.reply(d.loc, "s", "clipboard paste..."); + printf("\nClipboard Paste...\n"); + if(args == "s") + presetPaste(mw, rtosc_argument(msg, 0).s, ""); + else if(args == "ss") + presetPaste(mw, rtosc_argument(msg, 0).s, + rtosc_argument(msg, 1).s); + else if(args == "si") + presetPasteArray(mw, rtosc_argument(msg, 0).s, + rtosc_argument(msg, 1).i, ""); + else if(args == "ssi") + presetPasteArray(mw, rtosc_argument(msg, 0).s, + rtosc_argument(msg, 2).i, rtosc_argument(msg, 1).s); + else + assert(false && "bad arguments"); }}, + {"clipboard-type:", 0, 0, + [](const char *msg, rtosc::RtData &d) { + d.reply(d.loc, "s", presetsstore.clipboard.type.c_str()); + }}, + }; const rtosc::Ports preset_ports { {"scan-for-presets:", rDoc("Scan For Presets"), 0, dummy}, - {"copy:s", rDoc("Copy URL To Clipboard"), 0, dummy}, - {"paste:s", rDoc("Copy URL To Clipboard"), 0, dummy}, - {"add-preset:ss", rDoc("Add a preset <1> with associated name <2>"), 0, - [](const char *msg, rtosc::RtData &d) { - d.reply("/alert", "s", "Preset Could Not Be added..."); - }}, - {"delete-preset:s", rDoc("Add a preset <1> with associated name <2>"), 0, - [](const char *msg, rtosc::RtData &d) { - d.reply("/alert", "s", "Preset Could Not Be added..."); - }}, - {"clipboard-type:", rDoc("Current Preset Type In the Clipboard"), 0, - [](const char *msg, rtosc::RtData &d) { - d.reply("/alert", "s", "Unknown clipboard type..."); - }}, - {"clipboard-value:", rDoc("Current Value In the Clipboard"), 0, - [](const char *msg, rtosc::RtData &d) { - d.reply("/alert", "s", "Unknown clipboard type..."); - }}, - {"apply-preset:ss", rDoc("Apply preset file or 'clipboard' to the given OSC path"), 0, - [](const char *msg, rtosc::RtData &d) { - d.reply("/alert", "s", "Mismatched Clipboard Type..."); - }}, - {"set-clipboard:ss", rDoc("Set the current data in the clipboard"), 0, - [](const char *msg, rtosc::RtData &d) { - d.reply("/alert", "s", "Clipboard is unusable..."); - }}, + {"copy:s:ss:si:ssi", rDoc("Copy <s> URL to <s> Name/Clipboard from subfield <i>"), 0, dummy}, + {"paste:s:ss:si:ssi", rDoc("Paste <s> URL to <s> Name/Clipboard from subfield <i>"), 0, dummy}, + {"clipboard-type:", rDoc("Type Stored In Clipboard"), 0, dummy} }; //Relevant types to keep in mind @@ -114,8 +126,6 @@ std::vector<string> translate_preset_types(std::string metatype) /***************************************************************************** * Implementation Methods * *****************************************************************************/ -static string clip; - class Capture:public rtosc::RtData { public: @@ -146,6 +156,21 @@ template <class T> 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); @@ -178,16 +203,20 @@ std::string doCopy(MiddleWare &mw, string url) } template<class T, typename... Ts> -void doPaste(MiddleWare &mw, string url, string data, Ts&&... args) +void doPaste(MiddleWare &mw, string url, string type, string data, Ts&&... args) { - (void) data; - if(clip.length() < 20) + printf("Do Paste<%d>\n", data.size()); + if(data.length() < 20) return; //Generate a new object T *t = new T(std::forward<Ts>(args)...); XMLwrapper xml; - xml.putXMLdata(clip.data()); + xml.putXMLdata(data.data()); + + if(xml.enterbranch(type) == 0) + return; + t->getfromXML(&xml); //Send the pointer @@ -202,6 +231,52 @@ void doPaste(MiddleWare &mw, string url, string data, Ts&&... args) //Let the pointer be reclaimed later } +template<class T> +std::string doArrayCopy(MiddleWare &mw, int field, string url) +{ + XMLwrapper xml; + mw.doReadOnlyOp([&xml, url, field, &mw](){ + Master *m = mw.spawnMaster(); + //Get the pointer + T *t = (T*)capture<void*>(m, url+"self"); + //Extract Via mxml + t->copy(presetsstore, field, NULL); + }); + + return "";//xml.getXMLdata(); +} + +template<class T, typename... Ts> +void doArrayPaste(MiddleWare &mw, int field, string url, string type, string data, Ts&&... args) +{ + if(data.length() < 20) + return; + + //Generate a new object + T *t = new T(std::forward<Ts>(args)...); + + XMLwrapper xml; + xml.putXMLdata(data.c_str()); + if(xml.enterbranch(type) == 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'\n", buffer); + mw.transmitMsg(buffer); + + //Let the pointer be reclaimed later +} + /* * Dispatch to class specific operators * @@ -209,26 +284,30 @@ void doPaste(MiddleWare &mw, string url, string data, Ts&&... args) * extra handling. * See MiddleWare.cpp for these specifics */ -void doClassPaste(std::string type, MiddleWare &mw, string url, string data) +void doClassPaste(std::string type, std::string type_, MiddleWare &mw, string url, string data) { + printf("Class Paste\n"); if(type == "EnvelopeParams") - doPaste<EnvelopeParams>(mw, url, data); + doPaste<EnvelopeParams>(mw, url, type_, data); else if(type == "LFOParams") - doPaste<LFOParams>(mw, url, data); + doPaste<LFOParams>(mw, url, type_, data); else if(type == "FilterParams") - doPaste<FilterParams>(mw, url, data); + doPaste<FilterParams>(mw, url, type_, data); else if(type == "ADnoteParameters") - doPaste<ADnoteParameters>(mw, url, data, (FFTwrapper*)NULL); + doPaste<ADnoteParameters>(mw, url, type_, data, (FFTwrapper*)NULL); else if(type == "PADnoteParameters") - doPaste<PADnoteParameters>(mw, url, data, (FFTwrapper*)NULL); + doPaste<PADnoteParameters>(mw, url, type_, data, (FFTwrapper*)NULL); else if(type == "SUBnoteParameters") - doPaste<SUBnoteParameters>(mw, url, data); + doPaste<SUBnoteParameters>(mw, url, type_, data); else if(type == "OscilGen") - doPaste<OscilGen>(mw, url, data, (FFTwrapper*)NULL, (Resonance*)NULL); + doPaste<OscilGen>(mw, url, type_, data, (FFTwrapper*)NULL, (Resonance*)NULL); else if(type == "Resonance") - doPaste<Resonance>(mw, url, data); + doPaste<Resonance>(mw, url, type_, data); else if(type == "EffectMgr") - doPaste<EffectMgr>(mw, url, data, DummyAlloc, false); + doPaste<EffectMgr>(mw, url, type_, data, DummyAlloc, 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) @@ -254,6 +333,37 @@ std::string doClassCopy(std::string type, MiddleWare &mw, string url) return "UNDEF"; } +void doClassArrayPaste(std::string type, std::string type_, int field, MiddleWare &mw, string url, string data) +{ + if(type == "FilterParams") + doArrayPaste<FilterParams>(mw, field, url, type_, data); + else if(type == "ADnoteParameters") + doArrayPaste<ADnoteParameters>(mw, field, url, type_, data, (FFTwrapper*)NULL); +} + +std::string doClassArrayCopy(std::string type, int field, MiddleWare &mw, string url) +{ + if(type == "FilterParams") + return doArrayCopy<FilterParams>(mw, field, url); + else if(type == "ADnoteParameters") + return doArrayCopy<ADnoteParameters>(mw, field, url); + 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<std::string>(m, url+"preset-type"); + }); + printf("preset type = %s\n", result.c_str()); + return result; +} + std::string getUrlType(std::string url) { assert(!url.empty()); @@ -268,23 +378,6 @@ std::string getUrlType(std::string url) return ""; } -void doClassArrayPaste(std::string type, MiddleWare &mw, string url, string data, int idx) -{ - if(type == "ADnoteVoiceParam") - ; - else if(type == "FilterParams") - ; -} - -std::string doClassArrayCopy(std::string type, MiddleWare &mw, string url, int idx) -{ - if(type == "ADnoteVoiceParam") - return "UNDEF"; - else if(type == "FilterParams") - return "UNDEF"; - return "UNDEF"; -} - /***************************************************************************** * API Stubs * @@ -309,25 +402,37 @@ void clipBoardPaste(const char *url, Clipboard clip) (void) clip; } -MiddleWare *middlewarepointer; -void presetCopy(std::string url, std::string name) +void presetCopy(MiddleWare &mw, std::string url, std::string name) { (void) name; - clip = doClassCopy(getUrlType(url), *middlewarepointer, url); + doClassCopy(getUrlType(url), mw, url); printf("PresetCopy()\n"); - printf("clip = ``%s''\n", clip.c_str()); } -void presetPaste(std::string url, std::string name) +void presetPaste(MiddleWare &mw, std::string url, std::string name) { (void) name; - doClassPaste(getUrlType(url), *middlewarepointer, url, clip); printf("PresetPaste()\n"); + doClassPaste(getUrlType(url), getUrlPresetType(url, mw), mw, url, presetsstore.clipboard.data); +} +void presetCopyArray(MiddleWare &mw, std::string url, int field, std::string name) +{ + (void) name; + printf("PresetArrayCopy()\n"); + doClassArrayCopy(getUrlType(url), field, mw, url); +} +void presetPasteArray(MiddleWare &mw, std::string url, int field, std::string name) +{ + (void) name; + printf("PresetArrayPaste()\n"); + doClassArrayPaste(getUrlType(url), getUrlPresetType(url, mw), field, mw, url, presetsstore.clipboard.data); } +#if 0 void presetPaste(std::string url, int) { - doClassPaste(getUrlType(url), *middlewarepointer, url, clip); printf("PresetPaste()\n"); + doClassPaste(getUrlType(url), *middlewarepointer, url, presetsstore.clipboard.data); } +#endif void presetDelete(int) { printf("PresetDelete()\n"); diff --git a/src/Misc/PresetExtractor.h b/src/Misc/PresetExtractor.h @@ -11,12 +11,12 @@ struct Clipboard { Clipboard clipboardCopy(class MiddleWare &mw, std::string url); -void presetCopy(std::string url, std::string name); -void presetPaste(std::string url, std::string name); +void presetCopy(MiddleWare &mw, std::string url, std::string name); +void presetPaste(MiddleWare &mw, std::string url, std::string name); +void presetCopyArray(MiddleWare &mw, std::string url, int field, std::string name); +void presetPasteArray(MiddleWare &mw, std::string url, int field, std::string name); void presetPaste(std::string url, int); void presetDelete(int); void presetRescan(); std::string presetClipboardType(); bool presetCheckClipboardType(); - -extern MiddleWare *middlewarepointer; diff --git a/src/Misc/Util.h b/src/Misc/Util.h @@ -164,13 +164,11 @@ static inline void arrayNullify(T &t) {delete [] t; t = NULL; } [](const char *, rtosc::RtData &d){ \ d.reply(d.loc, "b", sizeof(d.obj), &d.obj);}}\ -#define rPresetType \ +#define rPaste \ {"preset-type", rProp(internal), 0, \ [](const char *, rtosc::RtData &d){ \ rObject *obj = (rObject*)d.obj; \ - d.reply(d.loc, "s", obj->type);}} - -#define rPaste \ + d.reply(d.loc, "s", obj->type);}},\ {"paste:b", rProp(internal) rDoc("paste port"), 0, \ [](const char *m, rtosc::RtData &d){ \ printf("rPaste...\n"); \ diff --git a/src/Params/ADnoteParameters.h b/src/Params/ADnoteParameters.h @@ -308,15 +308,14 @@ class ADnoteParameters:public PresetsArray int get_unison_size_index(int nvoice) const; void set_unison_size_index(int nvoice, int index); static const rtosc::Ports &ports; - private: void defaults(int n); //n is the nvoice + void add2XMLsection(XMLwrapper *xml, int n); + void getfromXMLsection(XMLwrapper *xml, int n); + private: void EnableVoice(int nvoice); void KillVoice(int nvoice); FFTwrapper *fft; - - void add2XMLsection(XMLwrapper *xml, int n); - void getfromXMLsection(XMLwrapper *xml, int n); }; #endif diff --git a/src/Params/EnvelopeParams.cpp b/src/Params/EnvelopeParams.cpp @@ -33,7 +33,6 @@ using namespace rtosc; static const rtosc::Ports localPorts = { rSelf(EnvelopeParams), - rPresetType, rPaste, rToggle(Pfreemode, "Complex Envelope Definitions"), rParamZyn(Penvpoints, rProp(internal), "Number of points in complex definition"), diff --git a/src/Params/FilterParams.cpp b/src/Params/FilterParams.cpp @@ -62,7 +62,6 @@ static const rtosc::Ports subports = { #define rChangeCb obj->changed = true; const rtosc::Ports FilterParams::ports = { rSelf(FilterParams), - rPresetType, rPaste, rArrayPaste, rParamZyn(Pcategory, "Class of filter"), diff --git a/src/Params/FilterParams.h b/src/Params/FilterParams.h @@ -91,11 +91,13 @@ class FilterParams:public PresetsArray float getformantamp(unsigned char amp); float getformantq(unsigned char q); + void defaults(int n); + + bool changed; static const rtosc::Ports ports; private: - void defaults(int n); //stored default parameters unsigned char Dtype; diff --git a/src/Params/LFOParams.cpp b/src/Params/LFOParams.cpp @@ -35,7 +35,6 @@ using namespace rtosc; #define rObject LFOParams static const rtosc::Ports _ports = { rSelf(LFOParams), - rPresetType, rPaste, rParamF(Pfreq, "frequency of LFO"), rParamZyn(Pintensity, "Intensity of LFO"), diff --git a/src/Params/PresetsArray.cpp b/src/Params/PresetsArray.cpp @@ -28,7 +28,6 @@ PresetsArray::PresetsArray() { type[0] = 0; - nelement = -1; } PresetsArray::~PresetsArray() @@ -41,6 +40,11 @@ void PresetsArray::setpresettype(const char *type) void PresetsArray::copy(PresetsStore &ps, const char *name) { + copy(ps, -1, name); +} + +void PresetsArray::copy(PresetsStore &ps, int nelement, const char *name) +{ XMLwrapper xml; //used only for the clipboard @@ -66,8 +70,6 @@ void PresetsArray::copy(PresetsStore &ps, const char *name) ps.copyclipboard(xml, type); else ps.copypreset(xml, type, name); - - nelement = -1; } #if 0 @@ -133,8 +135,3 @@ bool PresetsArray::checkclipboardtype(PresetsStore &ps) // // presetsstore.rescanforpresets(type); //} - -void PresetsArray::setelement(int n) -{ - nelement = n; -} diff --git a/src/Params/PresetsArray.h b/src/Params/PresetsArray.h @@ -35,9 +35,10 @@ class PresetsArray:public Presets virtual ~PresetsArray(); void copy(PresetsStore &ps, const char *name); /**<if name==NULL, the clipboard is used*/ + void copy(PresetsStore &ps, int elm, const char *name); /**<if name==NULL, the clipboard is used*/ //void paste(PresetsStore &ps, int npreset); //npreset==0 for clipboard //bool checkclipboardtype(PresetsStore &ps); - void setelement(int n); + //void setelement(int n); protected: void setpresettype(const char *type); private: @@ -45,7 +46,6 @@ class PresetsArray:public Presets //virtual void getfromXMLsection(XMLwrapper *xml, int n) = 0; //virtual void defaults() = 0; //virtual void defaults(int n) = 0; - int nelement; }; #endif diff --git a/src/Params/PresetsStore.h b/src/Params/PresetsStore.h @@ -53,7 +53,6 @@ class PresetsStore void scanforpresets(); - private: struct { std::string data; std::string type; diff --git a/src/UI/Connection.cpp b/src/UI/Connection.cpp @@ -171,6 +171,8 @@ void GUI::raiseUi(ui_handle_t gui, const char *message) if(!gui) return; MasterUI *mui = (MasterUI*)gui; + if(string("/damage") == message && rtosc_type(message, 0) == 's') + mui->osc->damage(rtosc_argument(message,0).s); mui->osc->tryLink(message); //printf("got message for UI '%s'\n", message); char buffer[1024]; @@ -318,7 +320,7 @@ class UI_Interface:public Fl_Osc_Interface virtual void damage(const char *path) override { #ifndef NO_UI - //printf("\n\nDamage(\"%s\")\n", path); + printf("\n\nDamage(\"%s\")\n", path); for(auto pair:map) { if(strstr(pair.first.c_str(), path)) { auto *tmp = dynamic_cast<Fl_Widget*>(pair.second); @@ -326,8 +328,10 @@ class UI_Interface:public Fl_Osc_Interface // printf("%x, %d %d [%s]\n", (int)pair.second, tmp->visible_r(), tmp->visible(), pair.first.c_str()); //else // printf("%x, (NULL)[%s]\n", (int)pair.second,pair.first.c_str()); - if(!tmp || tmp->visible_r()) + if(!tmp || tmp->visible_r()) { + printf("*"); pair.second->update(); + } } } #endif diff --git a/src/main.cpp b/src/main.cpp @@ -435,7 +435,6 @@ int main(int argc, char *argv[]) gui = GUI::createUi(middleware->spawnUiApi(), &Pexitprogram); middleware->setUiCallback(GUI::raiseUi, gui); middleware->setIdleCallback([](){GUI::tickUi(gui);}); - middlewarepointer = middleware; if(!noui) {