add Plugin LatencyChanged() signal and max latency report
authorRobin Gareus <robin@gareus.org>
Fri, 8 Apr 2016 16:16:01 +0000 (18:16 +0200)
committerRobin Gareus <robin@gareus.org>
Fri, 8 Apr 2016 16:16:01 +0000 (18:16 +0200)
libs/ardour/ardour/lv2_plugin.h
libs/ardour/ardour/plugin.h
libs/ardour/lv2_plugin.cc

index c93c159a781368865ca44a32c7e8652891df8b9f..f1907e80ae53dadf0d9adf9e3669de4d4ba51a56 100644 (file)
@@ -71,6 +71,7 @@ class LIBARDOUR_API LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee
        uint32_t    num_ports () const;
        uint32_t    parameter_count () const;
        float       default_value (uint32_t port);
+       framecnt_t  max_latency () const;
        framecnt_t  signal_latency () const;
        void        set_parameter (uint32_t port, float val);
        float       get_parameter (uint32_t port) const;
@@ -190,6 +191,8 @@ class LIBARDOUR_API LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee
        URIMap&       _uri_map;
        bool          _no_sample_accurate_ctrl;
        bool          _can_write_automation;
+       framecnt_t    _max_latency;
+       framecnt_t    _current_latency;
 
        friend const void* lv2plugin_get_port_value(const char* port_symbol,
                                                    void*       user_data,
index e219ec5bdd24ecf90c42cb69266ce74e7daced9d..087f5968bd0e66586d60a2e8856d7dfa7dd171a2 100644 (file)
@@ -199,6 +199,26 @@ class LIBARDOUR_API Plugin : public PBD::StatefulDestructible, public Latent
                return 0;
        }
 
+       /** Emitted when a Latency Changes
+        *
+        * (this cannot be part of ARDOUR::Latent because
+        * signals cannot be copy-constructed).
+        */
+       PBD::Signal2<void,framecnt_t, framecnt_t> LatencyChanged;
+
+       /* overload Latent::set_user_latency w/signal emission */
+       virtual void set_user_latency (framecnt_t val) {
+               bool changed = val != _user_latency;
+               framecnt_t old = effective_latency ();
+               _user_latency = val;
+               if (changed) {
+                       LatencyChanged (old, effective_latency ()); /* EMIT SIGNAL */
+               }
+       }
+
+       /** the max possible latency a plugin will have */
+       virtual framecnt_t max_latency () const { return 0; } // TODO = 0, require implementation
+
        /** Emitted when a preset is added or removed, respectively */
        PBD::Signal0<void> PresetAdded;
        PBD::Signal0<void> PresetRemoved;
index 46582a5fcfffde1d7cfe5e66b53bd5d6932504d4..e13328b97b89c33e667b20b7dc07203021bb43ed 100644 (file)
@@ -365,6 +365,8 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
        _was_activated          = false;
        _has_state_interface    = false;
        _can_write_automation   = false;
+       _max_latency            = 0;
+       _current_latency        = 0;
        _impl->block_length     = _session.get_block_size();
 
        _instance_access_feature.URI = "http://lv2plug.in/ns/ext/instance-access";
@@ -673,6 +675,9 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
                        lilv_instance_connect_port(_impl->instance, i, &_control_data[i]);
 
                        if (latent && i == latency_index) {
+                               LilvNode *max;
+                               lilv_port_get_range(_impl->plugin, port, NULL, NULL, &max);
+                               _max_latency = max ? lilv_node_as_float(max) : .02 * _sample_rate;
                                _latency_control_port  = &_control_data[i];
                                *_latency_control_port = 0;
                        }
@@ -2008,6 +2013,12 @@ LV2Plugin::describe_parameter(Evoral::Parameter which)
        }
 }
 
+framecnt_t
+LV2Plugin::max_latency () const
+{
+       return _max_latency;
+}
+
 framecnt_t
 LV2Plugin::signal_latency() const
 {
@@ -2546,6 +2557,13 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
        _next_cycle_speed = _session.transport_speed();
        _next_cycle_start = _session.transport_frame() + (nframes * _next_cycle_speed);
 
+       if (_latency_control_port) {
+               framecnt_t new_latency = signal_latency ();
+               if (_current_latency != new_latency) {
+                       LatencyChanged (_current_latency, new_latency); /* EMIT SIGNAL */
+               }
+               _current_latency = new_latency;
+       }
        return 0;
 }