fix latency report, take buffersize changes into account.
authorRobin Gareus <robin@gareus.org>
Sat, 7 Mar 2015 08:11:15 +0000 (09:11 +0100)
committerRobin Gareus <robin@gareus.org>
Sat, 7 Mar 2015 13:35:32 +0000 (14:35 +0100)
libs/backends/alsa/alsa_audiobackend.cc
libs/backends/alsa/alsa_audiobackend.h
libs/backends/coreaudio/coreaudio_backend.cc
libs/backends/coreaudio/coreaudio_backend.h
libs/backends/dummy/dummy_audiobackend.cc
libs/backends/dummy/dummy_audiobackend.h

index 2c262f5e2902d5b2dc66d0adeedc6949794dc3ce..a18d58ee586552ed87a4dbd6dd0efb9238015aeb 100644 (file)
@@ -232,7 +232,7 @@ AlsaAudioBackend::can_change_sample_rate_when_running () const
 bool
 AlsaAudioBackend::can_change_buffer_size_when_running () const
 {
-       return false;
+       return false; // why not? :)
 }
 
 int
@@ -257,6 +257,9 @@ AlsaAudioBackend::set_buffer_size (uint32_t bs)
        if (bs <= 0 || bs >= _max_buffer_size) {
                return -1;
        }
+       if (_run) {
+               return -1;
+       }
        _samples_per_period = bs;
        engine.buffer_size_change (bs);
        return 0;
@@ -965,7 +968,7 @@ AlsaAudioBackend::register_system_audio_ports()
        const int a_out = _n_outputs > 0 ? _n_outputs : 2;
 
        /* audio ports */
-       lr.min = lr.max = _samples_per_period + (_measure_latency ? 0 : _systemic_audio_input_latency);
+       lr.min = lr.max = (_measure_latency ? 0 : _systemic_audio_input_latency);
        for (int i = 1; i <= a_ins; ++i) {
                char tmp[64];
                snprintf(tmp, sizeof(tmp), "system:capture_%d", i);
@@ -975,7 +978,7 @@ AlsaAudioBackend::register_system_audio_ports()
                _system_inputs.push_back(static_cast<AlsaPort*>(p));
        }
 
-       lr.min = lr.max = _samples_per_period + (_measure_latency ? 0 : _systemic_audio_output_latency);
+       lr.min = lr.max = (_measure_latency ? 0 : _systemic_audio_output_latency);
        for (int i = 1; i <= a_out; ++i) {
                char tmp[64];
                snprintf(tmp, sizeof(tmp), "system:playback_%d", i);
@@ -1036,7 +1039,7 @@ AlsaAudioBackend::register_system_midi_ports()
                                        delete mout;
                                }
                                LatencyRange lr;
-                               lr.min = lr.max = _samples_per_period + (_measure_latency ? 0 : nfo->systemic_output_latency);
+                               lr.min = lr.max = (_measure_latency ? 0 : nfo->systemic_output_latency);
                                set_latency_range (p, false, lr);
                                static_cast<AlsaMidiPort*>(p)->set_n_periods(2);
                                _system_midi_out.push_back(static_cast<AlsaPort*>(p));
@@ -1074,7 +1077,7 @@ AlsaAudioBackend::register_system_midi_ports()
                                        continue;
                                }
                                LatencyRange lr;
-                               lr.min = lr.max = _samples_per_period + (_measure_latency ? 0 : nfo->systemic_input_latency);
+                               lr.min = lr.max = (_measure_latency ? 0 : nfo->systemic_input_latency);
                                set_latency_range (p, false, lr);
                                _system_midi_in.push_back(static_cast<AlsaPort*>(p));
                                _rmidi_in.push_back (midin);
