Browse Source

Continue Carla work for plugin-bridge; Cadence misc fixing

tags/v0.9.0
falkTX 13 years ago
parent
commit
c8201b52d1
19 changed files with 524 additions and 336 deletions
  1. +4
    -4
      Makefile
  2. +36
    -29
      src/cadence.py
  3. +3
    -3
      src/carla-backend/carla_backend.cpp
  4. +0
    -12
      src/carla-backend/carla_backend.h
  5. +248
    -130
      src/carla-backend/carla_bridge.cpp
  6. +1
    -0
      src/carla-backend/carla_engine_jack.cpp
  7. +4
    -0
      src/carla-backend/carla_osc.cpp
  8. +57
    -33
      src/carla-backend/carla_plugin.h
  9. +13
    -0
      src/carla-backend/carla_shared.cpp
  10. +1
    -0
      src/carla-backend/carla_shared.h
  11. +63
    -63
      src/carla-backend/carla_threads.cpp
  12. +0
    -2
      src/carla-backend/vst.cpp
  13. +1
    -0
      src/carla-bridge/carla_bridge.h
  14. +12
    -5
      src/carla-bridge/carla_bridge_osc.cpp
  15. +1
    -1
      src/carla-bridge/carla_bridge_osc.h
  16. +69
    -16
      src/carla-bridge/carla_bridge_plugin.cpp
  17. +5
    -19
      src/carla.py
  18. +0
    -13
      src/carla_backend.py
  19. +6
    -6
      src/jacksettings.py

+ 4
- 4
Makefile View File

@@ -174,19 +174,19 @@ carla_lilv:
$(MAKE) -C src/carla-lilv $(MAKE) -C src/carla-lilv


unix32: unix32:
# $(MAKE) -C src/carla-bridge unix32
$(MAKE) -C src/carla-bridge unix32
$(MAKE) -C src/carla-discovery unix32 $(MAKE) -C src/carla-discovery unix32


unix64: unix64:
# $(MAKE) -C src/carla-bridge unix64
$(MAKE) -C src/carla-bridge unix64
$(MAKE) -C src/carla-discovery unix64 $(MAKE) -C src/carla-discovery unix64


wine32: wine32:
# $(MAKE) -C src/carla-bridge wine32
$(MAKE) -C src/carla-bridge wine32
$(MAKE) -C src/carla-discovery wine32 $(MAKE) -C src/carla-discovery wine32


wine64: wine64:
# $(MAKE) -C src/carla-bridge wine64
$(MAKE) -C src/carla-bridge wine64
$(MAKE) -C src/carla-discovery wine64 $(MAKE) -C src/carla-discovery wine64






+ 36
- 29
src/cadence.py View File

@@ -100,6 +100,9 @@ class CadenceMainW(QMainWindow, ui_cadence.Ui_CadenceMainW):
self.settings = QSettings("Cadence", "Cadence") self.settings = QSettings("Cadence", "Cadence")
self.loadSettings(True) self.loadSettings(True)


# TODO
self.b_jack_restart.setEnabled(False)

# ------------------------------------------------------------- # -------------------------------------------------------------
# System Information # System Information


@@ -162,6 +165,7 @@ class CadenceMainW(QMainWindow, ui_cadence.Ui_CadenceMainW):
self.connect(self.pic_render, SIGNAL("clicked()"), lambda tool="cadence_render": self.func_start_tool(tool)) self.connect(self.pic_render, SIGNAL("clicked()"), lambda tool="cadence_render": self.func_start_tool(tool))
self.connect(self.pic_xycontroller, SIGNAL("clicked()"), lambda tool="cadence_xycontroller": self.func_start_tool(tool)) self.connect(self.pic_xycontroller, SIGNAL("clicked()"), lambda tool="cadence_xycontroller": self.func_start_tool(tool))


self.m_timer120 = None
self.m_timer1000 = self.startTimer(1000) self.m_timer1000 = self.startTimer(1000)


self.DBusReconnect() self.DBusReconnect()
@@ -171,25 +175,24 @@ class CadenceMainW(QMainWindow, ui_cadence.Ui_CadenceMainW):
member_keyword='member', interface_keyword='interface', sender_keyword='sender', ) member_keyword='member', interface_keyword='interface', sender_keyword='sender', )


def DBusReconnect(self): def DBusReconnect(self):
try:
DBus.jack = DBus.bus.get_object("org.jackaudio.service", "/org/jackaudio/Controller")
jacksettings.initBus(DBus.bus)
except:
DBus.jack = None
if haveDBus:
try:
DBus.jack = DBus.bus.get_object("org.jackaudio.service", "/org/jackaudio/Controller")
jacksettings.initBus(DBus.bus)
except:
DBus.jack = None


try:
DBus.a2j = dbus.Interface(DBus.bus.get_object("org.gna.home.a2jmidid", "/"), "org.gna.home.a2jmidid.control")
except:
DBus.a2j = None
try:
DBus.a2j = dbus.Interface(DBus.bus.get_object("org.gna.home.a2jmidid", "/"), "org.gna.home.a2jmidid.control")
except:
DBus.a2j = None


if DBus.jack: if DBus.jack:
if DBus.jack.IsStarted(): if DBus.jack.IsStarted():
self.jackStarted() self.jackStarted()
else: else:
self.jackStopped() self.jackStopped()

# FIXME
self.label_jack_realtime.setText("TODO")
self.label_jack_realtime.setText("Yes" if jacksettings.isRealtime() else "No")
else: else:
self.jackStopped() self.jackStopped()
self.label_jack_status.setText("Unavailable") self.label_jack_status.setText("Unavailable")
@@ -213,6 +216,7 @@ class CadenceMainW(QMainWindow, ui_cadence.Ui_CadenceMainW):
QTimer.singleShot(0, self, SLOT("slot_handleCrash_jack()")) QTimer.singleShot(0, self, SLOT("slot_handleCrash_jack()"))


elif kwds['interface'] == "org.jackaudio.JackControl": elif kwds['interface'] == "org.jackaudio.JackControl":
if DEBUG: print("org.jackaudio.JackControl", kwds['member'])
if kwds['member'] == "ServerStarted": if kwds['member'] == "ServerStarted":
self.jackStarted() self.jackStarted()
elif kwds['member'] == "ServerStopped": elif kwds['member'] == "ServerStopped":
@@ -280,7 +284,10 @@ class CadenceMainW(QMainWindow, ui_cadence.Ui_CadenceMainW):


@pyqtSlot() @pyqtSlot()
def slot_JackServerStop(self): def slot_JackServerStop(self):
DBus.jack.StopServer()
try:
DBus.jack.StopServer()
except:
QMessageBox.warning(self, self.tr("Warning"), self.tr("Failed to stop JACK, please check the logs for more information."))


@pyqtSlot() @pyqtSlot()
def slot_JackServerForceRestart(self): def slot_JackServerForceRestart(self):
@@ -292,7 +299,8 @@ class CadenceMainW(QMainWindow, ui_cadence.Ui_CadenceMainW):


@pyqtSlot() @pyqtSlot()
def slot_JackClearXruns(self): def slot_JackClearXruns(self):
DBus.jack.ResetXruns()
if DBus.jack:
DBus.jack.ResetXruns()


@pyqtSlot() @pyqtSlot()
def slot_handleCrash_a2j(self): def slot_handleCrash_a2j(self):
@@ -316,30 +324,29 @@ class CadenceMainW(QMainWindow, ui_cadence.Ui_CadenceMainW):


def timerEvent(self, event): def timerEvent(self, event):
if event.timerId() == self.m_timer120: if event.timerId() == self.m_timer120:
next_dsp_load = DBus.jack.GetLoad()
next_xruns = DBus.jack.GetXruns()
if DBus.jack and self.m_last_dsp_load != None:
next_dsp_load = DBus.jack.GetLoad()
next_xruns = DBus.jack.GetXruns()


