summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2020-01-29 01:22:48 +0100
committerRobin Gareus <robin@gareus.org>2020-01-29 01:32:06 +0100
commit6bc4f69c5c85a2494dab3936d121833b1dcca15a (patch)
tree43067fa6fc844991c16f64577972cf3bb7819006 /libs/ardour
parenteb7297e2fc9dd553d36095dd4441a06e793d318a (diff)
Fix loop recording alignment
DiskWriter::transport_looped() is called from the session when engine loops. This does not take local disk-reader run() latency offset into account. finish_capture() needs to be postponed until the disk-writer itself reaches the loop-position. This is achieved by postponing loop() and calling it once loop-length of samples has been captured. This works because engaging loop always seeks to the loop-position and first loop resets _capture_captured.
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/disk_writer.h5
-rw-r--r--libs/ardour/disk_writer.cc45
2 files changed, 41 insertions, 9 deletions
diff --git a/libs/ardour/ardour/disk_writer.h b/libs/ardour/ardour/disk_writer.h
index c17c2e539e..fab54e2404 100644
--- a/libs/ardour/ardour/disk_writer.h
+++ b/libs/ardour/ardour/disk_writer.h
@@ -169,6 +169,8 @@ private:
void check_record_status (samplepos_t transport_sample, double speed, bool can_record);
void finish_capture (boost::shared_ptr<ChannelList> c);
+ void loop (samplepos_t);
+
CaptureInfos capture_info;
mutable Glib::Threads::Mutex capture_info_lock;
@@ -187,6 +189,9 @@ private:
volatile gint _num_captured_loops;
samplepos_t _accumulated_capture_offset;
+ bool _transport_looped;
+ samplepos_t _transport_loop_sample;
+
boost::shared_ptr<SMFSource> _midi_write_source;
std::list<boost::shared_ptr<Source> > _last_capture_sources;
diff --git a/libs/ardour/disk_writer.cc b/libs/ardour/disk_writer.cc
index cb62f932b6..cddfe7b09b 100644
--- a/libs/ardour/disk_writer.cc
+++ b/libs/ardour/disk_writer.cc
@@ -59,6 +59,8 @@ DiskWriter::DiskWriter (Session& s, string const & str, DiskIOProcessor::Flag f)
, _samples_pending_write (0)
, _num_captured_loops (0)
, _accumulated_capture_offset (0)
+ , _transport_looped (false)
+ , _transport_loop_sample (0)
, _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI))
{
DiskIOProcessor::init ();
@@ -397,6 +399,29 @@ DiskWriter::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
_need_butler = false;
+ const Location* const loop_loc = _loop_location;
+ samplepos_t loop_start = 0;
+ samplepos_t loop_end = 0;
+ samplepos_t loop_length = 0;
+
+ if (_transport_looped && _capture_captured == 0) {
+ _transport_looped = false;
+ }
+
+ if (loop_loc) {
+ get_location_times (loop_loc, &loop_start, &loop_end, &loop_length);
+
+ if (_was_recording && _transport_looped && _capture_captured >= loop_length) {
+ samplecnt_t remain = _capture_captured - loop_length;
+ _capture_captured = loop_length;
+ loop (_transport_loop_sample);
+ _capture_captured = remain;
+ }
+
+ } else {
+ _transport_looped = false;
+ }
+
#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));
@@ -418,15 +443,6 @@ DiskWriter::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
_last_recordable_sample = max_samplepos;
}
- const Location* const loop_loc = _loop_location;
- samplepos_t loop_start = 0;
- samplepos_t loop_end = 0;
- samplepos_t loop_length = 0;
-
- if (loop_loc) {
- get_location_times (loop_loc, &loop_start, &loop_end, &loop_length);
- }
-
if (nominally_recording || (re && _was_recording && _session.get_record_enabled() && punch_in)) {
Evoral::OverlapType ot = Evoral::coverage (_first_recordable_sample, _last_recordable_sample, start_sample, end_sample);
@@ -1318,6 +1334,17 @@ DiskWriter::transport_stopped_wallclock (struct tm& when, time_t twhen, bool abo
void
DiskWriter::transport_looped (samplepos_t transport_sample)
{
+ if (_capture_captured) {
+ _transport_looped = true;
+ _transport_loop_sample = transport_sample;
+ _first_recordable_sample = transport_sample;
+ }
+}
+
+void
+DiskWriter::loop (samplepos_t transport_sample)
+{
+ _transport_looped = false;
if (_was_recording) {
// all we need to do is finish this capture, with modified capture length
boost::shared_ptr<ChannelList> c = channels.reader();