Browse Source

Carla: plugin-bridges work again, sort of

tags/v0.9.0
falkTX 12 years ago
parent
commit
d47b8367a5
17 changed files with 534 additions and 357 deletions
  1. +1
    -1
      c++/carla-backend/carla_backend_standalone.cpp
  2. +281
    -265
      c++/carla-backend/carla_bridge.cpp
  3. +4
    -0
      c++/carla-backend/carla_osc.cpp
  4. +11
    -9
      c++/carla-backend/carla_plugin.h
  5. +27
    -0
      c++/carla-backend/carla_shared.cpp
  6. +1
    -0
      c++/carla-backend/carla_shared.h
  7. +2
    -0
      c++/carla-backend/carla_threads.cpp
  8. +0
    -2
      c++/carla-backend/vst.cpp
  9. +2
    -1
      c++/carla-bridge/Makefile
  10. +8
    -0
      c++/carla-bridge/carla_bridge_client.h
  11. +10
    -0
      c++/carla-bridge/carla_bridge_osc.h
  12. +159
    -70
      c++/carla-bridge/carla_bridge_plugin.cpp
  13. +5
    -4
      c++/carla-bridge/carla_bridge_toolkit-qt4.cpp
  14. +1
    -1
      c++/carla-bridge/carla_bridge_ui-lv2.cpp
  15. +1
    -2
      c++/carla-bridge/carla_bridge_ui-vst.cpp
  16. +2
    -1
      c++/carla-includes/carla_includes.h
  17. +19
    -1
      c++/carla-includes/carla_osc_includes.h

+ 1
- 1
c++/carla-backend/carla_backend_standalone.cpp View File

@@ -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, nullptr, nullptr);
set_custom_data(id, CarlaBackend::CUSTOM_DATA_INVALID, "", ""); set_custom_data(id, CarlaBackend::CUSTOM_DATA_INVALID, "", "");
set_chunk_data(id, nullptr); 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); qDebug("------------------- TEST @%i: gui stuff --------------------", id);
show_gui(id, false); show_gui(id, false);


+ 281
- 265
c++/carla-backend/carla_bridge.cpp View File

@@ -52,6 +52,7 @@ public:
info.category = PLUGIN_CATEGORY_NONE; info.category = PLUGIN_CATEGORY_NONE;
info.uniqueId = 0; info.uniqueId = 0;


info.name = nullptr;
info.label = nullptr; info.label = nullptr;
info.maker = nullptr; info.maker = nullptr;
info.copyright = nullptr; info.copyright = nullptr;
@@ -88,6 +89,9 @@ public:


osc_clear_data(&osc.data); osc_clear_data(&osc.data);


if (info.name)
free((void*)info.name);

if (info.label) if (info.label)
free((void*)info.label); free((void*)info.label);


@@ -164,22 +168,34 @@ public:


void getLabel(char* const strBuf) 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) 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) 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) 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) void getParameterName(uint32_t parameterId, char* const strBuf)
@@ -208,156 +224,156 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Set data (internal stuff) // 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); qDebug("setOscBridgeInfo(%i, %p)", type, argv);


switch (type) 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: case PluginBridgePluginInfo:
{ {
@@ -384,119 +400,119 @@ public:
break; 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: case PluginBridgeUpdateNow:
initiated = true; initiated = true;
@@ -655,14 +671,14 @@ public:
// register plugin now so we can receive OSC (and wait for it) // register plugin now so we can receive OSC (and wait for it)
x_engine->__bridgePluginRegister(m_id, this); 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(); m_thread->start();


for (int i=0; i < 100; i++) for (int i=0; i < 100; i++)
{ {
if (initiated) if (initiated)
break; break;
carla_msleep(100);
carla_msleep(50);
} }


if (! initiated) if (! initiated)
@@ -670,7 +686,7 @@ public:
// unregister so it gets handled properly // unregister so it gets handled properly
x_engine->__bridgePluginRegister(m_id, nullptr); x_engine->__bridgePluginRegister(m_id, nullptr);


m_thread->quit();
m_thread->terminate();
setLastError("Timeout while waiting for a response from plugin-bridge"); setLastError("Timeout while waiting for a response from plugin-bridge");
return false; return false;
} }


