X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Flv2_plugin.cc;h=deff882d70ac409670744dc910428afc264bd843;hb=ac9219a3c884b69352ff5ab0d13f30fb15cf8e6e;hp=30134a5dbbbfdbd56ebbd17c0f75342f7b0e48ab;hpb=a6e0b60ae1df3676ba45eeb302108eecfe7a7797;p=ardour.git diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc index 30134a5dbb..deff882d70 100644 --- a/libs/ardour/lv2_plugin.cc +++ b/libs/ardour/lv2_plugin.cc @@ -26,13 +26,13 @@ #include #include -#include #include #include #include -#include "pbd/pathscanner.h" +#include "pbd/file_utils.h" +#include "pbd/stl_delete.h" #include "pbd/compose.h" #include "pbd/error.h" #include "pbd/xml++.h" @@ -48,7 +48,7 @@ #include "ardour/types.h" #include "ardour/utils.h" #include "ardour/worker.h" -#include "ardour/lv2_bundled_search_path.h" +#include "ardour/search_paths.h" #include "i18n.h" #include @@ -144,6 +144,8 @@ public: LilvNode* ui_GtkUI; LilvNode* ui_external; LilvNode* ui_externalkx; + LilvNode* units_unit; + LilvNode* units_midiNote; private: bool _bundle_checked; @@ -291,7 +293,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; @@ -405,7 +407,7 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate) throw failed_constructor(); } -#ifdef HAVE_NEW_LILV +#ifdef HAVE_LILV_0_16_0 // Load default state LilvState* state = lilv_state_new_from_world( _world.world, _uri_map.urid_map(), lilv_plugin_get_uri(_impl->plugin)); @@ -879,27 +881,6 @@ LV2Plugin::lv2_state_make_path(LV2_State_Make_Path_Handle handle, return g_strndup(abs_path.c_str(), abs_path.length()); } -static void -remove_directory(const std::string& path) -{ - if (!Glib::file_test(path, Glib::FILE_TEST_IS_DIR)) { - warning << string_compose("\"%1\" is not a directory", path) << endmsg; - return; - } - - Glib::RefPtr dir = Gio::File::create_for_path(path); - Glib::RefPtr e = dir->enumerate_children(); - Glib::RefPtr fi; - while ((fi = e->next_file())) { - if (fi->get_type() == Gio::FILE_TYPE_DIRECTORY) { - remove_directory(fi->get_name()); - } else { - dir->get_child(fi->get_name())->remove(); - } - } - dir->remove(); -} - void LV2Plugin::add_state(XMLNode* root) const { @@ -951,7 +932,7 @@ LV2Plugin::add_state(XMLNode* root) const } else { // State is identical, decrement version and nuke directory lilv_state_free(state); - remove_directory(new_dir); + PBD::remove_directory(new_dir); --_state_version; } @@ -1025,6 +1006,7 @@ LV2Plugin::load_preset(PresetRecord r) if (state) { lilv_state_restore(state, _impl->instance, set_port_value, this, 0, NULL); lilv_state_free(state); + Plugin::load_preset(r); } lilv_node_free(pset); @@ -1092,7 +1074,18 @@ 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_bundle = lilv_new_uri(_world.world, Glib::filename_to_uri(Glib::build_filename(bundle, "/")).c_str()); + LilvNode *node_preset = lilv_new_uri(_world.world, uri.c_str()); +#ifdef HAVE_LILV_0_19_2 + lilv_world_unload_resource(_world.world, node_preset); + lilv_world_unload_bundle(_world.world, node_bundle); +#endif + lilv_world_load_bundle(_world.world, node_bundle); + lilv_world_load_resource(_world.world, node_preset); + lilv_node_free(node_bundle); + lilv_node_free(node_preset); + return uri; } void @@ -1161,10 +1154,14 @@ LV2Plugin::write_from_ui(uint32_t index, * e.g 48kSPS / 128fpp -> audio-periods = 375 Hz * ui-periods = 25 Hz (SuperRapidScreenUpdate) * default minimumSize = 32K (see LV2Plugin::allocate_atom_event_buffers() - * -> 15 * 32K - * it is safe to overflow (but the plugin state may be inconsistent). + * + * it is NOT safe to overflow (msg.size will be misinterpreted) */ - rbs = max((size_t) 32768 * 6, rbs); + 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); } @@ -1193,8 +1190,12 @@ LV2Plugin::enable_ui_emmission() { if (!_to_ui) { /* 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) 32768 * 8, rbs); + rbs = max((size_t) bufsiz * 8, rbs); _to_ui = new RingBuffer(rbs); } } @@ -1329,8 +1330,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); @@ -1339,6 +1342,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 (); @@ -1363,6 +1368,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; } @@ -1502,7 +1508,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, @@ -1675,6 +1681,9 @@ LV2Plugin::connect_and_run(BufferSet& bufs, } } else if (!valid) { // Nothing we understand or care about, connect to scratch + // 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)); } @@ -1879,6 +1888,7 @@ LV2Plugin::latency_compute_run() // Run the plugin so that it can set its latency parameter + bool was_activated = _was_activated; activate(); uint32_t port_index = 0; @@ -1909,6 +1919,9 @@ LV2Plugin::latency_compute_run() run(bufsize); deactivate(); + if (was_activated) { + activate(); + } } const LilvPort* @@ -1925,7 +1938,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" */ @@ -1966,10 +1979,14 @@ LV2World::LV2World() 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); @@ -2004,21 +2021,19 @@ LV2World::load_bundled_plugins() { if (!_bundle_checked) { cout << "Scanning folders for bundled LV2s: " << ARDOUR::lv2_bundled_search_path().to_string() << endl; - PathScanner scanner; - vector *plugin_objects = scanner (ARDOUR::lv2_bundled_search_path().to_string(), lv2_filter, 0, true, true); - if (plugin_objects) { - for ( vector::iterator x = plugin_objects->begin(); x != plugin_objects->end (); ++x) { + + vector plugin_objects; + find_paths_matching_filter (plugin_objects, ARDOUR::lv2_bundled_search_path(), lv2_filter, 0, true, true, true); + for ( vector::iterator x = plugin_objects.begin(); x != plugin_objects.end (); ++x) { #ifdef PLATFORM_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; } @@ -2060,7 +2075,9 @@ LV2PluginInfo::discover() PluginInfoList* plugs = new PluginInfoList; const LilvPlugins* plugins = lilv_world_get_all_plugins(_world.world); - info << "LV2: Discovering " << lilv_plugins_size(plugins) << " plugins" << endmsg; + if (!Config->get_show_plugin_scan_window()) { + info << "LV2: Discovering " << lilv_plugins_size(plugins) << " plugins" << endmsg; + } LILV_FOREACH(plugins, i, plugins) { const LilvPlugin* p = lilv_plugins_get(plugins, i); @@ -2078,6 +2095,7 @@ LV2PluginInfo::discover() info->name = string(lilv_node_as_string(name)); lilv_node_free(name); + ARDOUR::PluginScanMessage(_("LV2"), info->name, false); const LilvPluginClass* pclass = lilv_plugin_get_class(p); const LilvNode* label = lilv_plugin_class_get_label(pclass);