@@ -174,19 +174,19 @@ carla_lilv: | |||
$(MAKE) -C src/carla-lilv | |||
unix32: | |||
# $(MAKE) -C src/carla-bridge unix32 | |||
$(MAKE) -C src/carla-bridge unix32 | |||
$(MAKE) -C src/carla-discovery unix32 | |||
unix64: | |||
# $(MAKE) -C src/carla-bridge unix64 | |||
$(MAKE) -C src/carla-bridge unix64 | |||
$(MAKE) -C src/carla-discovery unix64 | |||
wine32: | |||
# $(MAKE) -C src/carla-bridge wine32 | |||
$(MAKE) -C src/carla-bridge wine32 | |||
$(MAKE) -C src/carla-discovery wine32 | |||
wine64: | |||
# $(MAKE) -C src/carla-bridge wine64 | |||
$(MAKE) -C src/carla-bridge wine64 | |||
$(MAKE) -C src/carla-discovery wine64 | |||
@@ -100,6 +100,9 @@ class CadenceMainW(QMainWindow, ui_cadence.Ui_CadenceMainW): | |||
self.settings = QSettings("Cadence", "Cadence") | |||
self.loadSettings(True) | |||
# TODO | |||
self.b_jack_restart.setEnabled(False) | |||
# ------------------------------------------------------------- | |||
# 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_xycontroller, SIGNAL("clicked()"), lambda tool="cadence_xycontroller": self.func_start_tool(tool)) | |||
self.m_timer120 = None | |||
self.m_timer1000 = self.startTimer(1000) | |||
self.DBusReconnect() | |||
@@ -171,25 +175,24 @@ class CadenceMainW(QMainWindow, ui_cadence.Ui_CadenceMainW): | |||
member_keyword='member', interface_keyword='interface', sender_keyword='sender', ) | |||
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.IsStarted(): | |||
self.jackStarted() | |||
else: | |||
self.jackStopped() | |||
# FIXME | |||
self.label_jack_realtime.setText("TODO") | |||
self.label_jack_realtime.setText("Yes" if jacksettings.isRealtime() else "No") | |||
else: | |||
self.jackStopped() | |||
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()")) | |||
elif kwds['interface'] == "org.jackaudio.JackControl": | |||
if DEBUG: print("org.jackaudio.JackControl", kwds['member']) | |||
if kwds['member'] == "ServerStarted": | |||
self.jackStarted() | |||
elif kwds['member'] == "ServerStopped": | |||
@@ -280,7 +284,10 @@ class CadenceMainW(QMainWindow, ui_cadence.Ui_CadenceMainW): | |||
@pyqtSlot() | |||
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() | |||
def slot_JackServerForceRestart(self): | |||
@@ -292,7 +299,8 @@ class CadenceMainW(QMainWindow, ui_cadence.Ui_CadenceMainW): | |||
@pyqtSlot() | |||
def slot_JackClearXruns(self): | |||
DBus.jack.ResetXruns() | |||
if DBus.jack: | |||
DBus.jack.ResetXruns() | |||
@pyqtSlot() | |||
def slot_handleCrash_a2j(self): | |||
@@ -316,30 +324,29 @@ class CadenceMainW(QMainWindow, ui_cadence.Ui_CadenceMainW): | |||
def timerEvent(self, event): | |||
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: | |||
if DBus.jack and self.m_last_buffer_size != None: | |||
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: | |||
self.update() | |||
self.update() | |||
QMainWindow.timerEvent(self, event) | |||
@@ -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_sfz(const char* filename, const char* label); | |||
#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 | |||
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"); | |||
return -1; | |||
} | |||
else | |||
return add_plugin_bridge(btype, ptype, filename, label, extra_stuff); | |||
return add_plugin_bridge(btype, ptype, filename, label); | |||
} | |||
#endif | |||
@@ -237,18 +237,6 @@ struct GuiInfo { | |||
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; | |||
typedef void (*CallbackFunc)(CallbackType action, unsigned short plugin_id, int value1, int value2, double value3); | |||
@@ -27,6 +27,7 @@ CARLA_BACKEND_START_NAMESPACE | |||
#endif | |||
struct BridgeParamInfo { | |||
double value; | |||
QString name; | |||
QString unit; | |||
}; | |||
@@ -40,19 +41,23 @@ public: | |||
qDebug("BridgePlugin::BridgePlugin()"); | |||
m_type = ptype; | |||
m_hints = PLUGIN_IS_BRIDGE; | |||
m_label = nullptr; | |||
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); | |||
} | |||
@@ -84,14 +89,17 @@ public: | |||
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() | |||
{ | |||
return m_info.category; | |||
return info.category; | |||
} | |||
long unique_id() | |||
{ | |||
return m_info.unique_id; | |||
return info.uniqueId; | |||
} | |||
// ------------------------------------------------------------------- | |||
@@ -112,22 +120,22 @@ public: | |||
uint32_t ain_count() | |||
{ | |||
return m_info.ains; | |||
return info.ains; | |||
} | |||
uint32_t aout_count() | |||
{ | |||
return m_info.aouts; | |||
return info.aouts; | |||
} | |||
uint32_t min_count() | |||
{ | |||
return m_info.mins; | |||
return info.mins; | |||
} | |||
uint32_t mout_count() | |||
{ | |||
return m_info.mouts; | |||
return info.mouts; | |||
} | |||
// ------------------------------------------------------------------- | |||
@@ -135,22 +143,13 @@ public: | |||
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(); | |||
return chunk.size(); | |||
} | |||
return 0; | |||
} | |||
@@ -159,42 +158,45 @@ public: | |||
double get_parameter_value(uint32_t param_id) | |||
{ | |||
return param_buffers[param_id]; | |||
return params[param_id].value; | |||
} | |||
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) | |||
{ | |||
strncpy(buf_str, m_info.maker, STR_MAX); | |||
strncpy(buf_str, info.maker, STR_MAX); | |||
} | |||
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) | |||
{ | |||
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) | |||
{ | |||
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) | |||
{ | |||
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) | |||
{ | |||
info->type = GUI_NONE; | |||
if (m_hints & PLUGIN_HAS_GUI) | |||
info->type = GUI_EXTERNAL_OSC; | |||
else | |||
info->type = GUI_NONE; | |||
info->resizable = false; | |||
} | |||
@@ -205,49 +207,56 @@ public: | |||
{ | |||
qDebug("set_osc_bridge_info(%i, %p)", intoType, argv); | |||
// PluginBridgeProgramCountInfo, | |||
// PluginBridgeMidiProgramCountInfo, | |||
// PluginBridgePluginInfo, | |||
// PluginBridgeParameterInfo, | |||
// PluginBridgeProgramInfo, | |||
// PluginBridgeMidiProgramInfo, | |||
switch (intoType) | |||
{ | |||
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; | |||
} | |||
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; | |||
} | |||
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[] param_buffers; | |||
delete[] params; | |||
} | |||
// create new if needed | |||
param.count = argv[2]->i; | |||
param.count = pTotal; | |||
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 | |||
param.count = 0; | |||
@@ -269,21 +278,110 @@ public: | |||
param.ranges[i].step_small = 0.0001; | |||
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; | |||
} | |||
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: | |||
{ | |||
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) | |||
{ | |||
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; | |||
} | |||
@@ -318,6 +416,47 @@ public: | |||
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: | |||
callback_action(CALLBACK_RELOAD_ALL, m_id, 0, 0, 0.0); | |||
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) | |||
{ | |||
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) | |||
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); | |||
} | |||
void set_chunk_data(const char* string_data) | |||
{ | |||
osc_send_configure(&osc.data, "CarlaBridgeChunk", string_data); | |||
} | |||
// ------------------------------------------------------------------- | |||
// Set gui stuff | |||
@@ -360,26 +504,12 @@ public: | |||
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() | |||
{ | |||
saved = false; | |||
osc_send_configure(&osc.data, "CarlaBridgeSaveNow", "/tmp/test-path2"); | |||
osc_send_configure(&osc.data, "CarlaBridgeSaveNow", ""); | |||
for (int i=0; i < 100; i++) | |||
{ | |||
@@ -401,63 +531,41 @@ public: | |||
qDebug("BridgePlugin::delete_buffers() - start"); | |||
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"); | |||
} | |||
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); | |||
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 | |||
set_last_error("Invalid bridge info, cannot continue"); | |||
set_last_error("Bridge not possible, bridge-binary not found"); | |||
return false; | |||
} | |||
@@ -465,18 +573,28 @@ public: | |||
private: | |||
bool initiated; | |||
bool saved; | |||
const char* m_label; | |||
const BinaryType m_binary; | |||
PluginBridgeInfo m_info; | |||
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(); | |||
@@ -484,7 +602,7 @@ short add_plugin_bridge(BinaryType btype, PluginType ptype, const char* filename | |||
{ | |||
BridgePlugin* plugin = new BridgePlugin(btype, ptype, id); | |||
if (plugin->init(filename, label, (PluginBridgeInfo*)extra_stuff)) | |||
if (plugin->init(filename, label)) | |||
{ | |||
plugin->reload(); | |||
@@ -21,6 +21,7 @@ | |||
#include "carla_plugin.h" | |||
#include <iostream> | |||
#include <QtCore/QThread> | |||
CARLA_BACKEND_START_NAMESPACE | |||
@@ -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); | |||
if (strcmp(method, "/bridge_midi_program_info") == 0) | |||
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) | |||
return plugin->set_osc_bridge_info(PluginBridgeUpdateNow, argv); | |||
} | |||
@@ -24,7 +24,6 @@ | |||
#include "carla_shared.h" | |||
#ifdef BUILD_BRIDGE | |||
#include <QtCore/QThread> | |||
#include "carla_bridge_osc.h" | |||
#else | |||
#include "carla_osc.h" | |||
@@ -83,6 +82,8 @@ enum PluginBridgeInfoType { | |||
PluginBridgeParameterRangesInfo, | |||
PluginBridgeProgramInfo, | |||
PluginBridgeMidiProgramInfo, | |||
PluginBridgeCustomData, | |||
PluginBridgeChunkData, | |||
PluginBridgeUpdateNow, | |||
PluginBridgeSaved | |||
}; | |||
@@ -518,6 +519,9 @@ public: | |||
double value = active ? 1.0 : 0.0; | |||
if (callback_send) | |||
callback_action(CALLBACK_PARAMETER_CHANGED, m_id, PARAMETER_ACTIVE, 0, value); | |||
#ifndef BUILD_BRIDGE | |||
if (osc_send) | |||
{ | |||
@@ -529,9 +533,6 @@ public: | |||
#else | |||
Q_UNUSED(osc_send); | |||
#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) | |||
@@ -543,6 +544,9 @@ public: | |||
x_drywet = value; | |||
if (callback_send) | |||
callback_action(CALLBACK_PARAMETER_CHANGED, m_id, PARAMETER_DRYWET, 0, value); | |||
#ifndef BUILD_BRIDGE | |||
if (osc_send) | |||
{ | |||
@@ -554,9 +558,6 @@ public: | |||
#else | |||
Q_UNUSED(osc_send); | |||
#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) | |||
@@ -568,6 +569,9 @@ public: | |||
x_vol = value; | |||
if (callback_send) | |||
callback_action(CALLBACK_PARAMETER_CHANGED, m_id, PARAMETER_VOLUME, 0, value); | |||
#ifndef BUILD_BRIDGE | |||
if (osc_send) | |||
{ | |||
@@ -582,9 +586,6 @@ public: | |||
#else | |||
Q_UNUSED(osc_send); | |||
#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) | |||
@@ -596,6 +597,9 @@ public: | |||
x_bal_left = value; | |||
if (callback_send) | |||
callback_action(CALLBACK_PARAMETER_CHANGED, m_id, PARAMETER_BALANCE_LEFT, 0, value); | |||
#ifndef BUILD_BRIDGE | |||
if (osc_send) | |||
{ | |||
@@ -607,9 +611,6 @@ public: | |||
#else | |||
Q_UNUSED(osc_send); | |||
#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) | |||
@@ -621,6 +622,9 @@ public: | |||
x_bal_right = value; | |||
if (callback_send) | |||
callback_action(CALLBACK_PARAMETER_CHANGED, m_id, PARAMETER_BALANCE_RIGHT, 0, value); | |||
#ifndef BUILD_BRIDGE | |||
if (osc_send) | |||
{ | |||
@@ -632,9 +636,6 @@ public: | |||
#else | |||
Q_UNUSED(osc_send); | |||
#endif | |||
if (callback_send) | |||
callback_action(CALLBACK_PARAMETER_CHANGED, m_id, PARAMETER_BALANCE_RIGHT, 0, value); | |||
} | |||
#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) | |||
{ | |||
assert(param_id < param.count); | |||
if (param.data[param_id].type != PARAMETER_INPUT) | |||
return; | |||
if (callback_send) | |||
callback_action(CALLBACK_PARAMETER_CHANGED, m_id, param_id, 0, value); | |||
#ifndef BUILD_BRIDGE | |||
if (osc_send) | |||
{ | |||
@@ -666,16 +671,11 @@ public: | |||
#else | |||
Q_UNUSED(osc_send); | |||
#endif | |||
if (callback_send) | |||
callback_action(CALLBACK_PARAMETER_CHANGED, m_id, param_id, 0, value); | |||
Q_UNUSED(gui_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) | |||
return set_active(value > 0.0, osc_send, callback_send); | |||
if (rindex == PARAMETER_DRYWET) | |||
@@ -686,7 +686,6 @@ public: | |||
return set_balance_left(value, osc_send, callback_send); | |||
if (rindex == PARAMETER_BALANCE_RIGHT) | |||
return set_balance_right(value, osc_send, callback_send); | |||
#endif | |||
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) | |||
{ | |||
assert(index < param.count); | |||
assert(index < param.count && channel < 16); | |||
param.data[index].midi_channel = channel; | |||
#ifndef BUILD_BRIDGE | |||
@@ -773,6 +772,9 @@ public: | |||
{ | |||
prog.current = index; | |||
if (callback_send) | |||
callback_action(CALLBACK_PROGRAM_CHANGED, m_id, prog.current, 0, 0.0); | |||
#ifndef BUILD_BRIDGE | |||
if (osc_send) | |||
{ | |||
@@ -781,12 +783,8 @@ public: | |||
if (m_hints & PLUGIN_IS_BRIDGE) | |||
osc_send_program(&osc.data, prog.current); | |||
} | |||
if (callback_send) | |||
callback_action(CALLBACK_PROGRAM_CHANGED, m_id, prog.current, 0, 0.0); | |||
#else | |||
Q_UNUSED(osc_send); | |||
Q_UNUSED(callback_send); | |||
#endif | |||
// Change default parameter values | |||
@@ -808,6 +806,9 @@ public: | |||
{ | |||
midiprog.current = index; | |||
if (callback_send) | |||
callback_action(CALLBACK_MIDI_PROGRAM_CHANGED, m_id, midiprog.current, 0, 0.0); | |||
#ifndef BUILD_BRIDGE | |||
if (osc_send) | |||
{ | |||
@@ -816,12 +817,8 @@ public: | |||
if (m_hints & PLUGIN_IS_BRIDGE) | |||
osc_send_program(&osc.data, midiprog.current); | |||
} | |||
if (callback_send) | |||
callback_action(CALLBACK_MIDI_PROGRAM_CHANGED, m_id, midiprog.current, 0, 0.0); | |||
#else | |||
Q_UNUSED(osc_send); | |||
Q_UNUSED(callback_send); | |||
#endif | |||
// Sound banks never change defaults | |||
@@ -948,8 +945,17 @@ public: | |||
{ | |||
#ifdef BUILD_BRIDGE | |||
// 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_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); | |||
} | |||
} | |||
// 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 | |||
if (osc_global_registered()) | |||
{ | |||
@@ -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() | |||
@@ -30,6 +30,7 @@ const char* bool2str(bool yesno); | |||
const char* plugintype2str(PluginType type); | |||
const char* binarytype2str(BinaryType type); | |||
const char* customdatatype2str(CustomDataType type); | |||
CustomDataType customdatastr2type(const char* stype); | |||
short get_new_plugin_id(); | |||
const char* get_unique_name(const char* name); | |||
@@ -72,95 +72,95 @@ void CarlaCheckThread::run() | |||
// Process events now | |||
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; | |||
} | |||
} | |||
@@ -1286,14 +1286,12 @@ class VstPlugin : public CarlaPlugin | |||
case audioMasterAutomate: | |||
if (self) | |||
{ | |||
#ifndef BUILD_BRIDGE // FIXME | |||
if (CarlaEngine::isOnAudioThread()) | |||
{ | |||
self->set_parameter_value(index, opt, false, false, false); | |||
self->postpone_event(PluginPostEventParameterChange, index, opt); | |||
} | |||
else | |||
#endif | |||
self->set_parameter_value(index, opt, false, true, true); | |||
} | |||
break; | |||
@@ -185,6 +185,7 @@ public: | |||
#ifdef BUILD_BRIDGE_PLUGIN | |||
// plugin | |||
virtual void save_now() = 0; | |||
virtual void set_chunk_data(const char* string_data) = 0; | |||
#else | |||
// gui | |||
virtual void* get_widget() const = 0; | |||
@@ -161,10 +161,16 @@ int osc_handle_configure(lo_arg** argv) | |||
{ | |||
#ifdef BUILD_BRIDGE_PLUGIN | |||
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 | |||
Q_UNUSED(argv); | |||
#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) | |||
{ | |||
char target_path[strlen(global_osc_data.path)+20]; | |||
strcpy(target_path, global_osc_data.path); | |||
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 | |||
} | |||
} | |||
@@ -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_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_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); | |||
@@ -80,12 +80,12 @@ public: | |||
toolkit_plugin_idle(); | |||
} | |||
//Q_SLOT guiClosed() | |||
//{ | |||
Q_SLOT void guiClosed() | |||
{ | |||
//if (client) | |||
// client->queque_message(BRIDGE_MESSAGE_SHOW_GUI, 0, 0, 0.0); | |||
//osc_send_configure("CarlaBridgeHideGUI", ""); | |||
//} | |||
osc_send_configure("CarlaBridgeHideGUI", ""); | |||
} | |||
}; | |||
static QApplication* app = nullptr; | |||
static QDialog* gui = nullptr; | |||
@@ -132,19 +132,36 @@ void toolkit_plugin_idle() | |||
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++) | |||
{ | |||
@@ -153,6 +170,18 @@ void toolkit_plugin_idle() | |||
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)); | |||
} | |||
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() | |||
@@ -175,6 +204,9 @@ void toolkit_loop() | |||
PluginIdleTimer timer; | |||
timer.start(50); | |||
if (gui) | |||
timer.connect(gui, SIGNAL(finished(int)), &timer, SLOT(guiClosed())); | |||
app->setQuitOnLastWindowClosed(false); | |||
app->exec(); | |||
#endif | |||
@@ -239,12 +271,16 @@ public: | |||
{ | |||
if (CARLA_PLUGIN && index < CARLA_PLUGIN->prog_count()) | |||
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) | |||
{ | |||
if (CARLA_PLUGIN) | |||
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) | |||
@@ -286,6 +322,12 @@ public: | |||
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); | |||
break; | |||
} | |||
case CALLBACK_SHOW_GUI: | |||
if (value1 == 0) | |||
osc_send_configure("CarlaBridgeHideGUI", ""); | |||
break; | |||
case CALLBACK_RESIZE_GUI: | |||
if (client) | |||
client->queque_message(BRIDGE_MESSAGE_RESIZE_GUI, value1, value2, 0.0); | |||
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: | |||
if (client) | |||
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: | |||
break; | |||
} | |||
Q_UNUSED(value3); | |||
} | |||
// ------------------------------------------------------------------------- | |||
@@ -3102,33 +3102,19 @@ class CarlaMainW(QMainWindow, ui_carla.Ui_CarlaMainW): | |||
build = plugin['build'] | |||
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'] | |||
for rdf_item in self.ladspa_rdf_list: | |||
if (rdf_item.UniqueID == unique_id): | |||
if rdf_item.UniqueID == unique_id: | |||
return pointer(rdf_item) | |||
else: | |||
return c_nullptr | |||
elif (ptype == PLUGIN_DSSI): | |||
if (plugin['hints'] & PLUGIN_HAS_GUI): | |||
if plugin['hints'] & PLUGIN_HAS_GUI: | |||
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 | |||
else: | |||
@@ -768,19 +768,6 @@ class GuiInfo(Structure): | |||
("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) | |||
if LINUX or MACOS: | |||
@@ -364,8 +364,8 @@ class JackSettingsW(QDialog, ui_settings_jack.Ui_JackSettingsW): | |||
if value != jackctl.GetParameterValue(["driver", "device"])[2]: | |||
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.m_driver == "alsa": | |||
@@ -381,8 +381,8 @@ class JackSettingsW(QDialog, ui_settings_jack.Ui_JackSettingsW): | |||
if value != None: | |||
setDriverParameter("capture", value, True) | |||
elif resetIfNeeded: | |||
jackctl.ResetParameterValue(["driver", "capture"]) | |||
#elif resetIfNeeded: | |||
#jackctl.ResetParameterValue(["driver", "capture"]) | |||
if self.obj_driver_playback.isEnabled(): | |||
if self.m_driver == "alsa": | |||
@@ -398,8 +398,8 @@ class JackSettingsW(QDialog, ui_settings_jack.Ui_JackSettingsW): | |||
if value != None: | |||
setDriverParameter("playback", value, True) | |||
elif resetIfNeeded: | |||
jackctl.ResetParameterValue(["driver", "playback"]) | |||
#elif resetIfNeeded: | |||
#jackctl.ResetParameterValue(["driver", "playback"]) | |||
if self.obj_driver_rate.isEnabled(): | |||
value = dbus.UInt32(int(self.obj_driver_rate.currentText())) | |||