X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Froute.cc;h=3b615c517b1a00c12e6d31e65db259b0e0fa69ce;hb=11b02e90ac9b084cd25741b7a6bdc91c59749c16;hp=2d5857b20220becd00f19838654135249dd84ac6;hpb=79b1275b7c293ffa673e13c9e1affbc8deeed0a5;p=ardour.git diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 2d5857b202..3b615c517b 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -57,6 +57,7 @@ #include "ardour/delayline.h" #include "ardour/midi_buffer.h" #include "ardour/midi_port.h" +#include "ardour/midi_track.h" #include "ardour/monitor_control.h" #include "ardour/monitor_processor.h" #include "ardour/pannable.h" @@ -335,6 +336,10 @@ Route::process_output_buffers (BufferSet& bufs, */ automation_run (start_sample, nframes); + if (_pannable) { + _pannable->automation_run (start_sample + _signal_latency, nframes); + } + /* figure out if we're going to use gain automation */ if (gain_automation_ok) { _amp->set_gain_automation_buffer (_session.gain_automation_buffer ()); @@ -474,27 +479,6 @@ Route::process_output_buffers (BufferSet& bufs, } #endif - if (boost::dynamic_pointer_cast(*i) != 0) { - /* set potential sidechain ports, capture and playback latency. - * This effectively sets jack port latency which should include - * up/downstream latencies. - * - * However, the value is not used by Ardour (2017-09-20) and calling - * IO::latency() is expensive, so we punt. - * - * capture should be - * input()->latenct + latency, - * playback should be - * output->latency() + _signal_latency - latency - * - * Also see note below, _signal_latency may be smaller than latency - * if a plugin's latency increases while it's running. - */ - const samplecnt_t playback_latency = std::max ((samplecnt_t)0, _signal_latency - latency); - boost::dynamic_pointer_cast(*i)->set_sidechain_latency ( - /* input->latency() + */ latency, /* output->latency() + */ playback_latency); - } - bool re_inject_oob_data = false; if ((*i) == _disk_reader) { /* Well now, we've made it past the disk-writer and to the disk-reader. @@ -543,7 +527,7 @@ Route::process_output_buffers (BufferSet& bufs, #if 0 if ((*i) == _delayline) { - latency += _delayline->get_delay (); + latency += _delayline->delay (); } #endif } @@ -3111,6 +3095,9 @@ Route::silence_unlocked (samplecnt_t nframes) // update owned automated controllables automation_run (now, nframes); + if (_pannable) { + _pannable->automation_run (now, nframes); + } for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { boost::shared_ptr pi; @@ -3452,7 +3439,6 @@ Route::input_change_handler (IOChange change, void * /*src*/) contains ConfigurationChanged */ configure_processors (0); - _phase_control->resize (_input->n_ports().n_audio ()); io_changed (); /* EMIT SIGNAL */ } @@ -3990,6 +3976,9 @@ Route::update_signal_latency (bool apply_to_delayline) // here or in Session::* ? -> also zero send latencies, // and make sure that re-enabling a route updates things again... + samplecnt_t capt_lat_in = _input->connected_latency (false); + samplecnt_t play_lat_out = _output->connected_latency (true); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); samplecnt_t l_in = 0; @@ -3998,6 +3987,14 @@ Route::update_signal_latency (bool apply_to_delayline) if (boost::shared_ptr snd = boost::dynamic_pointer_cast (*i)) { snd->set_delay_in (l_out + _output->latency()); } + + if (boost::shared_ptr pi = boost::dynamic_pointer_cast (*i)) { + if (boost::shared_ptr pio = pi->sidechain_input ()) { + samplecnt_t lat = l_out + _output->latency(); + pio->set_private_port_latencies (lat, true); + pio->set_public_port_latencies (lat, true); + } + } (*i)->set_output_latency (l_out); if ((*i)->active ()) { l_out += (*i)->signal_latency (); @@ -4009,6 +4006,27 @@ Route::update_signal_latency (bool apply_to_delayline) _signal_latency = l_out; for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { + + /* set sidechain, send and insert port latencies */ + if (boost::shared_ptr pi = boost::dynamic_pointer_cast (*i)) { + if (pi->input ()) { + /* propagate playback latency from output to input */ + pi->input ()->set_private_port_latencies (play_lat_out + l_in, true); + } + if (pi->output ()) { + /* propagate capture latency from input to output */ + pi->output ()->set_private_port_latencies (capt_lat_in + l_in, false); + } + + } else if (boost::shared_ptr snd = boost::dynamic_pointer_cast (*i)) { + if (snd->output ()) { + /* set capture latency */ + snd->output ()->set_private_port_latencies (capt_lat_in + l_in, false); + /* take send-target's playback latency into account */ + snd->set_delay_out (snd->output ()->connected_latency (true)); + } + } + (*i)->set_input_latency (l_in); (*i)->set_playback_offset (_signal_latency + _output->latency ()); (*i)->set_capture_offset (_input->latency ()); @@ -4042,7 +4060,7 @@ void Route::apply_latency_compensation () { if (_delayline) { - samplecnt_t old = _delayline->get_delay (); + samplecnt_t old = _delayline->delay (); samplecnt_t play_lat_in = _input->connected_latency (true); samplecnt_t play_lat_out = _output->connected_latency (true); @@ -4058,7 +4076,7 @@ Route::apply_latency_compensation () _delayline->set_delay (latcomp > 0 ? latcomp : 0); - if (old != _delayline->get_delay ()) { + if (old != _delayline->delay ()) { signal_latency_updated (); /* EMIT SIGNAL */ } } @@ -4591,6 +4609,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 (); } @@ -4608,28 +4627,26 @@ Route::set_private_port_latencies (bool playback) const void Route::set_public_port_latencies (samplecnt_t value, bool playback) const { - /* this is called to set the JACK-visible port latencies, which take - latency compensation into account. - */ - - LatencyRange range; - - range.min = value; - range.max = value; - - { - const PortSet& ports (_input->ports()); - for (PortSet::const_iterator p = ports.begin(); p != ports.end(); ++p) { - p->set_public_latency_range (range, playback); + /* publish private latencies */ + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); + for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) { + boost::shared_ptr iop = boost::dynamic_pointer_cast(*i); + if (!iop) { + continue; } - } - - { - const PortSet& ports (_output->ports()); - for (PortSet::const_iterator p = ports.begin(); p != ports.end(); ++p) { - p->set_public_latency_range (range, playback); + if (iop->input ()) { + iop->input ()->set_public_port_latencies (iop->input()->latency(), true); + } + if (iop->output ()) { + iop->output ()->set_public_port_latencies (iop->output()->latency(), false); } } + + /* this is called to set the JACK-visible port latencies, which take + * latency compensation into account. + */ + _input->set_public_port_latencies (value, playback); + _output->set_public_port_latencies (value, playback); } /** Put the invisible processors in the right place in _processors. @@ -5025,7 +5042,11 @@ Route::the_instrument_unlocked () const return boost::shared_ptr(); } - +bool +Route::is_track() +{ + return dynamic_cast(this) != 0; +} void Route::non_realtime_locate (samplepos_t pos) @@ -5987,67 +6008,6 @@ Route::monitoring_state () const break; } - /* This is an implementation of the truth table in doc/monitor_modes.pdf; - I don't think it's ever going to be too pretty too look at. - */ - - bool const roll = _session.transport_rolling (); - bool const track_rec = _disk_writer->record_enabled (); - bool const auto_input = _session.config.get_auto_input (); - bool const software_monitor = Config->get_monitoring_model() == SoftwareMonitoring; - bool const tape_machine_mode = Config->get_tape_machine_mode (); - bool session_rec; - - /* I suspect that just use actively_recording() is good enough all the - * time, but just to keep the semantics the same as they were before - * sept 26th 2012, we differentiate between the cases where punch is - * enabled and those where it is not. - * - * rg: sept 30 2017: Above is not the case: punch-in/out location is - * global session playhead position. - * When this method is called from process_output_buffers() we need - * to use delay-compensated route's process-position. - * - * NB. Disk reader/writer may also be offset by a same amount of time. - * - * Also keep in mind that _session.transport_rolling() is false during - * pre-roll but the disk already produces output. - * - * TODO: FIXME - */ - - if (_session.config.get_punch_in() || _session.config.get_punch_out()) { - session_rec = _session.actively_recording (); - } else { - session_rec = _session.get_record_enabled(); - } - - if (track_rec) { - - if (!session_rec && roll && auto_input) { - return MonitoringDisk; - } else { - return software_monitor ? MonitoringInput : MonitoringSilence; - } - - } else { - - if (tape_machine_mode) { - - return MonitoringDisk; - - } else { - - if (!roll && auto_input) { - return software_monitor ? MonitoringInput : MonitoringSilence; - } else { - return MonitoringDisk; - } - - } - } - - abort(); /* NOTREACHED */ - return MonitoringSilence; + return get_auto_monitoring_state(); } #endif