diff options
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/ardour/processor.h | 6 | ||||
-rw-r--r-- | libs/ardour/ardour/route.h | 6 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 14 | ||||
-rw-r--r-- | libs/ardour/luabindings.cc | 5 | ||||
-rw-r--r-- | libs/ardour/processor.cc | 8 | ||||
-rw-r--r-- | libs/ardour/route.cc | 103 | ||||
-rw-r--r-- | libs/ardour/session.cc | 18 | ||||
-rw-r--r-- | libs/ardour/session_export.cc | 2 |
8 files changed, 95 insertions, 67 deletions
diff --git a/libs/ardour/ardour/processor.h b/libs/ardour/ardour/processor.h index fb77943a34..8f617abc19 100644 --- a/libs/ardour/ardour/processor.h +++ b/libs/ardour/ardour/processor.h @@ -70,9 +70,12 @@ class LIBARDOUR_API Processor : public SessionObject, public Automatable, public virtual samplecnt_t signal_latency() const { return 0; } - virtual void set_input_latency (samplecnt_t); + virtual void set_input_latency (samplecnt_t cnt) { _input_latency = cnt; } samplecnt_t input_latency () const { return _input_latency; } + virtual void set_output_latency (samplecnt_t cnt) { _output_latency = cnt; } + samplecnt_t output_latency () const { return _output_latency; } + virtual int set_block_size (pframes_t /*nframes*/) { return 0; } virtual bool requires_fixed_sized_buffers() const { return false; } @@ -153,6 +156,7 @@ protected: PluginPinWindowProxy *_pinmgr_proxy; SessionObject* _owner; samplecnt_t _input_latency; + samplecnt_t _output_latency; }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index 829ebd435b..1ecf36d445 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -339,11 +339,11 @@ public: samplecnt_t set_private_port_latencies (bool playback) const; void set_public_port_latencies (samplecnt_t, bool playback) const; - samplecnt_t update_signal_latency(); + samplecnt_t update_signal_latency (bool set_initial_delay = false); virtual void set_latency_compensation (samplecnt_t); void set_user_latency (samplecnt_t); - samplecnt_t initial_delay() const { return _initial_delay; } + samplecnt_t initial_delay() const { return _initial_delay; } samplecnt_t signal_latency() const { return _signal_latency; } PBD::Signal0<void> active_changed; @@ -628,8 +628,6 @@ public: bool _active; samplecnt_t _signal_latency; - samplecnt_t _signal_latency_at_amp_position; - samplecnt_t _signal_latency_at_trim_position; samplecnt_t _initial_delay; samplecnt_t _roll_delay; diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index b052ba5b69..8af452cc88 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -473,11 +473,13 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop void set_end_is_free (bool); int location_name(std::string& result, std::string base = std::string("")); - pframes_t get_block_size() const { return current_block_size; } - samplecnt_t worst_output_latency () const { return _worst_output_latency; } - samplecnt_t worst_input_latency () const { return _worst_input_latency; } - samplecnt_t worst_track_latency () const { return _worst_track_latency; } - samplecnt_t worst_playback_latency () const { return _worst_output_latency + _worst_track_latency; } + pframes_t get_block_size () const { return current_block_size; } + samplecnt_t worst_output_latency ()const { return _worst_output_latency; } + samplecnt_t worst_input_latency () const { return _worst_input_latency; } + samplecnt_t worst_track_latency () const { return _worst_track_latency; } + samplecnt_t worst_track_roll_delay () const { return _worst_track_roll_delay; } + samplecnt_t worst_track_out_latency () const { return _worst_track_out_latency; } + samplecnt_t worst_playback_latency () const { return _worst_output_latency + _worst_track_latency; } struct SaveAs { std::string new_parent_folder; /* parent folder where new session folder will be created */ @@ -1264,6 +1266,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop samplecnt_t _worst_output_latency; samplecnt_t _worst_input_latency; samplecnt_t _worst_track_latency; + samplecnt_t _worst_track_out_latency; + samplecnt_t _worst_track_roll_delay; bool _have_captured; bool _non_soloed_outs_muted; bool _listening; diff --git a/libs/ardour/luabindings.cc b/libs/ardour/luabindings.cc index 30beb08514..c64445b5b9 100644 --- a/libs/ardour/luabindings.cc +++ b/libs/ardour/luabindings.cc @@ -906,6 +906,7 @@ LuaBindings::common (lua_State* L) .addFunction ("midi", &IO::midi) .addFunction ("port_by_name", &IO::nth) .addFunction ("n_ports", &IO::n_ports) + .addFunction ("latency", &IO::latency) .endClass () .deriveWSPtrClass <PannerShell, SessionObject> ("PannerShell") @@ -1059,6 +1060,8 @@ LuaBindings::common (lua_State* L) .addFunction ("trim", &Route::trim) .addFunction ("peak_meter", (boost::shared_ptr<PeakMeter> (Route::*)())&Route::peak_meter) .addFunction ("set_meter_point", &Route::set_meter_point) + .addFunction ("initial_delay", &Route::initial_delay) + .addFunction ("signal_latency", &Route::signal_latency) .endClass () .deriveWSPtrClass <Playlist, SessionObject> ("Playlist") @@ -2166,6 +2169,8 @@ LuaBindings::common (lua_State* L) .addFunction ("worst_output_latency", &Session::worst_output_latency) .addFunction ("worst_input_latency", &Session::worst_input_latency) .addFunction ("worst_track_latency", &Session::worst_track_latency) + .addFunction ("worst_track_roll_delay", &Session::worst_track_roll_delay) + .addFunction ("worst_track_out_latency", &Session::worst_track_out_latency) .addFunction ("worst_playback_latency", &Session::worst_playback_latency) .addFunction ("cfg", &Session::cfg) .addFunction ("route_groups", &Session::route_groups) diff --git a/libs/ardour/processor.cc b/libs/ardour/processor.cc index 507fa78554..06a7c9676f 100644 --- a/libs/ardour/processor.cc +++ b/libs/ardour/processor.cc @@ -69,6 +69,7 @@ Processor::Processor(Session& session, const string& name) , _pinmgr_proxy (0) , _owner (0) , _input_latency (0) + , _output_latency (0) { } @@ -290,10 +291,3 @@ Processor::owner() const { return _owner; } - -void -Processor::set_input_latency (samplecnt_t cnt) -{ - _input_latency = cnt; -} - diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 029fb99501..f0bd724e44 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -94,8 +94,6 @@ Route::Route (Session& sess, string name, PresentationInfo::Flag flag, DataType , Muteable (sess, name) , _active (true) , _signal_latency (0) - , _signal_latency_at_amp_position (0) - , _signal_latency_at_trim_position (0) , _initial_delay (0) , _roll_delay (0) , _disk_io_point (DiskIOPreFader) @@ -332,14 +330,14 @@ Route::process_output_buffers (BufferSet& bufs, if (gain_automation_ok) { _amp->set_gain_automation_buffer (_session.gain_automation_buffer ()); _amp->setup_gain_automation ( - start_sample + _signal_latency_at_amp_position, - end_sample + _signal_latency_at_amp_position, + start_sample + _amp->output_latency (), + end_sample + _amp->output_latency (), nframes); _trim->set_gain_automation_buffer (_session.trim_automation_buffer ()); _trim->setup_gain_automation ( - start_sample + _signal_latency_at_trim_position, - end_sample + _signal_latency_at_trim_position, + start_sample + _trim->output_latency (), + end_sample + _trim->output_latency (), nframes); } else { _amp->apply_gain_automation (false); @@ -1809,8 +1807,6 @@ Route::configure_processors_unlocked (ProcessorStreams* err, Glib::Threads::RWLo // TODO check for a potential ReaderLock after ReaderLock ?? Glib::Threads::RWLock::ReaderLock lr (_processor_lock); - samplecnt_t chain_latency = _input->latency (); - list< pair<ChanCount,ChanCount> >::iterator c = configuration.begin(); for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p, ++c) { @@ -1822,9 +1818,6 @@ Route::configure_processors_unlocked (ProcessorStreams* err, Glib::Threads::RWLo return -1; } - (*p)->set_input_latency (chain_latency); - chain_latency += (*p)->signal_latency (); - processor_max_streams = ChanCount::max(processor_max_streams, c->first); processor_max_streams = ChanCount::max(processor_max_streams, c->second); @@ -2104,6 +2097,11 @@ Route::reorder_processors (const ProcessorList& new_order, ProcessorStreams* err g_atomic_int_set (&_pending_process_reorder, 1); } + /* update processor input/output latency + * (total signal_latency does not change) + */ + update_signal_latency (true); + return 0; } @@ -3679,6 +3677,10 @@ Route::apply_processor_changes_rt () } if (changed) { set_processor_positions (); + /* update processor input/output latency + * (total signal_latency does not change) + */ + update_signal_latency (true); } if (emissions != 0) { g_atomic_int_set (&_pending_signals, emissions); @@ -3851,8 +3853,9 @@ Route::add_export_point() Glib::Threads::RWLock::WriterLock lw (_processor_lock); // this aligns all tracks; but not tracks + busses - assert (_session.worst_track_latency () >= _initial_delay); - _capturing_processor.reset (new CapturingProcessor (_session, _session.worst_track_latency () - _initial_delay)); + samplecnt_t latency = _session.worst_track_roll_delay (); + assert (latency >= _initial_delay); + _capturing_processor.reset (new CapturingProcessor (_session, latency - _initial_delay)); _capturing_processor->activate (); configure_processors_unlocked (0, &lw); @@ -3863,40 +3866,40 @@ Route::add_export_point() } samplecnt_t -Route::update_signal_latency () +Route::update_signal_latency (bool set_initial_delay) { - samplecnt_t l = _output->user_latency(); - samplecnt_t lamp = 0; - bool before_amp = true; - samplecnt_t ltrim = 0; - bool before_trim = true; + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); + + samplecnt_t l_in = _input->latency (); + samplecnt_t l_out = 0; for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { if ((*i)->active ()) { - l += (*i)->signal_latency (); - } - if ((*i) == _amp) { - before_amp = false; - } - if ((*i) == _trim) { - before_amp = false; - } - if (before_amp) { - lamp = l; - } - if (before_trim) { - lamp = l; + l_out += (*i)->signal_latency (); + l_in += (*i)->signal_latency (); } + (*i)->set_input_latency (l_in); + (*i)->set_output_latency (l_out); + } + + l_out += _output->user_latency(); + + for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { + (*i)->set_output_latency (l_out - (*i)->output_latency ()); } - DEBUG_TRACE (DEBUG::Latency, string_compose ("%1: internal signal latency = %2\n", _name, l)); + DEBUG_TRACE (DEBUG::Latency, string_compose ("%1: internal signal latency = %2\n", _name, l_out)); - // TODO: (lamp - _signal_latency) to sync to output (read-ahed), currently _roll_delay shifts this around - _signal_latency_at_amp_position = lamp; - _signal_latency_at_trim_position = ltrim; + _signal_latency = l_out; - if (_signal_latency != l) { - _signal_latency = l; + lm.release (); + + if (set_initial_delay) { + /* see also Session::post_playback_latency() */ + set_latency_compensation (_session.worst_track_latency () + _session.worst_track_out_latency () - output ()->latency ()); + } + + if (_signal_latency != l_out) { signal_latency_changed (); /* EMIT SIGNAL */ } @@ -3914,9 +3917,10 @@ void Route::set_latency_compensation (samplecnt_t longest_session_latency) { samplecnt_t old = _initial_delay; + assert (!_disk_reader || _disk_reader->output_latency () <= _signal_latency); - if (_signal_latency < longest_session_latency) { - _initial_delay = longest_session_latency - _signal_latency; + if (_disk_reader && _signal_latency < longest_session_latency) { + _initial_delay = longest_session_latency - (_signal_latency - _disk_reader->input_latency ()); } else { _initial_delay = 0; } @@ -4651,7 +4655,7 @@ Route::setup_invisible_processors () ProcessorList::iterator trim = new_processors.end(); - if (_trim && _trim->active()) { + if (_trim->active()) { assert (!_trim->display_to_user ()); new_processors.push_front (_trim); trim = new_processors.begin(); @@ -4670,11 +4674,6 @@ Route::setup_invisible_processors () /* EXPORT PROCESSOR */ - if (_capturing_processor) { - assert (!_capturing_processor->display_to_user ()); - new_processors.push_front (_capturing_processor); - } - /* DISK READER & WRITER (for Track objects) */ if (_disk_reader || _disk_writer) { @@ -4714,6 +4713,18 @@ Route::setup_invisible_processors () } } + if (_capturing_processor) { + assert (!_capturing_processor->display_to_user ()); + ProcessorList::iterator reader_pos = find (new_processors.begin(), new_processors.end(), _disk_reader); + if (reader_pos != new_processors.end()) { + /* insert after disk-reader */ + new_processors.insert (++reader_pos, _capturing_processor); + } else { + new_processors.push_front (_capturing_processor); + } + } + + _processors = new_processors; for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 33ed2c22d3..af0f66a889 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -199,6 +199,8 @@ Session::Session (AudioEngine &eng, , _worst_output_latency (0) , _worst_input_latency (0) , _worst_track_latency (0) + , _worst_track_out_latency (0) + , _worst_track_roll_delay (0) , _have_captured (false) , _non_soloed_outs_muted (false) , _listening (false) @@ -6915,15 +6917,25 @@ Session::post_playback_latency () boost::shared_ptr<RouteList> r = routes.reader (); + _worst_track_out_latency = 0; + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { assert (!(*i)->is_auditioner()); // XXX remove me - if ((*i)->active()) { - _worst_track_latency = max (_worst_track_latency, (*i)->update_signal_latency ()); + if (!(*i)->active()) { continue ; } + _worst_track_latency = max (_worst_track_latency, (*i)->update_signal_latency ()); + if (boost::dynamic_pointer_cast<Track> (*i)) { + _worst_track_out_latency = max (_worst_track_out_latency, (*i)->output ()->latency ()); } } + _worst_track_roll_delay = 0; + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - (*i)->set_latency_compensation (_worst_track_latency); + if (!(*i)->active()) { continue ; } + (*i)->set_latency_compensation (_worst_track_latency + _worst_track_out_latency - (*i)->output ()->latency ()); + if (boost::dynamic_pointer_cast<Track> (*i)) { + _worst_track_roll_delay = max (_worst_track_roll_delay, (*i)->initial_delay ()); + } } } diff --git a/libs/ardour/session_export.cc b/libs/ardour/session_export.cc index 4ef304eac7..45e86073cd 100644 --- a/libs/ardour/session_export.cc +++ b/libs/ardour/session_export.cc @@ -141,7 +141,7 @@ Session::start_audio_export (samplepos_t position, bool realtime, bool region_ex * (this is all still very [w]hacky. Individual Bus and Track outputs * are not aligned but one can select them in the PortExportChannelSelector) */ - _export_latency = worst_track_latency (); + _export_latency = worst_track_roll_delay (); boost::shared_ptr<Route> master = master_out (); if (master && comensate_master_latency) { |