From ebcf65dd81bf816aad8ae27eaefdcdf8ba3da13e Mon Sep 17 00:00:00 2001 From: falkTX Date: Thu, 14 May 2015 16:51:04 +0200 Subject: [PATCH] Zyn in working state, let's hope :) --- source/includes/CarlaNative.hpp | 7 ++ source/native-plugins/zynaddsubfx-synth.cpp | 90 ++++++++++++++++++- source/native-plugins/zynaddsubfx-ui.cpp | 11 +++ .../zynaddsubfx/Misc/Master.cpp | 2 +- .../native-plugins/zynaddsubfx/Misc/Master.h | 6 +- .../zynaddsubfx/Misc/MiddleWare.cpp | 47 ++++++++-- .../zynaddsubfx/Misc/MiddleWare.h | 4 +- .../native-plugins/zynaddsubfx/UI/guimain.cpp | 6 ++ 8 files changed, 162 insertions(+), 11 deletions(-) diff --git a/source/includes/CarlaNative.hpp b/source/includes/CarlaNative.hpp index a79756f4e..439769773 100644 --- a/source/includes/CarlaNative.hpp +++ b/source/includes/CarlaNative.hpp @@ -208,6 +208,13 @@ protected: pHost->dispatcher(pHost->handle, NATIVE_HOST_OPCODE_UI_UNAVAILABLE, 0, 0, nullptr, 0.0f); } + void hostGiveIdle() const + { + CARLA_SAFE_ASSERT_RETURN(pHost != nullptr,); + + pHost->dispatcher(pHost->handle, NATIVE_HOST_OPCODE_HOST_IDLE, 0, 0, nullptr, 0.0f); + } + // ------------------------------------------------------------------- // Plugin parameter calls diff --git a/source/native-plugins/zynaddsubfx-synth.cpp b/source/native-plugins/zynaddsubfx-synth.cpp index 0e8863982..e910bd45c 100644 --- a/source/native-plugins/zynaddsubfx-synth.cpp +++ b/source/native-plugins/zynaddsubfx-synth.cpp @@ -440,22 +440,37 @@ protected: { fParameters[index] = (value >= 0.5f) ? 1.0f : 0.0f; + fMiddleWare->transmitMsg("/echo", "ss", "OSC_URL", ""); + fMiddleWare->activeUrl(""); + char msg[24]; std::sprintf(msg, "/part%i/Penabled", index-kParamPart01Enabled); fMiddleWare->transmitMsg(msg, (value >= 0.5f) ? "T" : "F"); } else if (index <= kParamPart16Volume) { + if (carla_compareFloats(fParameters[index], value)) + return; + fParameters[index] = std::round(carla_fixValue(0.0f, 127.0f, value)); + fMiddleWare->transmitMsg("/echo", "ss", "OSC_URL", ""); + fMiddleWare->activeUrl(""); + char msg[24]; std::sprintf(msg, "/part%i/Pvolume", index-kParamPart01Volume); fMiddleWare->transmitMsg(msg, "i", static_cast(fParameters[index])); } else if (index <= kParamPart16Panning) { + if (carla_compareFloats(fParameters[index], value)) + return; + fParameters[index] = std::round(carla_fixValue(0.0f, 127.0f, value)); + fMiddleWare->transmitMsg("/echo", "ss", "OSC_URL", ""); + fMiddleWare->activeUrl(""); + char msg[24]; std::sprintf(msg, "/part%i/Ppanning", index-kParamPart01Panning); fMiddleWare->transmitMsg(msg, "i", static_cast(fParameters[index])); @@ -530,6 +545,7 @@ protected: FloatVectorOperations::clear(outBuffer[1], static_cast(frames)); return; } + fMutex.lock(); } @@ -654,7 +670,7 @@ protected: const CarlaMutexLocker cml(fMutex); - fMaster->putalldata(const_cast(data), 0); + fMaster->putalldata(data); fMaster->applyparameters(); fMiddleWare->updateResources(fMaster); @@ -737,10 +753,17 @@ private: { fMiddleWare = new MiddleWare(fSynth); fMaster = fMiddleWare->spawnMaster(); + + fMiddleWare->setIdleCallback(_idleCallback, this); + fMiddleWare->setUiCallback(__uiCallback, this); + fMiddleWare->setMasterChangedCallback(_masterChangedCallback, this); } void _setMasterParameters() { + fMiddleWare->transmitMsg("/echo", "ss", "OSC_URL", ""); + fMiddleWare->activeUrl(""); + for (int i=kParamPart16Enabled+1; --i>=kParamPart01Enabled;) { char msg[24]; @@ -780,6 +803,71 @@ private: fMiddleWare = nullptr; } + void _uiCallback(const char* const msg) + { + if (std::strncmp(msg, "/part", 5) != 0) + return; + + const char* msgtmp = msg; + msgtmp += 5; + CARLA_SAFE_ASSERT_RETURN( msgtmp[0] >= '0' && msgtmp[0] <= '9',); + CARLA_SAFE_ASSERT_RETURN((msgtmp[1] >= '0' && msgtmp[1] <= '9') || msgtmp[1] == '/',); + + char partnstr[3] = { '\0', '\0', '\0' }; + + partnstr[0] = msgtmp[0]; + ++msgtmp; + + if (msgtmp[0] >= '0' && msgtmp[0] <= '9') + { + partnstr[1] = msgtmp[0]; + ++msgtmp; + } + + const int partn = std::atoi(partnstr); + ++msgtmp; + + /**/ if (std::strcmp(msgtmp, "Penabled") == 0) + { + const int index = kParamPart01Enabled+partn; + const bool enbl = rtosc_argument(msg,0).T; + + fParameters[index] = enbl ? 1.0f : 0.0f; + uiParameterChanged(kParamPart01Enabled+partn, enbl ? 1.0f : 0.0f); + } + else if (std::strcmp(msgtmp, "Pvolume") == 0) + { + const int index = kParamPart01Volume+partn; + const int value = rtosc_argument(msg,0).i; + + fParameters[index] = value; + uiParameterChanged(kParamPart01Volume+partn, value); + } + else if (std::strcmp(msgtmp, "Ppanning") == 0) + { + const int index = kParamPart01Panning+partn; + const int value = rtosc_argument(msg,0).i; + + fParameters[index] = value; + uiParameterChanged(kParamPart01Panning+partn, value); + } + } + + static void _idleCallback(void* ptr) + { + ((ZynAddSubFxPlugin*)ptr)->hostGiveIdle(); + } + + static void __uiCallback(void* ptr, const char* msg) + { + ((ZynAddSubFxPlugin*)ptr)->_uiCallback(msg); + } + + static void _masterChangedCallback(void* ptr, Master* m) + { + ((ZynAddSubFxPlugin*)ptr)->fMaster = m; + } + // ------------------------------------------------------------------- public: diff --git a/source/native-plugins/zynaddsubfx-ui.cpp b/source/native-plugins/zynaddsubfx-ui.cpp index ec90d5215..6c65e919d 100644 --- a/source/native-plugins/zynaddsubfx-ui.cpp +++ b/source/native-plugins/zynaddsubfx-ui.cpp @@ -109,6 +109,17 @@ public: protected: bool msgReceived(const char* const msg) noexcept override { + if (std::strcmp(msg, "control") == 0) + { + uint index; + float value; + CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(index), true); + CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true); + + // TODO + return true; + } + if (std::strcmp(msg, "show") == 0) { try { diff --git a/source/native-plugins/zynaddsubfx/Misc/Master.cpp b/source/native-plugins/zynaddsubfx/Misc/Master.cpp index a32a9c7d8..cc5be163c 100644 --- a/source/native-plugins/zynaddsubfx/Misc/Master.cpp +++ b/source/native-plugins/zynaddsubfx/Misc/Master.cpp @@ -999,7 +999,7 @@ int Master::getalldata(char **data) return strlen(*data) + 1; } -void Master::putalldata(char *data, int /*size*/) +void Master::putalldata(const char *data) { XMLwrapper *xml = new XMLwrapper(); if(!xml->putXMLdata(data)) { diff --git a/source/native-plugins/zynaddsubfx/Misc/Master.h b/source/native-plugins/zynaddsubfx/Misc/Master.h index ce63df384..8b8a0a12f 100644 --- a/source/native-plugins/zynaddsubfx/Misc/Master.h +++ b/source/native-plugins/zynaddsubfx/Misc/Master.h @@ -78,11 +78,11 @@ class Master void getfromXML(XMLwrapper *xml); - /**get all data to a newly allocated array (used for VST) + /**get all data to a newly allocated array (used for plugin) * @return the datasize*/ int getalldata(char **data) NONREALTIME; - /**put all data from the *data array to zynaddsubfx parameters (used for VST)*/ - void putalldata(char *data, int size); + /**put all data from the *data array to zynaddsubfx parameters (used for plugin)*/ + void putalldata(const char *data); //Midi IN void noteOn(char chan, char note, char velocity); diff --git a/source/native-plugins/zynaddsubfx/Misc/MiddleWare.cpp b/source/native-plugins/zynaddsubfx/Misc/MiddleWare.cpp index 4f9b8e50c..c07cfd1de 100644 --- a/source/native-plugins/zynaddsubfx/Misc/MiddleWare.cpp +++ b/source/native-plugins/zynaddsubfx/Misc/MiddleWare.cpp @@ -636,7 +636,7 @@ public: //Load the part if(idle) { while(alloc.wait_for(std::chrono::seconds(0)) != std::future_status::ready) { - idle(); + idle(idle_ptr); } } @@ -686,6 +686,9 @@ public: master = m; + if (mastercb) + mastercb(mastercb_ptr, m); + //Give it to the backend and wait for the old part to return for //deallocation uToB->write("/load-master", "b", sizeof(Master*), &m); @@ -809,7 +812,13 @@ public: ParamStore kits; //Callback When Waiting on async events - void(*idle)(void); + void(*idle)(void*); + void* idle_ptr; + + //Callback When Master changes + void(*mastercb)(void*,Master*); + void* mastercb_ptr; + //General UI callback cb_t cb; //UI handle @@ -852,6 +861,9 @@ MiddleWareImpl::MiddleWareImpl(MiddleWare *mw, SYNTH_T synth_, int prefered_port //dummy callback for starters cb = [](void*, const char*){}; idle = 0; + idle_ptr = 0; + mastercb = 0; + mastercb_ptr = 0; the_bToU = bToU; master = new Master(synth); @@ -996,7 +1008,24 @@ void MiddleWareImpl::bToUhandle(const char *rtmsg, bool dummy) broadcast = true; } else if(broadcast) { broadcast = false; +#ifdef CARLA_VERSION_STRING + if (!curr_url.empty()) // falktx: check added + cb(ui, rtmsg); + + // falktx: changed curr_url to last_url + if(last_url != "GUI") { + lo_message msg = lo_message_deserialise((void*)rtmsg, + rtosc_message_length(rtmsg, bToU->buffer_size()), NULL); + + //Send to known url + if(!last_url.empty()) { + lo_address addr = lo_address_new_from_url(last_url.c_str()); + lo_send_message(addr, rtmsg, msg); + } + } +#else cb(ui, rtmsg); + if(curr_url != "GUI") { lo_message msg = lo_message_deserialise((void*)rtmsg, rtosc_message_length(rtmsg, bToU->buffer_size()), NULL); @@ -1007,6 +1036,7 @@ void MiddleWareImpl::bToUhandle(const char *rtmsg, bool dummy) lo_send_message(addr, rtmsg, msg); } } +#endif } else if((dummy?last_url:curr_url) == "GUI" || !strcmp(rtmsg, "/close-ui")) { cb(ui, rtmsg); } else{ @@ -1270,15 +1300,22 @@ void MiddleWare::doReadOnlyOp(std::function fn) impl->doReadOnlyOp(fn); } -void MiddleWare::setUiCallback(void(*cb)(void*,const char *),void *ui) +void MiddleWare::setUiCallback(void(*cb)(void*,const char *), void *ui) { impl->cb = cb; impl->ui = ui; } -void MiddleWare::setIdleCallback(void(*cb)(void)) +void MiddleWare::setIdleCallback(void(*cb)(void*), void *ptr) +{ + impl->idle = cb; + impl->idle_ptr = ptr; +} + +void MiddleWare::setMasterChangedCallback(void(*cb)(void*,Master*), void *ptr) { - impl->idle = cb; + impl->mastercb = cb; + impl->mastercb_ptr = ptr; } void MiddleWare::transmitMsg(const char *msg) diff --git a/source/native-plugins/zynaddsubfx/Misc/MiddleWare.h b/source/native-plugins/zynaddsubfx/Misc/MiddleWare.h index 0b33941dd..3744c1dd4 100644 --- a/source/native-plugins/zynaddsubfx/Misc/MiddleWare.h +++ b/source/native-plugins/zynaddsubfx/Misc/MiddleWare.h @@ -18,7 +18,9 @@ class MiddleWare //Set callback to push UI events to void setUiCallback(void(*cb)(void*,const char *),void *ui); //Set callback to run while busy - void setIdleCallback(void(*cb)(void)); + void setIdleCallback(void(*cb)(void*),void *ptr); + //Set callback to run when master changed + void setMasterChangedCallback(void(*cb)(void*,Master*),void *ptr); //Handle events void tick(void); //Do A Readonly Operation (For Parameter Copy) diff --git a/source/native-plugins/zynaddsubfx/UI/guimain.cpp b/source/native-plugins/zynaddsubfx/UI/guimain.cpp index a1a65b12a..498d18297 100644 --- a/source/native-plugins/zynaddsubfx/UI/guimain.cpp +++ b/source/native-plugins/zynaddsubfx/UI/guimain.cpp @@ -220,10 +220,14 @@ rtosc::Ports uiPorts::ports = { ui->do_load_master(a0.s); } END BEGIN("vu-meter:bb") { +#ifdef DEBUG printf("Vu meter handler...\n"); +#endif if(a0.b.len == sizeof(vuData) && a1.b.len == sizeof(float)*NUM_MIDI_PARTS) { +#ifdef DEBUG printf("Normal behavior...\n"); +#endif //Refresh the primary VU meters ui->simplemastervu->update((vuData*)a0.b.data); ui->mastervu->update((vuData*)a0.b.data); @@ -245,7 +249,9 @@ void GUI::raiseUi(ui_handle_t gui, const char *message) return; MasterUI *mui = (MasterUI*)gui; mui->osc->tryLink(message); +#ifdef DEBUG printf("got message for UI '%s:%s'\n", message, rtosc_argument_string(message)); +#endif char buffer[1024]; memset(buffer, 0, sizeof(buffer)); rtosc::RtData d;