if self.m_last_dsp_load != next_dsp_load:
self.m_last_dsp_load = next_dsp_load
self.label_jack_dsp.setText("%.2f%%" % self.m_last_dsp_load)
if self.m_last_dsp_load != next_dsp_load:
self.m_last_dsp_load = next_dsp_load
self.label_jack_dsp.setText("%.2f%%" % self.m_last_dsp_load)


if self.m_last_xruns != next_xruns:
self.m_last_xruns = next_xruns
self.label_jack_xruns.setText(str(self.m_last_xruns))
if self.m_last_xruns != next_xruns:
self.m_last_xruns = next_xruns
self.label_jack_xruns.setText(str(self.m_last_xruns))


elif event.timerId() == self.m_timer1000: elif event.timerId() == self.m_timer1000:
if DBus.jack and self.m_last_buffer_size != None: if DBus.jack and self.m_last_buffer_size != None:
next_buffer_size = DBus.jack.GetBufferSize() next_buffer_size = DBus.jack.GetBufferSize()
else:
next_buffer_size = None


if self.m_last_buffer_size != next_buffer_size:
self.m_last_buffer_size = next_buffer_size
self.label_jack_bfsize.setText("%i samples" % self.m_last_buffer_size)
self.label_jack_latency.setText("%.1f ms" % DBus.jack.GetLatency())
if self.m_last_buffer_size != next_buffer_size:
self.m_last_buffer_size = next_buffer_size
self.label_jack_bfsize.setText("%i samples" % self.m_last_buffer_size)
self.label_jack_latency.setText("%.1f ms" % DBus.jack.GetLatency())


else: else:
self.update()
self.update()


QMainWindow.timerEvent(self, event) QMainWindow.timerEvent(self, event)




+ 3
- 3
src/carla-backend/carla_backend.cpp View File

@@ -35,7 +35,7 @@ short add_plugin_gig(const char* filename, const char* label);
short add_plugin_sf2(const char* filename, const char* label); short add_plugin_sf2(const char* filename, const char* label);
short add_plugin_sfz(const char* filename, const char* label); short add_plugin_sfz(const char* filename, const char* label);
#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
short add_plugin_bridge(BinaryType btype, PluginType ptype, const char* filename, const char* label, void* extra_stuff);
short add_plugin_bridge(BinaryType btype, PluginType ptype, const char* filename, const char* label);
#endif #endif


CarlaEngine carla_engine; CarlaEngine carla_engine;
@@ -132,8 +132,8 @@ short add_plugin(BinaryType btype, PluginType ptype, const char* filename, const
set_last_error("Cannot use bridged plugins while in global client mode"); set_last_error("Cannot use bridged plugins while in global client mode");
return -1; return -1;
} }
else
return add_plugin_bridge(btype, ptype, filename, label, extra_stuff);
return add_plugin_bridge(btype, ptype, filename, label);
} }
#endif #endif




+ 0
- 12
src/carla-backend/carla_backend.h View File

@@ -237,18 +237,6 @@ struct GuiInfo {
bool resizable; bool resizable;
}; };


struct PluginBridgeInfo {
PluginCategory category;
unsigned int hints;
const char* name;
const char* maker;
long unique_id;
quint32 ains;
quint32 aouts;
quint32 mins;
quint32 mouts;
};

class CarlaPlugin; class CarlaPlugin;


typedef void (*CallbackFunc)(CallbackType action, unsigned short plugin_id, int value1, int value2, double value3); typedef void (*CallbackFunc)(CallbackType action, unsigned short plugin_id, int value1, int value2, double value3);


+ 248
- 130
src/carla-backend/carla_bridge.cpp View File

@@ -27,6 +27,7 @@ CARLA_BACKEND_START_NAMESPACE
#endif #endif


struct BridgeParamInfo { struct BridgeParamInfo {
double value;
QString name; QString name;
QString unit; QString unit;
}; };
@@ -40,19 +41,23 @@ public:
qDebug("BridgePlugin::BridgePlugin()"); qDebug("BridgePlugin::BridgePlugin()");
m_type = ptype; m_type = ptype;
m_hints = PLUGIN_IS_BRIDGE; m_hints = PLUGIN_IS_BRIDGE;
m_label = nullptr;


initiated = saved = false; initiated = saved = false;


m_info.category = PLUGIN_CATEGORY_NONE;
m_info.hints = 0;
m_info.name = nullptr;
m_info.maker = nullptr;
m_info.unique_id = 0;
m_info.ains = 0;
m_info.aouts = 0;
m_info.mins = 0;
m_info.mouts = 0;
info.ains = 0;
info.aouts = 0;
info.mins = 0;
info.mouts = 0;

info.category = PLUGIN_CATEGORY_NONE;
info.uniqueId = 0;

info.label = nullptr;
info.maker = nullptr;
info.chunk = nullptr;
info.copyright = nullptr;

params = nullptr;


m_thread = new CarlaPluginThread(this, CarlaPluginThread::PLUGIN_THREAD_BRIDGE); m_thread = new CarlaPluginThread(this, CarlaPluginThread::PLUGIN_THREAD_BRIDGE);
} }
@@ -84,14 +89,17 @@ public:


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


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


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


if (m_info.maker)
free((void*)m_info.maker);
if (info.copyright)
free((void*)info.copyright);

if (info.chunk)
free((void*)info.chunk);
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -99,12 +107,12 @@ public:


PluginCategory category() PluginCategory category()
{ {
return m_info.category;
return info.category;
} }


