summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2019-02-16 00:13:30 +0100
committerRobin Gareus <robin@gareus.org>2019-02-16 01:10:50 +0100
commit3cffaeac74163535295513488756c55ba5e2dffa (patch)
tree3cf90ea9932a8f707f5dc8b04bf0113f2c743e79 /libs/ardour
parent26f37a47530bac5f1c21d660dcea0b794cc22f09 (diff)
Prepare to allow to disable latency-compensation
Previously "zero custom/user latency" meant "default plugin latency". This is now saved in a separate boolean allowing a user to reduce a processor's latency to zero. This also prepares for a global switch to use zero latency throughout the whole session.
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/latent.h48
-rw-r--r--libs/ardour/io.cc4
-rw-r--r--libs/ardour/ladspa_plugin.cc4
-rw-r--r--libs/ardour/latent.cc42
-rw-r--r--libs/ardour/plugin_insert.cc23
-rw-r--r--libs/ardour/port_insert.cc14
-rw-r--r--libs/ardour/processor.cc4
-rw-r--r--libs/ardour/route.cc24
-rw-r--r--libs/ardour/send.cc3
-rw-r--r--libs/ardour/vst_plugin.cc4
-rw-r--r--libs/ardour/wscript1
11 files changed, 119 insertions, 52 deletions
diff --git a/libs/ardour/ardour/latent.h b/libs/ardour/ardour/latent.h
index c4464f7ba4..b7d9a3fcd5 100644
--- a/libs/ardour/ardour/latent.h
+++ b/libs/ardour/ardour/latent.h
@@ -26,27 +26,61 @@
namespace ARDOUR {
class LIBARDOUR_API Latent {
- public:
+public:
Latent() : _user_latency (0) {}
virtual ~Latent() {}
virtual samplecnt_t signal_latency() const = 0;
- samplecnt_t user_latency () const { return _user_latency; }
+ /* effective latency to be used while processing */
samplecnt_t effective_latency() const {
- if (_user_latency) {
+ if (_zero_latency) {
+ return 0;
+ } else if (_use_user_latency) {
return _user_latency;
} else {
return signal_latency ();
}
}
- virtual void set_user_latency (samplecnt_t val) { _user_latency = val; }
+ /* custom user-set latency, if any */
+ samplecnt_t user_latency () const {
+ if (_use_user_latency) {
+ return _user_latency;
+ } else {
+ return 0;
+ }
+ }
+
+ void unset_user_latency () {
+ _use_user_latency = false;
+ _user_latency = 0;
+ }
+
+ virtual void set_user_latency (samplecnt_t val) {
+ _use_user_latency = true;
+ _user_latency = val;
+ }
+
+ static void force_zero_latency (bool en) {
+ _zero_latency = en;
+ }
- protected:
- samplecnt_t _user_latency;
+ static bool zero_latency () {
+ return _zero_latency;
+ }
+
+protected:
+ int set_state (const XMLNode& node, int version);
+ void add_state (XMLNode*) const;
+
+private:
+ samplecnt_t _use_user_latency;
+ samplecnt_t _user_latency;
+ static bool _zero_latency;
};
-}
+} /* namespace */
+
#endif /* __ardour_latent_h__*/
diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc
index 99cd41657f..59e452633a 100644
--- a/libs/ardour/io.cc
+++ b/libs/ardour/io.cc
@@ -536,7 +536,7 @@ IO::state ()
node->add_child_nocopy (*pnode);
}
- node->set_property (X_("user-latency"), _user_latency);
+ Latent::add_state (node);
return *node;
}
@@ -597,7 +597,7 @@ IO::set_state (const XMLNode& node, int version)
ConnectingLegal.connect_same_thread (connection_legal_c, boost::bind (&IO::connecting_became_legal, this));
}
- node.get_property ("user-latency", _user_latency);
+ Latent::set_state (node, version);
return 0;
}
diff --git a/libs/ardour/ladspa_plugin.cc b/libs/ardour/ladspa_plugin.cc
index be0edee8b5..bb59c6ec55 100644
--- a/libs/ardour/ladspa_plugin.cc
+++ b/libs/ardour/ladspa_plugin.cc
@@ -528,10 +528,6 @@ LadspaPlugin::describe_parameter (Evoral::Parameter which)
ARDOUR::samplecnt_t
LadspaPlugin::signal_latency () const
{
- if (_user_latency) {
- return _user_latency;
- }
-
if (_latency_control_port) {
return (samplecnt_t) floor (*_latency_control_port);
} else {
diff --git a/libs/ardour/latent.cc b/libs/ardour/latent.cc
new file mode 100644
index 0000000000..44ec0e7d30
--- /dev/null
+++ b/libs/ardour/latent.cc
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 Robin Gareus <robin@gareus.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "pbd/xml++.h"
+
+#include "ardour/latent.h"
+
+using namespace ARDOUR;
+
+bool ARDOUR::Latent::_zero_latency = false;
+
+int
+Latent::set_state (const XMLNode& node, int version)
+{
+ node.get_property ("user-latency", _user_latency);
+ if (!node.get_property ("use-user-latency", _use_user_latency)) {
+ _use_user_latency = _user_latency > 0;
+ }
+ return 0;
+}
+
+void
+Latent::add_state (XMLNode* node) const
+{
+ node->set_property ("user-latency", _user_latency);
+ node->set_property ("use-user-latency", _use_user_latency);
+}
diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc
index 3435fd2241..a4a5ad1972 100644
--- a/libs/ardour/plugin_insert.cc
+++ b/libs/ardour/plugin_insert.cc
@@ -651,8 +651,10 @@ PluginInsert::activate ()
if (!owner ()) {
return;
}
- if (_plugin_signal_latency != signal_latency ()) {
- _plugin_signal_latency = signal_latency ();
+
+ const samplecnt_t l = effective_latency ();
+ if (_plugin_signal_latency != l) {
+ _plugin_signal_latency = l;
latency_changed ();
}
}
@@ -671,8 +673,10 @@ PluginInsert::deactivate ()
for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
(*i)->deactivate ();
}
- if (_plugin_signal_latency != signal_latency ()) {
- _plugin_signal_latency = signal_latency ();
+
+ const samplecnt_t l = effective_latency ();
+ if (_plugin_signal_latency != l) {
+ _plugin_signal_latency = l;
latency_changed ();
}
}
@@ -1063,8 +1067,9 @@ PluginInsert::connect_and_run (BufferSet& bufs, samplepos_t start, samplepos_t e
}
}
- if (_plugin_signal_latency != signal_latency ()) {
- _plugin_signal_latency = signal_latency ();
+ const samplecnt_t l = effective_latency ();
+ if (_plugin_signal_latency != l) {
+ _plugin_signal_latency = l;
latency_changed ();
}
}
@@ -2906,11 +2911,7 @@ PluginInsert::signal_latency() const
if (!_pending_active) {
return 0;
}
- if (_user_latency) {
- return _user_latency;
- }
-
- return _plugins[0]->signal_latency ();
+ return plugin_latency ();
}
ARDOUR::PluginType
diff --git a/libs/ardour/port_insert.cc b/libs/ardour/port_insert.cc
index a6a05cede7..fd7d220d88 100644
--- a/libs/ardour/port_insert.cc
+++ b/libs/ardour/port_insert.cc
@@ -79,8 +79,8 @@ PortInsert::start_latency_detection ()
void
PortInsert::stop_latency_detection ()
{
- _latency_flush_samples = signal_latency() + _session.engine().samples_per_cycle();
- _latency_detect = false;
+ _latency_flush_samples = effective_latency() + _session.engine().samples_per_cycle();
+ _latency_detect = false;
}
void
@@ -232,11 +232,11 @@ PortInsert::signal_latency() const
need to take that into account too.
*/
- if (_measured_latency == 0) {
- return _session.engine().samples_per_cycle() + _input->signal_latency();
- } else {
- return _measured_latency;
- }
+ if (_measured_latency == 0) {
+ return _session.engine().samples_per_cycle() + _input->effective_latency ();
+ } else {
+ return _measured_latency;
+ }
}
/** Caller must hold process lock */
diff --git a/libs/ardour/processor.cc b/libs/ardour/processor.cc
index 39c3d68ad7..9f799a5060 100644
--- a/libs/ardour/processor.cc
+++ b/libs/ardour/processor.cc
@@ -146,7 +146,7 @@ Processor::state ()
}
}
- node->set_property("user-latency", _user_latency);
+ Latent::add_state (node);
return *node;
}
@@ -252,7 +252,7 @@ Processor::set_state (const XMLNode& node, int version)
}
}
- node.get_property ("user-latency", _user_latency);
+ Latent::set_state (node, version);
return 0;
}
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index a1f356351c..b48b3b5a2b 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -502,7 +502,7 @@ Route::process_output_buffers (BufferSet& bufs,
* So there can be cases where adding up all latencies may not equal _signal_latency.
*/
if ((*i)->active ()) {
- latency += (*i)->signal_latency ();
+ latency += (*i)->effective_latency ();
}
if (re_inject_oob_data) {
@@ -569,7 +569,7 @@ Route::bounce_process (BufferSet& buffers, samplepos_t start, samplecnt_t nframe
if (!(*i)->does_routing() && !boost::dynamic_pointer_cast<PeakMeter>(*i)) {
(*i)->run (buffers, start - latency, start - latency + nframes, 1.0, nframes, true);
buffers.set_count ((*i)->output_streams());
- latency += (*i)->signal_latency ();
+ latency += (*i)->effective_latency ();
}
if ((*i) == endpoint) {
@@ -598,7 +598,7 @@ Route::bounce_get_latency (boost::shared_ptr<Processor> endpoint,
break;
}
if (!(*i)->does_routing() && !boost::dynamic_pointer_cast<PeakMeter>(*i)) {
- latency += (*i)->signal_latency ();
+ latency += (*i)->effective_latency ();
}
if ((*i) == endpoint) {
break;
@@ -1129,7 +1129,7 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor>
}
}
- _output->set_user_latency (0);
+ _output->unset_user_latency ();
}
reset_instrument_info ();
@@ -1448,7 +1448,7 @@ Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStream
++i;
}
- _output->set_user_latency (0);
+ _output->unset_user_latency ();
}
if (!removed) {
@@ -1576,7 +1576,7 @@ Route::replace_processor (boost::shared_ptr<Processor> old, boost::shared_ptr<Pr
}
sub->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false));
- _output->set_user_latency (0);
+ _output->unset_user_latency ();
}
reset_instrument_info ();
@@ -1648,7 +1648,7 @@ Route::remove_processors (const ProcessorList& to_be_deleted, ProcessorStreams*
return 0;
}
- _output->set_user_latency (0);
+ _output->unset_user_latency ();
if (configure_processors_unlocked (err, &lm)) {
pstate.restore ();
@@ -4038,7 +4038,7 @@ Route::update_signal_latency (bool apply_to_delayline)
Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
samplecnt_t l_in = 0;
- samplecnt_t l_out = _output->user_latency();
+ samplecnt_t l_out = _output->effective_latency ();
for (ProcessorList::reverse_iterator i = _processors.rbegin(); i != _processors.rend(); ++i) {
if (boost::shared_ptr<Send> snd = boost::dynamic_pointer_cast<Send> (*i)) {
snd->set_delay_in (l_out + _output->latency());
@@ -4052,8 +4052,8 @@ Route::update_signal_latency (bool apply_to_delayline)
}
}
(*i)->set_output_latency (l_out);
- if ((*i)->active ()) {
- l_out += (*i)->signal_latency ();
+ if ((*i)->active ()) { // XXX
+ l_out += (*i)->effective_latency ();
}
}
@@ -4087,7 +4087,7 @@ Route::update_signal_latency (bool apply_to_delayline)
(*i)->set_playback_offset (_signal_latency + _output->latency ());
(*i)->set_capture_offset (_input->latency ());
if ((*i)->active ()) {
- l_in += (*i)->signal_latency ();
+ l_in += (*i)->effective_latency ();
}
}
@@ -4644,7 +4644,7 @@ Route::set_private_port_latencies (bool playback) const
for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
if ((*i)->active ()) {
- own_latency += (*i)->signal_latency ();
+ own_latency += (*i)->effective_latency ();
}
}
diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc
index a9b8f2b135..aef54150f8 100644
--- a/libs/ardour/send.cc
+++ b/libs/ardour/send.cc
@@ -141,9 +141,6 @@ Send::signal_latency () const
if (!_pending_active) {
return 0;
}
- if (_user_latency) {
- return _user_latency;
- }
if (_delay_out > _delay_in) {
return _delay_out - _delay_in;
}
diff --git a/libs/ardour/vst_plugin.cc b/libs/ardour/vst_plugin.cc
index 4183283bff..e4968b5158 100644
--- a/libs/ardour/vst_plugin.cc
+++ b/libs/ardour/vst_plugin.cc
@@ -645,10 +645,6 @@ VSTPlugin::describe_parameter (Evoral::Parameter param)
samplecnt_t
VSTPlugin::signal_latency () const
{
- if (_user_latency) {
- return _user_latency;
- }
-
#if ( defined(__x86_64__) || defined(_M_X64) )
return *((int32_t *) (((char *) &_plugin->flags) + 24)); /* initialDelay */
#else
diff --git a/libs/ardour/wscript b/libs/ardour/wscript
index 87238374d1..a8bb9d50d3 100644
--- a/libs/ardour/wscript
+++ b/libs/ardour/wscript
@@ -113,6 +113,7 @@ libardour_sources = [
'io_processor.cc',
'kmeterdsp.cc',
'ladspa_plugin.cc',
+ 'latent.cc',
'legatize.cc',
'location.cc',
'location_importer.cc',