summaryrefslogtreecommitdiff
path: root/libs/ardour/disk_writer.cc
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2017-09-28 06:31:12 +0200
committerRobin Gareus <robin@gareus.org>2017-09-29 05:03:48 +0200
commit8139becb1898187729b0ea57f145302d4975bf3a (patch)
tree79638d87c587765784fe56eeb530ff792442e0c5 /libs/ardour/disk_writer.cc
parent8ff3b5ecf6bd2b7d69b8f154ba8d21eb4fe86304 (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/disk_writer.cc')
-rw-r--r--libs/ardour/disk_writer.cc61
1 files changed, 33 insertions, 28 deletions
diff --git a/libs/ardour/disk_writer.cc b/libs/ardour/disk_writer.cc
index c05b19a12c..a3cfc69b1b 100644
--- a/libs/ardour/disk_writer.cc
+++ b/libs/ardour/disk_writer.cc
@@ -96,11 +96,9 @@ DiskWriter::check_record_status (samplepos_t transport_sample, double speed, boo
const int global_rec_enabled = 0x1;
const int fully_rec_enabled = (transport_rolling|track_rec_enabled|global_rec_enabled);
- /* merge together the 3 factors that affect record status, and compute
- * what has changed.
- */
+ /* merge together the 3 factors that affect record status, and compute what has changed. */
- rolling = _session.transport_speed() != 0.0f;
+ rolling = speed != 0.0f;
possibly_recording = (rolling << 2) | ((int)record_enabled() << 1) | (int)can_record;
change = possibly_recording ^ last_possibly_recording;
@@ -114,20 +112,28 @@ DiskWriter::check_record_status (samplepos_t transport_sample, double speed, boo
return;
}
- capture_start_sample = transport_sample;
- first_recordable_sample = capture_start_sample + _input_latency;
+ capture_start_sample = _session.transport_sample ();
+ first_recordable_sample = capture_start_sample;
+
if (_alignment_style == ExistingMaterial) {
- // XXX
+ first_recordable_sample += _capture_offset + _playback_offset;
}
- DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1: @ %7 (%9) FRF = %2 CSF = %4 CO = %5, EMO = %6 RD = %8 WOL %10 WTL %11\n",
- name(), first_recordable_sample, last_recordable_sample, capture_start_sample,
- 0,
- 0,
+ last_recordable_sample = max_samplepos;
+
+ DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1: @ %2 (STS: %3) CS:%4 FRS: %5 IL: %7, OL: %8 CO: %r9 PO: %10 WOL: %11 WIL: %12\n",
+ name(),
transport_sample,
_session.transport_sample(),
+ capture_start_sample,
+ first_recordable_sample,
+ last_recordable_sample,
+ _input_latency,
+ _output_latency,
+ _capture_offset,
+ _playback_offset,
_session.worst_output_latency(),
- _session.worst_track_latency()));
+ _session.worst_input_latency()));
prepare_record_status (capture_start_sample);
@@ -161,8 +167,7 @@ DiskWriter::check_record_status (samplepos_t transport_sample, double speed, boo
}
void
-DiskWriter::calculate_record_range (Evoral::OverlapType ot, samplepos_t transport_sample, samplecnt_t nframes,
- samplecnt_t & rec_nframes, samplecnt_t & rec_offset)
+DiskWriter::calculate_record_range (Evoral::OverlapType ot, samplepos_t transport_sample, samplecnt_t nframes, samplecnt_t & rec_nframes, samplecnt_t & rec_offset)
{
switch (ot) {
case Evoral::OverlapNone:
@@ -347,31 +352,31 @@ void
DiskWriter::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample,
double speed, pframes_t nframes, bool result_required)
{
+ if (!_active && !_pending_active) {
+ return;
+ }
+ _active = _pending_active;
+
uint32_t n;
boost::shared_ptr<ChannelList> c = channels.reader();
ChannelList::iterator chan;
+
samplecnt_t rec_offset = 0;
samplecnt_t rec_nframes = 0;
bool nominally_recording;
+
bool re = record_enabled ();
bool can_record = _session.actively_recording ();
- if (_active) {
- if (!_pending_active) {
- _active = false;
- return;
- }
- } else {
- if (_pending_active) {
- _active = true;
- } else {
- return;
- }
- }
-
_need_butler = false;
- check_record_status (start_sample, 1, can_record);
+#ifndef NDEBUG
+ if (speed != 0 && re) {
+ DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1: run() start: %2 end: %3 NF: %4\n", _name, start_sample, end_sample, nframes));
+ }
+#endif
+
+ check_record_status (start_sample, speed, can_record);
if (nframes == 0) {
return;