long unique_id() long unique_id()
{ {
return m_info.unique_id;
return info.uniqueId;
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -112,22 +120,22 @@ public:


uint32_t ain_count() uint32_t ain_count()
{ {
return m_info.ains;
return info.ains;
} }


uint32_t aout_count() uint32_t aout_count()
{ {
return m_info.aouts;
return info.aouts;
} }


uint32_t min_count() uint32_t min_count()
{ {
return m_info.mins;
return info.mins;
} }


uint32_t mout_count() uint32_t mout_count()
{ {
return m_info.mouts;
return info.mouts;
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -135,22 +143,13 @@ public:


int32_t chunk_data(void** data_ptr) int32_t chunk_data(void** data_ptr)
{ {
// TESTING
QFile sFile("/tmp/test-path2");

if (! sFile.open(QIODevice::ReadOnly | QIODevice::Text))
return 0;

static QByteArray chunk;
chunk = sFile.readAll();

if (chunk.size() >= 0)
if (info.chunk)
{ {
static QByteArray chunk;
chunk = QByteArray::fromBase64(info.chunk);
*data_ptr = chunk.data(); *data_ptr = chunk.data();
return chunk.size(); return chunk.size();
} }


return 0; return 0;
} }


@@ -159,42 +158,45 @@ public:


double get_parameter_value(uint32_t param_id) double get_parameter_value(uint32_t param_id)
{ {
return param_buffers[param_id];
return params[param_id].value;
} }


void get_label(char* buf_str) void get_label(char* buf_str)
{ {
strncpy(buf_str, m_label, STR_MAX);
strncpy(buf_str, info.label, STR_MAX);
} }


void get_maker(char* buf_str) void get_maker(char* buf_str)
{ {
strncpy(buf_str, m_info.maker, STR_MAX);
strncpy(buf_str, info.maker, STR_MAX);
} }


void get_copyright(char* buf_str) void get_copyright(char* buf_str)
{ {
strncpy(buf_str, m_info.maker, STR_MAX);
strncpy(buf_str, info.copyright, STR_MAX);
} }


void get_real_name(char* buf_str) void get_real_name(char* buf_str)
{ {
strncpy(buf_str, m_info.name, STR_MAX);
strncpy(buf_str, info.name, STR_MAX);
} }


void get_parameter_name(uint32_t param_id, char* buf_str) void get_parameter_name(uint32_t param_id, char* buf_str)
{ {
strncpy(buf_str, param_info[param_id].name.toUtf8().constData(), STR_MAX);
strncpy(buf_str, params[param_id].name.toUtf8().constData(), STR_MAX);
} }


void get_parameter_unit(uint32_t param_id, char* buf_str) void get_parameter_unit(uint32_t param_id, char* buf_str)
{ {
strncpy(buf_str, param_info[param_id].unit.toUtf8().constData(), STR_MAX);
strncpy(buf_str, params[param_id].unit.toUtf8().constData(), STR_MAX);
} }


void get_gui_info(GuiInfo* info) void get_gui_info(GuiInfo* info)
{ {
info->type = GUI_NONE;
if (m_hints & PLUGIN_HAS_GUI)
info->type = GUI_EXTERNAL_OSC;
else
info->type = GUI_NONE;
info->resizable = false; info->resizable = false;
} }


@@ -205,49 +207,56 @@ public:
{ {
qDebug("set_osc_bridge_info(%i, %p)", intoType, argv); qDebug("set_osc_bridge_info(%i, %p)", intoType, argv);


// PluginBridgeProgramCountInfo,
// PluginBridgeMidiProgramCountInfo,
// PluginBridgePluginInfo,
// PluginBridgeParameterInfo,

// PluginBridgeProgramInfo,
// PluginBridgeMidiProgramInfo,

switch (intoType) switch (intoType)
{ {
case PluginBridgeAudioCount: case PluginBridgeAudioCount:
{ {
m_info.ains = argv[0]->i;
m_info.aouts = argv[1]->i;
int aIns = argv[0]->i;
int aOuts = argv[1]->i;
int aTotal = argv[2]->i;

info.ains = aIns;
info.aouts = aOuts;

Q_UNUSED(aTotal);
break; break;
} }


case PluginBridgeMidiCount: case PluginBridgeMidiCount:
{ {
m_info.mins = argv[0]->i;
m_info.mouts = argv[1]->i;
int mIns = argv[0]->i;
int mOuts = argv[1]->i;
int mTotal = argv[2]->i;

info.mins = mIns;
info.mouts = mOuts;

Q_UNUSED(mTotal);
break; break;
} }


case PluginBridgeParameterCount: case PluginBridgeParameterCount:
{ {
int pIns = argv[0]->i;
int pOuts = argv[1]->i;
int pTotal = argv[2]->i;

// delete old data // delete old data
if (param.count > 0) if (param.count > 0)
{ {
delete[] param.data; delete[] param.data;
delete[] param.ranges; delete[] param.ranges;
delete[] param_buffers;
delete[] params;
} }


// create new if needed // create new if needed
param.count = argv[2]->i;
param.count = pTotal;


if (param.count > 0 && param.count < carla_options.max_parameters) if (param.count > 0 && param.count < carla_options.max_parameters)
{ {
param.data = new ParameterData[param.count];
param.ranges = new ParameterRanges[param.count];
param_buffers = new double[param.count];
param_info = new BridgeParamInfo[param.count];
param.data = new ParameterData[param.count];
param.ranges = new ParameterRanges[param.count];
params = new BridgeParamInfo[param.count];
} }
else else
param.count = 0; param.count = 0;
@@ -269,21 +278,110 @@ public:
param.ranges[i].step_small = 0.0001; param.ranges[i].step_small = 0.0001;
param.ranges[i].step_large = 0.1; param.ranges[i].step_large = 0.1;


param_buffers[i] = 0.0;
params[i].value = 0.0;
params[i].name = QString();
params[i].unit = QString();
}


param_info[i].name = QString();
param_info[i].unit = QString();
Q_UNUSED(pIns);
Q_UNUSED(pOuts);
break;
}

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; 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:
{
int category = argv[0]->i;
int hints = argv[1]->i;
const char* name = (const char*)&argv[2]->s;
const char* label = (const char*)&argv[3]->s;
const char* maker = (const char*)&argv[4]->s;
const char* copyright = (const char*)&argv[5]->s;
long unique_id = argv[6]->i;

m_hints = hints | PLUGIN_IS_BRIDGE;
info.category = (PluginCategory)category;
info.uniqueId = unique_id;

info.name = strdup(name);
info.label = strdup(label);
info.maker = strdup(maker);
info.copyright = strdup(copyright);

m_name = get_unique_name(name);
}

case PluginBridgeParameterInfo: case PluginBridgeParameterInfo:
{ {
int index = argv[0]->i; 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) if (index >= 0 && index < (int32_t)param.count)
{ {
param_info[index].name = QString((const char*)&argv[1]->s);
param_info[index].unit = QString((const char*)&argv[2]->s);
params[index].name = QString(name);
params[index].unit = QString(unit);
} }
break; break;
} }
@@ -318,6 +416,47 @@ public:
break; break;
} }


case PluginBridgeProgramInfo:
{
int index = argv[0]->i;
const char* name = (const char*)&argv[1]->s;

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;

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;

set_custom_data(customdatastr2type(stype), key, value, false);
break;
}

case PluginBridgeChunkData:
{
const char* string_data = (const char*)&argv[0]->s;
if (info.chunk)
free((void*)info.chunk);
info.chunk = strdup(string_data);
break;
}

case PluginBridgeUpdateNow: case PluginBridgeUpdateNow:
callback_action(CALLBACK_RELOAD_ALL, m_id, 0, 0, 0.0); callback_action(CALLBACK_RELOAD_ALL, m_id, 0, 0, 0.0);
initiated = true; initiated = true;
@@ -336,7 +475,7 @@ public:


void set_parameter_value(uint32_t param_id, double value, bool gui_send, bool osc_send, bool callback_send) void set_parameter_value(uint32_t param_id, double value, bool gui_send, bool osc_send, bool callback_send)
{ {
param_buffers[param_id] = fix_parameter_value(value, param.ranges[param_id]);
params[param_id].value = fix_parameter_value(value, param.ranges[param_id]);


if (gui_send) if (gui_send)
osc_send_control(&osc.data, param.data[param_id].rindex, value); osc_send_control(&osc.data, param.data[param_id].rindex, value);
@@ -344,6 +483,11 @@ public:
CarlaPlugin::set_parameter_value(param_id, value, gui_send, osc_send, callback_send); CarlaPlugin::set_parameter_value(param_id, value, gui_send, osc_send, callback_send);
} }


void set_chunk_data(const char* string_data)
{
osc_send_configure(&osc.data, "CarlaBridgeChunk", string_data);
}

// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Set gui stuff // Set gui stuff


@@ -360,26 +504,12 @@ public:


void reload() void reload()
{ {
// plugin checks
m_hints &= ~(PLUGIN_IS_SYNTH | PLUGIN_USES_CHUNKS | PLUGIN_CAN_DRYWET | PLUGIN_CAN_VOLUME | PLUGIN_CAN_BALANCE);

if (m_info.aouts > 0 && (m_info.ains == m_info.aouts || m_info.ains == 1))
m_hints |= PLUGIN_CAN_DRYWET;

if (m_info.aouts > 0)
m_hints |= PLUGIN_CAN_VOLUME;

if (m_info.aouts >= 2 && m_info.aouts % 2 == 0)
m_hints |= PLUGIN_CAN_BALANCE;

m_hints |= m_info.hints;
m_hints |= PLUGIN_USES_CHUNKS; // FIXME
} }


void prepare_for_save() void prepare_for_save()
{ {
saved = false; saved = false;
osc_send_configure(&osc.data, "CarlaBridgeSaveNow", "/tmp/test-path2");
osc_send_configure(&osc.data, "CarlaBridgeSaveNow", "");


for (int i=0; i < 100; i++) for (int i=0; i < 100; i++)
{ {
@@ -401,63 +531,41 @@ public:
qDebug("BridgePlugin::delete_buffers() - start"); qDebug("BridgePlugin::delete_buffers() - start");


if (param.count > 0) if (param.count > 0)
{
delete[] param_buffers;
delete[] param_info;
}
delete[] params;


param_buffers = nullptr;
param_info = nullptr;
params = nullptr;


qDebug("BridgePlugin::delete_buffers() - end"); qDebug("BridgePlugin::delete_buffers() - end");
} }


bool init(const char* filename, const char* label, PluginBridgeInfo* info)
bool init(const char* filename, const char* label)
{ {
if (info)
const char* bridge_binary = binarytype2str(m_binary);

if (bridge_binary)
{ {
m_info.category = info->category;
m_info.hints = info->hints;
m_info.unique_id = info->unique_id;
m_info.ains = info->ains;
m_info.aouts = info->aouts;
m_info.mins = info->mins;
m_info.mouts = info->mouts;

m_info.name = strdup(info->name);
m_info.maker = strdup(info->maker);

m_label = strdup(label);
m_name = get_unique_name(info->name);
m_filename = strdup(filename); m_filename = strdup(filename);


const char* bridge_binary = binarytype2str(m_binary);

if (bridge_binary)
{
// register plugin now so we can receive OSC (and wait for it)
CarlaPlugins[m_id] = this;
// register plugin now so we can receive OSC (and wait for it)
CarlaPlugins[m_id] = this;


m_thread->setOscData(bridge_binary, label, plugintype2str(m_type));
m_thread->start();
m_thread->setOscData(bridge_binary, label, plugintype2str(m_type));
m_thread->start();


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


if (! initiated)
set_last_error("Timeout while waiting for a response from plugin-bridge");
if (! initiated)
set_last_error("Timeout while waiting for a response from plugin-bridge");


return initiated;
}
else
set_last_error("Bridge not possible, bridge-binary not found");
return initiated;
} }
else else
set_last_error("Invalid bridge info, cannot continue");
set_last_error("Bridge not possible, bridge-binary not found");


return false; return false;
} }
@@ -465,18 +573,28 @@ public:
private: private:
bool initiated; bool initiated;
bool saved; bool saved;
const char* m_label;
const BinaryType m_binary; const BinaryType m_binary;
PluginBridgeInfo m_info;
CarlaPluginThread* m_thread; CarlaPluginThread* m_thread;


double* param_buffers;
BridgeParamInfo* param_info;
struct {
uint32_t ains, aouts;
uint32_t mins, mouts;
PluginCategory category;
long uniqueId;
const char* name;
const char* label;
const char* maker;
const char* copyright;
const char* chunk;
} info;

BridgeParamInfo* params;
}; };


short add_plugin_bridge(BinaryType btype, PluginType ptype, const char* filename, const char* label, void* extra_stuff)
short add_plugin_bridge(BinaryType btype, PluginType ptype, const char* filename, const char* label)
{ {
qDebug("add_plugin_bridge(%i, %i, %s, %s, %p)", btype, ptype, filename, label, extra_stuff);
qDebug("add_plugin_bridge(%i, %i, %s, %s)", btype, ptype, filename, label);


short id = get_new_plugin_id(); short id = get_new_plugin_id();


@@ -484,7 +602,7 @@ short add_plugin_bridge(BinaryType btype, PluginType ptype, const char* filename
{ {
BridgePlugin* plugin = new BridgePlugin(btype, ptype, id); BridgePlugin* plugin = new BridgePlugin(btype, ptype, id);


if (plugin->init(filename, label, (PluginBridgeInfo*)extra_stuff))
if (plugin->init(filename, label))
{ {
plugin->reload(); plugin->reload();




+ 1
- 0
src/carla-backend/carla_engine_jack.cpp View File

@@ -21,6 +21,7 @@
#include "carla_plugin.h" #include "carla_plugin.h"


#include <iostream> #include <iostream>
#include <QtCore/QThread>


CARLA_BACKEND_START_NAMESPACE CARLA_BACKEND_START_NAMESPACE




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

@@ -220,6 +220,10 @@ int osc_message_handler(const char* path, const char* types, lo_arg** argv, int
return plugin->set_osc_bridge_info(PluginBridgeProgramInfo, argv); return plugin->set_osc_bridge_info(PluginBridgeProgramInfo, argv);
if (strcmp(method, "/bridge_midi_program_info") == 0) if (strcmp(method, "/bridge_midi_program_info") == 0)
return plugin->set_osc_bridge_info(PluginBridgeMidiProgramInfo, argv); return plugin->set_osc_bridge_info(PluginBridgeMidiProgramInfo, argv);
if (strcmp(method, "/bridge_custom_data") == 0)
return plugin->set_osc_bridge_info(PluginBridgeCustomData, argv);
if (strcmp(method, "/bridge_chunk_data") == 0)
return plugin->set_osc_bridge_info(PluginBridgeChunkData, argv);
if (strcmp(method, "/bridge_update") == 0) if (strcmp(method, "/bridge_update") == 0)
return plugin->set_osc_bridge_info(PluginBridgeUpdateNow, argv); return plugin->set_osc_bridge_info(PluginBridgeUpdateNow, argv);
} }


+ 57
- 33
src/carla-backend/carla_plugin.h View File

@@ -24,7 +24,6 @@
#include "carla_shared.h" #include "carla_shared.h"


#ifdef BUILD_BRIDGE #ifdef BUILD_BRIDGE
#include <QtCore/QThread>
#include "carla_bridge_osc.h" #include "carla_bridge_osc.h"
#else #else
#include "carla_osc.h" #include "carla_osc.h"
@@ -83,6 +82,8 @@ enum PluginBridgeInfoType {
PluginBridgeParameterRangesInfo, PluginBridgeParameterRangesInfo,
PluginBridgeProgramInfo, PluginBridgeProgramInfo,
PluginBridgeMidiProgramInfo, PluginBridgeMidiProgramInfo,
PluginBridgeCustomData,
PluginBridgeChunkData,
PluginBridgeUpdateNow, PluginBridgeUpdateNow,
PluginBridgeSaved PluginBridgeSaved
}; };
@@ -518,6 +519,9 @@ public:


double value = active ? 1.0 : 0.0; double value = active ? 1.0 : 0.0;


if (callback_send)
callback_action(CALLBACK_PARAMETER_CHANGED, m_id, PARAMETER_ACTIVE, 0, value);

#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
if (osc_send) if (osc_send)
{ {
@@ -529,9 +533,6 @@ public:
#else #else
Q_UNUSED(osc_send); Q_UNUSED(osc_send);
#endif #endif

if (callback_send)
callback_action(CALLBACK_PARAMETER_CHANGED, m_id, PARAMETER_ACTIVE, 0, value);
} }


void set_drywet(double value, bool osc_send, bool callback_send) void set_drywet(double value, bool osc_send, bool callback_send)
@@ -543,6 +544,9 @@ public:


x_drywet = value; x_drywet = value;


if (callback_send)
callback_action(CALLBACK_PARAMETER_CHANGED, m_id, PARAMETER_DRYWET, 0, value);

#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
if (osc_send) if (osc_send)
{ {
@@ -554,9 +558,6 @@ public:
#else #else
Q_UNUSED(osc_send); Q_UNUSED(osc_send);
#endif #endif

if (callback_send)
callback_action(CALLBACK_PARAMETER_CHANGED, m_id, PARAMETER_DRYWET, 0, value);
} }


void set_volume(double value, bool osc_send, bool callback_send) void set_volume(double value, bool osc_send, bool callback_send)
@@ -568,6 +569,9 @@ public:


x_vol = value; x_vol = value;


if (callback_send)
callback_action(CALLBACK_PARAMETER_CHANGED, m_id, PARAMETER_VOLUME, 0, value);

#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
if (osc_send) if (osc_send)
{ {
@@ -582,9 +586,6 @@ public:
#else #else
Q_UNUSED(osc_send); Q_UNUSED(osc_send);
#endif #endif

if (callback_send)
callback_action(CALLBACK_PARAMETER_CHANGED, m_id, PARAMETER_VOLUME, 0, value);
} }


void set_balance_left(double value, bool osc_send, bool callback_send) void set_balance_left(double value, bool osc_send, bool callback_send)
@@ -596,6 +597,9 @@ public:


x_bal_left = value; x_bal_left = value;


if (callback_send)
callback_action(CALLBACK_PARAMETER_CHANGED, m_id, PARAMETER_BALANCE_LEFT, 0, value);

#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
if (osc_send) if (osc_send)
{ {
@@ -607,9 +611,6 @@ public:
#else #else
Q_UNUSED(osc_send); Q_UNUSED(osc_send);
#endif #endif

if (callback_send)
callback_action(CALLBACK_PARAMETER_CHANGED, m_id, PARAMETER_BALANCE_LEFT, 0, value);
} }


void set_balance_right(double value, bool osc_send, bool callback_send) void set_balance_right(double value, bool osc_send, bool callback_send)
@@ -621,6 +622,9 @@ public:


x_bal_right = value; x_bal_right = value;


if (callback_send)
callback_action(CALLBACK_PARAMETER_CHANGED, m_id, PARAMETER_BALANCE_RIGHT, 0, value);

#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
if (osc_send) if (osc_send)
{ {
@@ -632,9 +636,6 @@ public:
#else #else
Q_UNUSED(osc_send); Q_UNUSED(osc_send);
#endif #endif

if (callback_send)
callback_action(CALLBACK_PARAMETER_CHANGED, m_id, PARAMETER_BALANCE_RIGHT, 0, value);
} }


#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
@@ -652,9 +653,13 @@ public:
virtual void set_parameter_value(uint32_t param_id, double value, bool gui_send, bool osc_send, bool callback_send) virtual void set_parameter_value(uint32_t param_id, double value, bool gui_send, bool osc_send, bool callback_send)
{ {
assert(param_id < param.count); assert(param_id < param.count);

if (param.data[param_id].type != PARAMETER_INPUT) if (param.data[param_id].type != PARAMETER_INPUT)
return; return;


if (callback_send)
callback_action(CALLBACK_PARAMETER_CHANGED, m_id, param_id, 0, value);

#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
if (osc_send) if (osc_send)
{ {
@@ -666,16 +671,11 @@ public:
#else #else
Q_UNUSED(osc_send); Q_UNUSED(osc_send);
#endif #endif

if (callback_send)
callback_action(CALLBACK_PARAMETER_CHANGED, m_id, param_id, 0, value);

Q_UNUSED(gui_send); Q_UNUSED(gui_send);
} }


void set_parameter_value_by_rindex(int32_t rindex, double value, bool gui_send, bool osc_send, bool callback_send) void set_parameter_value_by_rindex(int32_t rindex, double value, bool gui_send, bool osc_send, bool callback_send)
{ {
#ifdef BUILD_BRIDGE
if (rindex == PARAMETER_ACTIVE) if (rindex == PARAMETER_ACTIVE)
return set_active(value > 0.0, osc_send, callback_send); return set_active(value > 0.0, osc_send, callback_send);
if (rindex == PARAMETER_DRYWET) if (rindex == PARAMETER_DRYWET)
@@ -686,7 +686,6 @@ public:
return set_balance_left(value, osc_send, callback_send); return set_balance_left(value, osc_send, callback_send);
if (rindex == PARAMETER_BALANCE_RIGHT) if (rindex == PARAMETER_BALANCE_RIGHT)
return set_balance_right(value, osc_send, callback_send); return set_balance_right(value, osc_send, callback_send);
#endif


for (uint32_t i=0; i < param.count; i++) for (uint32_t i=0; i < param.count; i++)
{ {
@@ -697,7 +696,7 @@ public:


void set_parameter_midi_channel(uint32_t index, uint8_t channel) void set_parameter_midi_channel(uint32_t index, uint8_t channel)
{ {
assert(index < param.count);
assert(index < param.count && channel < 16);
param.data[index].midi_channel = channel; param.data[index].midi_channel = channel;


#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
@@ -773,6 +772,9 @@ public:
{ {
prog.current = index; prog.current = index;


if (callback_send)
callback_action(CALLBACK_PROGRAM_CHANGED, m_id, prog.current, 0, 0.0);

#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
if (osc_send) if (osc_send)
{ {
@@ -781,12 +783,8 @@ public:
if (m_hints & PLUGIN_IS_BRIDGE) if (m_hints & PLUGIN_IS_BRIDGE)
osc_send_program(&osc.data, prog.current); osc_send_program(&osc.data, prog.current);
} }

if (callback_send)
callback_action(CALLBACK_PROGRAM_CHANGED, m_id, prog.current, 0, 0.0);
#else #else
Q_UNUSED(osc_send); Q_UNUSED(osc_send);
Q_UNUSED(callback_send);
#endif #endif


// Change default parameter values // Change default parameter values
@@ -808,6 +806,9 @@ public:
{ {
midiprog.current = index; midiprog.current = index;


if (callback_send)
callback_action(CALLBACK_MIDI_PROGRAM_CHANGED, m_id, midiprog.current, 0, 0.0);

#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
if (osc_send) if (osc_send)
{ {
@@ -816,12 +817,8 @@ public:
if (m_hints & PLUGIN_IS_BRIDGE) if (m_hints & PLUGIN_IS_BRIDGE)
osc_send_program(&osc.data, midiprog.current); osc_send_program(&osc.data, midiprog.current);
} }

if (callback_send)
callback_action(CALLBACK_MIDI_PROGRAM_CHANGED, m_id, midiprog.current, 0, 0.0);
#else #else
Q_UNUSED(osc_send); Q_UNUSED(osc_send);
Q_UNUSED(callback_send);
#endif #endif


// Sound banks never change defaults // Sound banks never change defaults
@@ -948,8 +945,17 @@ public:
{ {
#ifdef BUILD_BRIDGE #ifdef BUILD_BRIDGE
// Base data // Base data
//const PluginInfo* info = get_plugin_info(m_id);
//osc_send_bridge_plugin_info(m_type, category(), m_hints, get_real_plugin_name(m_id), info->label, info->maker, info->copyright, unique_id());
{
char buf_name[STR_MAX] = { 0 };
char buf_label[STR_MAX] = { 0 };
char buf_maker[STR_MAX] = { 0 };
char buf_copyright[STR_MAX] = { 0 };
get_real_name(buf_name);
get_label(buf_label);
get_maker(buf_maker);
get_copyright(buf_copyright);
osc_send_bridge_plugin_info(category(), m_hints, buf_name, buf_label, buf_maker, buf_copyright, unique_id());
}


osc_send_bridge_audio_count(ain_count(), aout_count(), ain_count() + aout_count()); osc_send_bridge_audio_count(ain_count(), aout_count(), ain_count() + aout_count());
osc_send_bridge_midi_count(min_count(), mout_count(), min_count() + mout_count()); osc_send_bridge_midi_count(min_count(), mout_count(), min_count() + mout_count());
@@ -975,6 +981,24 @@ public:
set_parameter_value(i, param.ranges[i].def, false, false, true); set_parameter_value(i, param.ranges[i].def, false, false, true);
} }
} }

// Programs
osc_send_bridge_program_count(prog.count);

for (i=0; i < prog.count; i++)
osc_send_bridge_program_info(i, prog.names[i]);

if (prog.current >= 0)
osc_send_program(prog.current);

// MIDI Programs
osc_send_bridge_midi_program_count(midiprog.count);

for (i=0; i < midiprog.count; i++)
osc_send_bridge_midi_program_info(i, midiprog.data[i].bank, midiprog.data[i].program, midiprog.data[i].name);

if (midiprog.current >= 0 && midiprog.count > 0)
osc_send_midi_program(midiprog.data[midiprog.current].bank, midiprog.data[midiprog.current].program, false);
#else #else
if (osc_global_registered()) if (osc_global_registered())
{ {


+ 13
- 0
src/carla-backend/carla_shared.cpp View File

@@ -146,6 +146,19 @@ const char* customdatatype2str(CustomDataType type)
} }
} }


CustomDataType customdatastr2type(const char* stype)
{
if (strcmp(stype, "string") == 0)
return CUSTOM_DATA_STRING;
if (strcmp(stype, "path") == 0)
return CUSTOM_DATA_PATH;
if (strcmp(stype, "chunk") == 0)
return CUSTOM_DATA_CHUNK;
if (strcmp(stype, "binary") == 0)
return CUSTOM_DATA_BINARY;
return CUSTOM_DATA_INVALID;
}

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


short get_new_plugin_id() short get_new_plugin_id()


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

@@ -30,6 +30,7 @@ const char* bool2str(bool yesno);
const char* plugintype2str(PluginType type); const char* plugintype2str(PluginType type);
const char* binarytype2str(BinaryType type); const char* binarytype2str(BinaryType type);
const char* customdatatype2str(CustomDataType type); const char* customdatatype2str(CustomDataType type);
CustomDataType customdatastr2type(const char* stype);


short get_new_plugin_id(); short get_new_plugin_id();
const char* get_unique_name(const char* name); const char* get_unique_name(const char* name);


+ 63
- 63
src/carla-backend/carla_threads.cpp View File

@@ -72,95 +72,95 @@ void CarlaCheckThread::run()
// Process events now // Process events now
for (j=0; j < MAX_POST_EVENTS; j++) for (j=0; j < MAX_POST_EVENTS; j++)
{ {
if (postEvents[j].type != PluginPostEventNull)
if (postEvents[j].type == PluginPostEventNull)
break;

switch (postEvents[j].type)
{ {
switch (postEvents[j].type)
{
case PluginPostEventDebug:
callback_action(CALLBACK_DEBUG, plugin->id(), postEvents[j].index, 0, postEvents[j].value);
break;
case PluginPostEventDebug:
callback_action(CALLBACK_DEBUG, plugin->id(), postEvents[j].index, 0, postEvents[j].value);
break;


case PluginPostEventParameterChange:
// Update OSC based UIs
osc_send_control(osc_data, postEvents[j].index, postEvents[j].value);
case PluginPostEventParameterChange:
// Update OSC based UIs
osc_send_control(osc_data, postEvents[j].index, postEvents[j].value);


// Update OSC control client
osc_global_send_set_parameter_value(plugin->id(), postEvents[j].index, postEvents[j].value);
// Update OSC control client
osc_global_send_set_parameter_value(plugin->id(), postEvents[j].index, postEvents[j].value);


// Update Host
callback_action(CALLBACK_PARAMETER_CHANGED, plugin->id(), postEvents[j].index, 0, postEvents[j].value);
// Update Host
callback_action(CALLBACK_PARAMETER_CHANGED, plugin->id(), postEvents[j].index, 0, postEvents[j].value);


break;
break;


case PluginPostEventProgramChange:
// Update OSC based UIs
osc_send_program(osc_data, postEvents[j].index);
case PluginPostEventProgramChange:
// Update OSC based UIs
osc_send_program(osc_data, postEvents[j].index);


// Update OSC control client
osc_global_send_set_program(plugin->id(), postEvents[j].index);
// Update OSC control client
osc_global_send_set_program(plugin->id(), postEvents[j].index);


for (k=0; k < plugin->param_count(); k++)
osc_global_send_set_default_value(plugin->id(), k, plugin->param_ranges(k)->def);
for (k=0; k < plugin->param_count(); k++)
osc_global_send_set_default_value(plugin->id(), k, plugin->param_ranges(k)->def);


// Update Host
callback_action(CALLBACK_PROGRAM_CHANGED, plugin->id(), postEvents[j].index, 0, 0.0);
// Update Host
callback_action(CALLBACK_PROGRAM_CHANGED, plugin->id(), postEvents[j].index, 0, 0.0);


break;
break;


case PluginPostEventMidiProgramChange:
if (postEvents[j].index < (int32_t)plugin->midiprog_count())
{
MidiProgramInfo midiprog = { false, 0, 0, nullptr };
plugin->get_midi_program_info(&midiprog, postEvents[j].index);
case PluginPostEventMidiProgramChange:
if (postEvents[j].index < (int32_t)plugin->midiprog_count())
{
MidiProgramInfo midiprog = { false, 0, 0, nullptr };
plugin->get_midi_program_info(&midiprog, postEvents[j].index);


// Update OSC based UIs
osc_send_midi_program(osc_data, midiprog.bank, midiprog.program, (plugin->type() == PLUGIN_DSSI));
// Update OSC based UIs
osc_send_midi_program(osc_data, midiprog.bank, midiprog.program, (plugin->type() == PLUGIN_DSSI));


// Update OSC control client
osc_global_send_set_midi_program(plugin->id(), postEvents[j].index);
// Update OSC control client
osc_global_send_set_midi_program(plugin->id(), postEvents[j].index);


for (k=0; k < plugin->param_count(); k++)
osc_global_send_set_default_value(plugin->id(), k, plugin->param_ranges(k)->def);
for (k=0; k < plugin->param_count(); k++)
osc_global_send_set_default_value(plugin->id(), k, plugin->param_ranges(k)->def);


// Update Host
callback_action(CALLBACK_MIDI_PROGRAM_CHANGED, plugin->id(), postEvents[j].index, 0, 0.0);
}
// Update Host
callback_action(CALLBACK_MIDI_PROGRAM_CHANGED, plugin->id(), postEvents[j].index, 0, 0.0);
}


break;
break;


case PluginPostEventNoteOn:
// Update OSC based UIs
//if (plugin->type() == PLUGIN_LV2)
// osc_send_note_on(osc_data, plugin->id(), post_events[j].index, post_events[j].value);
case PluginPostEventNoteOn:
// Update OSC based UIs
//if (plugin->type() == PLUGIN_LV2)
// osc_send_note_on(osc_data, plugin->id(), post_events[j].index, post_events[j].value);


// Update OSC control client
osc_global_send_note_on(plugin->id(), postEvents[j].index, postEvents[j].value);
// Update OSC control client
osc_global_send_note_on(plugin->id(), postEvents[j].index, postEvents[j].value);


// Update Host
callback_action(CALLBACK_NOTE_ON, plugin->id(), postEvents[j].index, postEvents[j].value, 0.0);
// Update Host
callback_action(CALLBACK_NOTE_ON, plugin->id(), postEvents[j].index, postEvents[j].value, 0.0);


break;
break;


case PluginPostEventNoteOff:
// Update OSC based UIs
//if (plugin->type() == PLUGIN_LV2)
// osc_send_note_off(osc_data, plugin->id(), post_events[j].index, 0);
case PluginPostEventNoteOff:
// Update OSC based UIs
//if (plugin->type() == PLUGIN_LV2)
// osc_send_note_off(osc_data, plugin->id(), post_events[j].index, 0);


// Update OSC control client
osc_global_send_note_off(plugin->id(), postEvents[j].index);
// Update OSC control client
osc_global_send_note_off(plugin->id(), postEvents[j].index);


// Update Host
callback_action(CALLBACK_NOTE_OFF, plugin->id(), postEvents[j].index, 0, 0.0);
// Update Host
callback_action(CALLBACK_NOTE_OFF, plugin->id(), postEvents[j].index, 0, 0.0);


break;
break;


case PluginPostEventCustom:
plugin->run_custom_event(&postEvents[j]);
break;
case PluginPostEventCustom:
plugin->run_custom_event(&postEvents[j]);
break;


default:
break;
}
default:
break;
} }
} }




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

@@ -1286,14 +1286,12 @@ class VstPlugin : public CarlaPlugin
case audioMasterAutomate: case audioMasterAutomate:
if (self) if (self)
{ {
#ifndef BUILD_BRIDGE // FIXME
if (CarlaEngine::isOnAudioThread()) if (CarlaEngine::isOnAudioThread())
{ {
self->set_parameter_value(index, opt, false, false, false); self->set_parameter_value(index, opt, false, false, false);
self->postpone_event(PluginPostEventParameterChange, index, opt); self->postpone_event(PluginPostEventParameterChange, index, opt);
} }
else else
#endif
self->set_parameter_value(index, opt, false, true, true); self->set_parameter_value(index, opt, false, true, true);
} }
break; break;


+ 1
- 0
src/carla-bridge/carla_bridge.h View File

@@ -185,6 +185,7 @@ public:
#ifdef BUILD_BRIDGE_PLUGIN #ifdef BUILD_BRIDGE_PLUGIN
// plugin // plugin
virtual void save_now() = 0; virtual void save_now() = 0;
virtual void set_chunk_data(const char* string_data) = 0;
#else #else
// gui // gui
virtual void* get_widget() const = 0; virtual void* get_widget() const = 0;


+ 12
- 5
src/carla-bridge/carla_bridge_osc.cpp View File

@@ -161,10 +161,16 @@ int osc_handle_configure(lo_arg** argv)
{ {
#ifdef BUILD_BRIDGE_PLUGIN #ifdef BUILD_BRIDGE_PLUGIN
const char* key = (const char*)&argv[0]->s; const char* key = (const char*)&argv[0]->s;
//const char* value = (const char*)&argv[1]->s;
const char* value = (const char*)&argv[1]->s;

if (client)
{
if (strcmp(key, "CarlaBridgeSaveNow") == 0)
client->save_now();
else if (strcmp(key, "CarlaBridgeChunk") == 0)
client->set_chunk_data(value);
}


if (client && strcmp(key, "CarlaBridgeSaveNow") == 0)
client->save_now();
#else #else
Q_UNUSED(argv); Q_UNUSED(argv);
#endif #endif
@@ -415,14 +421,15 @@ void osc_send_bridge_midi_program_count(int count)
} }
} }


void osc_send_bridge_plugin_info(int type, int category, int hints, const char* name, const char* label, const char* maker, const char* copyright, long unique_id)
void osc_send_bridge_plugin_info(int category, int hints, const char* name, const char* label, const char* maker, const char* copyright, long unique_id)
{ {
if (global_osc_data.target) if (global_osc_data.target)
{ {
char target_path[strlen(global_osc_data.path)+20]; char target_path[strlen(global_osc_data.path)+20];
strcpy(target_path, global_osc_data.path); strcpy(target_path, global_osc_data.path);
strcat(target_path, "/bridge_plugin_info"); strcat(target_path, "/bridge_plugin_info");
lo_send(global_osc_data.target, target_path, "iiissssh", type, category, hints, name, label, maker, copyright, unique_id);
lo_send(global_osc_data.target, target_path, "iissssi", category, hints, name, label, maker, copyright, unique_id);
// FIXME - should be long type
} }
} }




+ 1
- 1
src/carla-bridge/carla_bridge_osc.h View File

@@ -32,7 +32,7 @@ void osc_send_bridge_midi_count(int ins, int outs, int total);
void osc_send_bridge_param_count(int ins, int outs, int total); void osc_send_bridge_param_count(int ins, int outs, int total);
void osc_send_bridge_program_count(int count); void osc_send_bridge_program_count(int count);
void osc_send_bridge_midi_program_count(int count); void osc_send_bridge_midi_program_count(int count);
void osc_send_bridge_plugin_info(int type, int category, int hints, const char* name, const char* label, const char* maker, const char* copyright, long unique_id);
void osc_send_bridge_plugin_info(int category, int hints, const char* name, const char* label, const char* maker, const char* copyright, long unique_id);
void osc_send_bridge_param_info(int index, const char* name, const char* unit); void osc_send_bridge_param_info(int index, const char* name, const char* unit);
void osc_send_bridge_param_data(int index, int type, int rindex, int hints, int midi_channel, int midi_cc); void osc_send_bridge_param_data(int index, int type, int rindex, int hints, int midi_channel, int midi_cc);
void osc_send_bridge_param_ranges(int index, double def, double min, double max, double step, double step_small, double step_large); void osc_send_bridge_param_ranges(int index, double def, double min, double max, double step, double step_small, double step_large);


+ 69
- 16
src/carla-bridge/carla_bridge_plugin.cpp View File

@@ -80,12 +80,12 @@ public:
toolkit_plugin_idle(); toolkit_plugin_idle();
} }


//Q_SLOT guiClosed()
//{
Q_SLOT void guiClosed()
{
//if (client) //if (client)
// client->queque_message(BRIDGE_MESSAGE_SHOW_GUI, 0, 0, 0.0); // client->queque_message(BRIDGE_MESSAGE_SHOW_GUI, 0, 0, 0.0);
//osc_send_configure("CarlaBridgeHideGUI", "");
//}
osc_send_configure("CarlaBridgeHideGUI", "");
}
}; };
static QApplication* app = nullptr; static QApplication* app = nullptr;
static QDialog* gui = nullptr; static QDialog* gui = nullptr;
@@ -132,19 +132,36 @@ void toolkit_plugin_idle()


CARLA_PLUGIN->idle_gui(); CARLA_PLUGIN->idle_gui();


if (CARLA_PLUGIN->ain_count() > 0)
{
osc_send_bridge_ains_peak(1, ains_peak[0]);
osc_send_bridge_ains_peak(2, ains_peak[1]);
}
static const ParameterData* param_data;
static PluginPostEvent postEvents[MAX_POST_EVENTS];
CARLA_PLUGIN->post_events_copy(postEvents);


if (CARLA_PLUGIN->aout_count() > 0)
for (uint32_t i=0; i < MAX_POST_EVENTS; i++)
{ {
osc_send_bridge_aouts_peak(1, aouts_peak[0]);
osc_send_bridge_aouts_peak(2, aouts_peak[1]);
}
if (postEvents[i].type == PluginPostEventNull)
break;


const ParameterData* param_data;
switch (postEvents[i].type)
{
case PluginPostEventParameterChange:
callback_action(CALLBACK_PARAMETER_CHANGED, 0, postEvents[i].index, 0, postEvents[i].value);
break;
case PluginPostEventProgramChange:
callback_action(CALLBACK_PROGRAM_CHANGED, 0, postEvents[i].index, 0, 0.0);
break;
case PluginPostEventMidiProgramChange:
callback_action(CALLBACK_MIDI_PROGRAM_CHANGED, 0, postEvents[i].index, 0, 0.0);
break;
case PluginPostEventNoteOn:
callback_action(CALLBACK_NOTE_ON, 0, postEvents[i].index, postEvents[i].value, 0.0);
break;
case PluginPostEventNoteOff:
callback_action(CALLBACK_NOTE_OFF, 0, postEvents[i].index, 0, 0.0);
break;
default:
break;
}
}


for (uint32_t i=0; i < CARLA_PLUGIN->param_count(); i++) for (uint32_t i=0; i < CARLA_PLUGIN->param_count(); i++)
{ {
@@ -153,6 +170,18 @@ void toolkit_plugin_idle()
if (param_data->type == PARAMETER_OUTPUT && (param_data->hints & PARAMETER_IS_AUTOMABLE) > 0) if (param_data->type == PARAMETER_OUTPUT && (param_data->hints & PARAMETER_IS_AUTOMABLE) > 0)
osc_send_control(param_data->rindex, CARLA_PLUGIN->get_parameter_value(i)); osc_send_control(param_data->rindex, CARLA_PLUGIN->get_parameter_value(i));
} }

if (CARLA_PLUGIN->ain_count() > 0)
{
osc_send_bridge_ains_peak(1, ains_peak[0]);
osc_send_bridge_ains_peak(2, ains_peak[1]);
}

if (CARLA_PLUGIN->aout_count() > 0)
{
osc_send_bridge_aouts_peak(1, aouts_peak[0]);
osc_send_bridge_aouts_peak(2, aouts_peak[1]);
}
} }


void toolkit_loop() void toolkit_loop()
@@ -175,6 +204,9 @@ void toolkit_loop()
PluginIdleTimer timer; PluginIdleTimer timer;
timer.start(50); timer.start(50);


if (gui)
timer.connect(gui, SIGNAL(finished(int)), &timer, SLOT(guiClosed()));

app->setQuitOnLastWindowClosed(false); app->setQuitOnLastWindowClosed(false);
app->exec(); app->exec();
#endif #endif
@@ -239,12 +271,16 @@ public:
{ {
if (CARLA_PLUGIN && index < CARLA_PLUGIN->prog_count()) if (CARLA_PLUGIN && index < CARLA_PLUGIN->prog_count())
CARLA_PLUGIN->set_program(index, true, true, false, true); CARLA_PLUGIN->set_program(index, true, true, false, true);

callback_action(CALLBACK_RELOAD_PARAMETERS, 0, 0, 0, 0.0);
} }


void set_midi_program(uint32_t bank, uint32_t program) void set_midi_program(uint32_t bank, uint32_t program)
{ {
if (CARLA_PLUGIN) if (CARLA_PLUGIN)
CARLA_PLUGIN->set_midi_program_by_id(bank, program, true, true, false, true); CARLA_PLUGIN->set_midi_program_by_id(bank, program, true, true, false, true);

callback_action(CALLBACK_RELOAD_PARAMETERS, 0, 0, 0, 0.0);
} }


void note_on(uint8_t note, uint8_t velocity) void note_on(uint8_t note, uint8_t velocity)
@@ -286,6 +322,12 @@ public:


osc_send_configure("CarlaBridgeSaveNowDone", ""); osc_send_configure("CarlaBridgeSaveNowDone", "");
} }

void set_chunk_data(const char* string_data)
{
if (CARLA_PLUGIN)
CARLA_PLUGIN->set_chunk_data(string_data);
}
}; };


// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
@@ -315,10 +357,23 @@ void plugin_bridge_callback(CallbackType action, unsigned short, int value1, int
osc_send_midi(mdata); osc_send_midi(mdata);
break; break;
} }
case CALLBACK_SHOW_GUI:
if (value1 == 0)
osc_send_configure("CarlaBridgeHideGUI", "");
break;
case CALLBACK_RESIZE_GUI: case CALLBACK_RESIZE_GUI:
if (client) if (client)
client->queque_message(BRIDGE_MESSAGE_RESIZE_GUI, value1, value2, 0.0); client->queque_message(BRIDGE_MESSAGE_RESIZE_GUI, value1, value2, 0.0);
break; break;
case CALLBACK_RELOAD_PARAMETERS:
if (CARLA_PLUGIN)
{
for (uint32_t i=0; i < CARLA_PLUGIN->param_count(); i++)
{
osc_send_control(i, CARLA_PLUGIN->get_parameter_value(i));
}
}
break;
case CALLBACK_QUIT: case CALLBACK_QUIT:
if (client) if (client)
client->queque_message(BRIDGE_MESSAGE_QUIT, 0, 0, 0.0); client->queque_message(BRIDGE_MESSAGE_QUIT, 0, 0, 0.0);
@@ -326,8 +381,6 @@ void plugin_bridge_callback(CallbackType action, unsigned short, int value1, int
default: default:
break; break;
} }

Q_UNUSED(value3);
} }


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


+ 5
- 19
src/carla.py View File

@@ -3102,33 +3102,19 @@ class CarlaMainW(QMainWindow, ui_carla.Ui_CarlaMainW):
build = plugin['build'] build = plugin['build']
ptype = plugin['type'] ptype = plugin['type']


if (build != BINARY_NATIVE):
# Store object so we can return a pointer
if self.m_bridge_info is None:
self.m_bridge_info = PluginBridgeInfo()
self.m_bridge_info.hints = plugin['hints']
self.m_bridge_info.name = plugin['name'].encode("utf-8")
self.m_bridge_info.maker = plugin['maker'].encode("utf-8")
self.m_bridge_info.unique_id = plugin['unique_id']
self.m_bridge_info.ains = plugin['audio.ins']
self.m_bridge_info.aouts = plugin['audio.outs']
self.m_bridge_info.mins = plugin['midi.ins']
self.m_bridge_info.mouts = plugin['midi.outs']
return pointer(self.m_bridge_info)

elif (ptype == PLUGIN_LADSPA):
if (ptype == PLUGIN_LADSPA):
unique_id = plugin['unique_id'] unique_id = plugin['unique_id']
for rdf_item in self.ladspa_rdf_list: for rdf_item in self.ladspa_rdf_list:
if (rdf_item.UniqueID == unique_id):
if rdf_item.UniqueID == unique_id:
return pointer(rdf_item) return pointer(rdf_item)
else: else:
return c_nullptr return c_nullptr


elif (ptype == PLUGIN_DSSI): elif (ptype == PLUGIN_DSSI):
if (plugin['hints'] & PLUGIN_HAS_GUI):
if plugin['hints'] & PLUGIN_HAS_GUI:
gui = findDSSIGUI(plugin['binary'], plugin['name'], plugin['label']) gui = findDSSIGUI(plugin['binary'], plugin['name'], plugin['label'])
if (gui):
return gui.encode("utf-8")
if gui:
return gui if AVLINUX_PY2BUILD else gui.encode("utf-8")
return c_nullptr return c_nullptr


else: else:


+ 0
- 13
src/carla_backend.py View File

@@ -768,19 +768,6 @@ class GuiInfo(Structure):
("resizable", c_bool), ("resizable", c_bool),
] ]