+ 4
- 0
c++/carla-backend/carla_osc.cpp View File

@@ -142,6 +142,8 @@ int CarlaOsc::handleMessage(const char* const path, const int argc, const lo_arg
char method[32] = { 0 }; char method[32] = { 0 };
memcpy(method, path + (m_name_len + offset), 32); memcpy(method, path + (m_name_len + offset), 32);


qWarning("CarlaOsc::handleMessage() method: %s", method);

// Common OSC methods // Common OSC methods
if (strcmp(method, "/update") == 0) if (strcmp(method, "/update") == 0)
{ {
@@ -194,6 +196,8 @@ int CarlaOsc::handleMessage(const char* const path, const int argc, const lo_arg
// Plugin Bridges // Plugin Bridges
if (plugin->hints() & CarlaBackend::PLUGIN_IS_BRIDGE) if (plugin->hints() & CarlaBackend::PLUGIN_IS_BRIDGE)
{ {
qWarning("CarlaOsc::handleMessage() TO PLUGIN");

if (strcmp(method, "/bridge_ains_peak") == 0) if (strcmp(method, "/bridge_ains_peak") == 0)
return handle_bridge_ains_peak(plugin, argc, argv, types); return handle_bridge_ains_peak(plugin, argc, argv, types);
if (strcmp(method, "/bridge_aouts_peak") == 0) if (strcmp(method, "/bridge_aouts_peak") == 0)


+ 11
- 9
c++/carla-backend/carla_plugin.h View File

@@ -1419,7 +1419,6 @@ public:
*/ */
void registerToOsc() void registerToOsc()
{ {
return;
#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
if (! x_engine->isOscControllerRegisted()) if (! x_engine->isOscControllerRegisted())
return; return;
@@ -1560,6 +1559,9 @@ public:
free((void*)host); free((void*)host);
free((void*)port); free((void*)port);


if (m_hints & PLUGIN_IS_BRIDGE)
return;

osc_send_sample_rate(&osc.data, x_engine->getSampleRate()); osc_send_sample_rate(&osc.data, x_engine->getSampleRate());


for (size_t i=0; i < custom.size(); i++) for (size_t i=0; i < custom.size(); i++)
@@ -1585,14 +1587,14 @@ public:
for (uint32_t i=0; i < param.count; i++) for (uint32_t i=0; i < param.count; i++)
osc_send_control(&osc.data, param.data[i].rindex, getParameterValue(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);
// }
} }


/*! /*!


+ 27
- 0
c++/carla-backend/carla_shared.cpp View File

@@ -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) void* getPointer(const uintptr_t addr)


+ 1
- 0
c++/carla-backend/carla_shared.h View File

@@ -42,6 +42,7 @@ const char* ProcessModeType2str(const ProcessModeType type);
CustomDataType getCustomDataStringType(const char* const stype); CustomDataType getCustomDataStringType(const char* const stype);
const char* getCustomDataTypeString(const CustomDataType type); const char* getCustomDataTypeString(const CustomDataType type);
const char* getBinaryBidgePath(const BinaryType type); const char* getBinaryBidgePath(const BinaryType type);
const char* getPluginTypeString(const PluginType type);


void* getPointer(const uintptr_t addr); void* getPointer(const uintptr_t addr);
PluginCategory getPluginCategoryFromName(const char* const name); PluginCategory getPluginCategoryFromName(const char* const name);


+ 2
- 0
c++/carla-backend/carla_threads.cpp View File

@@ -274,7 +274,9 @@ void CarlaPluginThread::run()
break; break;


case PLUGIN_THREAD_BRIDGE: case PLUGIN_THREAD_BRIDGE:
qDebug("CarlaPluginThread::run() - bridge starting...");
m_process->waitForFinished(-1); m_process->waitForFinished(-1);
qDebug("CarlaPluginThread::run() - bridge ended");


#ifdef DEBUG #ifdef DEBUG
if (m_process->exitCode() == 0) if (m_process->exitCode() == 0)


+ 0
- 2
c++/carla-backend/vst.cpp View File

@@ -424,8 +424,6 @@ public:


void idleGui() void idleGui()
{ {
qDebug("VstPlugin::idleGui()");

effect->dispatcher(effect, effIdle, 0, 0, nullptr, 0.0f); effect->dispatcher(effect, effIdle, 0, 0, nullptr, 0.0f);


// FIXME // FIXME


+ 2
- 1
c++/carla-bridge/Makefile View File

@@ -9,10 +9,11 @@ WINECXX ?= wineg++
STRIP ?= strip STRIP ?= strip


BASE_FLAGS = -O2 -ffast-math -fomit-frame-pointer -mtune=generic -msse -mfpmath=sse -Wall 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 = $(BASE_FLAGS) -std=c++0x $(CXXFLAGS)
BUILD_FLAGS += -I. -I../carla-includes $(shell pkg-config --cflags liblo QtCore) 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 BUILD_FLAGS += -DVESTIGE_HEADER -I../carla-includes/vestige # Comment this line to not use vestige header


32BIT_FLAGS = -m32 32BIT_FLAGS = -m32


+ 8
- 0
c++/carla-bridge/carla_bridge_client.h View File

@@ -228,6 +228,14 @@ public:
m_osc.sendOscExiting(); m_osc.sendOscExiting();
} }


#ifdef BUILD_BRIDGE_PLUGIN
void sendOscBridgeUpdate()
{
qDebug("CarlaClient::sendOscBridgeUpdate()");
m_osc.sendOscBridgeUpdate();
}
#endif

#ifdef BRIDGE_LV2 #ifdef BRIDGE_LV2
void sendOscLv2TransferAtom(const char* const type, const char* const value) void sendOscLv2TransferAtom(const char* const type, const char* const value)
{ {


+ 10
- 0
c++/carla-bridge/carla_bridge_osc.h View File

@@ -113,6 +113,16 @@ public:
osc_send_exiting(&m_controlData); 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 #ifdef BRIDGE_LV2
void sendOscLv2TransferAtom(const char* const type, const char* const value) void sendOscLv2TransferAtom(const char* const type, const char* const value)
{ {


+ 159
- 70
c++/carla-bridge/carla_bridge_plugin.cpp View File

@@ -15,20 +15,25 @@
* For a full copy of the GNU General Public License see the COPYING file * 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_bridge_client.h"
#include "carla_plugin.h" #include "carla_plugin.h"


#include <windows.h>

#include <QtCore/QFile> #include <QtCore/QFile>


#ifndef __WINE__ #ifndef __WINE__
//#include <QtCore/QTimer>
# include <QtGui/QApplication>
//#include <QtGui/QDialog>
#include <QtCore/QTimerEvent>
#include <QtGui/QApplication>
#include <QtGui/QDialog>
#endif #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 CARLA_BRIDGE_START_NAMESPACE


@@ -41,8 +46,8 @@ public:
CarlaPluginClient(CarlaToolkit* const toolkit) CarlaPluginClient(CarlaToolkit* const toolkit)
: CarlaClient(toolkit) : CarlaClient(toolkit)
{ {
engine = nullptr;
plugin = nullptr;
engine = nullptr;
plugin = nullptr;
} }


~CarlaPluginClient() ~CarlaPluginClient()
@@ -195,6 +200,7 @@ public:
return; return;


plugin->idleGui(); plugin->idleGui();
//plugin->showGui(true);
} }


// --------------------------------------------------------------------- // ---------------------------------------------------------------------
@@ -231,8 +237,10 @@ public:
//quequeMessage(MESSAGE_QUIT, 0, 0, 0.0); //quequeMessage(MESSAGE_QUIT, 0, 0, 0.0);
break; break;
case CarlaBackend::CALLBACK_RESIZE_GUI: 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; break;
case CarlaBackend::CALLBACK_RELOAD_PARAMETERS: case CarlaBackend::CALLBACK_RELOAD_PARAMETERS:
//if (CARLA_PLUGIN) //if (CARLA_PLUGIN)
@@ -275,6 +283,48 @@ private:
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// toolkit // 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 class CarlaToolkitPlugin : public CarlaToolkit
{ {
public: public:
@@ -282,7 +332,6 @@ public:
: CarlaToolkit("carla-bridge-plugin") : CarlaToolkit("carla-bridge-plugin")
{ {
qDebug("CarlaToolkitPlugin::CarlaToolkitPlugin()"); qDebug("CarlaToolkitPlugin::CarlaToolkitPlugin()");

#ifdef __WINE__ #ifdef __WINE__
closeNow = false; closeNow = false;
hwnd = nullptr; hwnd = nullptr;
@@ -295,6 +344,11 @@ public:
~CarlaToolkitPlugin() ~CarlaToolkitPlugin()
{ {
qDebug("CarlaToolkitPlugin::~CarlaToolkitPlugin()"); qDebug("CarlaToolkitPlugin::~CarlaToolkitPlugin()");
#ifdef __WINE__
Q_ASSERT(! closeNow);
#else
Q_ASSERT(! app);
#endif
} }


void init() void init()
@@ -309,7 +363,7 @@ public:
wc.lpfnWndProc = windowProcA; wc.lpfnWndProc = windowProcA;
wc.cbClsExtra = 0; wc.cbClsExtra = 0;
wc.cbWndExtra = 0; wc.cbWndExtra = 0;
wc.hInstance = hInstG; //nullptr;
wc.hInstance = hInstGlobal;
wc.hIcon = LoadIconA(nullptr, IDI_APPLICATION); wc.hIcon = LoadIconA(nullptr, IDI_APPLICATION);
wc.hCursor = LoadCursorA(nullptr, IDC_ARROW); wc.hCursor = LoadCursorA(nullptr, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND; wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
@@ -320,22 +374,21 @@ public:
#else #else
Q_ASSERT(! app); Q_ASSERT(! app);


static int argc = 0;
static char* argv[] = { nullptr };
app = new QApplication(argc, argv, true);
app = new BridgeApplication;
#endif #endif
} }


void exec(CarlaClient* const client)
void exec(CarlaClient* const client, const bool showGui)
{ {
qDebug("CarlaToolkitPlugin::exec(%p)", client); qDebug("CarlaToolkitPlugin::exec(%p)", client);
Q_ASSERT(client); Q_ASSERT(client);


m_client = client; m_client = client;
m_client->sendOscUpdate();
m_client->sendOscBridgeUpdate();


#ifdef QTCREATOR_TEST
show();
#endif
if (showGui)
show();


#ifdef __WINE__ #ifdef __WINE__
Q_ASSERT(! closeNow); Q_ASSERT(! closeNow);
@@ -370,14 +423,13 @@ public:
#else #else
Q_ASSERT(app); Q_ASSERT(app);


app->exec();
app->exec((CarlaPluginClient*)client);
#endif #endif
} }


void quit() void quit()
{ {
qDebug("CarlaToolkitPlugin::quit()"); qDebug("CarlaToolkitPlugin::quit()");

#ifdef __WINE__ #ifdef __WINE__
if (closeNow && hwnd) if (closeNow && hwnd)
{ {
@@ -389,60 +441,92 @@ public:
#else #else
Q_ASSERT(app); Q_ASSERT(app);


if (app && dialog)
if (dialog)
{ {
dialog->close();

delete dialog; delete dialog;
dialog = nullptr; dialog = nullptr;
} }


if (! app)
return;

if (! app->closingDown())
app->quit();
if (app)
{
if (! app->closingDown())
app->quit();


delete app;
delete app;
app = nullptr;
}
#endif #endif
} }


void show() void show()
{ {
qDebug("CarlaToolkitPlugin::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() void hide()
{ {
qDebug("CarlaToolkitPlugin::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) void resize(int width, int height)
{ {
qDebug("CarlaToolkitPlugin::resize(%i, %i)", width, 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) void createWindow(const char* const pluginName)
{ {
#ifdef __WINE__ #ifdef __WINE__
hwnd = CreateWindowA("CLASS_CARLA_BRIDGE", pluginName, WS_OVERLAPPEDWINDOW &~ WS_THICKFRAME &~ WS_MAXIMIZEBOX, hwnd = CreateWindowA("CLASS_CARLA_BRIDGE", pluginName, WS_OVERLAPPEDWINDOW &~ WS_THICKFRAME &~ WS_MAXIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 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); SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)this);
SetWindowPos(hwnd, 0, 0, 0, 1100 + 6, 600 + 25, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER); SetWindowPos(hwnd, 0, 0, 0, 1100 + 6, 600 + 25, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER);
#else #else
dialog = new QDialog(nullptr); dialog = new QDialog(nullptr);
dialog->resize(10, 10); dialog->resize(10, 10);
dialog->setWindowTitle(pluginName);
//window->setLayout(new QVBoxLayout(dialog);
dialog->setWindowTitle(QString("%1 (GUI)").arg(pluginName));
#endif #endif
} }


@@ -455,6 +539,8 @@ public:
#endif #endif
} }


// ---------------------------------------------------------------------

private: private:
#ifdef __WINE__ #ifdef __WINE__
bool closeNow; bool closeNow;
@@ -488,7 +574,7 @@ private:
return DefWindowProcA(_hwnd, message, wParam, lParam); return DefWindowProcA(_hwnd, message, wParam, lParam);
} }
#else #else
QApplication* app;
BridgeApplication* app;
QDialog* dialog; QDialog* dialog;
#endif #endif
}; };
@@ -505,8 +591,7 @@ CARLA_BRIDGE_END_NAMESPACE
#ifdef __WINE__ #ifdef __WINE__
int WINAPI WinMain(HINSTANCE hInstX, HINSTANCE, LPSTR, int) int WINAPI WinMain(HINSTANCE hInstX, HINSTANCE, LPSTR, int)
{ {
hInstG = hInstX;
qWarning("test %li %p", hInstG, hInstG);
hInstGlobal = hInstX;


#define MAXCMDTOKENS 128 #define MAXCMDTOKENS 128
int argc; int argc;
@@ -556,30 +641,26 @@ int WINAPI WinMain(HINSTANCE hInstX, HINSTANCE, LPSTR, int)


if (strlen(argv[0]) == 0) if (strlen(argv[0]) == 0)
{ {
GetModuleFileName(hInstG, command, sizeof(command)-1);
GetModuleFileName(hInstGlobal, command, sizeof(command)-1);
argv[0] = command; argv[0] = command;
} }
#else #else
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
#endif #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) if (strcmp(name, "(none)") == 0)
name = nullptr; name = nullptr;
@@ -609,7 +690,7 @@ int main(int argc, char* argv[])
CarlaBridge::CarlaPluginClient client(&toolkit); CarlaBridge::CarlaPluginClient client(&toolkit);


// Init OSC // Init OSC
if (! client.oscInit(oscUrl))
if (useOsc && ! client.oscInit(oscUrl))
{ {
toolkit.quit(); toolkit.quit();
return -1; return -1;
@@ -634,12 +715,18 @@ int main(int argc, char* argv[])
{ {
CarlaBackend::CarlaPlugin* const plugin = engine.getPlugin(id); CarlaBackend::CarlaPlugin* const plugin = engine.getPlugin(id);
client.setStuff(&engine, plugin); 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 else
{ {
@@ -647,20 +734,22 @@ int main(int argc, char* argv[])
return 1; return 1;
} }


toolkit.exec(&client);
toolkit.exec(&client, !useOsc);


engine.removeAllPlugins(); engine.removeAllPlugins();
engine.close(); engine.close();


// Close OSC // Close OSC
client.sendOscExiting();
client.oscClose();
// Close client
//client.close();
if (useOsc)
{
client.sendOscExiting();
client.oscClose();
}


// Close toolkit // Close toolkit
toolkit.quit(); toolkit.quit();


return 0; return 0;
} }

#endif // BUILD_BRIDGE_PLUGIN

+ 5
- 4
c++/carla-bridge/carla_bridge_toolkit-qt4.cpp View File

@@ -20,20 +20,21 @@
#include <QtCore/QSettings> #include <QtCore/QSettings>
#include <QtCore/QTimer> #include <QtCore/QTimer>


#include <QtCore/QTimerEvent>
#include <QtGui/QApplication> #include <QtGui/QApplication>
#include <QtGui/QDialog> #include <QtGui/QDialog>
#include <QtGui/QVBoxLayout> #include <QtGui/QVBoxLayout>


CARLA_BRIDGE_START_NAMESPACE CARLA_BRIDGE_START_NAMESPACE


static int _argc = 0;
static char* _argv[] = { nullptr };
static int qargc = 0;
static char* qargv[] = { nullptr };


class BridgeApplication : public QApplication class BridgeApplication : public QApplication
{ {
public: public:
BridgeApplication() BridgeApplication()
: QApplication(_argc, _argv, true)
: QApplication(qargc, qargv, true)
{ {
msgTimer = 0; msgTimer = 0;
m_client = nullptr; m_client = nullptr;
@@ -42,7 +43,7 @@ public:
void exec(CarlaClient* const client) void exec(CarlaClient* const client)
{ {
m_client = client; m_client = client;
startTimer(50);
msgTimer = startTimer(50);


QApplication::exec(); QApplication::exec();
} }


+ 1
- 1
c++/carla-bridge/carla_bridge_ui-lv2.cpp View File

@@ -854,7 +854,7 @@ int main(int argc, char* argv[])


if (argc != 5) 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; return 1;
} }




+ 1
- 2
c++/carla-bridge/carla_bridge_ui-vst.cpp View File

@@ -425,7 +425,6 @@ protected:
{ {
if (event->timerId() == idleTimer && effect) if (event->timerId() == idleTimer && effect)
{ {
qDebug("timerEvent");
effect->dispatcher(effect, effIdle, 0, 0, nullptr, 0.0f); effect->dispatcher(effect, effIdle, 0, 0, nullptr, 0.0f);
effect->dispatcher(effect, effEditIdle, 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) 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; return 1;
} }




+ 2
- 1
c++/carla-includes/carla_includes.h View File

@@ -19,7 +19,7 @@
#define CARLA_INCLUDES_H #define CARLA_INCLUDES_H


#ifdef __WINE__ #ifdef __WINE__
//# define __socklen_t_defined
# define __socklen_t_defined
//# define __WINE_WINSOCK2__ //# define __WINE_WINSOCK2__
//# define HRESULT LONG //# define HRESULT LONG
# define Q_CORE_EXPORT # define Q_CORE_EXPORT
@@ -41,6 +41,7 @@
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
# include <winsock2.h> # include <winsock2.h>
# include <windows.h> # include <windows.h>
# define uintptr_t size_t // FIXME
# define carla_sleep(t) Sleep(t * 1000) # define carla_sleep(t) Sleep(t * 1000)
# define carla_msleep(t) Sleep(t) # define carla_msleep(t) Sleep(t)
# define carla_usleep(t) Sleep(t / 1000) # define carla_usleep(t) Sleep(t / 1000)


+ 19
- 1
c++/carla-includes/carla_osc_includes.h View File

@@ -73,7 +73,7 @@ static inline
void osc_send_control(const CarlaOscData* const oscData, const int32_t index, const float value) void osc_send_control(const CarlaOscData* const oscData, const int32_t index, const float value)
{ {
Q_ASSERT(oscData && oscData->path); 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); qDebug("osc_send_control(path:\"%s\", %i, %f)", oscData->path, index, value);


if (oscData->target) if (oscData->target)
@@ -246,6 +246,24 @@ void osc_send_quit(const CarlaOscData* const oscData)
} }
#endif #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 static inline
void osc_send_lv2_transfer_atom(const CarlaOscData* const oscData, const char* const type, const char* const value) void osc_send_lv2_transfer_atom(const CarlaOscData* const oscData, const char* const type, const char* const value)
{ {


Loading…
Cancel
Save