| @@ -138,7 +138,7 @@ def getStateDictFromXML(xml_node): | |||
| x_save_state_dict['Type'] = text | |||
| elif (tag == "Name"): | |||
| x_save_state_dict['Name'] = text | |||
| elif (tag == "Label"): | |||
| elif (tag in ("Label", "URI")): | |||
| x_save_state_dict['Label'] = text | |||
| elif (tag == "Binary"): | |||
| x_save_state_dict['Binary'] = text | |||
| @@ -2306,9 +2306,13 @@ class PluginWidget(QFrame, ui_carla_plugin.Ui_PluginWidget): | |||
| content += " <Info>\n" | |||
| content += " <Type>%s</Type>\n" % (x_save_state_dict['Type']) | |||
| 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 += "\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); | |||
| #ifndef BUILD_BRIDGE | |||
| if (btype != BINARY_NATIVE) | |||
| { | |||
| if (carla_options.global_jack_client) | |||
| @@ -112,6 +113,7 @@ short add_plugin(BinaryType btype, PluginType ptype, const char* filename, const | |||
| else | |||
| return add_plugin_bridge(btype, ptype, filename, label, extra_stuff); | |||
| } | |||
| #endif | |||
| switch (ptype) | |||
| { | |||
| @@ -78,7 +78,9 @@ enum PluginCategory { | |||
| enum ParameterType { | |||
| PARAMETER_UNKNOWN = 0, | |||
| PARAMETER_INPUT = 1, | |||
| PARAMETER_OUTPUT = 2 | |||
| PARAMETER_OUTPUT = 2, | |||
| PARAMETER_LATENCY = 3, | |||
| PARAMETER_BPM = 4 | |||
| }; | |||
| enum InternalParametersIndex { | |||
| @@ -226,7 +226,11 @@ public: | |||
| if (m_filename) | |||
| free((void*)m_filename); | |||
| #ifdef BUILD_BRIDGE | |||
| if (jack_client) | |||
| #else | |||
| if (jack_client && carla_options.global_jack_client == false) | |||
| #endif | |||
| jack_client_close(jack_client); | |||
| } | |||
| @@ -941,7 +945,9 @@ public: | |||
| if (jack_client == nullptr) | |||
| return; | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.global_jack_client == false) | |||
| #endif | |||
| jack_deactivate(jack_client); | |||
| 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()); | |||
| } | |||
| 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) | |||
| { | |||
| intptr_t* ptr = (intptr_t*)ptr_addr; | |||
| @@ -28,6 +28,7 @@ const char* plugintype2str(PluginType type); | |||
| short get_new_plugin_id(); | |||
| const char* get_unique_name(const char* name); | |||
| PluginCategory get_category_from_name(const char* name); | |||
| void* get_pointer(intptr_t ptr_addr); | |||
| void set_last_error(const char* error); | |||
| void carla_proc_lock(); | |||
| @@ -36,6 +36,7 @@ void CarlaCheckThread::run() | |||
| uint32_t j; | |||
| double value; | |||
| ParameterData* param_data; | |||
| PluginPostEvent post_events[MAX_POST_EVENTS]; | |||
| while (carla_is_engine_running()) | |||
| @@ -51,6 +52,8 @@ void CarlaCheckThread::run() | |||
| // Make a safe copy of events, and clear them | |||
| plugin->post_events_copy(post_events); | |||
| OscData* osc_data = plugin->osc_data(); | |||
| // Process events now | |||
| for (j=0; j < MAX_POST_EVENTS; j++) | |||
| { | |||
| @@ -63,61 +66,77 @@ void CarlaCheckThread::run() | |||
| break; | |||
| 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); | |||
| 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; | |||
| 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++) | |||
| // 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; | |||
| 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; | |||
| 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); | |||
| 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; | |||
| 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); | |||
| 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; | |||
| @@ -131,7 +150,7 @@ void CarlaCheckThread::run() | |||
| // Update ports | |||
| // 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) | |||
| // continue; | |||
| @@ -139,12 +158,14 @@ void CarlaCheckThread::run() | |||
| // Update | |||
| 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); | |||
| 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); | |||
| } | |||
| @@ -19,6 +19,8 @@ | |||
| #include "dssi/dssi.h" | |||
| #include <QtCore/QStringList> | |||
| class DssiPlugin : public CarlaPlugin | |||
| { | |||
| public: | |||
| @@ -54,17 +56,30 @@ public: | |||
| if (osc.thread) | |||
| { | |||
| // FIXME - wait a bit first, then kill | |||
| // Wait a bit first, then kill | |||
| 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"); | |||
| else | |||
| qDebug("DSSI GUI close - sucess"); | |||
| } | |||
| else | |||
| qDebug("DSSI GUI close - not running"); | |||
| delete osc.thread; | |||
| } | |||
| else | |||
| qDebug("DSSI GUI close - no thread registered"); | |||
| osc_clear_data(&osc.data); | |||
| } | |||
| @@ -85,9 +100,7 @@ public: | |||
| { | |||
| if (midi.port_min && aout.count > 0) | |||
| 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() | |||
| @@ -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) | |||
| { | |||
| fix_parameter_value(value, param.ranges[param_id]); | |||
| param_buffers[param_id] = value; | |||
| #ifndef BUILD_BRIDGE | |||
| @@ -168,33 +182,22 @@ public: | |||
| { | |||
| reload_programs(false); | |||
| } | |||
| #if 0 | |||
| else if (strcmp(key, "names") == 0) // Not in the API! | |||
| { | |||
| if (midiprog.count > 0) | |||
| { | |||
| //osc_send_set_program_count(&global_osc_data, m_id, midiprog.count); | |||
| // FIXME | |||
| // 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]); | |||
| } | |||
| @@ -202,6 +205,7 @@ public: | |||
| callback_action(CALLBACK_RELOAD_PROGRAMS, m_id, 0, 0, 0.0); | |||
| } | |||
| } | |||
| #endif | |||
| CarlaPlugin::set_custom_data(dtype, key, value, gui_send); | |||
| } | |||
| @@ -439,7 +443,7 @@ public: | |||
| if (max - min <= 0.0) | |||
| { | |||
| qWarning("Broken plugin parameter -> max - min <= 0"); | |||
| qWarning("Broken plugin parameter: max - min <= 0"); | |||
| max = min + 0.1; | |||
| } | |||
| @@ -474,9 +478,8 @@ public: | |||
| 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; | |||
| // MIDI CC value | |||
| @@ -493,17 +496,10 @@ public: | |||
| } | |||
| 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; | |||
| max = get_sample_rate(); | |||
| def = 0; | |||
| @@ -511,6 +507,12 @@ public: | |||
| step_small = 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 | |||
| { | |||
| @@ -616,7 +618,9 @@ public: | |||
| m_id = _id; | |||
| carla_proc_unlock(); | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.global_jack_client == false) | |||
| #endif | |||
| jack_activate(jack_client); | |||
| } | |||
| @@ -1006,6 +1010,18 @@ public: | |||
| CARLA_PROCESS_CONTINUE_CHECK; | |||
| // -------------------------------------------------------------------------------------------------------- | |||
| // Special Parameters | |||
| for (k=0; k < param.count; k++) | |||
| { | |||
| if (param.data[k].type == PARAMETER_LATENCY) | |||
| { | |||
| // TODO | |||
| break; | |||
| } | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------- | |||
| // 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) | |||
| { | |||
| 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; | |||
| } | |||
| } | |||
| @@ -52,7 +52,7 @@ bool is_ladspa_rdf_descriptor_valid(const LADSPA_RDF_Descriptor* rdf_descriptor, | |||
| } | |||
| 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; | |||
| } | |||
| } | |||
| @@ -131,8 +131,7 @@ public: | |||
| 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() | |||
| @@ -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) | |||
| { | |||
| fix_parameter_value(value, param.ranges[param_id]); | |||
| param_buffers[param_id] = value; | |||
| CarlaPlugin::set_parameter_value(param_id, value, gui_send, osc_send, callback_send); | |||
| @@ -458,7 +458,7 @@ public: | |||
| if (max - min <= 0.0) | |||
| { | |||
| qWarning("Broken plugin parameter -> max - min <= 0"); | |||
| qWarning("Broken plugin parameter: max - min <= 0"); | |||
| max = min + 0.1; | |||
| } | |||
| @@ -493,24 +493,16 @@ public: | |||
| 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; | |||
| } | |||
| 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; | |||
| max = get_sample_rate(); | |||
| def = 0; | |||
| @@ -518,6 +510,12 @@ public: | |||
| step_small = 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 | |||
| { | |||
| @@ -599,7 +597,9 @@ public: | |||
| m_id = _id; | |||
| carla_proc_unlock(); | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.global_jack_client == false) | |||
| #endif | |||
| jack_activate(jack_client); | |||
| } | |||
| @@ -737,6 +737,18 @@ public: | |||
| CARLA_PROCESS_CONTINUE_CHECK; | |||
| // -------------------------------------------------------------------------------------------------------- | |||
| // Special Parameters | |||
| for (k=0; k < param.count; k++) | |||
| { | |||
| if (param.data[k].type == PARAMETER_LATENCY) | |||
| { | |||
| // TODO | |||
| break; | |||
| } | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------- | |||
| // Plugin processing | |||
| @@ -934,7 +946,9 @@ public: | |||
| m_name = get_unique_name(descriptor->Name); | |||
| if (carla_jack_register_plugin(this, &jack_client)) | |||
| { | |||
| return true; | |||
| } | |||
| else | |||
| 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; | |||
| // 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 | |||
| const uint32_t lv2_feature_id_uri_map = 0; | |||
| @@ -1156,7 +1157,9 @@ public: | |||
| m_id = _id; | |||
| carla_proc_unlock(); | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.global_jack_client == false) | |||
| #endif | |||
| jack_activate(jack_client); | |||
| } | |||
| @@ -310,22 +310,26 @@ public: | |||
| // --------------------------------------- | |||
| // Audio Outputs | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.global_jack_client) | |||
| { | |||
| strcpy(port_name, m_name); | |||
| strcat(port_name, ":out-left"); | |||
| } | |||
| else | |||
| #endif | |||
| strcpy(port_name, "out-left"); | |||
| 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) | |||
| { | |||
| strcpy(port_name, m_name); | |||
| strcat(port_name, ":out-right"); | |||
| } | |||
| else | |||
| #endif | |||
| strcpy(port_name, "out-right"); | |||
| aout.ports[1] = jack_port_register(jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); | |||
| @@ -333,12 +337,14 @@ public: | |||
| // --------------------------------------- | |||
| // MIDI Input | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.global_jack_client) | |||
| { | |||
| strcpy(port_name, m_name); | |||
| strcat(port_name, ":midi-in"); | |||
| } | |||
| else | |||
| #endif | |||
| strcpy(port_name, "midi-in"); | |||
| midi.port_min = jack_port_register(jack_client, port_name, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); | |||
| @@ -346,22 +352,26 @@ public: | |||
| // --------------------------------------- | |||
| // Parameters | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.global_jack_client) | |||
| { | |||
| strcpy(port_name, m_name); | |||
| strcat(port_name, ":control-in"); | |||
| } | |||
| else | |||
| #endif | |||
| strcpy(port_name, "control-in"); | |||
| 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) | |||
| { | |||
| strcpy(port_name, m_name); | |||
| strcat(port_name, ":control-out"); | |||
| } | |||
| else | |||
| #endif | |||
| strcpy(port_name, "control-out"); | |||
| param.port_cout = jack_port_register(jack_client, port_name, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0); | |||
| @@ -608,7 +618,9 @@ public: | |||
| m_id = _id; | |||
| carla_proc_unlock(); | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.global_jack_client == false) | |||
| #endif | |||
| jack_activate(jack_client); | |||
| } | |||
| @@ -496,7 +496,9 @@ public: | |||
| m_id = _id; | |||
| carla_proc_unlock(); | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.global_jack_client == false) | |||
| #endif | |||
| jack_activate(jack_client); | |||
| } | |||
| @@ -1134,7 +1136,7 @@ public: | |||
| const int port_name_size = jack_port_name_size(); | |||
| char port_name[port_name_size]; | |||
| #ifndef BRIDGE_WINVST | |||
| #ifndef BUILD_BRIDGE | |||
| if (carla_options.global_jack_client) | |||
| { | |||
| strncpy(port_name, plugin->name, (port_name_size/2)-2); | |||
| @@ -134,7 +134,7 @@ class ParamSpinBox(QAbstractSpinBox): | |||
| self._minimum = 0.0 | |||
| self._maximum = 1.0 | |||
| self._default = 0.0 | |||
| self._value = 0.0 | |||
| self._value = None | |||
| self._step = 0.0 | |||
| self._step_small = 0.0 | |||
| self._step_large = 0.0 | |||
| @@ -230,7 +230,8 @@ class ParamSpinBox(QAbstractSpinBox): | |||
| for scalepoint in scalepoints: | |||
| 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) | |||
| @@ -317,7 +318,7 @@ class ParamSpinBox(QAbstractSpinBox): | |||
| self.set_value(self._default) | |||
| def stepBy(self, steps): | |||
| if (steps == 0): | |||
| if (steps == 0 or self._value == None): | |||
| return | |||
| value = self._value+(steps*self._step) | |||
| @@ -330,7 +331,7 @@ class ParamSpinBox(QAbstractSpinBox): | |||
| self.set_value(value) | |||
| def stepEnabled(self): | |||
| if (self._read_only): | |||
| if (self._read_only or self._value == None): | |||
| return QAbstractSpinBox.StepNone | |||
| elif (self._value <= self._minimum): | |||
| return QAbstractSpinBox.StepUpEnabled | |||