13
0

Prevent DelayLine::set_delay() while processing

It was possible that auto-connect-thread or GUI thread called
DelayLine::set_delay without acquiring the process-lock.
Changing the delay while processing is not supported and
can cause glitches.

backtrace:
```
DelayLine::set_delay
Send::update_delaylines
Send::set_delay_out
InternalReturn::set_playback_offset
Route::update_signal_latency
Session::update_route_latency
Session::update_latency_compensation
Session::auto_connect_thread_run

```
This commit is contained in:
Robin Gareus 2021-08-02 23:12:15 +03:00
parent 657743a8e4
commit 5c9f5ae895
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04

View File

@ -4319,13 +4319,25 @@ Route::update_signal_latency (bool apply_to_delayline, bool* delayline_update_ne
/* 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));
/* InternalReturn::set_playback_offset() below, also calls set_delay_out() */
const samplecnt_t snd_lat = snd->output ()->connected_latency (true);
if (apply_to_delayline) {
/* DelayLine::set_delay requires process-lock */
snd->set_delay_out (snd_lat);
} else if (delayline_update_needed && snd->get_delay_out () != snd_lat) {
*delayline_update_needed = true;
}
}
} else if (!apply_to_delayline && boost::dynamic_pointer_cast<InternalReturn> (*i)) {
/* InternalReturn::set_playback_offset() calls set_delay_out(), requires process lock */
const samplecnt_t poff = _signal_latency + _output_latency;
if (delayline_update_needed && (*i)->playback_offset () != poff) {
*delayline_update_needed = true;
}
} else {
(*i)->set_playback_offset (_signal_latency + _output_latency);
}
(*i)->set_input_latency (l_in);
(*i)->set_playback_offset (_signal_latency + _output_latency);
(*i)->set_capture_offset (in_latency);
if ((*i)->active ()) {
l_in += (*i)->effective_latency ();