X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Flv2_plugin.cc;h=36b77e6d59fb8a8f287defe69dceac24f960f34b;hb=d89573f8e73ee7f0c28a6b9a8b8ba0f8e78c69aa;hp=6d4a71869f0c9105bd02060d3ed39dca8e02a0f7;hpb=e487814e9dc52b712d7c5cd242ce4fac76397b1a;p=ardour.git diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc index 6d4a71869f..36b77e6d59 100644 --- a/libs/ardour/lv2_plugin.cc +++ b/libs/ardour/lv2_plugin.cc @@ -142,6 +142,9 @@ public: LilvNode* time_Position; LilvNode* ui_GtkUI; LilvNode* ui_external; + LilvNode* ui_externalkx; + LilvNode* units_unit; + LilvNode* units_midiNote; private: bool _bundle_checked; @@ -289,7 +292,7 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate) _latency_control_port = 0; _next_cycle_start = std::numeric_limits::max(); _next_cycle_speed = 1.0; - _block_length = _engine.frames_per_cycle(); + _block_length = _engine.samples_per_cycle(); _seq_size = _engine.raw_buffer_size(DataType::MIDI); _state_version = 0; _was_activated = false; @@ -561,11 +564,15 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate) if (!_impl->ui) { LILV_FOREACH(uis, i, uis) { const LilvUI* ui = lilv_uis_get(uis, i); - if (lilv_ui_is_a(ui, _world.ui_external)) { + if (lilv_ui_is_a(ui, _world.ui_externalkx)) { _impl->ui = ui; _impl->ui_type = _world.ui_external; break; } + if (lilv_ui_is_a(ui, _world.ui_external)) { + _impl->ui = ui; + _impl->ui_type = _world.ui_external; + } } } } @@ -613,7 +620,16 @@ LV2Plugin::is_external_ui() const if (!_impl->ui) { return false; } - return lilv_ui_is_a(_impl->ui, _world.ui_external); + return lilv_ui_is_a(_impl->ui, _world.ui_external) || lilv_ui_is_a(_impl->ui, _world.ui_externalkx); +} + +bool +LV2Plugin::is_external_kx() const +{ + if (!_impl->ui) { + return false; + } + return lilv_ui_is_a(_impl->ui, _world.ui_externalkx); } bool @@ -970,7 +986,7 @@ LV2Plugin::find_presets() lilv_node_as_string(name)))); } else { warning << string_compose( - _("Plugin \"%1\% preset \"%2%\" is missing a label\n"), + _("Plugin \"%1\" preset \"%2\" is missing a label\n"), lilv_node_as_string(lilv_plugin_get_uri(_impl->plugin)), lilv_node_as_string(preset)) << endmsg; } @@ -1006,8 +1022,10 @@ LV2Plugin::load_preset(PresetRecord r) LilvWorld* world = _world.world; LilvNode* pset = lilv_new_uri(world, r.uri.c_str()); LilvState* state = lilv_state_new_from_world(world, _uri_map.urid_map(), pset); + printf("LV2Plugin::load_preset %s\n", r.uri.c_str()); if (state) { + printf("found state\n"); lilv_state_restore(state, _impl->instance, set_port_value, this, 0, NULL); lilv_state_free(state); } @@ -1077,7 +1095,13 @@ LV2Plugin::do_save_preset(string name) lilv_state_free(state); - return Glib::filename_to_uri(Glib::build_filename(bundle, file_name)); + std::string uri = Glib::filename_to_uri(Glib::build_filename(bundle, file_name)); + LilvNode *node = lilv_new_uri(_world.world, uri.c_str()); + lilv_world_load_bundle(_world.world, node); + lilv_node_free(node); + printf("LV2Plugin::do_save_preset %s\n", uri.c_str()); + + return uri; } void @@ -1137,8 +1161,24 @@ LV2Plugin::write_from_ui(uint32_t index, const uint8_t* body) { if (!_from_ui) { - _from_ui = new RingBuffer( - _session.engine().raw_buffer_size(DataType::MIDI) * NBUFS); + size_t rbs = _session.engine().raw_buffer_size(DataType::MIDI) * NBUFS; + /* buffer data communication from plugin UI to plugin instance. + * this buffer needs to potentially hold + * (port's minimumSize) * (audio-periods) / (UI-periods) + * bytes. + * + * e.g 48kSPS / 128fpp -> audio-periods = 375 Hz + * ui-periods = 25 Hz (SuperRapidScreenUpdate) + * default minimumSize = 32K (see LV2Plugin::allocate_atom_event_buffers() + * + * it is NOT safe to overflow (msg.size will be misinterpreted) + */ + uint32_t bufsiz = 32768; + if (_atom_ev_buffers && _atom_ev_buffers[0]) { + bufsiz = lv2_evbuf_get_capacity(_atom_ev_buffers[0]); + } + rbs = max((size_t) bufsiz * 8, rbs); + _from_ui = new RingBuffer(rbs); } if (!write_to(_from_ui, index, protocol, size, body)) { @@ -1165,8 +1205,14 @@ void LV2Plugin::enable_ui_emmission() { if (!_to_ui) { - _to_ui = new RingBuffer( - _session.engine().raw_buffer_size(DataType::MIDI) * NBUFS); + /* see note in LV2Plugin::write_from_ui() */ + uint32_t bufsiz = 32768; + if (_atom_ev_buffers && _atom_ev_buffers[0]) { + bufsiz = lv2_evbuf_get_capacity(_atom_ev_buffers[0]); + } + size_t rbs = _session.engine().raw_buffer_size(DataType::MIDI) * NBUFS; + rbs = max((size_t) bufsiz * 8, rbs); + _to_ui = new RingBuffer(rbs); } } @@ -1233,6 +1279,8 @@ LV2Plugin::set_state(const XMLNode& node, int version) return -1; } +#ifndef NO_PLUGIN_STATE + if (version < 3000) { nodes = node.children("port"); } else { @@ -1288,6 +1336,7 @@ LV2Plugin::set_state(const XMLNode& node, int version) } latency_compute_run(); +#endif return Plugin::set_state(node, version); } @@ -1297,8 +1346,10 @@ LV2Plugin::get_parameter_descriptor(uint32_t which, ParameterDescriptor& desc) c { const LilvPort* port = lilv_plugin_get_port_by_index(_impl->plugin, which); + LilvNodes* portunits; LilvNode *def, *min, *max; lilv_port_get_range(_impl->plugin, port, &def, &min, &max); + portunits = lilv_port_get_value(_impl->plugin, port, _world.units_unit); desc.integer_step = lilv_port_has_property(_impl->plugin, port, _world.lv2_integer); desc.toggled = lilv_port_has_property(_impl->plugin, port, _world.lv2_toggled); @@ -1307,6 +1358,8 @@ LV2Plugin::get_parameter_descriptor(uint32_t which, ParameterDescriptor& desc) c desc.label = lilv_node_as_string(lilv_port_get_name(_impl->plugin, port)); desc.lower = min ? lilv_node_as_float(min) : 0.0f; desc.upper = max ? lilv_node_as_float(max) : 1.0f; + desc.midinote = lilv_nodes_contains(portunits, _world.units_midiNote); + if (desc.sr_dependent) { desc.lower *= _session.frame_rate (); desc.upper *= _session.frame_rate (); @@ -1331,6 +1384,7 @@ LV2Plugin::get_parameter_descriptor(uint32_t which, ParameterDescriptor& desc) c lilv_node_free(def); lilv_node_free(min); lilv_node_free(max); + lilv_nodes_free(portunits); return 0; } @@ -1350,11 +1404,6 @@ LV2Plugin::describe_parameter(Evoral::Parameter which) return X_("hidden"); } - if (lilv_port_has_property(_impl->plugin, - lilv_plugin_get_port_by_index(_impl->plugin, which.id()), _world.lv2_sampleRate)) { - return X_("hidden"); - } - if (lilv_port_has_property(_impl->plugin, lilv_plugin_get_port_by_index(_impl->plugin, which.id()), _world.lv2_reportsLatency)) { return X_("latency"); @@ -1475,7 +1524,7 @@ LV2Plugin::allocate_atom_event_buffers() return; } - DEBUG_TRACE(DEBUG::LV2, string_compose("allocate %1 atom_ev_buffers\n", total_atom_buffers)); + DEBUG_TRACE(DEBUG::LV2, string_compose("allocate %1 atom_ev_buffers of %d bytes\n", total_atom_buffers, minimumSize)); _atom_ev_buffers = (LV2_Evbuf**) malloc((total_atom_buffers + 1) * sizeof(LV2_Evbuf*)); for (int i = 0; i < total_atom_buffers; ++i ) { _atom_ev_buffers[i] = lv2_evbuf_new(minimumSize, LV2_EVBUF_ATOM, @@ -1648,7 +1697,10 @@ LV2Plugin::connect_and_run(BufferSet& bufs, } } else if (!valid) { // Nothing we understand or care about, connect to scratch - _ev_buffers[port_index] = silent_bufs.get_lv2_midi( + // see note for midi-buffer size above + scratch_bufs.ensure_lv2_bufsize((flags & PORT_INPUT), + 0, _port_minimumSize[port_index]); + _ev_buffers[port_index] = scratch_bufs.get_lv2_midi( (flags & PORT_INPUT), 0, (flags & PORT_EVENT)); } buf = lv2_evbuf_get_buffer(_ev_buffers[port_index]); @@ -1898,7 +1950,7 @@ LV2Plugin::Impl::designated_input (const char* uri, void** bufptrs[], void** buf return port; } -static bool lv2_filter (const string& str, void *arg) +static bool lv2_filter (const string& str, void* /*arg*/) { /* Not a dotfile, has a prefix before a period, suffix is "lv2" */ @@ -1938,10 +1990,16 @@ LV2World::LV2World() time_Position = lilv_new_uri(world, LV2_TIME__Position); ui_GtkUI = lilv_new_uri(world, LV2_UI__GtkUI); ui_external = lilv_new_uri(world, "http://lv2plug.in/ns/extensions/ui#external"); + ui_externalkx = lilv_new_uri(world, "http://kxstudio.sf.net/ns/lv2ext/external-ui#Widget"); + units_unit = lilv_new_uri(world, "http://lv2plug.in/ns/extensions/units#unit"); + units_midiNote = lilv_new_uri(world, "http://lv2plug.in/ns/extensions/units#midiNote"); } LV2World::~LV2World() { + lilv_node_free(units_midiNote); + lilv_node_free(units_unit); + lilv_node_free(ui_externalkx); lilv_node_free(ui_external); lilv_node_free(ui_GtkUI); lilv_node_free(time_Position); @@ -1980,16 +2038,18 @@ LV2World::load_bundled_plugins() if (plugin_objects) { for ( vector::iterator x = plugin_objects->begin(); x != plugin_objects->end (); ++x) { #ifdef WINDOWS - string uri = "file:///" + **x + "/"; + string uri = "file:///" + **x + "/"; #else - string uri = "file://" + **x + "/"; + string uri = "file://" + **x + "/"; #endif - LilvNode *node = lilv_new_uri(world, uri.c_str()); - lilv_world_load_bundle(world, node); - lilv_node_free(node); - } + LilvNode *node = lilv_new_uri(world, uri.c_str()); + lilv_world_load_bundle(world, node); + lilv_node_free(node); } + } delete (plugin_objects); + + _bundle_checked = true; } }