| @@ -1456,7 +1456,7 @@ void run_tests_standalone(short idMax) | |||
| //set_custom_data(id, CarlaBackend::CUSTOM_DATA_INVALID, nullptr, nullptr); | |||
| set_custom_data(id, CarlaBackend::CUSTOM_DATA_INVALID, "", ""); | |||
| set_chunk_data(id, nullptr); | |||
| set_gui_data(id, 0, (uintptr_t)1); | |||
| set_gui_data(id, (uintptr_t)1); | |||
| qDebug("------------------- TEST @%i: gui stuff --------------------", id); | |||
| show_gui(id, false); | |||
| @@ -52,6 +52,7 @@ public: | |||
| info.category = PLUGIN_CATEGORY_NONE; | |||
| info.uniqueId = 0; | |||
| info.name = nullptr; | |||
| info.label = nullptr; | |||
| info.maker = nullptr; | |||
| info.copyright = nullptr; | |||
| @@ -88,6 +89,9 @@ public: | |||
| osc_clear_data(&osc.data); | |||
| if (info.name) | |||
| free((void*)info.name); | |||
| if (info.label) | |||
| free((void*)info.label); | |||
| @@ -164,22 +168,34 @@ public: | |||
| void getLabel(char* const strBuf) | |||
| { | |||
| strncpy(strBuf, info.label, STR_MAX); | |||
| if (info.label) | |||
| strncpy(strBuf, info.label, STR_MAX); | |||
| else | |||
| CarlaPlugin::getLabel(strBuf); | |||
| } | |||
| void getMaker(char* const strBuf) | |||
| { | |||
| strncpy(strBuf, info.maker, STR_MAX); | |||
| if (info.maker) | |||
| strncpy(strBuf, info.maker, STR_MAX); | |||
| else | |||
| CarlaPlugin::getMaker(strBuf); | |||
| } | |||
| void getCopyright(char* const strBuf) | |||
| { | |||
| strncpy(strBuf, info.copyright, STR_MAX); | |||
| if (info.copyright) | |||
| strncpy(strBuf, info.copyright, STR_MAX); | |||
| else | |||
| CarlaPlugin::getCopyright(strBuf); | |||
| } | |||
| void getRealName(char* const strBuf) | |||
| { | |||
| strncpy(strBuf, info.name, STR_MAX); | |||
| if (info.name) | |||
| strncpy(strBuf, info.name, STR_MAX); | |||
| else | |||
| CarlaPlugin::getRealName(strBuf); | |||
| } | |||
| void getParameterName(uint32_t parameterId, char* const strBuf) | |||
| @@ -208,156 +224,156 @@ public: | |||
| // ------------------------------------------------------------------- | |||
| // Set data (internal stuff) | |||
| int setOscBridgeInfo(PluginBridgeInfoType type, lo_arg** const argv) | |||
| int setOscBridgeInfo(const PluginBridgeInfoType type, const lo_arg* const* const argv) | |||
| { | |||
| qDebug("setOscBridgeInfo(%i, %p)", type, argv); | |||
| switch (type) | |||
| { | |||
| case PluginBridgeAudioCount: | |||
| { | |||
| int aIns = argv[0]->i; | |||
| int aOuts = argv[1]->i; | |||
| int aTotal = argv[2]->i; | |||
| info.ains = aIns; | |||
| info.aouts = aOuts; | |||
| break; | |||
| Q_UNUSED(aTotal); | |||
| } | |||
| case PluginBridgeMidiCount: | |||
| { | |||
| int mIns = argv[0]->i; | |||
| int mOuts = argv[1]->i; | |||
| int mTotal = argv[2]->i; | |||
| info.mins = mIns; | |||
| info.mouts = mOuts; | |||
| break; | |||
| Q_UNUSED(mTotal); | |||
| } | |||
| case PluginBridgeParameterCount: | |||
| { | |||
| int pIns = argv[0]->i; | |||
| int pOuts = argv[1]->i; | |||
| int pTotal = argv[2]->i; | |||
| // delete old data | |||
| if (param.count > 0) | |||
| { | |||
| delete[] param.data; | |||
| delete[] param.ranges; | |||
| delete[] params; | |||
| } | |||
| // create new if needed | |||
| param.count = (pTotal < (int)carlaOptions.maxParameters) ? pTotal : 0; | |||
| if (param.count > 0) | |||
| { | |||
| param.data = new ParameterData[param.count]; | |||
| param.ranges = new ParameterRanges[param.count]; | |||
| params = new BridgeParamInfo[param.count]; | |||
| } | |||
| else | |||
| { | |||
| param.data = nullptr; | |||
| param.ranges = nullptr; | |||
| params = nullptr; | |||
| } | |||
| // initialize | |||
| for (uint32_t i=0; i < param.count; i++) | |||
| { | |||
| param.data[i].type = PARAMETER_UNKNOWN; | |||
| param.data[i].index = -1; | |||
| param.data[i].rindex = -1; | |||
| param.data[i].hints = 0; | |||
| param.data[i].midiChannel = 0; | |||
| param.data[i].midiCC = -1; | |||
| param.ranges[i].def = 0.0; | |||
| param.ranges[i].min = 0.0; | |||
| param.ranges[i].max = 1.0; | |||
| param.ranges[i].step = 0.01; | |||
| param.ranges[i].stepSmall = 0.0001; | |||
| param.ranges[i].stepLarge = 0.1; | |||
| params[i].value = 0.0; | |||
| params[i].name = QString(); | |||
| params[i].unit = QString(); | |||
| } | |||
| break; | |||
| Q_UNUSED(pIns); | |||
| Q_UNUSED(pOuts); | |||
| } | |||
| case PluginBridgeProgramCount: | |||
| { | |||
| int count = argv[0]->i; | |||
| // Delete old programs | |||
| if (prog.count > 0) | |||
| { | |||
| for (uint32_t i=0; i < prog.count; i++) | |||
| free((void*)prog.names[i]); | |||
| delete[] prog.names; | |||
| } | |||
| prog.count = 0; | |||
| prog.names = nullptr; | |||
| // Query new programs | |||
| prog.count = count; | |||
| if (prog.count > 0) | |||
| prog.names = new const char* [prog.count]; | |||
| // Update names (NULL) | |||
| for (uint32_t i=0; i < prog.count; i++) | |||
| prog.names[i] = nullptr; | |||
| break; | |||
| } | |||
| case PluginBridgeMidiProgramCount: | |||
| { | |||
| int count = argv[0]->i; | |||
| // Delete old programs | |||
| if (midiprog.count > 0) | |||
| { | |||
| for (uint32_t i=0; i < midiprog.count; i++) | |||
| free((void*)midiprog.data[i].name); | |||
| delete[] midiprog.data; | |||
| } | |||
| midiprog.count = 0; | |||
| midiprog.data = nullptr; | |||
| // Query new programs | |||
| midiprog.count = count; | |||
| if (midiprog.count > 0) | |||
| midiprog.data = new midi_program_t [midiprog.count]; | |||
| // Update data (NULL) | |||
| for (uint32_t i=0; i < midiprog.count; i++) | |||
| { | |||
| midiprog.data[i].bank = 0; | |||
| midiprog.data[i].program = 0; | |||
| midiprog.data[i].name = nullptr; | |||
| } | |||
| break; | |||
| } | |||
| // case PluginBridgeAudioCount: | |||
| // { | |||
| // int aIns = argv[0]->i; | |||
| // int aOuts = argv[1]->i; | |||
| // int aTotal = argv[2]->i; | |||
| // info.ains = aIns; | |||
| // info.aouts = aOuts; | |||
| // break; | |||
| // Q_UNUSED(aTotal); | |||
| // } | |||
| // case PluginBridgeMidiCount: | |||
| // { | |||
| // int mIns = argv[0]->i; | |||
| // int mOuts = argv[1]->i; | |||
| // int mTotal = argv[2]->i; | |||
| // info.mins = mIns; | |||
| // info.mouts = mOuts; | |||
| // break; | |||
| // Q_UNUSED(mTotal); | |||
| // } | |||
| // case PluginBridgeParameterCount: | |||
| // { | |||
| // int pIns = argv[0]->i; | |||
| // int pOuts = argv[1]->i; | |||
| // int pTotal = argv[2]->i; | |||
| // // delete old data | |||
| // if (param.count > 0) | |||
| // { | |||
| // delete[] param.data; | |||
| // delete[] param.ranges; | |||
| // delete[] params; | |||
| // } | |||
| // // create new if needed | |||
| // param.count = (pTotal < (int)carlaOptions.maxParameters) ? pTotal : 0; | |||
| // if (param.count > 0) | |||
| // { | |||
| // param.data = new ParameterData[param.count]; | |||
| // param.ranges = new ParameterRanges[param.count]; | |||
| // params = new BridgeParamInfo[param.count]; | |||
| // } | |||
| // else | |||
| // { | |||
| // param.data = nullptr; | |||
| // param.ranges = nullptr; | |||
| // params = nullptr; | |||
| // } | |||
| // // initialize | |||
| // for (uint32_t i=0; i < param.count; i++) | |||
| // { | |||
| // param.data[i].type = PARAMETER_UNKNOWN; | |||
| // param.data[i].index = -1; | |||
| // param.data[i].rindex = -1; | |||
| // param.data[i].hints = 0; | |||
| // param.data[i].midiChannel = 0; | |||
| // param.data[i].midiCC = -1; | |||
| // param.ranges[i].def = 0.0; | |||
| // param.ranges[i].min = 0.0; | |||
| // param.ranges[i].max = 1.0; | |||
| // param.ranges[i].step = 0.01; | |||
| // param.ranges[i].stepSmall = 0.0001; | |||
| // param.ranges[i].stepLarge = 0.1; | |||
| // params[i].value = 0.0; | |||
| // params[i].name = QString(); | |||
| // params[i].unit = QString(); | |||
| // } | |||
| // break; | |||
| // Q_UNUSED(pIns); | |||
| // Q_UNUSED(pOuts); | |||
| // } | |||
| // case PluginBridgeProgramCount: | |||
| // { | |||
| // int count = argv[0]->i; | |||
| // // Delete old programs | |||
| // if (prog.count > 0) | |||
| // { | |||
| // for (uint32_t i=0; i < prog.count; i++) | |||
| // free((void*)prog.names[i]); | |||
| // delete[] prog.names; | |||
| // } | |||
| // prog.count = 0; | |||
| // prog.names = nullptr; | |||
| // // Query new programs | |||
| // prog.count = count; | |||
| // if (prog.count > 0) | |||
| // prog.names = new const char* [prog.count]; | |||
| // // Update names (NULL) | |||
| // for (uint32_t i=0; i < prog.count; i++) | |||
| // prog.names[i] = nullptr; | |||
| // break; | |||
| // } | |||
| // case PluginBridgeMidiProgramCount: | |||
| // { | |||
| // int count = argv[0]->i; | |||
| // // Delete old programs | |||
| // if (midiprog.count > 0) | |||
| // { | |||
| // for (uint32_t i=0; i < midiprog.count; i++) | |||
| // free((void*)midiprog.data[i].name); | |||
| // delete[] midiprog.data; | |||
| // } | |||
| // midiprog.count = 0; | |||
| // midiprog.data = nullptr; | |||
| // // Query new programs | |||
| // midiprog.count = count; | |||
| // if (midiprog.count > 0) | |||
| // midiprog.data = new midi_program_t [midiprog.count]; | |||
| // // Update data (NULL) | |||
| // for (uint32_t i=0; i < midiprog.count; i++) | |||
| // { | |||
| // midiprog.data[i].bank = 0; | |||
| // midiprog.data[i].program = 0; | |||
| // midiprog.data[i].name = nullptr; | |||
| // } | |||
| // break; | |||
| // } | |||
| case PluginBridgePluginInfo: | |||
| { | |||
| @@ -384,119 +400,119 @@ public: | |||
| break; | |||
| } | |||
| case PluginBridgeParameterInfo: | |||
| { | |||
| int index = argv[0]->i; | |||
| const char* name = (const char*)&argv[1]->s; | |||
| const char* unit = (const char*)&argv[2]->s; | |||
| if (index >= 0 && index < (int32_t)param.count) | |||
| { | |||
| params[index].name = QString(name); | |||
| params[index].unit = QString(unit); | |||
| } | |||
| break; | |||
| } | |||
| case PluginBridgeParameterDataInfo: | |||
| { | |||
| int index = argv[0]->i; | |||
| int type = argv[1]->i; | |||
| int rindex = argv[2]->i; | |||
| int hints = argv[3]->i; | |||
| int channel = argv[4]->i; | |||
| int cc = argv[5]->i; | |||
| if (index >= 0 && index < (int32_t)param.count) | |||
| { | |||
| param.data[index].type = (ParameterType)type; | |||
| param.data[index].index = index; | |||
| param.data[index].rindex = rindex; | |||
| param.data[index].hints = hints; | |||
| param.data[index].midiChannel = channel; | |||
| param.data[index].midiCC = cc; | |||
| } | |||
| break; | |||
| } | |||
| case PluginBridgeParameterRangesInfo: | |||
| { | |||
| int index = argv[0]->i; | |||
| float def = argv[1]->f; | |||
| float min = argv[2]->f; | |||
| float max = argv[3]->f; | |||
| float step = argv[4]->f; | |||
| float stepSmall = argv[5]->f; | |||
| float stepLarge = argv[6]->f; | |||
| if (index >= 0 && index < (int32_t)param.count) | |||
| { | |||
| param.ranges[index].def = def; | |||
| param.ranges[index].min = min; | |||
| param.ranges[index].max = max; | |||
| param.ranges[index].step = step; | |||
| param.ranges[index].stepSmall = stepSmall; | |||
| param.ranges[index].stepLarge = stepLarge; | |||
| } | |||
| break; | |||
| } | |||
| case PluginBridgeProgramInfo: | |||
| { | |||
| int index = argv[0]->i; | |||
| const char* name = (const char*)&argv[1]->s; | |||
| if (index >= 0 && index < (int32_t)prog.count) | |||
| prog.names[index] = strdup(name); | |||
| break; | |||
| } | |||
| case PluginBridgeMidiProgramInfo: | |||
| { | |||
| int index = argv[0]->i; | |||
| int bank = argv[1]->i; | |||
| int program = argv[2]->i; | |||
| const char* name = (const char*)&argv[3]->s; | |||
| if (index >= 0 && index < (int32_t)midiprog.count) | |||
| { | |||
| midiprog.data[index].bank = bank; | |||
| midiprog.data[index].program = program; | |||
| midiprog.data[index].name = strdup(name); | |||
| } | |||
| break; | |||
| } | |||
| case PluginBridgeCustomData: | |||
| { | |||
| const char* stype = (const char*)&argv[0]->s; | |||
| const char* key = (const char*)&argv[1]->s; | |||
| const char* value = (const char*)&argv[2]->s; | |||
| setCustomData(getCustomDataStringType(stype), key, value, false); | |||
| break; | |||
| } | |||
| case PluginBridgeChunkData: | |||
| { | |||
| const char* const filePath = (const char*)&argv[0]->s; | |||
| QFile file(filePath); | |||
| if (file.open(QIODevice::ReadOnly)) | |||
| { | |||
| info.chunk = file.readAll(); | |||
| file.remove(); | |||
| } | |||
| break; | |||
| } | |||
| // case PluginBridgeParameterInfo: | |||
| // { | |||
| // int index = argv[0]->i; | |||
| // const char* name = (const char*)&argv[1]->s; | |||
| // const char* unit = (const char*)&argv[2]->s; | |||
| // if (index >= 0 && index < (int32_t)param.count) | |||
| // { | |||
| // params[index].name = QString(name); | |||
| // params[index].unit = QString(unit); | |||
| // } | |||
| // break; | |||
| // } | |||
| // case PluginBridgeParameterDataInfo: | |||
| // { | |||
| // int index = argv[0]->i; | |||
| // int type = argv[1]->i; | |||
| // int rindex = argv[2]->i; | |||
| // int hints = argv[3]->i; | |||
| // int channel = argv[4]->i; | |||
| // int cc = argv[5]->i; | |||
| // if (index >= 0 && index < (int32_t)param.count) | |||
| // { | |||
| // param.data[index].type = (ParameterType)type; | |||
| // param.data[index].index = index; | |||
| // param.data[index].rindex = rindex; | |||
| // param.data[index].hints = hints; | |||
| // param.data[index].midiChannel = channel; | |||
| // param.data[index].midiCC = cc; | |||
| // } | |||
| // break; | |||
| // } | |||
| // case PluginBridgeParameterRangesInfo: | |||
| // { | |||
| // int index = argv[0]->i; | |||
| // float def = argv[1]->f; | |||
| // float min = argv[2]->f; | |||
| // float max = argv[3]->f; | |||
| // float step = argv[4]->f; | |||
| // float stepSmall = argv[5]->f; | |||
| // float stepLarge = argv[6]->f; | |||
| // if (index >= 0 && index < (int32_t)param.count) | |||
| // { | |||
| // param.ranges[index].def = def; | |||
| // param.ranges[index].min = min; | |||
| // param.ranges[index].max = max; | |||
| // param.ranges[index].step = step; | |||
| // param.ranges[index].stepSmall = stepSmall; | |||
| // param.ranges[index].stepLarge = stepLarge; | |||
| // } | |||
| // break; | |||
| // } | |||
| // case PluginBridgeProgramInfo: | |||
| // { | |||
| // int index = argv[0]->i; | |||
| // const char* name = (const char*)&argv[1]->s; | |||
| // if (index >= 0 && index < (int32_t)prog.count) | |||
| // prog.names[index] = strdup(name); | |||
| // break; | |||
| // } | |||
| // case PluginBridgeMidiProgramInfo: | |||
| // { | |||
| // int index = argv[0]->i; | |||
| // int bank = argv[1]->i; | |||
| // int program = argv[2]->i; | |||
| // const char* name = (const char*)&argv[3]->s; | |||
| // if (index >= 0 && index < (int32_t)midiprog.count) | |||
| // { | |||
| // midiprog.data[index].bank = bank; | |||
| // midiprog.data[index].program = program; | |||
| // midiprog.data[index].name = strdup(name); | |||
| // } | |||
| // break; | |||
| // } | |||
| // case PluginBridgeCustomData: | |||
| // { | |||
| // const char* stype = (const char*)&argv[0]->s; | |||
| // const char* key = (const char*)&argv[1]->s; | |||
| // const char* value = (const char*)&argv[2]->s; | |||
| // setCustomData(getCustomDataStringType(stype), key, value, false); | |||
| // break; | |||
| // } | |||
| // case PluginBridgeChunkData: | |||
| // { | |||
| // const char* const filePath = (const char*)&argv[0]->s; | |||
| // QFile file(filePath); | |||
| // if (file.open(QIODevice::ReadOnly)) | |||
| // { | |||
| // info.chunk = file.readAll(); | |||
| // file.remove(); | |||
| // } | |||
| // break; | |||
| // } | |||
| case PluginBridgeUpdateNow: | |||
| initiated = true; | |||
| @@ -655,14 +671,14 @@ public: | |||
| // register plugin now so we can receive OSC (and wait for it) | |||
| x_engine->__bridgePluginRegister(m_id, this); | |||
| m_thread->setOscData(bridgeBinary, label, PluginType2str(m_type)); | |||
| m_thread->setOscData(bridgeBinary, label, getPluginTypeString(m_type)); | |||
| m_thread->start(); | |||
| for (int i=0; i < 100; i++) | |||
| { | |||
| if (initiated) | |||
| break; | |||
| carla_msleep(100); | |||
| carla_msleep(50); | |||
| } | |||
| if (! initiated) | |||
| @@ -670,7 +686,7 @@ public: | |||
| // unregister so it gets handled properly | |||
| x_engine->__bridgePluginRegister(m_id, nullptr); | |||
| m_thread->quit(); | |||
| m_thread->terminate(); | |||
| setLastError("Timeout while waiting for a response from plugin-bridge"); | |||
| return false; | |||
| } | |||
| @@ -142,6 +142,8 @@ int CarlaOsc::handleMessage(const char* const path, const int argc, const lo_arg | |||
| char method[32] = { 0 }; | |||
| memcpy(method, path + (m_name_len + offset), 32); | |||
| qWarning("CarlaOsc::handleMessage() method: %s", method); | |||
| // Common OSC methods | |||
| if (strcmp(method, "/update") == 0) | |||
| { | |||
| @@ -194,6 +196,8 @@ int CarlaOsc::handleMessage(const char* const path, const int argc, const lo_arg | |||
| // Plugin Bridges | |||
| if (plugin->hints() & CarlaBackend::PLUGIN_IS_BRIDGE) | |||
| { | |||
| qWarning("CarlaOsc::handleMessage() TO PLUGIN"); | |||
| if (strcmp(method, "/bridge_ains_peak") == 0) | |||
| return handle_bridge_ains_peak(plugin, argc, argv, types); | |||
| if (strcmp(method, "/bridge_aouts_peak") == 0) | |||
| @@ -1419,7 +1419,6 @@ public: | |||
| */ | |||
| void registerToOsc() | |||
| { | |||
| return; | |||
| #ifndef BUILD_BRIDGE | |||
| if (! x_engine->isOscControllerRegisted()) | |||
| return; | |||
| @@ -1560,6 +1559,9 @@ public: | |||
| free((void*)host); | |||
| free((void*)port); | |||
| if (m_hints & PLUGIN_IS_BRIDGE) | |||
| return; | |||
| osc_send_sample_rate(&osc.data, x_engine->getSampleRate()); | |||
| for (size_t i=0; i < custom.size(); i++) | |||
| @@ -1585,14 +1587,14 @@ public: | |||
| for (uint32_t i=0; i < param.count; i++) | |||
| osc_send_control(&osc.data, param.data[i].rindex, getParameterValue(i)); | |||
| if (m_hints & PLUGIN_IS_BRIDGE) | |||
| { | |||
| osc_send_control(&osc.data, PARAMETER_ACTIVE, m_active ? 1.0 : 0.0); | |||
| osc_send_control(&osc.data, PARAMETER_DRYWET, x_dryWet); | |||
| osc_send_control(&osc.data, PARAMETER_VOLUME, x_volume); | |||
| osc_send_control(&osc.data, PARAMETER_BALANCE_LEFT, x_balanceLeft); | |||
| osc_send_control(&osc.data, PARAMETER_BALANCE_RIGHT, x_balanceRight); | |||
| } | |||
| // if (m_hints & PLUGIN_IS_BRIDGE) | |||
| // { | |||
| // osc_send_control(&osc.data, PARAMETER_ACTIVE, m_active ? 1.0 : 0.0); | |||
| // osc_send_control(&osc.data, PARAMETER_DRYWET, x_dryWet); | |||
| // osc_send_control(&osc.data, PARAMETER_VOLUME, x_volume); | |||
| // osc_send_control(&osc.data, PARAMETER_BALANCE_LEFT, x_balanceLeft); | |||
| // osc_send_control(&osc.data, PARAMETER_BALANCE_RIGHT, x_balanceRight); | |||
| // } | |||
| } | |||
| /*! | |||
| @@ -383,6 +383,33 @@ const char* getBinaryBidgePath(const BinaryType type) | |||
| } | |||
| } | |||
| const char* getPluginTypeString(const PluginType type) | |||
| { | |||
| qDebug("CarlaBackend::getPluginTypeString(%s)", PluginType2str(type)); | |||
| switch (type) | |||
| { | |||
| case PLUGIN_NONE: | |||
| return "NONE"; | |||
| case PLUGIN_LADSPA: | |||
| return "LADSPA"; | |||
| case PLUGIN_DSSI: | |||
| return "DSSI"; | |||
| case PLUGIN_LV2: | |||
| return "LV2"; | |||
| case PLUGIN_VST: | |||
| return "VST"; | |||
| case PLUGIN_GIG: | |||
| return "GIG"; | |||
| case PLUGIN_SF2: | |||
| return "SF2"; | |||
| case PLUGIN_SFZ: | |||
| return "SFZ"; | |||
| } | |||
| return "NONE"; | |||
| } | |||
| // ------------------------------------------------------------------------------------------------------------------- | |||
| void* getPointer(const uintptr_t addr) | |||
| @@ -42,6 +42,7 @@ const char* ProcessModeType2str(const ProcessModeType type); | |||
| CustomDataType getCustomDataStringType(const char* const stype); | |||
| const char* getCustomDataTypeString(const CustomDataType type); | |||
| const char* getBinaryBidgePath(const BinaryType type); | |||
| const char* getPluginTypeString(const PluginType type); | |||
| void* getPointer(const uintptr_t addr); | |||
| PluginCategory getPluginCategoryFromName(const char* const name); | |||
| @@ -274,7 +274,9 @@ void CarlaPluginThread::run() | |||
| break; | |||
| case PLUGIN_THREAD_BRIDGE: | |||
| qDebug("CarlaPluginThread::run() - bridge starting..."); | |||
| m_process->waitForFinished(-1); | |||
| qDebug("CarlaPluginThread::run() - bridge ended"); | |||
| #ifdef DEBUG | |||
| if (m_process->exitCode() == 0) | |||
| @@ -424,8 +424,6 @@ public: | |||
| void idleGui() | |||
| { | |||
| qDebug("VstPlugin::idleGui()"); | |||
| effect->dispatcher(effect, effIdle, 0, 0, nullptr, 0.0f); | |||
| // FIXME | |||
| @@ -9,10 +9,11 @@ WINECXX ?= wineg++ | |||
| STRIP ?= strip | |||
| BASE_FLAGS = -O2 -ffast-math -fomit-frame-pointer -mtune=generic -msse -mfpmath=sse -Wall | |||
| BASE_FLAGS = -O0 -g | |||
| BUILD_FLAGS = $(BASE_FLAGS) -std=c++0x $(CXXFLAGS) | |||
| BUILD_FLAGS += -I. -I../carla-includes $(shell pkg-config --cflags liblo QtCore) | |||
| BUILD_FLAGS += -DBUILD_BRIDGE -DNDEBUG -DQT_NO_DEBUG -DQT_NO_DEBUG_STREAM -DQT_NO_DEBUG_OUTPUT | |||
| BUILD_FLAGS += -DBUILD_BRIDGE -DDEBUG #-DNDEBUG -DQT_NO_DEBUG -DQT_NO_DEBUG_STREAM -DQT_NO_DEBUG_OUTPUT | |||
| BUILD_FLAGS += -DVESTIGE_HEADER -I../carla-includes/vestige # Comment this line to not use vestige header | |||
| 32BIT_FLAGS = -m32 | |||
| @@ -228,6 +228,14 @@ public: | |||
| m_osc.sendOscExiting(); | |||
| } | |||
| #ifdef BUILD_BRIDGE_PLUGIN | |||
| void sendOscBridgeUpdate() | |||
| { | |||
| qDebug("CarlaClient::sendOscBridgeUpdate()"); | |||
| m_osc.sendOscBridgeUpdate(); | |||
| } | |||
| #endif | |||
| #ifdef BRIDGE_LV2 | |||
| void sendOscLv2TransferAtom(const char* const type, const char* const value) | |||
| { | |||
| @@ -113,6 +113,16 @@ public: | |||
| osc_send_exiting(&m_controlData); | |||
| } | |||
| #ifdef BUILD_BRIDGE_PLUGIN | |||
| void sendOscBridgeUpdate() | |||
| { | |||
| Q_ASSERT(m_controlData.target && m_serverPath); | |||
| if (m_controlData.target && m_serverPath) | |||
| osc_send_bridge_update(&m_controlData, m_serverPath); | |||
| } | |||
| #endif | |||
| #ifdef BRIDGE_LV2 | |||
| void sendOscLv2TransferAtom(const char* const type, const char* const value) | |||
| { | |||
| @@ -15,20 +15,25 @@ | |||
| * For a full copy of the GNU General Public License see the COPYING file | |||
| */ | |||
| #ifdef BUILD_BRIDGE_PLUGIN | |||
| #include "carla_bridge_client.h" | |||
| #include "carla_plugin.h" | |||
| #include <windows.h> | |||
| #include <QtCore/QFile> | |||
| #ifndef __WINE__ | |||
| //#include <QtCore/QTimer> | |||
| # include <QtGui/QApplication> | |||
| //#include <QtGui/QDialog> | |||
| #include <QtCore/QTimerEvent> | |||
| #include <QtGui/QApplication> | |||
| #include <QtGui/QDialog> | |||
| #endif | |||
| static HINSTANCE hInstG = nullptr; | |||
| #ifdef __WINE__ | |||
| static HINSTANCE hInstGlobal = nullptr; | |||
| #else | |||
| static int qargc = 0; | |||
| static char* qargv[] = { nullptr }; | |||
| #endif | |||
| CARLA_BRIDGE_START_NAMESPACE | |||
| @@ -41,8 +46,8 @@ public: | |||
| CarlaPluginClient(CarlaToolkit* const toolkit) | |||
| : CarlaClient(toolkit) | |||
| { | |||
| engine = nullptr; | |||
| plugin = nullptr; | |||
| engine = nullptr; | |||
| plugin = nullptr; | |||
| } | |||
| ~CarlaPluginClient() | |||
| @@ -195,6 +200,7 @@ public: | |||
| return; | |||
| plugin->idleGui(); | |||
| //plugin->showGui(true); | |||
| } | |||
| // --------------------------------------------------------------------- | |||
| @@ -231,8 +237,10 @@ public: | |||
| //quequeMessage(MESSAGE_QUIT, 0, 0, 0.0); | |||
| break; | |||
| case CarlaBackend::CALLBACK_RESIZE_GUI: | |||
| //quequeMessage(MESSAGE_RESIZE_GUI, value1, value2, 0.0); | |||
| //m_toolkit->resize(value1, value2); | |||
| qDebug("resize callback-------------------------------------------------------------------------------"); | |||
| quequeMessage(MESSAGE_RESIZE_GUI, value1, value2, 0.0); | |||
| //if (m_toolkit) | |||
| // m_toolkit->resize(value1, value2); | |||
| break; | |||
| case CarlaBackend::CALLBACK_RELOAD_PARAMETERS: | |||
| //if (CARLA_PLUGIN) | |||
| @@ -275,6 +283,48 @@ private: | |||
| // ------------------------------------------------------------------------- | |||
| // toolkit | |||
| #ifndef __WINE__ | |||
| class BridgeApplication : public QApplication | |||
| { | |||
| public: | |||
| BridgeApplication() | |||
| : QApplication(qargc, qargv) | |||
| { | |||
| msgTimer = 0; | |||
| m_client = nullptr; | |||
| } | |||
| void exec(CarlaPluginClient* const client) | |||
| { | |||
| m_client = client; | |||
| msgTimer = startTimer(50); | |||
| QApplication::exec(); | |||
| } | |||
| protected: | |||
| void timerEvent(QTimerEvent* const event) | |||
| { | |||
| if (event->timerId() == msgTimer) | |||
| { | |||
| if (m_client) | |||
| { | |||
| m_client->idle(); | |||
| if (! m_client->runMessages()) | |||
| killTimer(msgTimer); | |||
| } | |||
| } | |||
| QApplication::timerEvent(event); | |||
| } | |||
| private: | |||
| int msgTimer; | |||
| CarlaPluginClient* m_client; | |||
| }; | |||
| #endif | |||
| class CarlaToolkitPlugin : public CarlaToolkit | |||
| { | |||
| public: | |||
| @@ -282,7 +332,6 @@ public: | |||
| : CarlaToolkit("carla-bridge-plugin") | |||
| { | |||
| qDebug("CarlaToolkitPlugin::CarlaToolkitPlugin()"); | |||
| #ifdef __WINE__ | |||
| closeNow = false; | |||
| hwnd = nullptr; | |||
| @@ -295,6 +344,11 @@ public: | |||
| ~CarlaToolkitPlugin() | |||
| { | |||
| qDebug("CarlaToolkitPlugin::~CarlaToolkitPlugin()"); | |||
| #ifdef __WINE__ | |||
| Q_ASSERT(! closeNow); | |||
| #else | |||
| Q_ASSERT(! app); | |||
| #endif | |||
| } | |||
| void init() | |||
| @@ -309,7 +363,7 @@ public: | |||
| wc.lpfnWndProc = windowProcA; | |||
| wc.cbClsExtra = 0; | |||
| wc.cbWndExtra = 0; | |||
| wc.hInstance = hInstG; //nullptr; | |||
| wc.hInstance = hInstGlobal; | |||
| wc.hIcon = LoadIconA(nullptr, IDI_APPLICATION); | |||
| wc.hCursor = LoadCursorA(nullptr, IDC_ARROW); | |||
| wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND; | |||
| @@ -320,22 +374,21 @@ public: | |||
| #else | |||
| Q_ASSERT(! app); | |||
| static int argc = 0; | |||
| static char* argv[] = { nullptr }; | |||
| app = new QApplication(argc, argv, true); | |||
| app = new BridgeApplication; | |||
| #endif | |||
| } | |||
| void exec(CarlaClient* const client) | |||
| void exec(CarlaClient* const client, const bool showGui) | |||
| { | |||
| qDebug("CarlaToolkitPlugin::exec(%p)", client); | |||
| Q_ASSERT(client); | |||
| m_client = client; | |||
| m_client->sendOscUpdate(); | |||
| m_client->sendOscBridgeUpdate(); | |||
| #ifdef QTCREATOR_TEST | |||
| show(); | |||
| #endif | |||
| if (showGui) | |||
| show(); | |||
| #ifdef __WINE__ | |||
| Q_ASSERT(! closeNow); | |||
| @@ -370,14 +423,13 @@ public: | |||
| #else | |||
| Q_ASSERT(app); | |||
| app->exec(); | |||
| app->exec((CarlaPluginClient*)client); | |||
| #endif | |||
| } | |||
| void quit() | |||
| { | |||
| qDebug("CarlaToolkitPlugin::quit()"); | |||
| #ifdef __WINE__ | |||
| if (closeNow && hwnd) | |||
| { | |||
| @@ -389,60 +441,92 @@ public: | |||
| #else | |||
| Q_ASSERT(app); | |||
| if (app && dialog) | |||
| if (dialog) | |||
| { | |||
| dialog->close(); | |||
| delete dialog; | |||
| dialog = nullptr; | |||
| } | |||
| if (! app) | |||
| return; | |||
| if (! app->closingDown()) | |||
| app->quit(); | |||
| if (app) | |||
| { | |||
| if (! app->closingDown()) | |||
| app->quit(); | |||
| delete app; | |||
| delete app; | |||
| app = nullptr; | |||
| } | |||
| #endif | |||
| } | |||
| void show() | |||
| { | |||
| qDebug("CarlaToolkitPlugin::show()"); | |||
| #ifdef __WINE__ | |||
| Q_ASSERT(hwnd); | |||
| ShowWindow(hwnd, SW_SHOWNORMAL); | |||
| UpdateWindow(hwnd); | |||
| if (hwnd) | |||
| { | |||
| ShowWindow(hwnd, SW_SHOWNORMAL); | |||
| UpdateWindow(hwnd); | |||
| } | |||
| #else | |||
| Q_ASSERT(dialog); | |||
| if (dialog) | |||
| dialog->show(); | |||
| #endif | |||
| } | |||
| void hide() | |||
| { | |||
| qDebug("CarlaToolkitPlugin::hide()"); | |||
| #ifdef __WINE__ | |||
| Q_ASSERT(hwnd); | |||
| if (hwnd) | |||
| ShowWindow(hwnd, SW_HIDE); | |||
| #else | |||
| Q_ASSERT(dialog); | |||
| ShowWindow(hwnd, SW_HIDE); | |||
| if (dialog) | |||
| dialog->show(); | |||
| #endif | |||
| } | |||
| void resize(int width, int height) | |||
| { | |||
| qDebug("CarlaToolkitPlugin::resize(%i, %i)", width, height); | |||
| #ifdef __WINE__ | |||
| Q_ASSERT(hwnd); | |||
| SetWindowPos(hwnd, 0, 0, 0, width + 6, height + 25, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER); | |||
| if (hwnd) | |||
| SetWindowPos(hwnd, 0, 0, 0, width + 6, height + 25, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER); | |||
| #else | |||
| Q_ASSERT(dialog); | |||
| if (dialog) | |||
| dialog->setFixedSize(width, height); | |||
| #endif | |||
| } | |||
| // --------------------------------------------------------------------- | |||
| void createWindow(const char* const pluginName) | |||
| { | |||
| #ifdef __WINE__ | |||
| hwnd = CreateWindowA("CLASS_CARLA_BRIDGE", pluginName, WS_OVERLAPPEDWINDOW &~ WS_THICKFRAME &~ WS_MAXIMIZEBOX, | |||
| CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, | |||
| HWND_DESKTOP, nullptr, hInstG, nullptr); | |||
| if (! hwnd) | |||
| return; | |||
| HWND_DESKTOP, nullptr, hInstGlobal, nullptr); | |||
| SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)this); | |||
| SetWindowPos(hwnd, 0, 0, 0, 1100 + 6, 600 + 25, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER); | |||
| #else | |||
| dialog = new QDialog(nullptr); | |||
| dialog->resize(10, 10); | |||
| dialog->setWindowTitle(pluginName); | |||
| //window->setLayout(new QVBoxLayout(dialog); | |||
| dialog->setWindowTitle(QString("%1 (GUI)").arg(pluginName)); | |||
| #endif | |||
| } | |||
| @@ -455,6 +539,8 @@ public: | |||
| #endif | |||
| } | |||
| // --------------------------------------------------------------------- | |||
| private: | |||
| #ifdef __WINE__ | |||
| bool closeNow; | |||
| @@ -488,7 +574,7 @@ private: | |||
| return DefWindowProcA(_hwnd, message, wParam, lParam); | |||
| } | |||
| #else | |||
| QApplication* app; | |||
| BridgeApplication* app; | |||
| QDialog* dialog; | |||
| #endif | |||
| }; | |||
| @@ -505,8 +591,7 @@ CARLA_BRIDGE_END_NAMESPACE | |||
| #ifdef __WINE__ | |||
| int WINAPI WinMain(HINSTANCE hInstX, HINSTANCE, LPSTR, int) | |||
| { | |||
| hInstG = hInstX; | |||
| qWarning("test %li %p", hInstG, hInstG); | |||
| hInstGlobal = hInstX; | |||
| #define MAXCMDTOKENS 128 | |||
| int argc; | |||
| @@ -556,30 +641,26 @@ int WINAPI WinMain(HINSTANCE hInstX, HINSTANCE, LPSTR, int) | |||
| if (strlen(argv[0]) == 0) | |||
| { | |||
| GetModuleFileName(hInstG, command, sizeof(command)-1); | |||
| GetModuleFileName(hInstGlobal, command, sizeof(command)-1); | |||
| argv[0] = command; | |||
| } | |||
| #else | |||
| int main(int argc, char* argv[]) | |||
| { | |||
| #endif | |||
| //if (argc != 6) | |||
| //{ | |||
| //qWarning("%s :: bad arguments", argv[0]); | |||
| //return 1; | |||
| //} | |||
| //const char* const oscUrl = argv[1]; | |||
| //const char* const stype = argv[2]; | |||
| //const char* const filename = argv[3]; | |||
| //const char* name = argv[4]; | |||
| //const char* const label = argv[5]; | |||
| const char* const oscUrl = "osc.udp://null"; | |||
| const char* const stype = "VST"; | |||
| const char* const filename = "/home/falktx/.wine/drive_c/Program Files (x86)/VstPlugins/IL Harmless.dll"; | |||
| const char* name = "(none)"; | |||
| const char* const label = "DemoBuild"; | |||
| if (argc != 6) | |||
| { | |||
| qWarning("usage: %s <osc-url|\"null\"> <type> <filename> <name|\"(none)\"> <label>", argv[0]); | |||
| return 1; | |||
| } | |||
| const char* const oscUrl = argv[1]; | |||
| const char* const stype = argv[2]; | |||
| const char* const filename = argv[3]; | |||
| const char* name = argv[4]; | |||
| const char* const label = argv[5]; | |||
| const bool useOsc = strcmp(oscUrl, "null"); | |||
| if (strcmp(name, "(none)") == 0) | |||
| name = nullptr; | |||
| @@ -609,7 +690,7 @@ int main(int argc, char* argv[]) | |||
| CarlaBridge::CarlaPluginClient client(&toolkit); | |||
| // Init OSC | |||
| if (! client.oscInit(oscUrl)) | |||
| if (useOsc && ! client.oscInit(oscUrl)) | |||
| { | |||
| toolkit.quit(); | |||
| return -1; | |||
| @@ -634,12 +715,18 @@ int main(int argc, char* argv[]) | |||
| { | |||
| CarlaBackend::CarlaPlugin* const plugin = engine.getPlugin(id); | |||
| client.setStuff(&engine, plugin); | |||
| plugin->setEnabled(true); | |||
| plugin->setActive(true, false, false); | |||
| toolkit.createWindow(plugin->name()); | |||
| plugin->setGuiData(0, toolkit.getWindowHandle()); | |||
| plugin->showGui(true); | |||
| { | |||
| // create window if needed | |||
| toolkit.createWindow(plugin->name()); | |||
| plugin->setGuiData(toolkit.getWindowHandle()); | |||
| } | |||
| if (! useOsc) | |||
| { | |||
| plugin->setActive(true, false, false); | |||
| plugin->showGui(true); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| @@ -647,20 +734,22 @@ int main(int argc, char* argv[]) | |||
| return 1; | |||
| } | |||
| toolkit.exec(&client); | |||
| toolkit.exec(&client, !useOsc); | |||
| engine.removeAllPlugins(); | |||
| engine.close(); | |||
| // Close OSC | |||
| client.sendOscExiting(); | |||
| client.oscClose(); | |||
| // Close client | |||
| //client.close(); | |||
| if (useOsc) | |||
| { | |||
| client.sendOscExiting(); | |||
| client.oscClose(); | |||
| } | |||
| // Close toolkit | |||
| toolkit.quit(); | |||
| return 0; | |||
| } | |||
| #endif // BUILD_BRIDGE_PLUGIN | |||
| @@ -20,20 +20,21 @@ | |||
| #include <QtCore/QSettings> | |||
| #include <QtCore/QTimer> | |||
| #include <QtCore/QTimerEvent> | |||
| #include <QtGui/QApplication> | |||
| #include <QtGui/QDialog> | |||
| #include <QtGui/QVBoxLayout> | |||
| CARLA_BRIDGE_START_NAMESPACE | |||
| static int _argc = 0; | |||
| static char* _argv[] = { nullptr }; | |||
| static int qargc = 0; | |||
| static char* qargv[] = { nullptr }; | |||
| class BridgeApplication : public QApplication | |||
| { | |||
| public: | |||
| BridgeApplication() | |||
| : QApplication(_argc, _argv, true) | |||
| : QApplication(qargc, qargv, true) | |||
| { | |||
| msgTimer = 0; | |||
| m_client = nullptr; | |||
| @@ -42,7 +43,7 @@ public: | |||
| void exec(CarlaClient* const client) | |||
| { | |||
| m_client = client; | |||
| startTimer(50); | |||
| msgTimer = startTimer(50); | |||
| QApplication::exec(); | |||
| } | |||
| @@ -854,7 +854,7 @@ int main(int argc, char* argv[]) | |||
| if (argc != 5) | |||
| { | |||
| qCritical("usage: %s <osc-url|\"null\"> <plugin-uri> <ui-uri> <ui-title>", argv[0]); | |||
| qWarning("usage: %s <osc-url|\"null\"> <plugin-uri> <ui-uri> <ui-title>", argv[0]); | |||
| return 1; | |||
| } | |||
| @@ -425,7 +425,6 @@ protected: | |||
| { | |||
| if (event->timerId() == idleTimer && effect) | |||
| { | |||
| qDebug("timerEvent"); | |||
| effect->dispatcher(effect, effIdle, 0, 0, nullptr, 0.0f); | |||
| effect->dispatcher(effect, effEditIdle, 0, 0, nullptr, 0.0f); | |||
| } | |||
| @@ -449,7 +448,7 @@ int main(int argc, char* argv[]) | |||
| if (argc != 4) | |||
| { | |||
| qCritical("usage: %s <osc-url|\"null\"> <binary> <ui-title>", argv[0]); | |||
| qWarning("usage: %s <osc-url|\"null\"> <binary> <ui-title>", argv[0]); | |||
| return 1; | |||
| } | |||
| @@ -19,7 +19,7 @@ | |||
| #define CARLA_INCLUDES_H | |||
| #ifdef __WINE__ | |||
| //# define __socklen_t_defined | |||
| # define __socklen_t_defined | |||
| //# define __WINE_WINSOCK2__ | |||
| //# define HRESULT LONG | |||
| # define Q_CORE_EXPORT | |||
| @@ -41,6 +41,7 @@ | |||
| #ifdef Q_OS_WIN | |||
| # include <winsock2.h> | |||
| # include <windows.h> | |||
| # define uintptr_t size_t // FIXME | |||
| # define carla_sleep(t) Sleep(t * 1000) | |||
| # define carla_msleep(t) Sleep(t) | |||
| # define carla_usleep(t) Sleep(t / 1000) | |||
| @@ -73,7 +73,7 @@ static inline | |||
| void osc_send_control(const CarlaOscData* const oscData, const int32_t index, const float value) | |||
| { | |||
| Q_ASSERT(oscData && oscData->path); | |||
| Q_ASSERT(index >= 0); | |||
| Q_ASSERT(index != -1); | |||
| qDebug("osc_send_control(path:\"%s\", %i, %f)", oscData->path, index, value); | |||
| if (oscData->target) | |||
| @@ -246,6 +246,24 @@ void osc_send_quit(const CarlaOscData* const oscData) | |||
| } | |||
| #endif | |||
| #ifdef BUILD_BRIDGE_PLUGIN | |||
| static inline | |||
| void osc_send_bridge_update(const CarlaOscData* const oscData, const char* const url) | |||
| { | |||
| Q_ASSERT(oscData && oscData->path); | |||
| Q_ASSERT(url); | |||
| qDebug("osc_send_bridge_update(path:\"%s\", \"%s\")", oscData->path, url); | |||
| if (oscData->target) | |||
| { | |||
| char targetPath[strlen(oscData->path)+15]; | |||
| strcpy(targetPath, oscData->path); | |||
| strcat(targetPath, "/bridge_update"); | |||
| lo_send(oscData->target, targetPath, "s", url); | |||
| } | |||
| } | |||
| #endif | |||
| static inline | |||
| void osc_send_lv2_transfer_atom(const CarlaOscData* const oscData, const char* const type, const char* const value) | |||
| { | |||