| @@ -54,7 +54,6 @@ public: | |||
| info.label = nullptr; | |||
| info.maker = nullptr; | |||
| info.chunk = nullptr; | |||
| info.copyright = nullptr; | |||
| params = nullptr; | |||
| @@ -98,8 +97,7 @@ public: | |||
| if (info.copyright) | |||
| free((void*)info.copyright); | |||
| if (info.chunk) | |||
| free((void*)info.chunk); | |||
| info.chunk.clear(); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| @@ -145,12 +143,10 @@ public: | |||
| { | |||
| assert(dataPtr); | |||
| if (info.chunk) | |||
| if (! info.chunk.isEmpty()) | |||
| { | |||
| static QByteArray chunk; | |||
| chunk = QByteArray::fromBase64(info.chunk); | |||
| *dataPtr = chunk.data(); | |||
| return chunk.size(); | |||
| *dataPtr = info.chunk.data(); | |||
| return info.chunk.size(); | |||
| } | |||
| return 0; | |||
| @@ -487,18 +483,19 @@ public: | |||
| case PluginBridgeChunkData: | |||
| { | |||
| const char* stringData = (const char*)&argv[0]->s; | |||
| const char* const filePath = (const char*)&argv[0]->s; | |||
| QFile file(filePath); | |||
| if (info.chunk) | |||
| free((void*)info.chunk); | |||
| info.chunk = strdup(stringData); | |||
| if (file.open(QIODevice::ReadOnly)) | |||
| { | |||
| info.chunk = file.readAll(); | |||
| file.remove(); | |||
| } | |||
| break; | |||
| } | |||
| case PluginBridgeUpdateNow: | |||
| callback_action(CALLBACK_RELOAD_ALL, m_id, 0, 0, 0.0); | |||
| initiated = true; | |||
| break; | |||
| @@ -546,7 +543,20 @@ public: | |||
| void setChunkData(const char* const stringData) | |||
| { | |||
| assert(stringData); | |||
| osc_send_configure(&osc.data, CARLA_BRIDGE_MSG_SET_CHUNK, stringData); | |||
| QString filePath; | |||
| filePath += "/tmp/.CarlaChunk_"; | |||
| filePath += m_name; | |||
| QFile file(filePath); | |||
| if (file.open(QIODevice::WriteOnly | QIODevice::Text)) | |||
| { | |||
| QTextStream out(&file); | |||
| out << stringData; | |||
| file.close(); | |||
| osc_send_configure(&osc.data, CARLA_BRIDGE_MSG_SET_CHUNK, filePath.toUtf8().constData()); | |||
| } | |||
| } | |||
| void setProgram(int32_t index, bool sendGui, bool sendOsc, bool sendCallback, bool block) | |||
| @@ -676,7 +686,7 @@ private: | |||
| const char* label; | |||
| const char* maker; | |||
| const char* copyright; | |||
| const char* chunk; | |||
| QByteArray chunk; | |||
| } info; | |||
| BridgeParamInfo* params; | |||
| @@ -73,7 +73,7 @@ const char* const CARLA_BRIDGE_MSG_HIDE_GUI = "CarlaBridgeHideGUI"; //!< Plu | |||
| const char* const CARLA_BRIDGE_MSG_SAVED = "CarlaBridgeSaved"; //!< Plugin -> Host call, tells host state is saved | |||
| const char* const CARLA_BRIDGE_MSG_SAVE_NOW = "CarlaBridgeSaveNow"; //!< Host -> Plugin call, tells plugin to save state now | |||
| const char* const CARLA_BRIDGE_MSG_SET_CHUNK = "CarlaBridgeSetChunk"; //!< Host -> Plugin call, tells plugin to set chunk as \a value | |||
| const char* const CARLA_BRIDGE_MSG_SET_CUSTOM = "CarlaBridgeSetCustom"; //!< Host -> Plugin call, tells plugin to set a custom data set using \a value ("type:key:value") | |||
| const char* const CARLA_BRIDGE_MSG_SET_CUSTOM = "CarlaBridgeSetCustom"; //!< Host -> Plugin call, tells plugin to set a custom data set using \a value ("type·key·value") | |||
| #ifndef BUILD_BRIDGE | |||
| enum PluginBridgeInfoType { | |||
| @@ -50,7 +50,8 @@ enum BridgeMessageType { | |||
| BRIDGE_MESSAGE_NOTE_OFF = 5, // note, 0, 0 | |||
| BRIDGE_MESSAGE_SHOW_GUI = 6, // show, 0, 0 | |||
| BRIDGE_MESSAGE_RESIZE_GUI = 7, // width, height, 0 | |||
| BRIDGE_MESSAGE_QUIT = 8 | |||
| BRIDGE_MESSAGE_SAVE_NOW = 8, | |||
| BRIDGE_MESSAGE_QUIT = 9 | |||
| }; | |||
| struct QuequeBridgeMessage { | |||
| @@ -145,6 +146,11 @@ public: | |||
| case BRIDGE_MESSAGE_RESIZE_GUI: | |||
| toolkit_window_resize(m->value1, m->value2); | |||
| break; | |||
| case BRIDGE_MESSAGE_SAVE_NOW: | |||
| #ifdef BUILD_BRIDGE_PLUGIN | |||
| save_now(); | |||
| #endif | |||
| break; | |||
| case BRIDGE_MESSAGE_QUIT: | |||
| toolkit_quit(); | |||
| m_lock.unlock(); | |||
| @@ -186,7 +192,7 @@ public: | |||
| // plugin | |||
| virtual void save_now() = 0; | |||
| virtual void set_custom_data(const char* const type, const char* const key, const char* const value) = 0; | |||
| virtual void set_chunk_data(const char* const stringData) = 0; | |||
| virtual void set_chunk_data(const char* const filePath) = 0; | |||
| #else | |||
| // gui | |||
| virtual void* get_widget() const = 0; | |||
| @@ -20,10 +20,12 @@ | |||
| #include "carla_midi.h" | |||
| #include <QtCore/QString> | |||
| #include <QtCore/QStringList> | |||
| #ifdef BUILD_BRIDGE_PLUGIN | |||
| static const size_t client_name_len = 13; | |||
| static const char* const client_name = "plugin-bridge"; | |||
| #include "carla_plugin.h" | |||
| #else | |||
| static const size_t client_name_len = 13; | |||
| static const char* const client_name = "lv2-ui-bridge"; | |||
| @@ -160,15 +162,34 @@ int osc_message_handler(const char* path, const char* types, lo_arg** argv, int | |||
| int osc_handle_configure(lo_arg** argv) | |||
| { | |||
| #ifdef BUILD_BRIDGE_PLUGIN | |||
| using namespace CarlaBackend; | |||
| const char* key = (const char*)&argv[0]->s; | |||
| const char* value = (const char*)&argv[1]->s; | |||
| if (client) | |||
| { | |||
| if (strcmp(key, "CarlaBridgeSaveNow") == 0) | |||
| client->save_now(); | |||
| else if (strcmp(key, "CarlaBridgeChunk") == 0) | |||
| if (strcmp(key, CARLA_BRIDGE_MSG_SAVE_NOW) == 0) | |||
| { | |||
| client->queque_message(BRIDGE_MESSAGE_SAVE_NOW, 0, 0, 0.0); | |||
| } | |||
| else if (strcmp(key, CARLA_BRIDGE_MSG_SET_CHUNK) == 0) | |||
| { | |||
| client->set_chunk_data(value); | |||
| } | |||
| else if (strcmp(key, CARLA_BRIDGE_MSG_SET_CUSTOM) == 0) | |||
| { | |||
| QStringList vList = QString(value).split("·", QString::KeepEmptyParts); | |||
| if (vList.size() == 3) | |||
| { | |||
| const char* const cType = vList.at(0).toUtf8().constData(); | |||
| const char* const cKey = vList.at(1).toUtf8().constData(); | |||
| const char* const cValue = vList.at(2).toUtf8().constData(); | |||
| client->set_custom_data(cType, cKey, cValue); | |||
| } | |||
| } | |||
| } | |||
| #else | |||
| @@ -95,6 +95,7 @@ static QDialog* gui = nullptr; | |||
| #define nextShowMsgFALSE 1 | |||
| #define nextShowMsgTRUE 2 | |||
| static int nextShowMsg = nextShowMsgNULL; | |||
| static const char* nextChunkFilePath = nullptr; | |||
| // ------------------------------------------------------------------------- | |||
| // toolkit calls | |||
| @@ -130,6 +131,22 @@ void toolkit_plugin_idle() | |||
| nextShowMsg = nextShowMsgNULL; | |||
| } | |||
| if (nextChunkFilePath) | |||
| { | |||
| QFile file(nextChunkFilePath); | |||
| free((void*)nextChunkFilePath); | |||
| nextChunkFilePath = nullptr; | |||
| if (file.open(QIODevice::ReadOnly | QIODevice::Text)) | |||
| { | |||
| QString stringData = file.readAll(); | |||
| file.remove(); | |||
| CARLA_PLUGIN->setChunkData(stringData.toUtf8().constData()); | |||
| } | |||
| } | |||
| CARLA_PLUGIN->idleGui(); | |||
| static PluginPostEvent postEvents[MAX_POST_EVENTS]; | |||
| @@ -299,8 +316,6 @@ public: | |||
| // plugin | |||
| void save_now() | |||
| { | |||
| qDebug("PluginData::save_now()"); | |||
| CARLA_PLUGIN->prepareForSave(); | |||
| for (uint32_t i=0; i < CARLA_PLUGIN->customDataCount(); i++) | |||
| @@ -316,8 +331,19 @@ public: | |||
| if (data && dataSize >= 4) | |||
| { | |||
| QByteArray chunk((const char*)data, dataSize); | |||
| osc_send_bridge_chunk_data(chunk.toBase64().data()); | |||
| QString filePath; | |||
| filePath += "/tmp/.CarlaChunk_"; | |||
| filePath += CARLA_PLUGIN->name(); | |||
| QFile file(filePath); | |||
| if (file.open(QIODevice::WriteOnly)) | |||
| { | |||
| QByteArray chunk((const char*)data, dataSize); | |||
| file.write(chunk); | |||
| file.close(); | |||
| osc_send_bridge_chunk_data(filePath.toUtf8().constData()); | |||
| } | |||
| } | |||
| } | |||
| @@ -330,10 +356,12 @@ public: | |||
| CARLA_PLUGIN->setCustomData(customdatastr2type(type), key, value, false); | |||
| } | |||
| void set_chunk_data(const char* const stringData) | |||
| void set_chunk_data(const char* const filePath) | |||
| { | |||
| if (CARLA_PLUGIN) | |||
| CARLA_PLUGIN->setChunkData(stringData); | |||
| nextChunkFilePath = strdup(filePath); | |||
| while (nextChunkFilePath) | |||
| carla_msleep(25); | |||
| } | |||
| }; | |||
| @@ -603,6 +631,13 @@ int main(int argc, char* argv[]) | |||
| return 1; | |||
| } | |||
| // delete old data | |||
| if (nextChunkFilePath) | |||
| { | |||
| free((void*)nextChunkFilePath); | |||
| nextChunkFilePath = nullptr; | |||
| } | |||
| // Close plugin client | |||
| delete client; | |||
| client = nullptr; | |||
| @@ -1183,7 +1183,7 @@ class CarlaAboutW(QDialog, ui_carla_about.Ui_CarlaAboutW): | |||
| host_osc_url = cString(CarlaHost.get_host_osc_url()) | |||
| self.le_osc_url.setText(host_osc_url) | |||
| self.l_osc_cmds.setText("" | |||
| self.l_osc_cmds.setText( | |||
| " /set_active <i-value>\n" | |||
| " /set_drywet <f-value>\n" | |||
| " /set_volume <f-value>\n" | |||
| @@ -1193,8 +1193,8 @@ class CarlaAboutW(QDialog, ui_carla_about.Ui_CarlaAboutW): | |||
| " /set_program <i-index>\n" | |||
| " /set_midi_program <i-index>\n" | |||
| " /note_on <i-note> <i-velo>\n" | |||
| " /note_off <i-note> <i-velo>\n" | |||
| ) | |||
| " /note_off <i-note>\n" | |||
| ) | |||
| self.l_example.setText("/Carla/2/set_parameter 2 0.5") | |||
| self.l_example_help.setText("<i>(as in this example, \"2\" is the plugin number)</i>") | |||
| @@ -1210,11 +1210,11 @@ class CarlaAboutW(QDialog, ui_carla_about.Ui_CarlaAboutW): | |||
| "<li>http://lv2plug.in/ns/ext/instance-access</li>" | |||
| "<li>http://lv2plug.in/ns/ext/log</li>" | |||
| "<li>http://lv2plug.in/ns/ext/midi</li>" | |||
| #"<li>http://lv2plug.in/ns/ext/patch</li>" | |||
| "<li>http://lv2plug.in/ns/ext/patch</li>" | |||
| "<li>http://lv2plug.in/ns/ext/port-props</li>" | |||
| #"<li>http://lv2plug.in/ns/ext/presets</li>" | |||
| "<li>http://lv2plug.in/ns/ext/state</li>" | |||
| #"<li>http://lv2plug.in/ns/ext/time</li>" | |||
| "<li>http://lv2plug.in/ns/ext/time</li>" | |||
| "<li>http://lv2plug.in/ns/ext/uri-map</li>" | |||
| "<li>http://lv2plug.in/ns/ext/urid</li>" | |||
| "<li>http://lv2plug.in/ns/ext/worker</li>" | |||