| @@ -20,7 +20,7 @@ | |||
| #include "carla_includes.h" | |||
| #include <stdint.h> | |||
| #include <cstdint> | |||
| #define CARLA_BRIDGE_START_NAMESPACE namespace CarlaBridge { | |||
| #define CARLA_BRIDGE_END_NAMESPACE } | |||
| @@ -31,8 +31,7 @@ | |||
| #include <cstdlib> | |||
| #include <QtCore/QMutex> | |||
| //CARLA_BRIDGE_START_NAMESPACE; | |||
| namespace CarlaBridge { | |||
| CARLA_BRIDGE_START_NAMESPACE | |||
| class CarlaBridgeClient | |||
| { | |||
| @@ -96,10 +95,16 @@ public: | |||
| } | |||
| #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 | |||
| @@ -208,8 +213,8 @@ public: | |||
| #else | |||
| // gui | |||
| 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 | |||
| // --------------------------------------------------------------------- | |||
| @@ -218,7 +223,7 @@ public: | |||
| protected: | |||
| bool libOpen(const char* const filename) | |||
| { | |||
| m_lib = ::lib_open(filename); | |||
| m_lib = lib_open(filename); | |||
| m_filename = strdup(filename); | |||
| return bool(m_lib); | |||
| } | |||
| @@ -226,20 +231,24 @@ protected: | |||
| bool libClose() | |||
| { | |||
| if (m_lib) | |||
| return ::lib_close(m_lib); | |||
| { | |||
| const bool closed = lib_close(m_lib); | |||
| m_lib = nullptr; | |||
| return closed; | |||
| } | |||
| return false; | |||
| } | |||
| void* libSymbol(const char* const symbol) | |||
| { | |||
| if (m_lib) | |||
| return ::lib_symbol(m_lib, symbol); | |||
| return lib_symbol(m_lib, symbol); | |||
| return nullptr; | |||
| } | |||
| const char* libError() | |||
| { | |||
| return ::lib_error(m_filename ? m_filename : ""); | |||
| return lib_error(m_filename ? m_filename : ""); | |||
| } | |||
| #endif | |||
| @@ -142,9 +142,9 @@ int CarlaBridgeOsc::handleMessage(const char* const path, const int argc, const | |||
| #ifdef BRIDGE_LV2 | |||
| 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) | |||
| return handle_lv2_event_transfer(argc, argv, types); | |||
| return handle_lv2_transfer_event(argc, argv, types); | |||
| #endif | |||
| #if 0 | |||
| @@ -82,9 +82,14 @@ public: | |||
| 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: | |||
| @@ -121,8 +126,8 @@ private: | |||
| int handle_quit(); | |||
| #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 | |||
| }; | |||
| @@ -425,17 +425,18 @@ public: | |||
| 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) | |||
| { | |||
| @@ -456,7 +457,7 @@ public: | |||
| 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_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) | |||
| lv2_atom_forge_string(&forge, value, strlen(value)); | |||
| @@ -464,8 +465,8 @@ public: | |||
| lv2_atom_forge_path(&forge, value, strlen(value)); | |||
| 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); | |||
| 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, &refFrame); | |||
| @@ -522,20 +523,24 @@ public: | |||
| } | |||
| 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) | |||
| { | |||
| 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) | |||
| 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; | |||
| }; | |||
| 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()"); | |||
| //CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "ii"); | |||
| CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "ss"); | |||
| if (! client) | |||
| 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; | |||
| lv2client->handleAtomTransfer(); | |||
| lv2client->handleTransferAtom(type, value); | |||
| 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()"); | |||
| CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(3, "sss"); | |||
| CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "ss"); | |||
| if (! client) | |||
| return 1; | |||
| const char* type = (const char*)&argv[0]->s; | |||
| const char* key = (const char*)&argv[1]->s; | |||
| const char* value = (const char*)&argv[2]->s; | |||
| CarlaBridgeLv2Client* lv2client = (CarlaBridgeLv2Client*)client; | |||
| lv2client->handleEventTransfer(type, key, value); | |||
| lv2client->handleTransferEvent(type, value); | |||
| return 0; | |||
| } | |||
| @@ -21,8 +21,7 @@ | |||
| #include <QtGui/QDialog> | |||
| //CARLA_BRIDGE_START_NAMESPACE; | |||
| namespace CarlaBridge { | |||
| CARLA_BRIDGE_START_NAMESPACE; | |||
| // ------------------------------------------------------------------------- | |||
| @@ -32,14 +31,20 @@ namespace CarlaBridge { | |||
| class CarlaBridgeVstClient : public CarlaBridgeClient | |||
| { | |||
| public: | |||
| CarlaBridgeVstClient(CarlaBridgeToolkit* const toolkit) : CarlaBridgeClient(toolkit) | |||
| CarlaBridgeVstClient(CarlaBridgeToolkit* const toolkit) | |||
| : CarlaBridgeClient(toolkit) | |||
| { | |||
| effect = nullptr; | |||
| widget = new QDialog; | |||
| // make client valid | |||
| unique1 = unique2 = rand(); | |||
| } | |||
| ~CarlaBridgeVstClient() | |||
| { | |||
| // make client invalid | |||
| unique2 += 1; | |||
| } | |||
| // --------------------------------------------------------------------- | |||
| @@ -50,7 +55,7 @@ public: | |||
| // ----------------------------------------------------------------- | |||
| // open DLL | |||
| if ( !lib_open(binary)) | |||
| if (! libOpen(binary)) | |||
| return false; | |||
| // ----------------------------------------------------------------- | |||
| @@ -92,17 +97,18 @@ public: | |||
| // ----------------------------------------------------------------- | |||
| // 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 height = vstRect->bottom - vstRect->top; | |||
| widget->setFixedSize(width, height); | |||
| return true; | |||
| //return true; | |||
| } | |||
| return false; | |||
| return true; | |||
| //return false; | |||
| } | |||
| 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) | |||
| { | |||
| // 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) | |||
| { | |||
| case audioMasterAutomate: | |||
| //osc_send_control(index, opt); | |||
| if (self) | |||
| self->sendOscControl(index, opt); | |||
| break; | |||
| case audioMasterVersion: | |||
| @@ -218,8 +241,8 @@ public: | |||
| #endif | |||
| 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; | |||
| case audioMasterGetSampleRate: | |||
| @@ -290,7 +313,8 @@ public: | |||
| return kVstLangEnglish; | |||
| case audioMasterUpdateDisplay: | |||
| //osc_send_configure("reloadprograms", ""); | |||
| if (self) | |||
| self->sendOscConfigure("reloadprograms", ""); | |||
| break; | |||
| default: | |||
| @@ -304,8 +328,10 @@ public: | |||
| } | |||
| private: | |||
| int unique1; | |||
| AEffect* effect; | |||
| QDialog* widget; | |||
| int unique2; | |||
| }; | |||
| CARLA_BRIDGE_END_NAMESPACE | |||
| @@ -247,35 +247,36 @@ void osc_send_quit(const CarlaOscData* const oscData) | |||
| #endif | |||
| 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); | |||
| 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) | |||
| { | |||
| char targetPath[strlen(oscData->path)+19]; | |||
| strcpy(targetPath, oscData->path); | |||
| strcat(targetPath, "/lv2_atom_transfer"); | |||
| lo_send(oscData->target, targetPath, ""); | |||
| lo_send(oscData->target, targetPath, "ss", type, value); | |||
| } | |||
| } | |||
| 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(type); | |||
| Q_ASSERT(key); | |||
| 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) | |||
| { | |||
| char targetPath[strlen(oscData->path)+20]; | |||
| strcpy(targetPath, oscData->path); | |||
| strcat(targetPath, "/lv2_event_transfer"); | |||
| lo_send(oscData->target, targetPath, "sss", type, key, value); | |||
| lo_send(oscData->target, targetPath, "ss", type, value); | |||
| } | |||
| } | |||