@@ -1317,14 +1320,28 @@ AlsaAudioBackend::set_latency_range (PortEngine::PortHandle port, bool for_playb
 LatencyRange
 AlsaAudioBackend::get_latency_range (PortEngine::PortHandle port, bool for_playback)
 {
+       LatencyRange r;
        if (!valid_port (port)) {
                PBD::error << _("AlsaPort::get_latency_range (): invalid port.") << endmsg;
-               LatencyRange r;
                r.min = 0;
                r.max = 0;
                return r;
        }
-       return static_cast<AlsaPort*>(port)->latency_range (for_playback);
+       AlsaPort *p = static_cast<AlsaPort*>(port);
+       assert(p);
+
+       r = p->latency_range (for_playback);
+       if (p->is_physical() && p->is_terminal()) {
+               if (p->is_input() && for_playback) {
+                       r.min += _samples_per_period;
+                       r.max += _samples_per_period;
+               }
+               if (p->is_output() && !for_playback) {
+                       r.min += _samples_per_period;
+                       r.max += _samples_per_period;
+               }
+       }
+       return r;
 }
 
 /* Discovering physical ports */
index fe29caf1662f83548516eb853ffab4e048cdcc08..270d1da044e45420dbf731b2fef02e4126caf786 100644 (file)
@@ -89,7 +89,7 @@ class AlsaPort {
 
                virtual void* get_buffer (pframes_t nframes) = 0;
 
-               const LatencyRange& latency_range (bool for_playback) const
+               const LatencyRange latency_range (bool for_playback) const
                {
                        return for_playback ? _playback_latency_range : _capture_latency_range;
                }
index 5a4651409427ad3cb902123e4041e6bd37e9efd1..0152598d1b73630ffeb2db390b95ada8d85cc472 100644 (file)
@@ -895,7 +895,7 @@ CoreAudioBackend::register_system_audio_ports()
 #endif
 
        /* audio ports */
-       lr.min = lr.max = _samples_per_period + coreaudio_reported_input_latency + (_measure_latency ? 0 : _systemic_audio_input_latency);
+       lr.min = lr.max = coreaudio_reported_input_latency + (_measure_latency ? 0 : _systemic_audio_input_latency);
        for (int i = 0; i < a_ins; ++i) {
                char tmp[64];
                snprintf(tmp, sizeof(tmp), "system:capture_%s", _pcmio->cached_port_name(i, true).c_str());
@@ -905,7 +905,7 @@ CoreAudioBackend::register_system_audio_ports()
                _system_inputs.push_back(static_cast<CoreBackendPort*>(p));
        }
 
-       lr.min = lr.max = _samples_per_period + coreaudio_reported_output_latency + (_measure_latency ? 0 : _systemic_audio_output_latency);
+       lr.min = lr.max = coreaudio_reported_output_latency + (_measure_latency ? 0 : _systemic_audio_output_latency);
        for (int i = 0; i < a_out; ++i) {
                char tmp[64];
                snprintf(tmp, sizeof(tmp), "system:playback_%s", _pcmio->cached_port_name(i, false).c_str());
@@ -1247,14 +1247,27 @@ CoreAudioBackend::set_latency_range (PortEngine::PortHandle port, bool for_playb
 LatencyRange
 CoreAudioBackend::get_latency_range (PortEngine::PortHandle port, bool for_playback)
 {
+       LatencyRange r;
        if (!valid_port (port)) {
                PBD::error << _("CoreBackendPort::get_latency_range (): invalid port.") << endmsg;
-               LatencyRange r;
                r.min = 0;
                r.max = 0;
-               return r;
        }
-       return static_cast<CoreBackendPort*>(port)->latency_range (for_playback);
+       CoreBackendPort* p = static_cast<CoreBackendPort*>(port);
+       assert(p);
+
+       r = p->latency_range (for_playback);
+       if (p->is_physical() && p->is_terminal() && p->type() == DataType::AUDIO) {
+               if (p->is_input() && for_playback) {
+                       r.min += _samples_per_period;
+                       r.max += _samples_per_period;
+               }
+               if (p->is_output() && !for_playback) {
+                       r.min += _samples_per_period;
+                       r.max += _samples_per_period;
+               }
+       }
+       return r;
 }
 
 /* Discovering physical ports */
index cfdf20625fa6c81c596fda06b921b8bb6922f8c8..ecc7107c71d43dc4d9c5ef9590e10975b70ebfca 100644 (file)
@@ -87,7 +87,7 @@ class CoreBackendPort {
 
                virtual void* get_buffer (pframes_t nframes) = 0;
 
-               const LatencyRange& latency_range (bool for_playback) const
+               const LatencyRange latency_range (bool for_playback) const
                {
                        return for_playback ? _playback_latency_range : _capture_latency_range;
                }
index 790056b5e81ed693602239c2f9c8525db28a1108..885a85628bc31a511eeaab17233dc169d3f21235 100644 (file)
@@ -206,10 +206,8 @@ DummyAudioBackend::set_buffer_size (uint32_t bs)
         * with 'Loopback' there is exactly once cycle latency,
         * divide it between In + Out;
         */
-       const size_t l_in = _samples_per_period * .25;
-       const size_t l_out = _samples_per_period - l_in;
        LatencyRange lr;
-       lr.min = lr.max = l_in + _systemic_input_latency;
+       lr.min = lr.max = _systemic_input_latency;
        for (std::vector<DummyAudioPort*>::const_iterator it = _system_inputs.begin (); it != _system_inputs.end (); ++it) {
                set_latency_range (*it, false, lr);
        }
@@ -217,7 +215,7 @@ DummyAudioBackend::set_buffer_size (uint32_t bs)
                set_latency_range (*it, false, lr);
        }
 
-       lr.min = lr.max = l_out + _systemic_output_latency;
+       lr.min = lr.max = _systemic_output_latency;
        for (std::vector<DummyAudioPort*>::const_iterator it = _system_outputs.begin (); it != _system_outputs.end (); ++it) {
                set_latency_range (*it, true, lr);
        }
@@ -765,12 +763,9 @@ DummyAudioBackend::register_system_ports()
        const int m_ins = _n_midi_inputs == UINT_MAX ? 0 : _n_midi_inputs;
        const int m_out = _n_midi_outputs == UINT_MAX ? a_ins : _n_midi_outputs;
 
-       /* with 'Loopback' there is exactly once cycle latency, divide it between In + Out; */
-       const size_t l_in = _samples_per_period * .25;
-       const size_t l_out = _samples_per_period - l_in;
 
        /* audio ports */
-       lr.min = lr.max = l_in + _systemic_input_latency;
+       lr.min = lr.max = _systemic_input_latency;
        for (int i = 1; i <= a_ins; ++i) {
                char tmp[64];
                snprintf(tmp, sizeof(tmp), "system:capture_%d", i);
@@ -781,7 +776,7 @@ DummyAudioBackend::register_system_ports()
                static_cast<DummyAudioPort*>(p)->setup_generator (gt, _samplerate);
        }
 
-       lr.min = lr.max = l_out + _systemic_output_latency;
+       lr.min = lr.max = _systemic_output_latency;
        for (int i = 1; i <= a_out; ++i) {
                char tmp[64];
                snprintf(tmp, sizeof(tmp), "system:playback_%d", i);
@@ -792,7 +787,7 @@ DummyAudioBackend::register_system_ports()
        }
 
        /* midi ports */
-       lr.min = lr.max = l_in + _systemic_input_latency;
+       lr.min = lr.max = _systemic_input_latency;
        for (int i = 0; i < m_ins; ++i) {
                char tmp[64];
                snprintf(tmp, sizeof(tmp), "system:midi_capture_%d", i+1);
@@ -805,7 +800,7 @@ DummyAudioBackend::register_system_ports()
                }
        }
 
-       lr.min = lr.max = l_out + _systemic_output_latency;
+       lr.min = lr.max = _systemic_output_latency;
        for (int i = 1; i <= m_out; ++i) {
                char tmp[64];
                snprintf(tmp, sizeof(tmp), "system:midi_playback_%d", i);
@@ -1049,14 +1044,32 @@ DummyAudioBackend::set_latency_range (PortEngine::PortHandle port, bool for_play
 LatencyRange
 DummyAudioBackend::get_latency_range (PortEngine::PortHandle port, bool for_playback)
 {
+       LatencyRange r;
        if (!valid_port (port)) {
                PBD::error << _("DummyPort::get_latency_range (): invalid port.") << endmsg;
-               LatencyRange r;
                r.min = 0;
                r.max = 0;
                return r;
        }
-       return static_cast<DummyPort*>(port)->latency_range (for_playback);
+       DummyPort *p =  static_cast<DummyPort*>(port);
+       assert(p);
+
+       r = p->latency_range (for_playback);
+       if (p->is_physical() && p->is_terminal()) {
+               if (p->is_input() && for_playback) {
+                       const size_t l_in = _samples_per_period * .25;
+                       r.min += _samples_per_period;
+                       r.max += _samples_per_period;
+               }
+               if (p->is_output() && !for_playback) {
+                       /* with 'Loopback' there is exactly once cycle latency, divide it between In + Out; */
+                       const size_t l_in = _samples_per_period * .25;
+                       const size_t l_out = _samples_per_period - l_in;
+                       r.min += _samples_per_period;
+                       r.max += _samples_per_period;
+               }
+       }
+       return r;
 }
 
 /* Discovering physical ports */
index 11597cfc31469da53f90460471b1d74f2676f6fa..226018d58444dc51315b5ed33c027e76b5a0ab15 100644 (file)
@@ -93,7 +93,7 @@ class DummyPort {
                virtual void* get_buffer (pframes_t nframes) = 0;
                void next_period () { _gen_cycle = false; }
 
-               const LatencyRange& latency_range (bool for_playback) const
+               const LatencyRange latency_range (bool for_playback) const
                {
                        return for_playback ? _playback_latency_range : _capture_latency_range;
                }