allow latent self-automating plugins
[ardour.git] / libs / ardour / lv2_plugin.cc
index 6a5ed97aaebfa5a6860f80bd0396247a4f8d2139..ca0a5b45e3f13a0378239a32ad5fddd67035ed64 100644 (file)
@@ -17,6 +17,7 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+#include <cctype>
 #include <string>
 #include <vector>
 #include <limits>
@@ -237,6 +238,14 @@ log_vprintf(LV2_Log_Handle /*handle*/,
 {
        char* str = NULL;
        const int ret = g_vasprintf(&str, fmt, args);
+       /* strip trailing whitespace */
+       while (strlen (str) > 0 && isspace (str[strlen (str) - 1])) {
+               str[strlen (str) - 1] = '\0';
+       }
+       if (strlen (str) == 0) {
+               return 0;
+       }
+
        if (type == URIMap::instance().urids.log_Error) {
                error << str << endmsg;
        } else if (type == URIMap::instance().urids.log_Warning) {
@@ -634,6 +643,7 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
 
                _port_flags.push_back(flags);
                _port_minimumSize.push_back(minimumSize);
+               DEBUG_TRACE(DEBUG::LV2, string_compose("port %1 buffer %2 bytes\n", i, minimumSize));
        }
 
        _control_data = new float[num_ports];
@@ -1126,7 +1136,7 @@ LV2Plugin::add_state(XMLNode* root) const
 
        XMLNode*    child;
        char        buf[32];
-       LocaleGuard lg(X_("C"));
+       LocaleGuard lg;
 
        for (uint32_t i = 0; i < parameter_count(); ++i) {
                if (parameter_is_input(i) && parameter_is_control(i)) {
@@ -1799,13 +1809,13 @@ int
 LV2Plugin::set_state(const XMLNode& node, int version)
 {
        XMLNodeList          nodes;
-       const XMLProperty*   prop;
+       XMLProperty const * prop;
        XMLNodeConstIterator iter;
        XMLNode*             child;
        const char*          sym;
        const char*          value;
        uint32_t             port_id;
-       LocaleGuard          lg(X_("C"));
+       LocaleGuard          lg;
 
        if (node.name() != state_node_name()) {
                error << _("Bad node sent to LV2Plugin::set_state") << endmsg;
@@ -2119,8 +2129,7 @@ LV2Plugin::allocate_atom_event_buffers()
                        LilvNodes* atom_supports = lilv_port_get_value(
                                p, port, _world.atom_supports);
 
-                       if (!lilv_nodes_contains(buffer_types, _world.atom_Sequence)
-                                       || !lilv_nodes_contains(atom_supports, _world.midi_MidiEvent)) {
+                       if (lilv_nodes_contains(buffer_types, _world.atom_Sequence)) {
                                if (lilv_port_is_a(p, port, _world.lv2_InputPort)) {
                                        count_atom_in++;
                                }
@@ -2147,7 +2156,7 @@ LV2Plugin::allocate_atom_event_buffers()
                return;
        }
 
-       DEBUG_TRACE(DEBUG::LV2, string_compose("allocate %1 atom_ev_buffers of %d bytes\n", total_atom_buffers, minimumSize));
+       DEBUG_TRACE(DEBUG::LV2, string_compose("allocate %1 atom_ev_buffers of %2 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,
@@ -2310,7 +2319,7 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
                                        if (_session.transport_frame() != _next_cycle_start ||
                                            _session.transport_speed() != _next_cycle_speed) {
                                                // Transport has changed, write position at cycle start
-                                               tmap.bbt_time(_session.transport_frame(), bbt);
+                                               bbt = tmap.bbt_at_frame (_session.transport_frame());
                                                write_position(&_impl->forge, _ev_buffers[port_index],
                                                               tmetric, bbt, _session.transport_speed(),
                                                               _session.transport_frame(), 0);
@@ -2342,7 +2351,7 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
                                                ++m;
                                        } else {
                                                tmetric.set_metric(metric);
-                                               bbt = metric->start();
+                                               bbt = tmap.bbt_at_pulse (metric->pulse());
                                                write_position(&_impl->forge, _ev_buffers[port_index],
                                                               tmetric, bbt, _session.transport_speed(),
                                                               metric->frame(),
@@ -2463,11 +2472,13 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
                                                                // -> add automation event..
                                                                AutomationCtrlPtr c = get_automation_control (p);
                                                                if (c && c->ac->automation_state() == Touch) {
+                                                                       framepos_t when = std::max ((framepos_t) 0, _session.transport_frame() + frames - _current_latency);
+                                                                       assert (_session.transport_frame() + frames - _current_latency >= 0);
                                                                        if (c->guard) {
                                                                                c->guard = false;
-                                                                               c->ac->list()->add (_session.transport_frame() + frames, v, true, true);
+                                                                               c->ac->list()->add (when, v, true, true);
                                                                        } else {
-                                                                               c->ac->set_double (v, _session.transport_frame() + frames, true);
+                                                                               c->ac->set_double (v, when, true);
                                                                        }
                                                                }
                                                        }
@@ -2492,7 +2503,7 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
                                                                const uint32_t p = ((const LV2_Atom_Int*)parameter)->body;
                                                                AutomationCtrlPtr c = get_automation_control (p);
                                                                if (c) {
-                                                                       c->ac->start_touch (_session.transport_frame());
+                                                                       c->ac->start_touch (std::max ((framepos_t)0, _session.transport_frame() - _current_latency));
                                                                        c->guard = true;
                                                                }
                                                        }
@@ -2506,7 +2517,7 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
                                                                const uint32_t p = ((const LV2_Atom_Int*)parameter)->body;
                                                                AutomationCtrlPtr c = get_automation_control (p);
                                                                if (c) {
-                                                                       c->ac->stop_touch (true, _session.transport_frame());
+                                                                       c->ac->stop_touch (true, std::max ((framepos_t)0, _session.transport_frame() - _current_latency));
                                                                }
                                                        }
                                                }