X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Flv2_plugin.cc;h=46c80d56580c1210e5fa1a2e334046eef807ab47;hb=de4c0eb27c84a48828e276fc702e139d25eeba72;hp=cae4a299113bc0fafb953d03220d9669883177de;hpb=3cc644b467bf335b1cc75164114b177e7de15aec;p=ardour.git diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc index cae4a29911..46c80d5658 100644 --- a/libs/ardour/lv2_plugin.cc +++ b/libs/ardour/lv2_plugin.cc @@ -36,9 +36,15 @@ #include "pbd/stl_delete.h" #include "pbd/compose.h" #include "pbd/error.h" +#include "pbd/locale_guard.h" #include "pbd/replace_all.h" #include "pbd/xml++.h" +#ifdef PLATFORM_WINDOWS +#include // CSIDL_* +#include "pbd/windows_special_dirs.h" +#endif + #include "libardour-config.h" #include "ardour/audio_buffer.h" @@ -189,6 +195,7 @@ public: LilvNode* auto_automation_control; // atom:supports LilvNode* auto_automation_controlled; // lv2:portProperty LilvNode* auto_automation_controller; // lv2:portProperty + LilvNode* inline_display_in_gui; // lv2:optionalFeature #endif private: @@ -223,19 +230,36 @@ work_respond(LV2_Worker_Respond_Handle handle, #ifdef LV2_EXTENDED /* inline display extension */ -static void -queue_draw (LV2_Inline_Display_Handle handle) +void +LV2Plugin::queue_draw (LV2_Inline_Display_Handle handle) { LV2Plugin* plugin = (LV2Plugin*)handle; plugin->QueueDraw(); /* EMIT SIGNAL */ } -static void -midnam_update (LV2_Midnam_Handle handle) +void +LV2Plugin::midnam_update (LV2_Midnam_Handle handle) { LV2Plugin* plugin = (LV2Plugin*)handle; + plugin->_midnam_dirty = true; plugin->UpdateMidnam (); /* EMIT SIGNAL */ } + +void +LV2Plugin::bankpatch_notify (LV2_BankPatch_Handle handle, uint8_t chn, uint32_t bank, uint8_t pgm) +{ + LV2Plugin* plugin = (LV2Plugin*)handle; + if (chn > 15) { + return; + } + plugin->seen_bankpatch = true; + if (pgm > 127 || bank > 16383) { + plugin->_bankpatch[chn] = UINT32_MAX; + } else { + plugin->_bankpatch[chn] = (bank << 7) | pgm; + } + plugin->BankPatchChange (chn); /* EMIT SIGNAL */ +} #endif /* log extension */ @@ -322,13 +346,14 @@ struct LV2Plugin::Impl { #ifdef LV2_EXTENDED LV2_Inline_Display* queue_draw; LV2_Midnam* midnam; + LV2_BankPatch* bankpatch; #endif }; LV2Plugin::LV2Plugin (AudioEngine& engine, Session& session, const void* c_plugin, - framecnt_t rate) + samplecnt_t rate) : Plugin (engine, session) , Workee () , _impl(new Impl()) @@ -366,7 +391,7 @@ LV2Plugin::LV2Plugin (const LV2Plugin& other) } void -LV2Plugin::init(const void* c_plugin, framecnt_t rate) +LV2Plugin::init(const void* c_plugin, samplecnt_t rate) { DEBUG_TRACE(DEBUG::LV2, "init\n"); @@ -382,13 +407,14 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate) _bpm_control_port = 0; _freewheel_control_port = 0; _latency_control_port = 0; - _next_cycle_start = std::numeric_limits::max(); + _next_cycle_start = std::numeric_limits::max(); _next_cycle_speed = 1.0; _seq_size = _engine.raw_buffer_size(DataType::MIDI); _state_version = 0; _was_activated = false; _has_state_interface = false; _can_write_automation = false; + _inline_display_in_gui = false; _max_latency = 0; _current_latency = 0; _impl->block_length = _session.get_block_size(); @@ -414,7 +440,7 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate) lilv_node_free(state_uri); lilv_node_free(state_iface_uri); - _features = (LV2_Feature**)calloc(13, sizeof(LV2_Feature*)); + _features = (LV2_Feature**)calloc(14, sizeof(LV2_Feature*)); _features[0] = &_instance_access_feature; _features[1] = &_data_access_feature; _features[2] = &_make_path_feature; @@ -449,6 +475,15 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate) _midnam_feature.URI = LV2_MIDNAM__update; _midnam_feature.data = _impl->midnam; _features[n_features++] = &_midnam_feature; + + _impl->bankpatch = (LV2_BankPatch*) + malloc (sizeof(LV2_BankPatch)); + _impl->bankpatch->handle = this; + _impl->bankpatch->notify = bankpatch_notify; + + _bankpatch_feature.URI = LV2_BANKPATCH__notify; + _bankpatch_feature.data = _impl->bankpatch; + _features[n_features++] = &_bankpatch_feature; #endif #ifdef HAVE_LV2_1_2_0 @@ -482,6 +517,13 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate) _features[n_features++] = &_options_feature; #endif +#ifdef LV2_EXTENDED + seen_bankpatch = false; + for (uint32_t chn = 0; chn < 16; ++chn) { + _bankpatch[chn] = UINT32_MAX; + } +#endif + LV2_State_Make_Path* make_path = (LV2_State_Make_Path*)malloc( sizeof(LV2_State_Make_Path)); make_path->handle = this; @@ -549,6 +591,7 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate) _midname_interface = (const LV2_Midnam_Interface*) extension_data (LV2_MIDNAM__interface); if (_midname_interface) { + _midnam_dirty = true; read_midnam (); } #endif @@ -592,6 +635,9 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate) if (lilv_nodes_contains (optional_features, _world.auto_can_write_automatation)) { _can_write_automation = true; } + if (lilv_nodes_contains (optional_features, _world.inline_display_in_gui)) { + _inline_display_in_gui = true; + } lilv_nodes_free(optional_features); #endif @@ -742,7 +788,7 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate) lilv_port_get_range(plugin, port, &def, NULL, NULL); _defaults[i] = def ? lilv_node_as_float(def) : 0.0f; if (lilv_port_has_property (plugin, port, _world.lv2_sampleRate)) { - _defaults[i] *= _session.frame_rate (); + _defaults[i] *= _session.sample_rate (); } lilv_node_free(def); @@ -855,7 +901,7 @@ LV2Plugin::requires_fixed_sized_buffers () const */ if (get_info()->n_inputs.n_midi() > 0) { /* we don't yet implement midi buffer offsets (for split cycles). - * Also connect_and_run() also uses _session.transport_frame() directly + * Also connect_and_run() also uses _session.transport_sample() directly * (for BBT) which is not offset for plugin cycle split. */ return true; @@ -889,6 +935,7 @@ LV2Plugin::~LV2Plugin () #ifdef LV2_EXTENDED free(_impl->queue_draw); free(_impl->midnam); + free(_impl->bankpatch); #endif free(_features); @@ -961,6 +1008,11 @@ LV2Plugin::has_inline_display () { return _display_interface ? true : false; } +bool +LV2Plugin::inline_display_in_gui () { + return _inline_display_in_gui; +} + Plugin::Display_Image_Surface* LV2Plugin::render_inline_display (uint32_t w, uint32_t h) { if (_display_interface) { @@ -979,7 +1031,7 @@ LV2Plugin::has_midnam () { bool LV2Plugin::read_midnam () { bool rv = false; - if (!_midname_interface) { + if (!_midname_interface || !_midnam_dirty) { return rv; } char* midnam = _midname_interface->midnam ((void*)_impl->instance->lv2_handle); @@ -997,6 +1049,10 @@ LV2Plugin::read_midnam () { } #endif _midname_interface->free (midnam); + if (rv) { + UpdatedMidnam (); + _midnam_dirty = false; + } return rv; } @@ -1165,22 +1221,22 @@ LV2Plugin::get_layout (uint32_t which, UILayoutHint& h) const case 2: h.x0 = 1; h.x1 = 3; h.y0 = 2; h.y1 = 3; break; // Frequency 1 case 3: h.x0 = 1; h.x1 = 3; h.y0 = 0; h.y1 = 1; break; // Gain 1 - case 4: h.x0 = 2; h.x1 = 4; h.y0 = 1; h.y1 = 2; break; // Bandwidth 1 + case 4: h.x0 = 1; h.x1 = 3; h.y0 = 1; h.y1 = 2; break; // Bandwidth 1 case 18: h.x0 = 1; h.x1 = 4; h.y0 = 5; h.y1 = 6; break; // enable 1 case 5: h.x0 = 4; h.x1 = 6; h.y0 = 2; h.y1 = 3; break; // Frequency 2 case 6: h.x0 = 4; h.x1 = 6; h.y0 = 0; h.y1 = 1; break; // Gain 2 - case 7: h.x0 = 5; h.x1 = 7; h.y0 = 1; h.y1 = 2; break; // Bandwidth 2 + case 7: h.x0 = 4; h.x1 = 6; h.y0 = 1; h.y1 = 2; break; // Bandwidth 2 case 19: h.x0 = 4; h.x1 = 7; h.y0 = 5; h.y1 = 6; break; // enable 2 case 8: h.x0 = 7; h.x1 = 9; h.y0 = 2; h.y1 = 3; break; // Frequency 3 case 9: h.x0 = 7; h.x1 = 9; h.y0 = 0; h.y1 = 1; break; // Gain 3 - case 10: h.x0 = 8; h.x1 = 10; h.y0 = 1; h.y1 = 2; break; // Bandwidth 3 + case 10: h.x0 = 7; h.x1 = 9; h.y0 = 1; h.y1 = 2; break; // Bandwidth 3 case 20: h.x0 = 7; h.x1 = 10; h.y0 = 5; h.y1 = 6; break; // enable 3 case 11: h.x0 = 10; h.x1 = 12; h.y0 = 2; h.y1 = 3; break; // Frequency 4 case 12: h.x0 = 10; h.x1 = 12; h.y0 = 0; h.y1 = 1; break; // Gain 4 - case 13: h.x0 = 11; h.x1 = 13; h.y0 = 1; h.y1 = 2; break; // Bandwidth 4 + case 13: h.x0 = 10; h.x1 = 12; h.y0 = 1; h.y1 = 2; break; // Bandwidth 4 case 21: h.x0 = 10; h.x1 = 13; h.y0 = 5; h.y1 = 6; break; // enable 4 case 14: h.x0 = 13; h.x1 = 14; h.y0 = 2; h.y1 = 3; break; // Frequency H @@ -1264,7 +1320,7 @@ LV2Plugin::file_dir() const const std::string LV2Plugin::state_dir(unsigned num) const { - return Glib::build_filename(plugin_dir(), string_compose("state%1", num)); + return Glib::build_filename(plugin_dir(), string("state") + PBD::to_string (num)); } /** Implementation of state:makePath for files created at instantiation time. @@ -1298,21 +1354,19 @@ LV2Plugin::add_state(XMLNode* root) const assert(_insert_id != PBD::ID("0")); XMLNode* child; - char buf[32]; LocaleGuard lg; for (uint32_t i = 0; i < parameter_count(); ++i) { if (parameter_is_input(i) && parameter_is_control(i)) { child = new XMLNode("Port"); - child->add_property("symbol", port_symbol(i)); - snprintf(buf, sizeof(buf), "%+f", _shadow_data[i]); - child->add_property("value", string(buf)); + child->set_property("symbol", port_symbol(i)); + child->set_property("value", _shadow_data[i]); root->add_child_nocopy(*child); } } if (!_plugin_state_dir.empty()) { - root->add_property("template-dir", _plugin_state_dir); + root->set_property("template-dir", _plugin_state_dir); } if (_has_state_interface) { @@ -1368,7 +1422,7 @@ LV2Plugin::add_state(XMLNode* root) const saved_state = _state_version; } - root->add_property("state-dir", string_compose("state%1", saved_state)); + root->set_property("state-dir", string("state") + PBD::to_string (saved_state)); } } @@ -1434,6 +1488,7 @@ set_port_value(const char* port_symbol, const uint32_t port_index = self->port_index(port_symbol); if (port_index != (uint32_t)-1) { self->set_parameter(port_index, *(const float*)value); + self->PresetPortSetValue (port_index, *(const float*)value); /* EMIT SIGNAL */ } } @@ -1493,9 +1548,28 @@ LV2Plugin::do_save_preset(string name) const string prefix = legalize_for_uri(lilv_node_as_string(plug_name)); const string base_name = legalize_for_uri(name); const string file_name = base_name + ".ttl"; +#ifdef PLATFORM_WINDOWS + /* http://lv2plug.in/pages/filesystem-hierarchy-standard.html */ + std::string appdata = PBD::get_win_special_folder_path (CSIDL_APPDATA); + if (appdata.empty ()) { + // TODO consider a fallback location + return ""; + } + const string bundle = Glib::build_filename ( + appdata, "LV2", prefix + "_" + base_name + ".lv2"); +#else + /* while macOS/OSX user-specific path is + * + * $HOME/Library/Audio/Plug-Ins/LV2/ + * + * liblilv's LV2 search path on all unices does include ~/.lv2/ + * Ardour has been saving lv2 presets to ~/.lv2 for along time, + * so just keep them there. + */ const string bundle = Glib::build_filename( Glib::get_home_dir(), Glib::build_filename(".lv2", prefix + "_" + base_name + ".lv2")); +#endif #ifdef HAVE_LILV_0_21_3 /* delete reference to old preset (if any) */ @@ -1647,7 +1721,8 @@ LV2Plugin::write_from_ui(uint32_t index, if (_atom_ev_buffers && _atom_ev_buffers[0]) { bufsiz = lv2_evbuf_get_capacity(_atom_ev_buffers[0]); } - rbs = max((size_t) bufsiz * 8, rbs); + int fact = ceilf(_session.sample_rate () / 3000.f); + rbs = max((size_t) bufsiz * std::max (8, fact), rbs); _from_ui = new RingBuffer(rbs); } @@ -1750,19 +1825,19 @@ LV2Plugin::set_property(uint32_t key, const Variant& value) // Set up forge to write to temporary buffer on the stack LV2_Atom_Forge* forge = &_impl->ui_forge; - LV2_Atom_Forge_Frame frame; + LV2_Atom_Forge_Frame sample; uint8_t buf[PATH_MAX]; // Ought to be enough for anyone... lv2_atom_forge_set_buffer(forge, buf, sizeof(buf)); // Serialize patch:Set message to set property #ifdef HAVE_LV2_1_10_0 - lv2_atom_forge_object(forge, &frame, 0, _uri_map.urids.patch_Set); + lv2_atom_forge_object(forge, &sample, 0, _uri_map.urids.patch_Set); lv2_atom_forge_key(forge, _uri_map.urids.patch_property); lv2_atom_forge_urid(forge, key); lv2_atom_forge_key(forge, _uri_map.urids.patch_value); #else - lv2_atom_forge_blank(forge, &frame, 0, _uri_map.urids.patch_Set); + lv2_atom_forge_blank(forge, &sample, 0, _uri_map.urids.patch_Set); lv2_atom_forge_property_head(forge, _uri_map.urids.patch_property, 0); lv2_atom_forge_urid(forge, key); lv2_atom_forge_property_head(forge, _uri_map.urids.patch_value, 0); @@ -1803,7 +1878,16 @@ load_parameter_descriptor_units(LilvWorld* lworld, ParameterDescriptor& desc, co LilvNode* render = get_value(lworld, unit, _world.units_render); if (render) { desc.print_fmt = lilv_node_as_string(render); - replace_all (desc.print_fmt, "%f", "%.2f"); + /* override lilv's default "%f" format */ + if (desc.integer_step) { + replace_all (desc.print_fmt, "%f", "%.0f"); + } else if (desc.upper - desc.lower >= 1000) { + replace_all (desc.print_fmt, "%f", "%.1f"); + } else if (desc.upper - desc.lower >= 100) { + replace_all (desc.print_fmt, "%f", "%.2f"); + } else { + replace_all (desc.print_fmt, "%f", "%.3f"); + } lilv_node_free(render); } } @@ -1824,14 +1908,26 @@ load_parameter_descriptor(LV2World& world, if (label) { desc.label = lilv_node_as_string(label); } - if (def && lilv_node_is_float(def)) { - desc.normal = lilv_node_as_float(def); + if (def) { + if (lilv_node_is_float(def)) { + desc.normal = lilv_node_as_float(def); + } else if (lilv_node_is_int(def)) { + desc.normal = lilv_node_as_int(def); + } } - if (minimum && lilv_node_is_float(minimum)) { - desc.lower = lilv_node_as_float(minimum); + if (minimum) { + if (lilv_node_is_float(minimum)) { + desc.lower = lilv_node_as_float(minimum); + } else if (lilv_node_is_int(minimum)) { + desc.lower = lilv_node_as_int(minimum); + } } - if (maximum && lilv_node_is_float(maximum)) { - desc.upper = lilv_node_as_float(maximum); + if (maximum) { + if (lilv_node_is_float(maximum)) { + desc.upper = lilv_node_as_float(maximum); + } else if (lilv_node_is_int(maximum)) { + desc.upper = lilv_node_as_int(maximum); + } } load_parameter_descriptor_units(lworld, desc, units); desc.datatype = datatype; @@ -1892,16 +1988,16 @@ LV2Plugin::announce_property_values() // Set up forge to write to temporary buffer on the stack LV2_Atom_Forge* forge = &_impl->ui_forge; - LV2_Atom_Forge_Frame frame; + LV2_Atom_Forge_Frame sample; uint8_t buf[PATH_MAX]; // Ought to be enough for anyone... lv2_atom_forge_set_buffer(forge, buf, sizeof(buf)); // Serialize patch:Get message with no subject (implicitly plugin instance) #ifdef HAVE_LV2_1_10_0 - lv2_atom_forge_object(forge, &frame, 0, _uri_map.urids.patch_Get); + lv2_atom_forge_object(forge, &sample, 0, _uri_map.urids.patch_Get); #else - lv2_atom_forge_blank(forge, &frame, 0, _uri_map.urids.patch_Get); + lv2_atom_forge_blank(forge, &sample, 0, _uri_map.urids.patch_Get); #endif // Write message to UI=>Plugin ring @@ -1990,12 +2086,8 @@ int LV2Plugin::set_state(const XMLNode& node, int version) { XMLNodeList nodes; - XMLProperty const * prop; XMLNodeConstIterator iter; XMLNode* child; - const char* sym; - const char* value; - uint32_t port_id; LocaleGuard lg; if (node.name() != state_node_name()) { @@ -2015,15 +2107,16 @@ LV2Plugin::set_state(const XMLNode& node, int version) child = *iter; - if ((prop = child->property("symbol")) != 0) { - sym = prop->value().c_str(); - } else { + std::string sym; + if (!child->get_property("symbol", sym)) { warning << _("LV2: port has no symbol, ignored") << endmsg; continue; } map::iterator i = _port_indices.find(sym); + uint32_t port_id; + if (i != _port_indices.end()) { port_id = i->second; } else { @@ -2031,31 +2124,32 @@ LV2Plugin::set_state(const XMLNode& node, int version) continue; } - if ((prop = child->property("value")) != 0) { - value = prop->value().c_str(); - } else { + float val; + if (!child->get_property("value", val)) { warning << _("LV2: port has no value, ignored") << endmsg; continue; } - set_parameter(port_id, atof(value)); + set_parameter(port_id, val); } - if ((prop = node.property("template-dir")) != 0) { - set_state_dir (prop->value ()); + std::string template_dir; + if (node.get_property("template-dir", template_dir)) { + set_state_dir (template_dir); } _state_version = 0; - if ((prop = node.property("state-dir")) != 0) { - if (sscanf(prop->value().c_str(), "state%u", &_state_version) != 1) { + std::string state_dir; + if (node.get_property("state-dir", state_dir) != 0) { + if (sscanf(state_dir.c_str(), "state%u", &_state_version) != 1) { error << string_compose( "LV2: failed to parse state version from \"%1\"", - prop->value()) << endmsg; + state_dir) << endmsg; } std::string state_file = Glib::build_filename( plugin_dir(), - Glib::build_filename(prop->value(), "state.ttl")); + Glib::build_filename(state_dir, "state.ttl")); LilvState* state = lilv_state_new_from_file( _world.world, _uri_map.urid_map(), NULL, state_file.c_str()); @@ -2108,41 +2202,18 @@ LV2Plugin::get_parameter_descriptor(uint32_t which, ParameterDescriptor& desc) c load_parameter_descriptor_units(_world.world, desc, portunits); if (desc.sr_dependent) { - desc.lower *= _session.frame_rate (); - desc.upper *= _session.frame_rate (); + desc.lower *= _session.sample_rate (); + desc.upper *= _session.sample_rate (); } - desc.min_unbound = false; // TODO: LV2 extension required - desc.max_unbound = false; // TODO: LV2 extension required - desc.enumeration = lilv_port_has_property(_impl->plugin, port, _world.lv2_enumeration); desc.scale_points = get_scale_points(which); - desc.update_steps(); - if (steps) { - //override auto-calculated steps in update_steps() - float s = lilv_node_as_float (steps); - const float delta = desc.upper - desc.lower; - - desc.step = desc.smallstep = (delta / s); - desc.largestep = std::min ((delta / 5.0f), 10.f * desc.smallstep); - - if (desc.logarithmic) { - // TODO marry AutomationControl::internal_to_interface () with - // http://lv2plug.in/ns/ext/port-props/#rangeSteps - desc.smallstep = desc.smallstep / logf(s); - desc.step = desc.step / logf(s); - desc.largestep = desc.largestep / logf(s); - } else if (desc.integer_step) { - desc.smallstep = 1.0; - desc.step = std::max(1.f, rintf (desc.step)); - desc.largestep = std::max(1.f, rintf (desc.largestep)); - } - DEBUG_TRACE(DEBUG::LV2, string_compose("parameter %1 small: %2, step: %3 largestep: %4\n", - which, desc.smallstep, desc.step, desc.largestep)); + desc.rangesteps = lilv_node_as_float (steps); } + desc.update_steps(); lilv_node_free(def); lilv_node_free(min); @@ -2275,17 +2346,17 @@ LV2Plugin::describe_parameter(Evoral::Parameter which) } } -framecnt_t +samplecnt_t LV2Plugin::max_latency () const { return _max_latency; } -framecnt_t +samplecnt_t LV2Plugin::signal_latency() const { if (_latency_control_port) { - return (framecnt_t)floor(*_latency_control_port); + return (samplecnt_t)floor(*_latency_control_port); } else { return 0; } @@ -2427,17 +2498,17 @@ write_position(LV2_Atom_Forge* forge, Timecode::BBT_Time& bbt, double speed, double bpm, - framepos_t position, - framecnt_t offset) + samplepos_t position, + samplecnt_t offset) { const URIMap::URIDs& urids = URIMap::instance().urids; uint8_t pos_buf[256]; lv2_atom_forge_set_buffer(forge, pos_buf, sizeof(pos_buf)); - LV2_Atom_Forge_Frame frame; + LV2_Atom_Forge_Frame sample; #ifdef HAVE_LV2_1_10_0 - lv2_atom_forge_object(forge, &frame, 0, urids.time_Position); - lv2_atom_forge_key(forge, urids.time_frame); + lv2_atom_forge_object(forge, &sample, 0, urids.time_Position); + lv2_atom_forge_key(forge, urids.time_sample); lv2_atom_forge_long(forge, position); lv2_atom_forge_key(forge, urids.time_speed); lv2_atom_forge_float(forge, speed); @@ -2453,8 +2524,8 @@ write_position(LV2_Atom_Forge* forge, lv2_atom_forge_key(forge, urids.time_beatsPerMinute); lv2_atom_forge_float(forge, bpm); #else - lv2_atom_forge_blank(forge, &frame, 1, urids.time_Position); - lv2_atom_forge_property_head(forge, urids.time_frame, 0); + lv2_atom_forge_blank(forge, &sample, 1, urids.time_Position); + lv2_atom_forge_property_head(forge, urids.time_sample, 0); lv2_atom_forge_long(forge, position); lv2_atom_forge_property_head(forge, urids.time_speed, 0); lv2_atom_forge_float(forge, speed); @@ -2479,9 +2550,9 @@ write_position(LV2_Atom_Forge* forge, int LV2Plugin::connect_and_run(BufferSet& bufs, - framepos_t start, framepos_t end, double speed, + samplepos_t start, samplepos_t end, double speed, ChanMapping in_map, ChanMapping out_map, - pframes_t nframes, framecnt_t offset) + pframes_t nframes, samplecnt_t offset) { DEBUG_TRACE(DEBUG::LV2, string_compose("%1 run %2 offset %3\n", name(), nframes, offset)); Plugin::connect_and_run(bufs, start, end, speed, in_map, out_map, nframes, offset); @@ -2497,7 +2568,7 @@ LV2Plugin::connect_and_run(BufferSet& bufs, } if (_bpm_control_port) { - *_bpm_control_port = tmap.tempo_at_frame (start).note_types_per_minute(); + *_bpm_control_port = tmap.tempo_at_sample (start).note_types_per_minute(); } #ifdef LV2_EXTENDED @@ -2568,8 +2639,8 @@ LV2Plugin::connect_and_run(BufferSet& bufs, if (valid && (flags & PORT_INPUT)) { if ((flags & PORT_POSITION)) { - Timecode::BBT_Time bbt (tmap.bbt_at_frame (start)); - double bpm = tmap.tempo_at_frame (start).note_types_per_minute(); + Timecode::BBT_Time bbt (tmap.bbt_at_sample (start)); + double bpm = tmap.tempo_at_sample (start).note_types_per_minute(); double beatpos = (bbt.bars - 1) * tmetric.meter().divisions_per_bar() + (bbt.beats - 1) + (bbt.ticks / Timecode::BBT_Time::ticks_per_beat); @@ -2594,14 +2665,14 @@ LV2Plugin::connect_and_run(BufferSet& bufs, // Now merge MIDI and any transport events into the buffer const uint32_t type = _uri_map.urids.midi_MidiEvent; - const framepos_t tend = end; + const samplepos_t tend = end; ++metric_i; while (m != m_end || (metric_i != tmap.metrics_end() && - (*metric_i)->frame() < tend)) { + (*metric_i)->sample() < tend)) { MetricSection* metric = (metric_i != tmap.metrics_end()) ? *metric_i : NULL; - if (m != m_end && (!metric || metric->frame() > (*m).time())) { - const Evoral::Event ev(*m, false); + if (m != m_end && (!metric || metric->sample() > (*m).time())) { + const Evoral::Event ev(*m, false); if (ev.time() < nframes) { LV2_Evbuf_Iterator eend = lv2_evbuf_end(_ev_buffers[port_index]); lv2_evbuf_write(&eend, ev.time(), 0, type, ev.size(), ev.buffer()); @@ -2610,12 +2681,12 @@ LV2Plugin::connect_and_run(BufferSet& bufs, } else { tmetric.set_metric(metric); Timecode::BBT_Time bbt; - bbt = tmap.bbt_at_frame (metric->frame()); - double bpm = tmap.tempo_at_frame (start/*XXX*/).note_types_per_minute(); + bbt = tmap.bbt_at_sample (metric->sample()); + double bpm = tmap.tempo_at_sample (start/*XXX*/).note_types_per_minute(); write_position(&_impl->forge, _ev_buffers[port_index], tmetric, bbt, speed, bpm, - metric->frame(), - metric->frame() - start); + metric->sample(), + metric->sample() - start); ++metric_i; } } @@ -2707,9 +2778,9 @@ LV2Plugin::connect_and_run(BufferSet& bufs, for (LV2_Evbuf_Iterator i = lv2_evbuf_begin(buf); lv2_evbuf_is_valid(i); i = lv2_evbuf_next(i)) { - uint32_t frames, subframes, type, size; + uint32_t samples, subframes, type, size; uint8_t* data; - lv2_evbuf_get(i, &frames, &subframes, &type, &size, &data); + lv2_evbuf_get(i, &samples, &subframes, &type, &size, &data); #ifdef LV2_EXTENDED // Intercept Automation Write Events @@ -2731,13 +2802,13 @@ LV2Plugin::connect_and_run(BufferSet& bufs, const float v = ((const LV2_Atom_Float*)value)->body; // -> add automation event.. DEBUG_TRACE(DEBUG::LV2Automate, - string_compose ("Event p: %1 t: %2 v: %3\n", p, frames, v)); + string_compose ("Event p: %1 t: %2 v: %3\n", p, samples, v)); AutomationCtrlPtr c = get_automation_control (p); if (c && (c->ac->automation_state() == Touch || c->ac->automation_state() == Write) ) { - framepos_t when = std::max ((framepos_t) 0, start + frames - _current_latency); - assert (start + frames - _current_latency >= 0); + samplepos_t when = std::max ((samplepos_t) 0, start + samples - _current_latency); + assert (start + samples - _current_latency >= 0); if (c->guard) { c->guard = false; c->ac->list()->add (when, v, true, true); @@ -2799,7 +2870,7 @@ LV2Plugin::connect_and_run(BufferSet& bufs, AutomationCtrlPtr c = get_automation_control (p); DEBUG_TRACE(DEBUG::LV2Automate, string_compose ("Start Touch p: %1\n", p)); if (c) { - c->ac->start_touch (std::max ((framepos_t)0, start - _current_latency)); + c->ac->start_touch (std::max ((samplepos_t)0, start - _current_latency)); c->guard = true; } } @@ -2814,7 +2885,7 @@ LV2Plugin::connect_and_run(BufferSet& bufs, AutomationCtrlPtr c = get_automation_control (p); DEBUG_TRACE(DEBUG::LV2Automate, string_compose ("End Touch p: %1\n", p)); if (c) { - c->ac->stop_touch (true, std::max ((framepos_t)0, start - _current_latency)); + c->ac->stop_touch (std::max ((samplepos_t)0, start - _current_latency)); } } } @@ -2884,17 +2955,17 @@ LV2Plugin::connect_and_run(BufferSet& bufs, * so it needs to be realative to that. */ TempoMetric t = tmap.metric_at(start); - _current_bpm = tmap.tempo_at_frame (start).note_types_per_minute(); - Timecode::BBT_Time bbt (tmap.bbt_at_frame (start)); + _current_bpm = tmap.tempo_at_sample (start).note_types_per_minute(); + Timecode::BBT_Time bbt (tmap.bbt_at_sample (start)); double beatpos = (bbt.bars - 1) * t.meter().divisions_per_bar() + (bbt.beats - 1) + (bbt.ticks / Timecode::BBT_Time::ticks_per_beat); beatpos *= tmetric.meter().note_divisor() / 4.0; - _next_cycle_beat = beatpos + nframes * speed * _current_bpm / (60.f * _session.frame_rate()); + _next_cycle_beat = beatpos + nframes * speed * _current_bpm / (60.f * _session.sample_rate()); } if (_latency_control_port) { - framecnt_t new_latency = signal_latency (); + samplecnt_t new_latency = signal_latency (); _current_latency = new_latency; } return 0; @@ -3049,7 +3120,7 @@ LV2Plugin::latency_compute_run() uint32_t out_index = 0; // this is done in the main thread. non realtime. - const framecnt_t bufsize = _engine.samples_per_cycle(); + const samplecnt_t bufsize = _engine.samples_per_cycle(); float *buffer = (float*) malloc(_engine.samples_per_cycle() * sizeof(float)); memset(buffer, 0, sizeof(float) * bufsize); @@ -3159,6 +3230,7 @@ LV2World::LV2World() auto_automation_control = lilv_new_uri(world, LV2_AUTOMATE_URI__control); auto_automation_controlled = lilv_new_uri(world, LV2_AUTOMATE_URI__controlled); auto_automation_controller = lilv_new_uri(world, LV2_AUTOMATE_URI__controller); + inline_display_in_gui = lilv_new_uri(world, LV2_INLINEDISPLAY__in_gui); #endif #ifdef HAVE_LV2_1_2_0 bufz_powerOf2BlockLength = lilv_new_uri(world, LV2_BUF_SIZE__powerOf2BlockLength); @@ -3284,7 +3356,7 @@ LV2PluginInfo::load(Session& session) if (!uri) { throw failed_constructor(); } const LilvPlugin* lp = lilv_plugins_get_by_uri(plugins, uri); if (!lp) { throw failed_constructor(); } - plugin.reset(new LV2Plugin(session.engine(), session, lp, session.frame_rate())); + plugin.reset(new LV2Plugin(session.engine(), session, lp, session.sample_rate())); lilv_node_free(uri); plugin->set_info(PluginInfoPtr(shared_from_this ())); return plugin; @@ -3342,10 +3414,7 @@ LV2PluginInfo::in_category (const std::string &c) const { // TODO use untranslated lilv_plugin_get_class() // match gtk2_ardour/plugin_selector.cc - if (category == c) { - return true; - } - return false; + return category == c; } bool