diff options
author | Robin Gareus <robin@gareus.org> | 2017-09-28 06:31:12 +0200 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2017-09-29 05:03:48 +0200 |
commit | 8139becb1898187729b0ea57f145302d4975bf3a (patch) | |
tree | 79638d87c587765784fe56eeb530ff792442e0c5 /libs/ardour/session_process.cc | |
parent | 8ff3b5ecf6bd2b7d69b8f154ba8d21eb4fe86304 (diff) |
Ongoing work on latency compensation
The general goal is to align transport-sample to be the audible frame
and use that as "anchor" for all processing.
transport_sample cannot become negative (00:00:00:00 is the first audible
frame).
Internally transport pre-rolls (read-ahead) before the transport starts
to move. This allows inputs and disk to prefill the pipeline.
When starting to roll, the session counts down a global "remaning preroll"
counter, which is the worst-latency from in-to-out.
Each route in turn will start processing at its own output-latency.
Route::process_output_buffers() - which does the actual processing
incl disk i/o - begins by offsetting the "current sample" by the
route's process-latency and decrements the offset for each latent
processor. At the end of the function the output will be aligned
and match transport-sample - downstream-playback-latency (if any).
PS. This commit is a first step only: transport looping & vari-speed have
not yet been implemented/updated.
Diffstat (limited to 'libs/ardour/session_process.cc')
-rw-r--r-- | libs/ardour/session_process.cc | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc index 1674cd9a7a..ed5422cf07 100644 --- a/libs/ardour/session_process.cc +++ b/libs/ardour/session_process.cc @@ -292,18 +292,47 @@ Session::process_with_events (pframes_t nframes) process_event (ev); } - /* count in */ + /* only count-in when going to roll at speed 1.0 */ if (_transport_speed != 1.0 && _count_in_samples > 0) { _count_in_samples = 0; } + if (_transport_speed == 0.0) { + _remaining_latency_preroll = 0; + } + + assert (_count_in_samples == 0 || _remaining_latency_preroll == 0 || _count_in_samples == _remaining_latency_preroll); - if (_count_in_samples > 0) { - samplecnt_t ns = std::min ((samplecnt_t)nframes, _count_in_samples); + if (_count_in_samples > 0 || _remaining_latency_preroll > 0) { + samplecnt_t ns; + + if (_remaining_latency_preroll > 0) { + ns = std::min ((samplecnt_t)nframes, _remaining_latency_preroll); + } else { + ns = std::min ((samplecnt_t)nframes, _count_in_samples); + } + + if (_count_in_samples > 0) { + run_click (_transport_sample - _count_in_samples, ns); + assert (_count_in_samples >= ns); + _count_in_samples -= ns; + } - no_roll (ns); - run_click (_transport_sample - _count_in_samples, ns); + if (_remaining_latency_preroll > 0) { + if (_count_in_samples == 0) { + click (_transport_sample - _remaining_latency_preroll, ns); + } + if (process_routes (ns, session_needs_butler)) { + fail_roll (ns); + } + } else { + no_roll (ns); + } + + if (_remaining_latency_preroll > 0) { + assert (_remaining_latency_preroll >= ns); + _remaining_latency_preroll -= ns; + } - _count_in_samples -= ns; nframes -= ns; /* process events.. */ |