diff options
author | Robin Gareus <robin@gareus.org> | 2019-02-16 00:13:30 +0100 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2019-02-16 01:10:50 +0100 |
commit | 3cffaeac74163535295513488756c55ba5e2dffa (patch) | |
tree | 3cf90ea9932a8f707f5dc8b04bf0113f2c743e79 /libs/ardour | |
parent | 26f37a47530bac5f1c21d660dcea0b794cc22f09 (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.h | 48 | ||||
-rw-r--r-- | libs/ardour/io.cc | 4 | ||||
-rw-r--r-- | libs/ardour/ladspa_plugin.cc | 4 | ||||
-rw-r--r-- | libs/ardour/latent.cc | 42 | ||||
-rw-r--r-- | libs/ardour/plugin_insert.cc | 23 | ||||
-rw-r--r-- | libs/ardour/port_insert.cc | 14 | ||||
-rw-r--r-- | libs/ardour/processor.cc | 4 | ||||
-rw-r--r-- | libs/ardour/route.cc | 24 | ||||
-rw-r--r-- | libs/ardour/send.cc | 3 | ||||
-rw-r--r-- | libs/ardour/vst_plugin.cc | 4 | ||||
-rw-r--r-- | libs/ardour/wscript | 1 |
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', |