@@ -138,7 +138,7 @@ def getStateDictFromXML(xml_node): | |||||
x_save_state_dict['Type'] = text | x_save_state_dict['Type'] = text | ||||
elif (tag == "Name"): | elif (tag == "Name"): | ||||
x_save_state_dict['Name'] = text | x_save_state_dict['Name'] = text | ||||
elif (tag == "Label"): | |||||
elif (tag in ("Label", "URI")): | |||||
x_save_state_dict['Label'] = text | x_save_state_dict['Label'] = text | ||||
elif (tag == "Binary"): | elif (tag == "Binary"): | ||||
x_save_state_dict['Binary'] = text | x_save_state_dict['Binary'] = text | ||||
@@ -2306,9 +2306,13 @@ class PluginWidget(QFrame, ui_carla_plugin.Ui_PluginWidget): | |||||
content += " <Info>\n" | content += " <Info>\n" | ||||
content += " <Type>%s</Type>\n" % (x_save_state_dict['Type']) | content += " <Type>%s</Type>\n" % (x_save_state_dict['Type']) | ||||
content += " <Name>%s</Name>\n" % (x_save_state_dict['Name']) | content += " <Name>%s</Name>\n" % (x_save_state_dict['Name']) | ||||
content += " <Label>%s</Label>\n" % (x_save_state_dict['Label']) | |||||
content += " <Binary>%s</Binary>\n" % (x_save_state_dict['Binary']) | |||||
content += " <UniqueID>%li</UniqueID>\n" % (x_save_state_dict['UniqueID']) | |||||
if (self.pinfo['type'] == PLUGIN_LV2): | |||||
content += " <URI>%s</URI>\n" % (x_save_state_dict['Label']) | |||||
else: | |||||
content += " <Label>%s</Label>\n" % (x_save_state_dict['Label']) | |||||
content += " <Binary>%s</Binary>\n" % (x_save_state_dict['Binary']) | |||||
if (x_save_state_dict['UniqueID'] != 0): | |||||
content += " <UniqueID>%li</UniqueID>\n" % (x_save_state_dict['UniqueID']) | |||||
content += " </Info>\n" | content += " </Info>\n" | ||||
content += "\n" | content += "\n" | ||||
@@ -102,6 +102,7 @@ short add_plugin(BinaryType btype, PluginType ptype, const char* filename, const | |||||
{ | { | ||||
qDebug("add_plugin(%i, %i, %s, %s, %p)", btype, ptype, filename, label, extra_stuff); | qDebug("add_plugin(%i, %i, %s, %s, %p)", btype, ptype, filename, label, extra_stuff); | ||||
#ifndef BUILD_BRIDGE | |||||
if (btype != BINARY_NATIVE) | if (btype != BINARY_NATIVE) | ||||
{ | { | ||||
if (carla_options.global_jack_client) | if (carla_options.global_jack_client) | ||||
@@ -112,6 +113,7 @@ short add_plugin(BinaryType btype, PluginType ptype, const char* filename, const | |||||
else | else | ||||
return add_plugin_bridge(btype, ptype, filename, label, extra_stuff); | return add_plugin_bridge(btype, ptype, filename, label, extra_stuff); | ||||
} | } | ||||
#endif | |||||
switch (ptype) | switch (ptype) | ||||
{ | { | ||||
@@ -78,7 +78,9 @@ enum PluginCategory { | |||||
enum ParameterType { | enum ParameterType { | ||||
PARAMETER_UNKNOWN = 0, | PARAMETER_UNKNOWN = 0, | ||||
PARAMETER_INPUT = 1, | PARAMETER_INPUT = 1, | ||||
PARAMETER_OUTPUT = 2 | |||||
PARAMETER_OUTPUT = 2, | |||||
PARAMETER_LATENCY = 3, | |||||
PARAMETER_BPM = 4 | |||||
}; | }; | ||||
enum InternalParametersIndex { | enum InternalParametersIndex { | ||||
@@ -226,7 +226,11 @@ public: | |||||
if (m_filename) | if (m_filename) | ||||
free((void*)m_filename); | free((void*)m_filename); | ||||
#ifdef BUILD_BRIDGE | |||||
if (jack_client) | |||||
#else | |||||
if (jack_client && carla_options.global_jack_client == false) | if (jack_client && carla_options.global_jack_client == false) | ||||
#endif | |||||
jack_client_close(jack_client); | jack_client_close(jack_client); | ||||
} | } | ||||
@@ -941,7 +945,9 @@ public: | |||||
if (jack_client == nullptr) | if (jack_client == nullptr) | ||||
return; | return; | ||||
#ifndef BUILD_BRIDGE | |||||
if (carla_options.global_jack_client == false) | if (carla_options.global_jack_client == false) | ||||
#endif | |||||
jack_deactivate(jack_client); | jack_deactivate(jack_client); | ||||
for (uint32_t i=0; i < ain.count; i++) | for (uint32_t i=0; i < ain.count; i++) | ||||
@@ -185,6 +185,74 @@ const char* get_unique_name(const char* name) | |||||
return strdup(qname.toUtf8().constData()); | return strdup(qname.toUtf8().constData()); | ||||
} | } | ||||
PluginCategory get_category_from_name(const char* name) | |||||
{ | |||||
QString qname(name); | |||||
if (qname.isEmpty()) | |||||
return PLUGIN_CATEGORY_NONE; | |||||
else | |||||
qname = qname.toLower(); | |||||
// generic tags first | |||||
if (qname.contains("delay", Qt::CaseSensitive)) | |||||
return PLUGIN_CATEGORY_DELAY; | |||||
if (qname.contains("reverb", Qt::CaseSensitive)) | |||||
return PLUGIN_CATEGORY_DELAY; | |||||
if (qname.contains("filter", Qt::CaseSensitive)) | |||||
return PLUGIN_CATEGORY_FILTER; | |||||
if (qname.contains("dynamics", Qt::CaseSensitive)) | |||||
return PLUGIN_CATEGORY_DYNAMICS; | |||||
if (qname.contains("amplifier", Qt::CaseSensitive)) | |||||
return PLUGIN_CATEGORY_DYNAMICS; | |||||
if (qname.contains("compressor", Qt::CaseSensitive)) | |||||
return PLUGIN_CATEGORY_DYNAMICS; | |||||
if (qname.contains("enhancer", Qt::CaseSensitive)) | |||||
return PLUGIN_CATEGORY_DYNAMICS; | |||||
if (qname.contains("exciter", Qt::CaseSensitive)) | |||||
return PLUGIN_CATEGORY_DYNAMICS; | |||||
if (qname.contains("gate", Qt::CaseSensitive)) | |||||
return PLUGIN_CATEGORY_DYNAMICS; | |||||
if (qname.contains("limiter", Qt::CaseSensitive)) | |||||
return PLUGIN_CATEGORY_DYNAMICS; | |||||
if (qname.contains("modulator", Qt::CaseSensitive)) | |||||
return PLUGIN_CATEGORY_MODULATOR; | |||||
if (qname.contains("chorus", Qt::CaseSensitive)) | |||||
return PLUGIN_CATEGORY_MODULATOR; | |||||
if (qname.contains("flanger", Qt::CaseSensitive)) | |||||
return PLUGIN_CATEGORY_MODULATOR; | |||||
if (qname.contains("phaser", Qt::CaseSensitive)) | |||||
return PLUGIN_CATEGORY_MODULATOR; | |||||
if (qname.contains("saturator", Qt::CaseSensitive)) | |||||
return PLUGIN_CATEGORY_MODULATOR; | |||||
if (qname.contains("utility", Qt::CaseSensitive)) | |||||
return PLUGIN_CATEGORY_UTILITY; | |||||
if (qname.contains("analyzer", Qt::CaseSensitive)) | |||||
return PLUGIN_CATEGORY_UTILITY; | |||||
if (qname.contains("converter", Qt::CaseSensitive)) | |||||
return PLUGIN_CATEGORY_UTILITY; | |||||
if (qname.contains("deesser", Qt::CaseSensitive)) | |||||
return PLUGIN_CATEGORY_UTILITY; | |||||
if (qname.contains("mixer", Qt::CaseSensitive)) | |||||
return PLUGIN_CATEGORY_UTILITY; | |||||
// common tags | |||||
if (qname.contains("verb", Qt::CaseSensitive)) | |||||
return PLUGIN_CATEGORY_DELAY; | |||||
if (qname.contains("eq", Qt::CaseSensitive)) | |||||
return PLUGIN_CATEGORY_EQ; | |||||
if (qname.contains("tool", Qt::CaseSensitive)) | |||||
return PLUGIN_CATEGORY_UTILITY; | |||||
return PLUGIN_CATEGORY_NONE; | |||||
} | |||||
void* get_pointer(intptr_t ptr_addr) | void* get_pointer(intptr_t ptr_addr) | ||||
{ | { | ||||
intptr_t* ptr = (intptr_t*)ptr_addr; | intptr_t* ptr = (intptr_t*)ptr_addr; | ||||
@@ -28,6 +28,7 @@ const char* plugintype2str(PluginType type); | |||||
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); | ||||
PluginCategory get_category_from_name(const char* name); | |||||
void* get_pointer(intptr_t ptr_addr); | void* get_pointer(intptr_t ptr_addr); | ||||
void set_last_error(const char* error); | void set_last_error(const char* error); | ||||
void carla_proc_lock(); | void carla_proc_lock(); | ||||
@@ -36,6 +36,7 @@ void CarlaCheckThread::run() | |||||
uint32_t j; | uint32_t j; | ||||
double value; | double value; | ||||
ParameterData* param_data; | |||||
PluginPostEvent post_events[MAX_POST_EVENTS]; | PluginPostEvent post_events[MAX_POST_EVENTS]; | ||||
while (carla_is_engine_running()) | while (carla_is_engine_running()) | ||||
@@ -51,6 +52,8 @@ void CarlaCheckThread::run() | |||||
// Make a safe copy of events, and clear them | // Make a safe copy of events, and clear them | ||||
plugin->post_events_copy(post_events); | plugin->post_events_copy(post_events); | ||||
OscData* osc_data = plugin->osc_data(); | |||||
// Process events now | // Process events now | ||||
for (j=0; j < MAX_POST_EVENTS; j++) | for (j=0; j < MAX_POST_EVENTS; j++) | ||||
{ | { | ||||
@@ -63,61 +66,77 @@ void CarlaCheckThread::run() | |||||
break; | break; | ||||
case PostEventParameterChange: | case PostEventParameterChange: | ||||
// Update OSC based UIs | |||||
osc_send_control(osc_data, post_events[j].index, post_events[j].value); | |||||
// Update OSC control client | |||||
//osc_send_set_parameter_value(&global_osc_data, plugin->id(), post_events[j].index, post_events[j].value); | //osc_send_set_parameter_value(&global_osc_data, plugin->id(), post_events[j].index, post_events[j].value); | ||||
callback_action(CALLBACK_PARAMETER_CHANGED, plugin->id(), post_events[j].index, 0, post_events[j].value); | |||||
// FIXME - can this happen? | |||||
//if (plugin->hints() & PLUGIN_IS_BRIDGE) | |||||
// osc_send_control(plugin->osc_data(), post_events[j].index, post_events[j].value); | |||||
// Update Host | |||||
callback_action(CALLBACK_PARAMETER_CHANGED, plugin->id(), post_events[j].index, 0, post_events[j].value); | |||||
break; | break; | ||||
case PostEventProgramChange: | case PostEventProgramChange: | ||||
//osc_send_set_program(&global_osc_data, plugin->id(), post_events[j].index); | |||||
callback_action(CALLBACK_PROGRAM_CHANGED, plugin->id(), post_events[j].index, 0, 0.0); | |||||
// FIXME - can this happen? | |||||
//if (plugin->hints() & PLUGIN_IS_BRIDGE) | |||||
// osc_send_program(plugin->osc_data(), post_events[j].index); | |||||
// Update OSC based UIs | |||||
osc_send_program(osc_data, post_events[j].index); | |||||
// Update OSC control client | |||||
//osc_send_set_program(&global_osc_data, plugin->id(), post_events[j].index); | |||||
//for (uint32_t k=0; k < plugin->param_count(); k++) | //for (uint32_t k=0; k < plugin->param_count(); k++) | ||||
// osc_send_set_default_value(&global_osc_data, plugin->id(), k, plugin->param_ranges(k)->def); | // osc_send_set_default_value(&global_osc_data, plugin->id(), k, plugin->param_ranges(k)->def); | ||||
// Update Host | |||||
callback_action(CALLBACK_PROGRAM_CHANGED, plugin->id(), post_events[j].index, 0, 0.0); | |||||
break; | break; | ||||
case PostEventMidiProgramChange: | case PostEventMidiProgramChange: | ||||
//osc_send_set_midi_program(&global_osc_data, plugin->id(), post_events[j].index); | |||||
callback_action(CALLBACK_MIDI_PROGRAM_CHANGED, plugin->id(), post_events[j].index, 0, 0.0); | |||||
//if (plugin->type() == PLUGIN_DSSI) | |||||
// osc_send_program_as_midi(plugin->osc_data(), plugin->midiprog.data[post_events[j].index].bank, plugin->midiprog.data[post_events[j].index].program); | |||||
// FIXME - can this happen? | |||||
//if (plugin->hints & PLUGIN_IS_BRIDGE) | |||||
// osc_send_midi_program(&plugin->osc.data, plugin->midiprog.data[post_events[j].index].bank, plugin->midiprog.data[post_events[j].index].program); | |||||
//for (uint32_t k=0; k < plugin->param_count(); k++) | |||||
// osc_send_set_default_value(&global_osc_data, plugin->id(), k, plugin->param_ranges(k)->def); | |||||
if (post_events[j].index < (int32_t)plugin->midiprog_count()) | |||||
{ | |||||
MidiProgramInfo midiprog = { false, 0, 0, nullptr }; | |||||
plugin->get_midi_program_info(&midiprog, post_events[j].index); | |||||
// Update OSC based UIs | |||||
if (plugin->type() == PLUGIN_DSSI) | |||||
osc_send_program_as_midi(osc_data, midiprog.bank, midiprog.program); | |||||
else | |||||
osc_send_midi_program(osc_data, midiprog.bank, midiprog.program); | |||||
// Update OSC control client | |||||
//osc_send_set_midi_program(&global_osc_data, plugin->id(), post_events[j].index); | |||||
//for (uint32_t k=0; k < plugin->param_count(); k++) | |||||
// osc_send_set_default_value(&global_osc_data, plugin->id(), k, plugin->param_ranges(k)->def); | |||||
// Update Host | |||||
callback_action(CALLBACK_MIDI_PROGRAM_CHANGED, plugin->id(), post_events[j].index, 0, 0.0); | |||||
} | |||||
break; | break; | ||||
case PostEventNoteOn: | case PostEventNoteOn: | ||||
// 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_send_note_on(&global_osc_data, plugin->id(), post_events[j].index, post_events[j].value); | //osc_send_note_on(&global_osc_data, plugin->id(), post_events[j].index, post_events[j].value); | ||||
callback_action(CALLBACK_NOTE_ON, plugin->id(), post_events[j].index, post_events[j].value, 0.0); | |||||
// FIXME - can this happen? | |||||
//if (plugin->hints & PLUGIN_IS_BRIDGE) | |||||
// osc_send_note_on(&plugin->osc.data, plugin->id, post_events[j].index, post_events[j].value); | |||||
// Update Host | |||||
callback_action(CALLBACK_NOTE_ON, plugin->id(), post_events[j].index, post_events[j].value, 0.0); | |||||
break; | break; | ||||
case PostEventNoteOff: | case PostEventNoteOff: | ||||
// 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_send_note_off(&global_osc_data, plugin->id(), post_events[j].index); | //osc_send_note_off(&global_osc_data, plugin->id(), post_events[j].index); | ||||
callback_action(CALLBACK_NOTE_OFF, plugin->id(), post_events[j].index, 0, 0.0); | |||||
// FIXME - can this happen? | |||||
//if (plugin->hints & PLUGIN_IS_BRIDGE) | |||||
// osc_send_note_off(&plugin->osc.data, plugin->id, post_events[j].index, 0); | |||||
// Update Host | |||||
callback_action(CALLBACK_NOTE_OFF, plugin->id(), post_events[j].index, 0, 0.0); | |||||
break; | break; | ||||
@@ -131,7 +150,7 @@ void CarlaCheckThread::run() | |||||
// Update ports | // Update ports | ||||
// Check if it needs update | // Check if it needs update | ||||
bool update_ports_gui = (plugin->osc_data()->target != nullptr); | |||||
bool update_ports_gui = (osc_data->target != nullptr); | |||||
//if (global_osc_data.target == nullptr && update_ports_gui == false) | //if (global_osc_data.target == nullptr && update_ports_gui == false) | ||||
// continue; | // continue; | ||||
@@ -139,12 +158,14 @@ void CarlaCheckThread::run() | |||||
// Update | // Update | ||||
for (j=0; j < plugin->param_count(); j++) | for (j=0; j < plugin->param_count(); j++) | ||||
{ | { | ||||
if (plugin->param_data(j)->type == PARAMETER_OUTPUT && (plugin->param_data(j)->hints & PARAMETER_IS_AUTOMABLE) > 0) | |||||
param_data = plugin->param_data(j); | |||||
if (param_data->type == PARAMETER_OUTPUT && (param_data->hints & PARAMETER_IS_AUTOMABLE) > 0) | |||||
{ | { | ||||
value = plugin->get_parameter_value(j); | value = plugin->get_parameter_value(j); | ||||
if (update_ports_gui) | if (update_ports_gui) | ||||
osc_send_control(plugin->osc_data(), plugin->param_data(j)->rindex, value); | |||||
osc_send_control(osc_data, param_data->rindex, value); | |||||
//osc_send_set_parameter_value(&global_osc_data, plugin->id(), j, value); | //osc_send_set_parameter_value(&global_osc_data, plugin->id(), j, value); | ||||
} | } | ||||
@@ -19,6 +19,8 @@ | |||||
#include "dssi/dssi.h" | #include "dssi/dssi.h" | ||||
#include <QtCore/QStringList> | |||||
class DssiPlugin : public CarlaPlugin | class DssiPlugin : public CarlaPlugin | ||||
{ | { | ||||
public: | public: | ||||
@@ -54,17 +56,30 @@ public: | |||||
if (osc.thread) | if (osc.thread) | ||||
{ | { | ||||
// FIXME - wait a bit first, then kill | |||||
// Wait a bit first, then kill | |||||
if (osc.thread->isRunning()) | if (osc.thread->isRunning()) | ||||
{ | { | ||||
osc.thread->quit(); | |||||
if (osc.thread->wait(3000) == false) // 3 sec | |||||
qDebug("DSSI GUI close - running, closing now"); | |||||
if (osc.thread->wait(3000) == false) | |||||
qDebug("DSSI GUI close - closed sucessfully"); | |||||
else | |||||
{ | |||||
qDebug("DSSI GUI close - still running, closing now"); | |||||
osc.thread->quit(); | |||||
} | |||||
if (osc.thread->wait(1000) == false) | |||||
qWarning("Failed to properly stop DSSI GUI thread"); | qWarning("Failed to properly stop DSSI GUI thread"); | ||||
else | |||||
qDebug("DSSI GUI close - sucess"); | |||||
} | } | ||||
else | |||||
qDebug("DSSI GUI close - not running"); | |||||
delete osc.thread; | delete osc.thread; | ||||
} | } | ||||
else | |||||
qDebug("DSSI GUI close - no thread registered"); | |||||
osc_clear_data(&osc.data); | osc_clear_data(&osc.data); | ||||
} | } | ||||
@@ -85,9 +100,7 @@ public: | |||||
{ | { | ||||
if (midi.port_min && aout.count > 0) | if (midi.port_min && aout.count > 0) | ||||
return PLUGIN_CATEGORY_SYNTH; | return PLUGIN_CATEGORY_SYNTH; | ||||
// TODO - try to get category from label | |||||
return PLUGIN_CATEGORY_NONE; | |||||
return get_category_from_name(m_name); | |||||
} | } | ||||
virtual long unique_id() | virtual long unique_id() | ||||
@@ -145,6 +158,7 @@ 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) | ||||
{ | { | ||||
fix_parameter_value(value, param.ranges[param_id]); | |||||
param_buffers[param_id] = value; | param_buffers[param_id] = value; | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
@@ -168,33 +182,22 @@ public: | |||||
{ | { | ||||
reload_programs(false); | reload_programs(false); | ||||
} | } | ||||
#if 0 | |||||
else if (strcmp(key, "names") == 0) // Not in the API! | else if (strcmp(key, "names") == 0) // Not in the API! | ||||
{ | { | ||||
if (midiprog.count > 0) | if (midiprog.count > 0) | ||||
{ | { | ||||
//osc_send_set_program_count(&global_osc_data, m_id, midiprog.count); | //osc_send_set_program_count(&global_osc_data, m_id, midiprog.count); | ||||
// FIXME | |||||
// Parse names | // Parse names | ||||
int j, k, last_str_n = 0; | |||||
int str_len = strlen(value); | |||||
char name[256]; | |||||
QStringList nameList = QString(value).split(","); | |||||
uint32_t nameCount = nameList.count(); | |||||
for (uint32_t i=0; i < prog.count; i++) | |||||
for (uint32_t i=0; i < midiprog.count && i < nameCount; i++) | |||||
{ | { | ||||
for (j=0, k=last_str_n; j < 256 && k+j < str_len; j++) | |||||
{ | |||||
name[j] = value[k+j]; | |||||
if (value[k+j] == ',') | |||||
{ | |||||
name[j] = 0; | |||||
last_str_n = k+j+1; | |||||
free((void*)midiprog.data[i].name); | |||||
midiprog.data[i].name = strdup(name); | |||||
break; | |||||
} | |||||
} | |||||
const char* name = nameList.at(i).toUtf8().constData(); | |||||
free((void*)midiprog.data[i].name); | |||||
midiprog.data[i].name = strdup(name); | |||||
//osc_send_set_program_name(&global_osc_data, m_id, i, midiprog.names[i]); | //osc_send_set_program_name(&global_osc_data, m_id, i, midiprog.names[i]); | ||||
} | } | ||||
@@ -202,6 +205,7 @@ public: | |||||
callback_action(CALLBACK_RELOAD_PROGRAMS, m_id, 0, 0, 0.0); | callback_action(CALLBACK_RELOAD_PROGRAMS, m_id, 0, 0, 0.0); | ||||
} | } | ||||
} | } | ||||
#endif | |||||
CarlaPlugin::set_custom_data(dtype, key, value, gui_send); | CarlaPlugin::set_custom_data(dtype, key, value, gui_send); | ||||
} | } | ||||
@@ -439,7 +443,7 @@ public: | |||||
if (max - min <= 0.0) | if (max - min <= 0.0) | ||||
{ | { | ||||
qWarning("Broken plugin parameter -> max - min <= 0"); | |||||
qWarning("Broken plugin parameter: max - min <= 0"); | |||||
max = min + 0.1; | max = min + 0.1; | ||||
} | } | ||||
@@ -474,9 +478,8 @@ public: | |||||
if (LADSPA_IS_PORT_INPUT(PortType)) | if (LADSPA_IS_PORT_INPUT(PortType)) | ||||
{ | { | ||||
param.data[j].type = PARAMETER_INPUT; | |||||
param.data[j].hints |= PARAMETER_IS_ENABLED; | |||||
param.data[j].hints |= PARAMETER_IS_AUTOMABLE; | |||||
param.data[j].type = PARAMETER_INPUT; | |||||
param.data[j].hints |= (PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE); | |||||
needs_cin = true; | needs_cin = true; | ||||
// MIDI CC value | // MIDI CC value | ||||
@@ -493,17 +496,10 @@ public: | |||||
} | } | ||||
else if (LADSPA_IS_PORT_OUTPUT(PortType)) | else if (LADSPA_IS_PORT_OUTPUT(PortType)) | ||||
{ | { | ||||
param.data[j].type = PARAMETER_OUTPUT; | |||||
param.data[j].hints |= PARAMETER_IS_ENABLED; | |||||
if (strcmp(ldescriptor->PortNames[i], "latency") != 0 && strcmp(ldescriptor->PortNames[i], "_latency") != 0) | |||||
if (strcmp(ldescriptor->PortNames[i], "latency") == 0 || strcmp(ldescriptor->PortNames[i], "_latency") == 0) | |||||
{ | { | ||||
param.data[j].hints |= PARAMETER_IS_AUTOMABLE; | |||||
needs_cout = true; | |||||
} | |||||
else | |||||
{ | |||||
// latency parameter | |||||
param.data[j].type = PARAMETER_LATENCY; | |||||
param.data[j].hints = 0; | |||||
min = 0; | min = 0; | ||||
max = get_sample_rate(); | max = get_sample_rate(); | ||||
def = 0; | def = 0; | ||||
@@ -511,6 +507,12 @@ public: | |||||
step_small = 1; | step_small = 1; | ||||
step_large = 1; | step_large = 1; | ||||
} | } | ||||
else | |||||
{ | |||||
param.data[j].type = PARAMETER_OUTPUT; | |||||
param.data[j].hints |= (PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE); | |||||
needs_cout = true; | |||||
} | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
@@ -616,7 +618,9 @@ public: | |||||
m_id = _id; | m_id = _id; | ||||
carla_proc_unlock(); | carla_proc_unlock(); | ||||
#ifndef BUILD_BRIDGE | |||||
if (carla_options.global_jack_client == false) | if (carla_options.global_jack_client == false) | ||||
#endif | |||||
jack_activate(jack_client); | jack_activate(jack_client); | ||||
} | } | ||||
@@ -1006,6 +1010,18 @@ public: | |||||
CARLA_PROCESS_CONTINUE_CHECK; | CARLA_PROCESS_CONTINUE_CHECK; | ||||
// -------------------------------------------------------------------------------------------------------- | |||||
// Special Parameters | |||||
for (k=0; k < param.count; k++) | |||||
{ | |||||
if (param.data[k].type == PARAMETER_LATENCY) | |||||
{ | |||||
// TODO | |||||
break; | |||||
} | |||||
} | |||||
// -------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------- | ||||
// Plugin processing | // Plugin processing | ||||
@@ -44,7 +44,7 @@ bool is_ladspa_rdf_descriptor_valid(const LADSPA_RDF_Descriptor* rdf_descriptor, | |||||
{ | { | ||||
if (is_port_good(rdf_descriptor->Ports[i].Type, descriptor->PortDescriptors[i]) == false) | if (is_port_good(rdf_descriptor->Ports[i].Type, descriptor->PortDescriptors[i]) == false) | ||||
{ | { | ||||
qWarning("WARNING - Plugin has RDF data, but invalid PortTypes - %i != %i", rdf_descriptor->Ports[i].Type, descriptor->PortDescriptors[i]); | |||||
qWarning("WARNING - Plugin has RDF data, but invalid PortTypes: %i != %i", rdf_descriptor->Ports[i].Type, descriptor->PortDescriptors[i]); | |||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
@@ -52,7 +52,7 @@ bool is_ladspa_rdf_descriptor_valid(const LADSPA_RDF_Descriptor* rdf_descriptor, | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
qWarning("WARNING - Plugin has RDF data, but invalid PortCount -> %li > %li", rdf_descriptor->PortCount, descriptor->PortCount); | |||||
qWarning("WARNING - Plugin has RDF data, but invalid PortCount: %li > %li", rdf_descriptor->PortCount, descriptor->PortCount); | |||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
@@ -131,8 +131,7 @@ public: | |||||
return PLUGIN_CATEGORY_SYNTH; | return PLUGIN_CATEGORY_SYNTH; | ||||
} | } | ||||
// TODO - try to get category from label | |||||
return PLUGIN_CATEGORY_NONE; | |||||
return get_category_from_name(m_name); | |||||
} | } | ||||
virtual long unique_id() | virtual long unique_id() | ||||
@@ -262,6 +261,7 @@ 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) | ||||
{ | { | ||||
fix_parameter_value(value, param.ranges[param_id]); | |||||
param_buffers[param_id] = value; | param_buffers[param_id] = value; | ||||
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); | ||||
@@ -458,7 +458,7 @@ public: | |||||
if (max - min <= 0.0) | if (max - min <= 0.0) | ||||
{ | { | ||||
qWarning("Broken plugin parameter -> max - min <= 0"); | |||||
qWarning("Broken plugin parameter: max - min <= 0"); | |||||
max = min + 0.1; | max = min + 0.1; | ||||
} | } | ||||
@@ -493,24 +493,16 @@ public: | |||||
if (LADSPA_IS_PORT_INPUT(PortType)) | if (LADSPA_IS_PORT_INPUT(PortType)) | ||||
{ | { | ||||
param.data[j].type = PARAMETER_INPUT; | |||||
param.data[j].hints |= PARAMETER_IS_ENABLED; | |||||
param.data[j].hints |= PARAMETER_IS_AUTOMABLE; | |||||
param.data[j].type = PARAMETER_INPUT; | |||||
param.data[j].hints |= (PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE); | |||||
needs_cin = true; | needs_cin = true; | ||||
} | } | ||||
else if (LADSPA_IS_PORT_OUTPUT(PortType)) | else if (LADSPA_IS_PORT_OUTPUT(PortType)) | ||||
{ | { | ||||
param.data[j].type = PARAMETER_OUTPUT; | |||||
param.data[j].hints |= PARAMETER_IS_ENABLED; | |||||
if (strcmp(descriptor->PortNames[i], "latency") != 0 && strcmp(descriptor->PortNames[i], "_latency") != 0) | |||||
{ | |||||
param.data[j].hints |= PARAMETER_IS_AUTOMABLE; | |||||
needs_cout = true; | |||||
} | |||||
else | |||||
if (strcmp(descriptor->PortNames[i], "latency") == 0 || strcmp(descriptor->PortNames[i], "_latency") == 0) | |||||
{ | { | ||||
// latency parameter | |||||
param.data[j].type = PARAMETER_LATENCY; | |||||
param.data[j].hints = 0; | |||||
min = 0; | min = 0; | ||||
max = get_sample_rate(); | max = get_sample_rate(); | ||||
def = 0; | def = 0; | ||||
@@ -518,6 +510,12 @@ public: | |||||
step_small = 1; | step_small = 1; | ||||
step_large = 1; | step_large = 1; | ||||
} | } | ||||
else | |||||
{ | |||||
param.data[j].type = PARAMETER_OUTPUT; | |||||
param.data[j].hints |= (PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE); | |||||
needs_cout = true; | |||||
} | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
@@ -599,7 +597,9 @@ public: | |||||
m_id = _id; | m_id = _id; | ||||
carla_proc_unlock(); | carla_proc_unlock(); | ||||
#ifndef BUILD_BRIDGE | |||||
if (carla_options.global_jack_client == false) | if (carla_options.global_jack_client == false) | ||||
#endif | |||||
jack_activate(jack_client); | jack_activate(jack_client); | ||||
} | } | ||||
@@ -737,6 +737,18 @@ public: | |||||
CARLA_PROCESS_CONTINUE_CHECK; | CARLA_PROCESS_CONTINUE_CHECK; | ||||
// -------------------------------------------------------------------------------------------------------- | |||||
// Special Parameters | |||||
for (k=0; k < param.count; k++) | |||||
{ | |||||
if (param.data[k].type == PARAMETER_LATENCY) | |||||
{ | |||||
// TODO | |||||
break; | |||||
} | |||||
} | |||||
// -------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------- | ||||
// Plugin processing | // Plugin processing | ||||
@@ -934,7 +946,9 @@ public: | |||||
m_name = get_unique_name(descriptor->Name); | m_name = get_unique_name(descriptor->Name); | ||||
if (carla_jack_register_plugin(this, &jack_client)) | if (carla_jack_register_plugin(this, &jack_client)) | ||||
{ | |||||
return true; | return true; | ||||
} | |||||
else | else | ||||
set_last_error("Failed to register plugin in JACK"); | set_last_error("Failed to register plugin in JACK"); | ||||
} | } | ||||
@@ -54,7 +54,8 @@ const unsigned int PLUGIN_HAS_EXTENSION_STATE = 0x1000; | |||||
const unsigned int PLUGIN_HAS_EXTENSION_DYNPARAM = 0x2000; | const unsigned int PLUGIN_HAS_EXTENSION_DYNPARAM = 0x2000; | ||||
// parameter hints | // parameter hints | ||||
const unsigned int PARAMETER_HAS_STRICT_BOUNDS = 0x100; | |||||
const unsigned int PARAMETER_IS_TRIGGER = 0x100; | |||||
const unsigned int PARAMETER_HAS_STRICT_BOUNDS = 0x200; | |||||
// feature ids | // feature ids | ||||
const uint32_t lv2_feature_id_uri_map = 0; | const uint32_t lv2_feature_id_uri_map = 0; | ||||
@@ -1156,7 +1157,9 @@ public: | |||||
m_id = _id; | m_id = _id; | ||||
carla_proc_unlock(); | carla_proc_unlock(); | ||||
#ifndef BUILD_BRIDGE | |||||
if (carla_options.global_jack_client == false) | if (carla_options.global_jack_client == false) | ||||
#endif | |||||
jack_activate(jack_client); | jack_activate(jack_client); | ||||
} | } | ||||
@@ -310,22 +310,26 @@ public: | |||||
// --------------------------------------- | // --------------------------------------- | ||||
// Audio Outputs | // Audio Outputs | ||||
#ifndef BUILD_BRIDGE | |||||
if (carla_options.global_jack_client) | if (carla_options.global_jack_client) | ||||
{ | { | ||||
strcpy(port_name, m_name); | strcpy(port_name, m_name); | ||||
strcat(port_name, ":out-left"); | strcat(port_name, ":out-left"); | ||||
} | } | ||||
else | else | ||||
#endif | |||||
strcpy(port_name, "out-left"); | strcpy(port_name, "out-left"); | ||||
aout.ports[0] = jack_port_register(jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); | aout.ports[0] = jack_port_register(jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); | ||||
#ifndef BUILD_BRIDGE | |||||
if (carla_options.global_jack_client) | if (carla_options.global_jack_client) | ||||
{ | { | ||||
strcpy(port_name, m_name); | strcpy(port_name, m_name); | ||||
strcat(port_name, ":out-right"); | strcat(port_name, ":out-right"); | ||||
} | } | ||||
else | else | ||||
#endif | |||||
strcpy(port_name, "out-right"); | strcpy(port_name, "out-right"); | ||||
aout.ports[1] = jack_port_register(jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); | aout.ports[1] = jack_port_register(jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); | ||||
@@ -333,12 +337,14 @@ public: | |||||
// --------------------------------------- | // --------------------------------------- | ||||
// MIDI Input | // MIDI Input | ||||
#ifndef BUILD_BRIDGE | |||||
if (carla_options.global_jack_client) | if (carla_options.global_jack_client) | ||||
{ | { | ||||
strcpy(port_name, m_name); | strcpy(port_name, m_name); | ||||
strcat(port_name, ":midi-in"); | strcat(port_name, ":midi-in"); | ||||
} | } | ||||
else | else | ||||
#endif | |||||
strcpy(port_name, "midi-in"); | strcpy(port_name, "midi-in"); | ||||
midi.port_min = jack_port_register(jack_client, port_name, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); | midi.port_min = jack_port_register(jack_client, port_name, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); | ||||
@@ -346,22 +352,26 @@ public: | |||||
// --------------------------------------- | // --------------------------------------- | ||||
// Parameters | // Parameters | ||||
#ifndef BUILD_BRIDGE | |||||
if (carla_options.global_jack_client) | if (carla_options.global_jack_client) | ||||
{ | { | ||||
strcpy(port_name, m_name); | strcpy(port_name, m_name); | ||||
strcat(port_name, ":control-in"); | strcat(port_name, ":control-in"); | ||||
} | } | ||||
else | else | ||||
#endif | |||||
strcpy(port_name, "control-in"); | strcpy(port_name, "control-in"); | ||||
param.port_cin = jack_port_register(jack_client, port_name, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); | param.port_cin = jack_port_register(jack_client, port_name, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); | ||||
#ifndef BUILD_BRIDGE | |||||
if (carla_options.global_jack_client) | if (carla_options.global_jack_client) | ||||
{ | { | ||||
strcpy(port_name, m_name); | strcpy(port_name, m_name); | ||||
strcat(port_name, ":control-out"); | strcat(port_name, ":control-out"); | ||||
} | } | ||||
else | else | ||||
#endif | |||||
strcpy(port_name, "control-out"); | strcpy(port_name, "control-out"); | ||||
param.port_cout = jack_port_register(jack_client, port_name, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0); | param.port_cout = jack_port_register(jack_client, port_name, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0); | ||||
@@ -608,7 +618,9 @@ public: | |||||
m_id = _id; | m_id = _id; | ||||
carla_proc_unlock(); | carla_proc_unlock(); | ||||
#ifndef BUILD_BRIDGE | |||||
if (carla_options.global_jack_client == false) | if (carla_options.global_jack_client == false) | ||||
#endif | |||||
jack_activate(jack_client); | jack_activate(jack_client); | ||||
} | } | ||||
@@ -496,7 +496,9 @@ public: | |||||
m_id = _id; | m_id = _id; | ||||
carla_proc_unlock(); | carla_proc_unlock(); | ||||
#ifndef BUILD_BRIDGE | |||||
if (carla_options.global_jack_client == false) | if (carla_options.global_jack_client == false) | ||||
#endif | |||||
jack_activate(jack_client); | jack_activate(jack_client); | ||||
} | } | ||||
@@ -1134,7 +1136,7 @@ public: | |||||
const int port_name_size = jack_port_name_size(); | const int port_name_size = jack_port_name_size(); | ||||
char port_name[port_name_size]; | char port_name[port_name_size]; | ||||
#ifndef BRIDGE_WINVST | |||||
#ifndef BUILD_BRIDGE | |||||
if (carla_options.global_jack_client) | if (carla_options.global_jack_client) | ||||
{ | { | ||||
strncpy(port_name, plugin->name, (port_name_size/2)-2); | strncpy(port_name, plugin->name, (port_name_size/2)-2); | ||||
@@ -134,7 +134,7 @@ class ParamSpinBox(QAbstractSpinBox): | |||||
self._minimum = 0.0 | self._minimum = 0.0 | ||||
self._maximum = 1.0 | self._maximum = 1.0 | ||||
self._default = 0.0 | self._default = 0.0 | ||||
self._value = 0.0 | |||||
self._value = None | |||||
self._step = 0.0 | self._step = 0.0 | ||||
self._step_small = 0.0 | self._step_small = 0.0 | ||||
self._step_large = 0.0 | self._step_large = 0.0 | ||||
@@ -230,7 +230,8 @@ class ParamSpinBox(QAbstractSpinBox): | |||||
for scalepoint in scalepoints: | for scalepoint in scalepoints: | ||||
self.box.addItem("%f - %s" % (scalepoint['value'], scalepoint['label'])) | self.box.addItem("%f - %s" % (scalepoint['value'], scalepoint['label'])) | ||||
self.set_scalepoint_value(self._value) | |||||
if (self._value != None): | |||||
self.set_scalepoint_value(self._value) | |||||
self.connect(self.box, SIGNAL("currentIndexChanged(QString)"), self.handleValueChangedFromBox) | self.connect(self.box, SIGNAL("currentIndexChanged(QString)"), self.handleValueChangedFromBox) | ||||
@@ -317,7 +318,7 @@ class ParamSpinBox(QAbstractSpinBox): | |||||
self.set_value(self._default) | self.set_value(self._default) | ||||
def stepBy(self, steps): | def stepBy(self, steps): | ||||
if (steps == 0): | |||||
if (steps == 0 or self._value == None): | |||||
return | return | ||||
value = self._value+(steps*self._step) | value = self._value+(steps*self._step) | ||||
@@ -330,7 +331,7 @@ class ParamSpinBox(QAbstractSpinBox): | |||||
self.set_value(value) | self.set_value(value) | ||||
def stepEnabled(self): | def stepEnabled(self): | ||||
if (self._read_only): | |||||
if (self._read_only or self._value == None): | |||||
return QAbstractSpinBox.StepNone | return QAbstractSpinBox.StepNone | ||||
elif (self._value <= self._minimum): | elif (self._value <= self._minimum): | ||||
return QAbstractSpinBox.StepUpEnabled | return QAbstractSpinBox.StepUpEnabled | ||||