class PluginBridgeInfo(Structure):
_fields_ = [
("category", c_enum),
("hints", c_uint),
("name", c_char_p),
("maker", c_char_p),
("unique_id", c_long),
("ains", c_uint32),
("aouts", c_uint32),
("mins", c_uint32),
("mouts", c_uint32)
]

CallbackFunc = CFUNCTYPE(None, c_enum, c_ushort, c_int, c_int, c_double) CallbackFunc = CFUNCTYPE(None, c_enum, c_ushort, c_int, c_int, c_double)


if LINUX or MACOS: if LINUX or MACOS:


+ 6
- 6
src/jacksettings.py View File

@@ -364,8 +364,8 @@ class JackSettingsW(QDialog, ui_settings_jack.Ui_JackSettingsW):
if value != jackctl.GetParameterValue(["driver", "device"])[2]: if value != jackctl.GetParameterValue(["driver", "device"])[2]:
jackctl.SetParameterValue(["driver", "device"], value) jackctl.SetParameterValue(["driver", "device"], value)


elif resetIfNeeded:
jackctl.ResetParameterValue(["driver", "device"])
#elif resetIfNeeded:
#jackctl.ResetParameterValue(["driver", "device"])


if self.obj_driver_capture.isEnabled(): if self.obj_driver_capture.isEnabled():
if self.m_driver == "alsa": if self.m_driver == "alsa":
@@ -381,8 +381,8 @@ class JackSettingsW(QDialog, ui_settings_jack.Ui_JackSettingsW):
if value != None: if value != None:
setDriverParameter("capture", value, True) setDriverParameter("capture", value, True)


elif resetIfNeeded:
jackctl.ResetParameterValue(["driver", "capture"])
#elif resetIfNeeded:
#jackctl.ResetParameterValue(["driver", "capture"])


if self.obj_driver_playback.isEnabled(): if self.obj_driver_playback.isEnabled():
if self.m_driver == "alsa": if self.m_driver == "alsa":
@@ -398,8 +398,8 @@ class JackSettingsW(QDialog, ui_settings_jack.Ui_JackSettingsW):
if value != None: if value != None:
setDriverParameter("playback", value, True) setDriverParameter("playback", value, True)


elif resetIfNeeded:
jackctl.ResetParameterValue(["driver", "playback"])
#elif resetIfNeeded:
#jackctl.ResetParameterValue(["driver", "playback"])


if self.obj_driver_rate.isEnabled(): if self.obj_driver_rate.isEnabled():
value = dbus.UInt32(int(self.obj_driver_rate.currentText())) value = dbus.UInt32(int(self.obj_driver_rate.currentText()))


Loading…
Cancel
Save