Expose compensated port-latency, fix ambig. latency detection
Previously Ardour only announced processor latency. Routes that had additional latency to compensate for those have not published this delay. This is of no concern with internal backends, however with JACK, Ardour reported incorrect *individual* port-latencies of routes that perform PDC. Since public port latency now includes delay-compensation, some extra work is required to unset it before recalculating latency of paths that include external ports.
This commit is contained in:
parent
c342e4bfa9
commit
f301e692a7
@ -355,7 +355,7 @@ public:
|
||||
virtual void apply_latency_compensation ();
|
||||
|
||||
samplecnt_t set_private_port_latencies (bool playback) const;
|
||||
void set_public_port_latencies (samplecnt_t, bool playback) const;
|
||||
void set_public_port_latencies (samplecnt_t, bool playback, bool with_latcomp) const;
|
||||
|
||||
samplecnt_t signal_latency() const { return _signal_latency; }
|
||||
samplecnt_t playback_latency (bool incl_downstream = false) const;
|
||||
|
@ -1432,6 +1432,7 @@ private:
|
||||
void remove_monitor_section ();
|
||||
|
||||
void update_latency (bool playback);
|
||||
void set_owned_port_public_latency (bool playback);
|
||||
bool update_route_latency (bool reverse, bool apply_to_delayline, bool* delayline_update_needed);
|
||||
void initialize_latencies ();
|
||||
void set_worst_output_latency ();
|
||||
|
@ -367,7 +367,7 @@ Port::set_public_latency_range (LatencyRange const& range, bool playback) const
|
||||
|
||||
if (_port_handle) {
|
||||
LatencyRange r (range);
|
||||
if (externally_connected () && 0 == (_flags & TransportSyncPort)) {
|
||||
if (externally_connected () && 0 == (_flags & TransportSyncPort) && sends_output () == playback) {
|
||||
#if 0
|
||||
r.min *= _speed_ratio;
|
||||
r.max *= _speed_ratio;
|
||||
@ -399,10 +399,6 @@ Port::set_private_latency_range (LatencyRange& range, bool playback)
|
||||
_private_capture_latency.min,
|
||||
_private_capture_latency.max));
|
||||
}
|
||||
|
||||
/* push to public (port system) location so that everyone else can see it */
|
||||
|
||||
set_public_latency_range (range, playback);
|
||||
}
|
||||
|
||||
const LatencyRange&
|
||||
@ -426,14 +422,14 @@ Port::private_latency_range (bool playback) const
|
||||
}
|
||||
|
||||
LatencyRange
|
||||
Port::public_latency_range (bool /*playback*/) const
|
||||
Port::public_latency_range (bool playback) const
|
||||
{
|
||||
/*Note: this method is no longer used. It exists purely for debugging reasons */
|
||||
LatencyRange r;
|
||||
|
||||
if (_port_handle) {
|
||||
r = port_engine.get_latency_range (_port_handle, sends_output() ? true : false);
|
||||
if (externally_connected () && 0 == (_flags & TransportSyncPort)) {
|
||||
r = port_engine.get_latency_range (_port_handle, playback);
|
||||
if (externally_connected () && 0 == (_flags & TransportSyncPort) && sends_output () == playback) {
|
||||
#if 0
|
||||
r.min /= _speed_ratio;
|
||||
r.max /= _speed_ratio;
|
||||
@ -450,7 +446,7 @@ Port::public_latency_range (bool /*playback*/) const
|
||||
DEBUG_TRACE (DEBUG::LatencyIO, string_compose (
|
||||
"GET PORT %1: %4 PUBLIC latency range %2 .. %3\n",
|
||||
name(), r.min, r.max,
|
||||
sends_output() ? "PLAYBACK" : "CAPTURE"));
|
||||
playback ? "PLAYBACK" : "CAPTURE"));
|
||||
}
|
||||
|
||||
return r;
|
||||
@ -487,7 +483,7 @@ Port::get_connected_latency_range (LatencyRange& range, bool playback) const
|
||||
|
||||
if (remote_port) {
|
||||
lr = port_engine.get_latency_range (remote_port, playback);
|
||||
if (externally_connected () && 0 == (_flags & TransportSyncPort)) {
|
||||
if (externally_connected () && 0 == (_flags & TransportSyncPort) && sends_output () == playback) {
|
||||
#if 0
|
||||
lr.min /= _speed_ratio;
|
||||
lr.max /= _speed_ratio;
|
||||
|
@ -4412,7 +4412,12 @@ Route::apply_latency_compensation ()
|
||||
cout << "ROUTE " << name() << " delay for " << latcomp << " (c: " << latcomp_capt << ")" << endl;
|
||||
#endif
|
||||
|
||||
_delayline->set_delay (latcomp > 0 ? latcomp : 0);
|
||||
if (_delayline->set_delay (latcomp > 0 ? latcomp : 0)) {
|
||||
DEBUG_TRACE (DEBUG::LatencyRoute, string_compose ("%1: delay changed to %2\n", _name, latcomp));
|
||||
/* public port latency update is needed,
|
||||
* Session::update_latency() calls this->set_public_port_latencies()
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -4975,7 +4980,7 @@ Route::set_private_port_latencies (bool playback) const
|
||||
}
|
||||
|
||||
void
|
||||
Route::set_public_port_latencies (samplecnt_t value, bool playback) const
|
||||
Route::set_public_port_latencies (samplecnt_t value, bool playback, bool with_latcomp) const
|
||||
{
|
||||
/* publish private latencies */
|
||||
Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
|
||||
@ -4985,9 +4990,10 @@ Route::set_public_port_latencies (samplecnt_t value, bool playback) const
|
||||
continue;
|
||||
}
|
||||
if (iop->input ()) {
|
||||
assert (iop->input () != _input); // no delivery for Input
|
||||
iop->input ()->set_public_port_latencies (iop->input()->latency(), true);
|
||||
}
|
||||
if (iop->output ()) {
|
||||
if (iop->output () && iop->output () != _output) {
|
||||
iop->output ()->set_public_port_latencies (iop->output()->latency(), false);
|
||||
}
|
||||
}
|
||||
@ -4995,8 +5001,20 @@ 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.
|
||||
*/
|
||||
_input->set_public_port_latencies (value, playback);
|
||||
_output->set_public_port_latencies (value, playback);
|
||||
if (playback) {
|
||||
_output->set_public_port_latencies (_output->latency (), playback);
|
||||
if (_delayline && with_latcomp) {
|
||||
value += _delayline->delay ();
|
||||
}
|
||||
_input->set_public_port_latencies (value, playback);
|
||||
} else {
|
||||
_input->set_public_port_latencies (_input->latency(), playback);
|
||||
if (_delayline && with_latcomp) {
|
||||
value += _delayline->delay ();
|
||||
}
|
||||
_output->set_public_port_latencies (value, playback);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Put the invisible processors in the right place in _processors.
|
||||
|
@ -6675,6 +6675,21 @@ restart:
|
||||
return changed;
|
||||
}
|
||||
|
||||
void
|
||||
Session::set_owned_port_public_latency (bool playback)
|
||||
{
|
||||
/* special routes or IO or ports owned by the session */
|
||||
if (auditioner) {
|
||||
samplecnt_t latency = auditioner->set_private_port_latencies (playback);
|
||||
auditioner->set_public_port_latencies (latency, playback, true);
|
||||
}
|
||||
_click_io->set_public_port_latencies (_click_io->connected_latency (playback), playback);
|
||||
|
||||
if (_midi_ports) {
|
||||
_midi_ports->set_public_latency (playback);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Session::update_latency (bool playback)
|
||||
{
|
||||
@ -6744,10 +6759,18 @@ Session::update_latency (bool playback)
|
||||
reverse (r->begin(), r->end());
|
||||
}
|
||||
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
|
||||
/* private port latency includes plugin and I/O delay,
|
||||
* but no latency compensation delaylines.
|
||||
*/
|
||||
samplecnt_t latency = (*i)->set_private_port_latencies (playback);
|
||||
(*i)->set_public_port_latencies (latency, playback);
|
||||
/* However we also need to reset the latency of connected external
|
||||
* ports, since those includes latency compensation delaylines.
|
||||
*/
|
||||
(*i)->set_public_port_latencies (latency, playback, false);
|
||||
}
|
||||
|
||||
set_owned_port_public_latency (playback);
|
||||
|
||||
if (playback) {
|
||||
/* Processing needs to be blocked while re-configuring delaylines.
|
||||
*
|
||||
@ -6773,6 +6796,18 @@ Session::update_latency (bool playback)
|
||||
update_route_latency (false, false, NULL);
|
||||
}
|
||||
|
||||
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
|
||||
/* Publish port latency. This includes latency-compensation
|
||||
* delaylines in the direction of signal flow.
|
||||
*/
|
||||
samplecnt_t latency = (*i)->set_private_port_latencies (playback);
|
||||
(*i)->set_public_port_latencies (latency, playback, true);
|
||||
}
|
||||
|
||||
/* now handle non-route ports that we are responsible for */
|
||||
set_owned_port_public_latency (playback);
|
||||
|
||||
|
||||
DEBUG_TRACE (DEBUG::LatencyCompensation, "Engine latency callback: DONE\n");
|
||||
LatencyUpdated (playback); /* EMIT SIGNAL */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user