| @@ -20,7 +20,7 @@ | |||||
| #include "carla_includes.h" | #include "carla_includes.h" | ||||
| #include <stdint.h> | |||||
| #include <cstdint> | |||||
| #define CARLA_BRIDGE_START_NAMESPACE namespace CarlaBridge { | #define CARLA_BRIDGE_START_NAMESPACE namespace CarlaBridge { | ||||
| #define CARLA_BRIDGE_END_NAMESPACE } | #define CARLA_BRIDGE_END_NAMESPACE } | ||||
| @@ -31,8 +31,7 @@ | |||||
| #include <cstdlib> | #include <cstdlib> | ||||
| #include <QtCore/QMutex> | #include <QtCore/QMutex> | ||||
| //CARLA_BRIDGE_START_NAMESPACE; | |||||
| namespace CarlaBridge { | |||||
| CARLA_BRIDGE_START_NAMESPACE | |||||
| class CarlaBridgeClient | class CarlaBridgeClient | ||||
| { | { | ||||
| @@ -96,10 +95,16 @@ public: | |||||
| } | } | ||||
| #ifdef BRIDGE_LV2 | #ifdef BRIDGE_LV2 | ||||
| void sendOscLv2EventTransfer(const char* const type, const char* const key, const char* const value) | |||||
| void sendOscLv2TransferAtom(const char* const type, const char* const value) | |||||
| { | { | ||||
| qDebug("sendOscLv2EventTransfer(\"%s\", \"%s\", \"%s\")", type, key, value); | |||||
| m_osc.sendOscLv2EventTransfer(type, key, value); | |||||
| qDebug("sendOscLv2TransferAtom(\"%s\", \"%s\")", type, value); | |||||
| m_osc.sendOscLv2TransferAtom(type, value); | |||||
| } | |||||
| void sendOscLv2TransferEvent(const char* const type, const char* const value) | |||||
| { | |||||
| qDebug("sendOscLv2TransferEvent(\"%s\", \"%s\")", type, value); | |||||
| m_osc.sendOscLv2TransferEvent(type, value); | |||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -208,8 +213,8 @@ public: | |||||
| #else | #else | ||||
| // gui | // gui | ||||
| virtual void* getWidget() const = 0; | virtual void* getWidget() const = 0; | ||||
| virtual bool isResizable() const = 0; | |||||
| virtual bool needsReparent() const = 0; | |||||
| virtual bool isResizable() const = 0; | |||||
| virtual bool needsReparent() const = 0; | |||||
| #endif | #endif | ||||
| // --------------------------------------------------------------------- | // --------------------------------------------------------------------- | ||||
| @@ -218,7 +223,7 @@ public: | |||||
| protected: | protected: | ||||
| bool libOpen(const char* const filename) | bool libOpen(const char* const filename) | ||||
| { | { | ||||
| m_lib = ::lib_open(filename); | |||||
| m_lib = lib_open(filename); | |||||
| m_filename = strdup(filename); | m_filename = strdup(filename); | ||||
| return bool(m_lib); | return bool(m_lib); | ||||
| } | } | ||||
| @@ -226,20 +231,24 @@ protected: | |||||
| bool libClose() | bool libClose() | ||||
| { | { | ||||
| if (m_lib) | if (m_lib) | ||||
| return ::lib_close(m_lib); | |||||
| { | |||||
| const bool closed = lib_close(m_lib); | |||||
| m_lib = nullptr; | |||||
| return closed; | |||||
| } | |||||
| return false; | return false; | ||||
| } | } | ||||
| void* libSymbol(const char* const symbol) | void* libSymbol(const char* const symbol) | ||||
| { | { | ||||
| if (m_lib) | if (m_lib) | ||||
| return ::lib_symbol(m_lib, symbol); | |||||
| return lib_symbol(m_lib, symbol); | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| const char* libError() | const char* libError() | ||||
| { | { | ||||
| return ::lib_error(m_filename ? m_filename : ""); | |||||
| return lib_error(m_filename ? m_filename : ""); | |||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -142,9 +142,9 @@ int CarlaBridgeOsc::handleMessage(const char* const path, const int argc, const | |||||
| #ifdef BRIDGE_LV2 | #ifdef BRIDGE_LV2 | ||||
| if (strcmp(method, "/lv2_atom_transfer") == 0) | if (strcmp(method, "/lv2_atom_transfer") == 0) | ||||
| return handle_lv2_atom_transfer(argc, argv, types); | |||||
| return handle_lv2_transfer_atom(argc, argv, types); | |||||
| if (strcmp(method, "/lv2_event_transfer") == 0) | if (strcmp(method, "/lv2_event_transfer") == 0) | ||||
| return handle_lv2_event_transfer(argc, argv, types); | |||||
| return handle_lv2_transfer_event(argc, argv, types); | |||||
| #endif | #endif | ||||
| #if 0 | #if 0 | ||||
| @@ -82,9 +82,14 @@ public: | |||||
| osc_send_exiting(&m_controlData); | osc_send_exiting(&m_controlData); | ||||
| } | } | ||||
| void sendOscLv2EventTransfer(const char* const type, const char* const key, const char* const value) | |||||
| void sendOscLv2TransferAtom(const char* const type, const char* const value) | |||||
| { | { | ||||
| osc_send_lv2_event_transfer(&m_controlData, type, key, value); | |||||
| osc_send_lv2_transfer_atom(&m_controlData, type, value); | |||||
| } | |||||
| void sendOscLv2TransferEvent(const char* const type, const char* const value) | |||||
| { | |||||
| osc_send_lv2_transfer_event(&m_controlData, type, value); | |||||
| } | } | ||||
| private: | private: | ||||
| @@ -121,8 +126,8 @@ private: | |||||
| int handle_quit(); | int handle_quit(); | ||||
| #ifdef BRIDGE_LV2 | #ifdef BRIDGE_LV2 | ||||
| int handle_lv2_atom_transfer(CARLA_BRIDGE_OSC_HANDLE_ARGS); | |||||
| int handle_lv2_event_transfer(CARLA_BRIDGE_OSC_HANDLE_ARGS); | |||||
| int handle_lv2_transfer_atom(CARLA_BRIDGE_OSC_HANDLE_ARGS); | |||||
| int handle_lv2_transfer_event(CARLA_BRIDGE_OSC_HANDLE_ARGS); | |||||
| #endif | #endif | ||||
| }; | }; | ||||
| @@ -425,17 +425,18 @@ public: | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| void handleAtomTransfer() | |||||
| void handleTransferAtom(const char* const type, const char* const value) | |||||
| { | { | ||||
| // TODO | |||||
| qDebug("CarlaBridgeLv2Client::handleTransferEvent(%s, %s)", type, value); | |||||
| Q_ASSERT(type); | |||||
| Q_ASSERT(value); | |||||
| } | } | ||||
| void handleEventTransfer(const char* const type, const char* const key, const char* const value) | |||||
| void handleTransferEvent(const char* const type, const char* const value) | |||||
| { | { | ||||
| qDebug("CarlaBridgeLv2Client::handleEventTransfer(%s, %s, %s)", type, key, value); | |||||
| assert(type); | |||||
| assert(key); | |||||
| assert(value); | |||||
| qDebug("CarlaBridgeLv2Client::handleTransferEvent(%s, %s)", type, value); | |||||
| Q_ASSERT(type); | |||||
| Q_ASSERT(value); | |||||
| if (handle && descriptor && descriptor->port_event) | if (handle && descriptor && descriptor->port_event) | ||||
| { | { | ||||
| @@ -456,7 +457,7 @@ public: | |||||
| lv2_atom_forge_property_head(&forge, uridPatchBody, CARLA_URI_MAP_ID_NULL); | lv2_atom_forge_property_head(&forge, uridPatchBody, CARLA_URI_MAP_ID_NULL); | ||||
| lv2_atom_forge_blank(&forge, &bodyFrame, 2, CARLA_URI_MAP_ID_NULL); | lv2_atom_forge_blank(&forge, &bodyFrame, 2, CARLA_URI_MAP_ID_NULL); | ||||
| lv2_atom_forge_property_head(&forge, getCustomURID(key), CARLA_URI_MAP_ID_NULL); | |||||
| //lv2_atom_forge_property_head(&forge, getCustomURID(key), CARLA_URI_MAP_ID_NULL); | |||||
| if (strcmp(type, "string") == 0) | if (strcmp(type, "string") == 0) | ||||
| lv2_atom_forge_string(&forge, value, strlen(value)); | lv2_atom_forge_string(&forge, value, strlen(value)); | ||||
| @@ -464,8 +465,8 @@ public: | |||||
| lv2_atom_forge_path(&forge, value, strlen(value)); | lv2_atom_forge_path(&forge, value, strlen(value)); | ||||
| else if (strcmp(type, "chunk") == 0) | else if (strcmp(type, "chunk") == 0) | ||||
| lv2_atom_forge_literal(&forge, value, strlen(value), CARLA_URI_MAP_ID_ATOM_CHUNK, CARLA_URI_MAP_ID_NULL); | lv2_atom_forge_literal(&forge, value, strlen(value), CARLA_URI_MAP_ID_ATOM_CHUNK, CARLA_URI_MAP_ID_NULL); | ||||
| else | |||||
| lv2_atom_forge_literal(&forge, value, strlen(value), getCustomURID(key), CARLA_URI_MAP_ID_NULL); | |||||
| //else | |||||
| // lv2_atom_forge_literal(&forge, value, strlen(value), getCustomURID(key), CARLA_URI_MAP_ID_NULL); | |||||
| lv2_atom_forge_pop(&forge, &bodyFrame); | lv2_atom_forge_pop(&forge, &bodyFrame); | ||||
| lv2_atom_forge_pop(&forge, &refFrame); | lv2_atom_forge_pop(&forge, &refFrame); | ||||
| @@ -522,20 +523,24 @@ public: | |||||
| } | } | ||||
| else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM) | else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM) | ||||
| { | { | ||||
| // TODO | |||||
| //LV2_Atom* atom = (LV2_Atom*)buffer; | |||||
| //QByteArray chunk((const char*)buffer, buffer_size); | |||||
| //osc_send_lv2_atom_transfer(lv2ui->get_custom_uri_string(atom->type), LV2_ATOM__atomTransfer, chunk.toBase64().constData()); | |||||
| const LV2_Atom* const atom = (const LV2_Atom*)buffer; | |||||
| QByteArray chunk((const char*)buffer, bufferSize); | |||||
| sendOscLv2TransferAtom(getCustomURIString(atom->type), chunk.toBase64().constData()); | |||||
| if (descriptor && descriptor->port_event) | |||||
| descriptor->port_event(handle, 0, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM, atom); | |||||
| } | } | ||||
| else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT) | else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT) | ||||
| { | { | ||||
| const LV2_Atom* const atom = (LV2_Atom*)buffer; | |||||
| const LV2_Atom* const atom = (const LV2_Atom*)buffer; | |||||
| QByteArray chunk((const char*)buffer, bufferSize); | |||||
| sendOscLv2TransferEvent(getCustomURIString(atom->type), chunk.toBase64().constData()); | |||||
| if (descriptor && descriptor->port_event) | if (descriptor && descriptor->port_event) | ||||
| descriptor->port_event(handle, 0, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom); | descriptor->port_event(handle, 0, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom); | ||||
| QByteArray chunk((const char*)buffer, bufferSize); | |||||
| sendOscLv2EventTransfer(getCustomURIString(atom->type), LV2_ATOM__eventTransfer, chunk.toBase64().constData()); | |||||
| } | } | ||||
| } | } | ||||
| @@ -803,38 +808,36 @@ private: | |||||
| std::vector<const char*> customURIDs; | std::vector<const char*> customURIDs; | ||||
| }; | }; | ||||
| int CarlaBridgeOsc::handle_lv2_atom_transfer(CARLA_BRIDGE_OSC_HANDLE_ARGS) | |||||
| int CarlaBridgeOsc::handle_lv2_transfer_atom(CARLA_BRIDGE_OSC_HANDLE_ARGS) | |||||
| { | { | ||||
| qDebug("CarlaBridgeOsc::handle_lv2_atom_transfer()"); | qDebug("CarlaBridgeOsc::handle_lv2_atom_transfer()"); | ||||
| //CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "ii"); | |||||
| CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "ss"); | |||||
| if (! client) | if (! client) | ||||
| return 1; | return 1; | ||||
| Q_UNUSED(argc); | |||||
| Q_UNUSED(argv); | |||||
| Q_UNUSED(types); | |||||
| const char* type = (const char*)&argv[0]->s; | |||||
| const char* value = (const char*)&argv[2]->s; | |||||
| CarlaBridgeLv2Client* const lv2client = (CarlaBridgeLv2Client*)client; | CarlaBridgeLv2Client* const lv2client = (CarlaBridgeLv2Client*)client; | ||||
| lv2client->handleAtomTransfer(); | |||||
| lv2client->handleTransferAtom(type, value); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| int CarlaBridgeOsc::handle_lv2_event_transfer(CARLA_BRIDGE_OSC_HANDLE_ARGS) | |||||
| int CarlaBridgeOsc::handle_lv2_transfer_event(CARLA_BRIDGE_OSC_HANDLE_ARGS) | |||||
| { | { | ||||
| qDebug("CarlaBridgeOsc::handle_lv2_event_transfer()"); | qDebug("CarlaBridgeOsc::handle_lv2_event_transfer()"); | ||||
| CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(3, "sss"); | |||||
| CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "ss"); | |||||
| if (! client) | if (! client) | ||||
| return 1; | return 1; | ||||
| const char* type = (const char*)&argv[0]->s; | const char* type = (const char*)&argv[0]->s; | ||||
| const char* key = (const char*)&argv[1]->s; | |||||
| const char* value = (const char*)&argv[2]->s; | const char* value = (const char*)&argv[2]->s; | ||||
| CarlaBridgeLv2Client* lv2client = (CarlaBridgeLv2Client*)client; | CarlaBridgeLv2Client* lv2client = (CarlaBridgeLv2Client*)client; | ||||
| lv2client->handleEventTransfer(type, key, value); | |||||
| lv2client->handleTransferEvent(type, value); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -21,8 +21,7 @@ | |||||
| #include <QtGui/QDialog> | #include <QtGui/QDialog> | ||||
| //CARLA_BRIDGE_START_NAMESPACE; | |||||
| namespace CarlaBridge { | |||||
| CARLA_BRIDGE_START_NAMESPACE; | |||||
| // ------------------------------------------------------------------------- | // ------------------------------------------------------------------------- | ||||
| @@ -32,14 +31,20 @@ namespace CarlaBridge { | |||||
| class CarlaBridgeVstClient : public CarlaBridgeClient | class CarlaBridgeVstClient : public CarlaBridgeClient | ||||
| { | { | ||||
| public: | public: | ||||
| CarlaBridgeVstClient(CarlaBridgeToolkit* const toolkit) : CarlaBridgeClient(toolkit) | |||||
| CarlaBridgeVstClient(CarlaBridgeToolkit* const toolkit) | |||||
| : CarlaBridgeClient(toolkit) | |||||
| { | { | ||||
| effect = nullptr; | effect = nullptr; | ||||
| widget = new QDialog; | widget = new QDialog; | ||||
| // make client valid | |||||
| unique1 = unique2 = rand(); | |||||
| } | } | ||||
| ~CarlaBridgeVstClient() | ~CarlaBridgeVstClient() | ||||
| { | { | ||||
| // make client invalid | |||||
| unique2 += 1; | |||||
| } | } | ||||
| // --------------------------------------------------------------------- | // --------------------------------------------------------------------- | ||||
| @@ -50,7 +55,7 @@ public: | |||||
| // ----------------------------------------------------------------- | // ----------------------------------------------------------------- | ||||
| // open DLL | // open DLL | ||||
| if ( !lib_open(binary)) | |||||
| if (! libOpen(binary)) | |||||
| return false; | return false; | ||||
| // ----------------------------------------------------------------- | // ----------------------------------------------------------------- | ||||
| @@ -92,17 +97,18 @@ public: | |||||
| // ----------------------------------------------------------------- | // ----------------------------------------------------------------- | ||||
| // initialize gui stuff | // initialize gui stuff | ||||
| ERect* vstRect; | |||||
| ERect* vstRect = nullptr; | |||||
| if (effect->dispatcher(effect, effEditGetRect, 0, 0, &vstRect, 0.0f)) | |||||
| if (effect->dispatcher(effect, effEditGetRect, 0, 0, &vstRect, 0.0f) && vstRect) | |||||
| { | { | ||||
| int width = vstRect->right - vstRect->left; | int width = vstRect->right - vstRect->left; | ||||
| int height = vstRect->bottom - vstRect->top; | int height = vstRect->bottom - vstRect->top; | ||||
| widget->setFixedSize(width, height); | widget->setFixedSize(width, height); | ||||
| return true; | |||||
| //return true; | |||||
| } | } | ||||
| return false; | |||||
| return true; | |||||
| //return false; | |||||
| } | } | ||||
| void close() | void close() | ||||
| @@ -163,10 +169,27 @@ public: | |||||
| static intptr_t VstHostCallback(AEffect* effect, int32_t opcode, int32_t index, intptr_t value, void* ptr, float opt) | static intptr_t VstHostCallback(AEffect* effect, int32_t opcode, int32_t index, intptr_t value, void* ptr, float opt) | ||||
| { | { | ||||
| // Check if 'resvd1' points to this client | |||||
| CarlaBridgeVstClient* self = nullptr; | |||||
| #ifdef VESTIGE_HEADER | |||||
| if (effect && effect->ptr1) | |||||
| { | |||||
| self = (CarlaBridgeVstClient*)effect->ptr1; | |||||
| #else | |||||
| if (effect && effect->resvd1) | |||||
| { | |||||
| self = (CarlaBridgeVstClient*)getPointer(effect->resvd1); | |||||
| #endif | |||||
| if (self->unique1 != self->unique2) | |||||
| self = nullptr; | |||||
| } | |||||
| switch (opcode) | switch (opcode) | ||||
| { | { | ||||
| case audioMasterAutomate: | case audioMasterAutomate: | ||||
| //osc_send_control(index, opt); | |||||
| if (self) | |||||
| self->sendOscControl(index, opt); | |||||
| break; | break; | ||||
| case audioMasterVersion: | case audioMasterVersion: | ||||
| @@ -218,8 +241,8 @@ public: | |||||
| #endif | #endif | ||||
| case audioMasterSizeWindow: | case audioMasterSizeWindow: | ||||
| //if (client) | |||||
| // client->queque_message(BRIDGE_MESSAGE_RESIZE_GUI, index, value, 0.0f); | |||||
| if (self) | |||||
| self->quequeMessage(MESSAGE_RESIZE_GUI, index, value, 0.0); | |||||
| return 1; | return 1; | ||||
| case audioMasterGetSampleRate: | case audioMasterGetSampleRate: | ||||
| @@ -290,7 +313,8 @@ public: | |||||
| return kVstLangEnglish; | return kVstLangEnglish; | ||||
| case audioMasterUpdateDisplay: | case audioMasterUpdateDisplay: | ||||
| //osc_send_configure("reloadprograms", ""); | |||||
| if (self) | |||||
| self->sendOscConfigure("reloadprograms", ""); | |||||
| break; | break; | ||||
| default: | default: | ||||
| @@ -304,8 +328,10 @@ public: | |||||
| } | } | ||||
| private: | private: | ||||
| int unique1; | |||||
| AEffect* effect; | AEffect* effect; | ||||
| QDialog* widget; | QDialog* widget; | ||||
| int unique2; | |||||
| }; | }; | ||||
| CARLA_BRIDGE_END_NAMESPACE | CARLA_BRIDGE_END_NAMESPACE | ||||
| @@ -247,35 +247,36 @@ void osc_send_quit(const CarlaOscData* const oscData) | |||||
| #endif | #endif | ||||
| static inline | static inline | ||||
| void osc_send_lv2_atom_transfer(const CarlaOscData* const oscData /* TODO */) | |||||
| void osc_send_lv2_transfer_atom(const CarlaOscData* const oscData, const char* const type, const char* const value) | |||||
| { | { | ||||
| Q_ASSERT(oscData && oscData->path); | Q_ASSERT(oscData && oscData->path); | ||||
| qDebug("osc_send_lv2_atom_transfer(path:\"%s\")", oscData->path); | |||||
| Q_ASSERT(type); | |||||
| Q_ASSERT(value); | |||||
| qDebug("osc_send_lv2_transfer_atom(path:\"%s\", \"%s\", \"%s\")", oscData->path, type, value); | |||||
| if (oscData->target) | if (oscData->target) | ||||
| { | { | ||||
| char targetPath[strlen(oscData->path)+19]; | char targetPath[strlen(oscData->path)+19]; | ||||
| strcpy(targetPath, oscData->path); | strcpy(targetPath, oscData->path); | ||||
| strcat(targetPath, "/lv2_atom_transfer"); | strcat(targetPath, "/lv2_atom_transfer"); | ||||
| lo_send(oscData->target, targetPath, ""); | |||||
| lo_send(oscData->target, targetPath, "ss", type, value); | |||||
| } | } | ||||
| } | } | ||||
| static inline | static inline | ||||
| void osc_send_lv2_event_transfer(const CarlaOscData* const oscData, const char* const type, const char* const key, const char* const value) | |||||
| void osc_send_lv2_transfer_event(const CarlaOscData* const oscData, const char* const type, const char* const value) | |||||
| { | { | ||||
| Q_ASSERT(oscData && oscData->path); | Q_ASSERT(oscData && oscData->path); | ||||
| Q_ASSERT(type); | Q_ASSERT(type); | ||||
| Q_ASSERT(key); | |||||
| Q_ASSERT(value); | Q_ASSERT(value); | ||||
| qDebug("osc_send_lv2_event_transfer(path:\"%s\", \"%s\", \"%s\", \"%s\")", oscData->path, type, key, value); | |||||
| qDebug("osc_send_lv2_transfer_event(path:\"%s\", \"%s\", \"%s\")", oscData->path, type, value); | |||||
| if (oscData->target) | if (oscData->target) | ||||
| { | { | ||||
| char targetPath[strlen(oscData->path)+20]; | char targetPath[strlen(oscData->path)+20]; | ||||
| strcpy(targetPath, oscData->path); | strcpy(targetPath, oscData->path); | ||||
| strcat(targetPath, "/lv2_event_transfer"); | strcat(targetPath, "/lv2_event_transfer"); | ||||
| lo_send(oscData->target, targetPath, "sss", type, key, value); | |||||
| lo_send(oscData->target, targetPath, "ss", type, value); | |||||
| } | } | ||||
| } | } | ||||