Propagate Latency to backend/system ports
Set accumulated capture-latency for physical-outputs and accumulated playback-latency for physical-inputs after Ardour is done setting all non-physical port latencies. This will be needed for latency-compensation of the complete graph.
This commit is contained in:
parent
25f45022db
commit
ab3889fff8
@ -1386,6 +1386,39 @@ AlsaAudioBackend::register_system_audio_ports()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* set playback-latency for _system_inputs
|
||||||
|
* and capture-latency for _system_outputs
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
AlsaAudioBackend::update_system_port_latecies ()
|
||||||
|
{
|
||||||
|
for (std::vector<AlsaPort*>::const_iterator it = _system_inputs.begin (); it != _system_inputs.end (); ++it) {
|
||||||
|
(*it)->update_connected_latency (true);
|
||||||
|
}
|
||||||
|
for (std::vector<AlsaPort*>::const_iterator it = _system_outputs.begin (); it != _system_outputs.end (); ++it) {
|
||||||
|
(*it)->update_connected_latency (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::vector<AlsaPort*>::const_iterator it = _system_midi_in.begin (); it != _system_midi_in.end (); ++it) {
|
||||||
|
(*it)->update_connected_latency (true);
|
||||||
|
}
|
||||||
|
for (std::vector<AlsaPort*>::const_iterator it = _system_midi_out.begin (); it != _system_midi_out.end (); ++it) {
|
||||||
|
(*it)->update_connected_latency (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (AudioSlaves::iterator s = _slaves.begin (); s != _slaves.end (); ++s) {
|
||||||
|
if ((*s)->dead) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (std::vector<AlsaPort*>::const_iterator it = (*s)->inputs.begin (); it != (*s)->inputs.end (); ++it) {
|
||||||
|
(*it)->update_connected_latency (true);
|
||||||
|
}
|
||||||
|
for (std::vector<AlsaPort*>::const_iterator it = (*s)->outputs.begin (); it != (*s)->outputs.end (); ++it) {
|
||||||
|
(*it)->update_connected_latency (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* libs/ardouralsautil/devicelist.cc appends either of
|
/* libs/ardouralsautil/devicelist.cc appends either of
|
||||||
* " (IO)", " (I)", or " (O)"
|
* " (IO)", " (I)", or " (O)"
|
||||||
* depending of the device is full-duples or half-duplex
|
* depending of the device is full-duples or half-duplex
|
||||||
@ -2136,6 +2169,7 @@ AlsaAudioBackend::main_process_thread ()
|
|||||||
manager.graph_order_callback();
|
manager.graph_order_callback();
|
||||||
}
|
}
|
||||||
if (connections_changed || ports_changed) {
|
if (connections_changed || ports_changed) {
|
||||||
|
update_system_port_latecies (); // flush, clear
|
||||||
engine.latency_callback(false);
|
engine.latency_callback(false);
|
||||||
engine.latency_callback(true);
|
engine.latency_callback(true);
|
||||||
}
|
}
|
||||||
@ -2339,7 +2373,6 @@ AlsaPort::~AlsaPort () {
|
|||||||
disconnect_all ();
|
disconnect_all ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int AlsaPort::connect (AlsaPort *port)
|
int AlsaPort::connect (AlsaPort *port)
|
||||||
{
|
{
|
||||||
if (!port) {
|
if (!port) {
|
||||||
@ -2380,7 +2413,6 @@ int AlsaPort::connect (AlsaPort *port)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AlsaPort::_connect (AlsaPort *port, bool callback)
|
void AlsaPort::_connect (AlsaPort *port, bool callback)
|
||||||
{
|
{
|
||||||
_connections.insert (port);
|
_connections.insert (port);
|
||||||
@ -2445,6 +2477,36 @@ bool AlsaPort::is_physically_connected () const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AlsaPort::set_latency_range (const LatencyRange &latency_range, bool for_playback)
|
||||||
|
{
|
||||||
|
if (for_playback) {
|
||||||
|
_playback_latency_range = latency_range;
|
||||||
|
} else {
|
||||||
|
_capture_latency_range = latency_range;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::set<AlsaPort*>::const_iterator it = _connections.begin (); it != _connections.end (); ++it) {
|
||||||
|
if ((*it)->is_physical ()) {
|
||||||
|
(*it)->update_connected_latency (is_input ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AlsaPort::update_connected_latency (bool for_playback)
|
||||||
|
{
|
||||||
|
LatencyRange lr;
|
||||||
|
lr.min = lr.max = 0;
|
||||||
|
for (std::set<AlsaPort*>::const_iterator it = _connections.begin (); it != _connections.end (); ++it) {
|
||||||
|
LatencyRange l;
|
||||||
|
l = (*it)->latency_range (for_playback);
|
||||||
|
lr.min = std::max (lr.min, l.min);
|
||||||
|
lr.max = std::max (lr.max, l.max);
|
||||||
|
}
|
||||||
|
set_latency_range (lr, for_playback);
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
AlsaAudioPort::AlsaAudioPort (AlsaAudioBackend &b, const std::string& name, PortFlags flags)
|
AlsaAudioPort::AlsaAudioPort (AlsaAudioBackend &b, const std::string& name, PortFlags flags)
|
||||||
|
@ -99,17 +99,9 @@ class AlsaPort {
|
|||||||
return for_playback ? _playback_latency_range : _capture_latency_range;
|
return for_playback ? _playback_latency_range : _capture_latency_range;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_latency_range (const LatencyRange &latency_range, bool for_playback)
|
void set_latency_range (const LatencyRange &latency_range, bool for_playback);
|
||||||
{
|
|
||||||
if (for_playback)
|
void update_connected_latency (bool for_playback);
|
||||||
{
|
|
||||||
_playback_latency_range = latency_range;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_capture_latency_range = latency_range;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AlsaAudioBackend &_alsa_backend;
|
AlsaAudioBackend &_alsa_backend;
|
||||||
@ -419,6 +411,7 @@ class AlsaAudioBackend : public AudioBackend {
|
|||||||
int register_system_audio_ports ();
|
int register_system_audio_ports ();
|
||||||
int register_system_midi_ports (const std::string device = "");
|
int register_system_midi_ports (const std::string device = "");
|
||||||
void unregister_ports (bool system_only = false);
|
void unregister_ports (bool system_only = false);
|
||||||
|
void update_system_port_latecies ();
|
||||||
|
|
||||||
std::vector<AlsaPort *> _system_inputs;
|
std::vector<AlsaPort *> _system_inputs;
|
||||||
std::vector<AlsaPort *> _system_outputs;
|
std::vector<AlsaPort *> _system_outputs;
|
||||||
|
@ -1162,6 +1162,24 @@ CoreAudioBackend::register_system_audio_ports()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CoreAudioBackend::update_system_port_latecies ()
|
||||||
|
{
|
||||||
|
for (std::vector<CoreBackendPort*>::const_iterator it = _system_inputs.begin (); it != _system_inputs.end (); ++it) {
|
||||||
|
(*it)->update_connected_latency (true);
|
||||||
|
}
|
||||||
|
for (std::vector<CoreBackendPort*>::const_iterator it = _system_outputs.begin (); it != _system_outputs.end (); ++it) {
|
||||||
|
(*it)->update_connected_latency (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::vector<CoreBackendPort*>::const_iterator it = _system_midi_in.begin (); it != _system_midi_in.end (); ++it) {
|
||||||
|
(*it)->update_connected_latency (true);
|
||||||
|
}
|
||||||
|
for (std::vector<CoreBackendPort*>::const_iterator it = _system_midi_out.begin (); it != _system_midi_out.end (); ++it) {
|
||||||
|
(*it)->update_connected_latency (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CoreAudioBackend::coremidi_rediscover()
|
CoreAudioBackend::coremidi_rediscover()
|
||||||
{
|
{
|
||||||
@ -1644,6 +1662,7 @@ CoreAudioBackend::pre_process ()
|
|||||||
manager.graph_order_callback();
|
manager.graph_order_callback();
|
||||||
}
|
}
|
||||||
if (connections_changed || ports_changed) {
|
if (connections_changed || ports_changed) {
|
||||||
|
update_system_port_latecies ();
|
||||||
engine.latency_callback(false);
|
engine.latency_callback(false);
|
||||||
engine.latency_callback(true);
|
engine.latency_callback(true);
|
||||||
}
|
}
|
||||||
@ -2081,7 +2100,6 @@ void CoreBackendPort::_disconnect (CoreBackendPort *port, bool callback)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CoreBackendPort::disconnect_all ()
|
void CoreBackendPort::disconnect_all ()
|
||||||
{
|
{
|
||||||
while (!_connections.empty ()) {
|
while (!_connections.empty ()) {
|
||||||
@ -2108,6 +2126,37 @@ bool CoreBackendPort::is_physically_connected () const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CoreBackendPort::set_latency_range (const LatencyRange &latency_range, bool for_playback)
|
||||||
|
{
|
||||||
|
if (for_playback) {
|
||||||
|
_playback_latency_range = latency_range;
|
||||||
|
} else {
|
||||||
|
_capture_latency_range = latency_range;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::set<CoreBackendPort*>::const_iterator it = _connections.begin (); it != _connections.end (); ++it) {
|
||||||
|
if ((*it)->is_physical ()) {
|
||||||
|
(*it)->update_connected_latency (is_input ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CoreBackendPort::update_connected_latency (bool for_playback)
|
||||||
|
{
|
||||||
|
LatencyRange lr;
|
||||||
|
lr.min = lr.max = 0;
|
||||||
|
const std::set<CoreBackendPort *>& cp = get_connections ();
|
||||||
|
for (std::set<CoreBackendPort*>::const_iterator it = cp.begin (); it != cp.end (); ++it) {
|
||||||
|
LatencyRange l;
|
||||||
|
l = (*it)->latency_range (for_playback);
|
||||||
|
lr.min = std::max (lr.min, l.min);
|
||||||
|
lr.max = std::max (lr.max, l.max);
|
||||||
|
}
|
||||||
|
set_latency_range (lr, for_playback);
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
CoreAudioPort::CoreAudioPort (CoreAudioBackend &b, const std::string& name, PortFlags flags)
|
CoreAudioPort::CoreAudioPort (CoreAudioBackend &b, const std::string& name, PortFlags flags)
|
||||||
|
@ -96,17 +96,9 @@ class CoreBackendPort {
|
|||||||
return for_playback ? _playback_latency_range : _capture_latency_range;
|
return for_playback ? _playback_latency_range : _capture_latency_range;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_latency_range (const LatencyRange &latency_range, bool for_playback)
|
void set_latency_range (const LatencyRange &latency_range, bool for_playback);
|
||||||
{
|
|
||||||
if (for_playback)
|
void update_connected_latency (bool for_playback);
|
||||||
{
|
|
||||||
_playback_latency_range = latency_range;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_capture_latency_range = latency_range;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CoreAudioBackend &_osx_backend;
|
CoreAudioBackend &_osx_backend;
|
||||||
@ -463,6 +455,7 @@ class CoreAudioBackend : public AudioBackend {
|
|||||||
PortHandle add_port (const std::string& shortname, ARDOUR::DataType, ARDOUR::PortFlags);
|
PortHandle add_port (const std::string& shortname, ARDOUR::DataType, ARDOUR::PortFlags);
|
||||||
int register_system_audio_ports ();
|
int register_system_audio_ports ();
|
||||||
void unregister_ports (bool system_only = false);
|
void unregister_ports (bool system_only = false);
|
||||||
|
void update_system_port_latecies ();
|
||||||
|
|
||||||
std::vector<CoreBackendPort *> _system_inputs;
|
std::vector<CoreBackendPort *> _system_inputs;
|
||||||
std::vector<CoreBackendPort *> _system_outputs;
|
std::vector<CoreBackendPort *> _system_outputs;
|
||||||
|
@ -1500,6 +1500,24 @@ PortAudioBackend::unregister_ports (bool system_only)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PortAudioBackend::update_system_port_latecies ()
|
||||||
|
{
|
||||||
|
for (std::vector<PamPort*>::const_iterator it = _system_inputs.begin (); it != _system_inputs.end (); ++it) {
|
||||||
|
(*it)->update_connected_latency (true);
|
||||||
|
}
|
||||||
|
for (std::vector<PamPort*>::const_iterator it = _system_outputs.begin (); it != _system_outputs.end (); ++it) {
|
||||||
|
(*it)->update_connected_latency (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::vector<PamPort*>::const_iterator it = _system_midi_in.begin (); it != _system_midi_in.end (); ++it) {
|
||||||
|
(*it)->update_connected_latency (true);
|
||||||
|
}
|
||||||
|
for (std::vector<PamPort*>::const_iterator it = _system_midi_out.begin (); it != _system_midi_out.end (); ++it) {
|
||||||
|
(*it)->update_connected_latency (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
PortAudioBackend::connect (const std::string& src, const std::string& dst)
|
PortAudioBackend::connect (const std::string& src, const std::string& dst)
|
||||||
{
|
{
|
||||||
@ -2132,6 +2150,7 @@ PortAudioBackend::process_port_connection_changes ()
|
|||||||
manager.graph_order_callback();
|
manager.graph_order_callback();
|
||||||
}
|
}
|
||||||
if (connections_changed || ports_changed) {
|
if (connections_changed || ports_changed) {
|
||||||
|
update_system_port_latecies ();
|
||||||
engine.latency_callback(false);
|
engine.latency_callback(false);
|
||||||
engine.latency_callback(true);
|
engine.latency_callback(true);
|
||||||
}
|
}
|
||||||
@ -2322,6 +2341,36 @@ bool PamPort::is_physically_connected () const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PamPort::set_latency_range (const LatencyRange &latency_range, bool for_playback)
|
||||||
|
{
|
||||||
|
if (for_playback) {
|
||||||
|
_playback_latency_range = latency_range;
|
||||||
|
} else {
|
||||||
|
_capture_latency_range = latency_range;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::vector<PamPort*>::const_iterator it = _connections.begin (); it != _connections.end (); ++it) {
|
||||||
|
if ((*it)->is_physical ()) {
|
||||||
|
(*it)->update_connected_latency (is_input ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PamPort::update_connected_latency (bool for_playback)
|
||||||
|
{
|
||||||
|
LatencyRange lr;
|
||||||
|
lr.min = lr.max = 0;
|
||||||
|
for (std::set<PamPort*>::const_iterator it = _connections.begin (); it != _connections.end (); ++it) {
|
||||||
|
LatencyRange l;
|
||||||
|
l = (*it)->latency_range (for_playback);
|
||||||
|
lr.min = std::max (lr.min, l.min);
|
||||||
|
lr.max = std::max (lr.max, l.max);
|
||||||
|
}
|
||||||
|
set_latency_range (lr, for_playback);
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
PortAudioPort::PortAudioPort (PortAudioBackend &b, const std::string& name, PortFlags flags)
|
PortAudioPort::PortAudioPort (PortAudioBackend &b, const std::string& name, PortFlags flags)
|
||||||
|
@ -93,17 +93,9 @@ class PamPort { // PortAudio / PortMidi Backend Port
|
|||||||
return for_playback ? _playback_latency_range : _capture_latency_range;
|
return for_playback ? _playback_latency_range : _capture_latency_range;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_latency_range (const LatencyRange &latency_range, bool for_playback)
|
void set_latency_range (const LatencyRange &latency_range, bool for_playback);
|
||||||
{
|
|
||||||
if (for_playback)
|
void update_connected_latency (bool for_playback);
|
||||||
{
|
|
||||||
_playback_latency_range = latency_range;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_capture_latency_range = latency_range;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PortAudioBackend &_osx_backend;
|
PortAudioBackend &_osx_backend;
|
||||||
@ -436,6 +428,7 @@ class PortAudioBackend : public AudioBackend {
|
|||||||
int register_system_audio_ports ();
|
int register_system_audio_ports ();
|
||||||
int register_system_midi_ports ();
|
int register_system_midi_ports ();
|
||||||
void unregister_ports (bool system_only = false);
|
void unregister_ports (bool system_only = false);
|
||||||
|
void update_system_port_latecies ();
|
||||||
|
|
||||||
std::vector<PamPort *> _ports;
|
std::vector<PamPort *> _ports;
|
||||||
std::vector<PamPort *> _system_inputs;
|
std::vector<PamPort *> _system_inputs;
|
||||||
|
Loading…
Reference in New Issue
Block a user