View Issue Details

IDProjectCategoryView StatusLast Update
0002878ardourbugspublic2020-04-19 20:14
Reporterscrewtop Assigned Topaul  
PrioritynormalSeveritymajorReproducibilityalways
Status closedResolutionfixed 
Summary0002878: Recorded tracks not laid down at correct time on timeline (output latency compensation cancellation)
DescriptionWhen recording new material in a session, the material is recorded onto the timeline at a later position than it should be. The recording point of the new region is ahead (i.e. towards the right, on the timeline) of where it should be, by the output latency amount. It should be <input latency> frames behind the playhead, but is instead <output latency> frames ahead of <input latency> frames behind the playhead. Ardour is effectively cancelling out its own output latency compensation when recording.
Additional InformationTo reproduce:

1. Start jackd with 4 s of extra output latency (e.g. -O 192000 for 48 kHz).
2. In Ardour, capture a couple of bars of test audio, and disarm the track.
3. Move the captured region to bar 6.
4. Position the playhead at bar 3.
5. Prepare and arm a second track for recording, and record the same test audio, in time (in terms of sound) with the existing audio.

The new material appears alongside the original track, but it should actually be 4 s earlier on the timeline. The 4 s of output latency correction has incorrectly been negated during the recording of the new track.

While recording the second track, the recording position is observed to be ahead of the playback head by 4 s. It should actually be at the playback head.

Tested on:
Ardour/GTK 2.8.3 (SVN 5854)
jackd 0.116.2 (SVN 3649)
Linux kernel 2.6.31.1
Echo Gina24 PCI

I have classed this as a major bug as this is a fundamental aspect of Ardour's operation.
Tagscompensation, delay, lag, latency, loopback, overdub

Activities

screwtop

2009-10-23 04:59

reporter   ~0006853

These forum threads discuss this issue:
http://ardour.org/node/2929
http://ardour.org/node/3077
http://ardour.org/node/3085

tokenrove

2009-10-26 15:18

reporter   ~0006890

This is a regression from 2.8 (4918), where the problem does not occur. I've been too busy to figure it out, but it has kept me from upgrading.

screwtop

2009-12-03 01:38

reporter   ~0007219

Update for Ardour 2.8.4 (6077): the behaviour is slightly (but not fundamentally) different. The recording position is now at the playhead position, but only because the playhead position now shows "JACK" time rather than "Ardour" time, and so the recording position is still ahead of where it should be by the total output latency (4 s in the test case described above).

screwtop

2009-12-04 03:40

reporter   ~0007222

Actually, this problem (new material being recorded at the current JACK time rather than the current Ardour time) seems to have been introduced much earlier than 2.8. I had thought my spare machine running 2.1 showed the correct behaviour, but I can't replicate that now. Even my old 0.99.3 installation has this problem with the input latency. Time to hit IRC again...

2009-12-28 23:23

 

latency-compensation-fix.patch (2,651 bytes)   
Index: libs/ardour/diskstream.cc
===================================================================
--- libs/ardour/diskstream.cc	(revision 6409)
+++ libs/ardour/diskstream.cc	(working copy)
@@ -296,7 +296,7 @@
 	if (capture_info.size() > n) {
 		return capture_info[n]->frames;
 	}
-	else {
+	else {  
 		return capture_captured;
 	}
 }
@@ -525,7 +525,16 @@
 			/* was stopped, now rolling (and recording) */
 
 			if (_alignment_style == ExistingMaterial) {
+			  
 				first_recordable_frame += _session.worst_output_latency();
+				
+				//cerr << "** Offset rec from stop " << endl;
+				//cerr << "Capture Offset   : " << _capture_offset << endl;
+				//cerr << "Worst O/P Latency: " << _session.worst_output_latency() << endl;
+				//cerr << "Roll Delay: " << _roll_delay << endl;
+				//cerr << "First Recordable Frame: " << first_recordable_frame << endl;
+				//cerr << "Transport Frame: " << transport_frame << endl;
+
 			} else {
 				first_recordable_frame += _roll_delay;
 			}
@@ -545,16 +554,7 @@
 					   appropriate spot given the roll delay.
 					*/
 
-					capture_start_frame -= _roll_delay;
 
-					/* XXX paul notes (august 2005): i don't know why
-					   this is needed.
-					*/
-
-					first_recordable_frame += _capture_offset;
-
-				} else {
-
 					/* autopunch toggles recording at the precise
 					   transport frame, and then the DS waits
 					   to start recording for a time that depends
@@ -562,6 +562,13 @@
 					*/
 
 					first_recordable_frame += _session.worst_output_latency();
+					
+					//cerr << "** Punch in manual/auto " << endl;
+					//cerr << "Capture Offset   : " << _capture_offset << endl;
+					//cerr << "Worst O/P Latency: " << _session.worst_output_latency() << endl;
+					//cerr << "Roll Delay: " << _roll_delay << endl;
+					//cerr << "First Recordable Frame: " << first_recordable_frame << endl;
+					//cerr << "Transport Frame: " << transport_frame << endl;
 				}
 
 			} else {
@@ -589,7 +596,15 @@
 			last_recordable_frame += _roll_delay;
 		}
 		
-		first_recordable_frame = max_frames;
+		//first_recordable_frame = max_frames;
+
+		//cerr << "** Stop record - " << can_record << " | " << record_enabled() << endl;
+		//cerr << "Capture Offset   : " << _capture_offset << endl;
+		//cerr << "Worst O/P Latency: " << _session.worst_output_latency() << endl;
+		//cerr << "Roll Delay: " << _roll_delay << endl;
+		//cerr << "First Recordable Frame: " << first_recordable_frame << endl;
+		//cerr << "Last Recordable Frame: " << last_recordable_frame << endl;
+		//cerr << "Transport Frame: " << transport_frame << endl;
 	}
 
 	last_possibly_recording = possibly_recording;

latency-compensation-fix.patch (2,651 bytes)   

lincoln

2009-12-28 23:25

reporter   ~0007267

Attached patch against Ardour 3.0 svn latest that should take care of placing the recorded material in the correct position. This patch also resolves the auto punch out happening early that is reported elsewhere. Give it a go and see if it clears the issue.

2009-12-28 23:40

 

latency-compensation-fix-2.patch (2,952 bytes)   
Index: libs/ardour/diskstream.cc
===================================================================
--- libs/ardour/diskstream.cc	(revision 6409)
+++ libs/ardour/diskstream.cc	(working copy)
@@ -296,7 +296,7 @@
 	if (capture_info.size() > n) {
 		return capture_info[n]->frames;
 	}
-	else {
+	else {  
 		return capture_captured;
 	}
 }
@@ -525,7 +525,16 @@
 			/* was stopped, now rolling (and recording) */
 
 			if (_alignment_style == ExistingMaterial) {
+			  
 				first_recordable_frame += _session.worst_output_latency();
+				
+				//cerr << "** Offset rec from stop " << endl;
+				//cerr << "Capture Offset   : " << _capture_offset << endl;
+				//cerr << "Worst O/P Latency: " << _session.worst_output_latency() << endl;
+				//cerr << "Roll Delay: " << _roll_delay << endl;
+				//cerr << "First Recordable Frame: " << first_recordable_frame << endl;
+				//cerr << "Transport Frame: " << transport_frame << endl;
+
 			} else {
 				first_recordable_frame += _roll_delay;
 			}
@@ -536,25 +545,13 @@
 
 			if (_alignment_style == ExistingMaterial) {
 
-
-				if (!_session.config.get_punch_in()) {
-
 					/* manual punch in happens at the correct transport frame
 					   because the user hit a button. but to get alignment correct
 					   we have to back up the position of the new region to the
 					   appropriate spot given the roll delay.
 					*/
 
-					capture_start_frame -= _roll_delay;
 
-					/* XXX paul notes (august 2005): i don't know why
-					   this is needed.
-					*/
-
-					first_recordable_frame += _capture_offset;
-
-				} else {
-
 					/* autopunch toggles recording at the precise
 					   transport frame, and then the DS waits
 					   to start recording for a time that depends
@@ -562,7 +559,13 @@
 					*/
 
 					first_recordable_frame += _session.worst_output_latency();
-				}
+					
+					//cerr << "** Punch in manual/auto " << endl;
+					//cerr << "Capture Offset   : " << _capture_offset << endl;
+					//cerr << "Worst O/P Latency: " << _session.worst_output_latency() << endl;
+					//cerr << "Roll Delay: " << _roll_delay << endl;
+					//cerr << "First Recordable Frame: " << first_recordable_frame << endl;
+					//cerr << "Transport Frame: " << transport_frame << endl;
 
 			} else {
 
@@ -589,7 +592,15 @@
 			last_recordable_frame += _roll_delay;
 		}
 		
-		first_recordable_frame = max_frames;
+		//first_recordable_frame = max_frames;
+
+		//cerr << "** Stop record - " << can_record << " | " << record_enabled() << endl;
+		//cerr << "Capture Offset   : " << _capture_offset << endl;
+		//cerr << "Worst O/P Latency: " << _session.worst_output_latency() << endl;
+		//cerr << "Roll Delay: " << _roll_delay << endl;
+		//cerr << "First Recordable Frame: " << first_recordable_frame << endl;
+		//cerr << "Last Recordable Frame: " << last_recordable_frame << endl;
+		//cerr << "Transport Frame: " << transport_frame << endl;
 	}
 
 	last_possibly_recording = possibly_recording;

lincoln

2009-12-28 23:40

reporter   ~0007268

please use second patch.

lincoln

2010-01-16 15:04

reporter   ~0007319

This patch was committed to 3.0 SVN. Please check out patch for Ardour 2

2010-01-16 15:04

 

latency_compensation_fix-ardour2.patch (2,875 bytes)   
Index: libs/ardour/audio_diskstream.cc
===================================================================
--- libs/ardour/audio_diskstream.cc	(revision 6459)
+++ libs/ardour/audio_diskstream.cc	(working copy)
@@ -417,10 +417,10 @@
 
 			if (_alignment_style == ExistingMaterial) {
 				//cerr << "A FRF += " << _session.worst_output_latency () << endl;
-				// first_recordable_frame += _session.worst_output_latency();
+				first_recordable_frame += _session.worst_output_latency();
 			} else {
 				// cerr << "B FRF += " << _roll_delay<< endl;
-				// first_recordable_frame += _roll_delay;
+				first_recordable_frame += _roll_delay;
   			}
 
 		} else {
@@ -429,49 +429,25 @@
 
 			if (_alignment_style == ExistingMaterial) {
 
-				if (!Config->get_punch_in()) {
+				/* manual punch in happens at the correct transport frame
+				    because the user hit a button. but to get alignment correct 
+				    we have to back up the position of the new region to the 
+				    appropriate spot given the roll delay.
+				*/
 
-					/* manual punch in happens at the correct transport frame
-					   because the user hit a button. but to get alignment correct 
-					   we have to back up the position of the new region to the 
-					   appropriate spot given the roll delay.
-					*/
 
-					capture_start_frame -= _roll_delay;
+				/* autopunch toggles recording at the precise
+				   transport frame, and then the DS waits
+				   to start recording for a time that depends
+				   on the output latency.
+				*/
 
-					/* XXX paul notes (august 2005): i don't know why
-					   this is needed.
-					*/
-
-					// cerr << "1 FRF += " << _capture_offset << endl;
-					first_recordable_frame += _capture_offset;
-
-				} else {
-
-					/* autopunch toggles recording at the precise
-					   transport frame, and then the DS waits
-					   to start recording for a time that depends
-					   on the output latency.
-					*/
-
-					// cerr << "2 FRF += " << _session.worst_output_latency() << endl;
-					first_recordable_frame += _session.worst_output_latency();
-				}
-
+				first_recordable_frame += _session.worst_output_latency();
 			} else {
-
-				if (Config->get_punch_in()) {
-					// cerr << "3 FRF += " << _roll_delay << endl;
-					first_recordable_frame += _roll_delay;
-				} else {
-					capture_start_frame -= _roll_delay;
-				}
+				capture_start_frame -= _roll_delay;
 			}
-			
 		}
 
-		// cerr << _name << " FRF = " << first_recordable_frame << " CSF = " << capture_start_frame << endl;
-
 		if (recordable() && destructive()) {
 			boost::shared_ptr<ChannelList> c = channels.reader();
 			for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
@@ -503,8 +479,6 @@
 		} else {
 			last_recordable_frame += _roll_delay;
 		}
-
-      first_recordable_frame = max_frames;
 	}
 
 	last_possibly_recording = possibly_recording;

paul

2010-01-16 21:35

administrator   ~0007321

applied, rev 6509. thanks once again lincoln.

system

2020-04-19 20:14

developer   ~0021994

Issue has been closed automatically, by Trigger Close Plugin.
Feel free to re-open with additional information if you think the issue is not resolved.

Issue History

Date Modified Username Field Change
2009-10-23 00:56 screwtop New Issue
2009-10-23 00:59 screwtop Tag Attached: compensation
2009-10-23 00:59 screwtop Tag Attached: delay
2009-10-23 00:59 screwtop Tag Attached: lag
2009-10-23 00:59 screwtop Tag Attached: latency
2009-10-23 00:59 screwtop Tag Attached: loopback
2009-10-23 00:59 screwtop Tag Attached: overdub
2009-10-23 04:59 screwtop Note Added: 0006853
2009-10-26 15:18 tokenrove Note Added: 0006890
2009-12-03 01:38 screwtop Note Added: 0007219
2009-12-04 03:40 screwtop Note Added: 0007222
2009-12-28 23:23 lincoln File Added: latency-compensation-fix.patch
2009-12-28 23:25 lincoln Note Added: 0007267
2009-12-28 23:40 lincoln File Added: latency-compensation-fix-2.patch
2009-12-28 23:40 lincoln Note Added: 0007268
2010-01-16 15:04 lincoln Note Added: 0007319
2010-01-16 15:04 lincoln File Added: latency_compensation_fix-ardour2.patch
2010-01-16 21:35 paul cost => 0.00
2010-01-16 21:35 paul Note Added: 0007321
2010-01-16 21:35 paul Status new => resolved
2010-01-16 21:35 paul Resolution open => fixed
2010-01-16 21:35 paul Assigned To => paul
2010-04-24 10:28 cth103 Category bugs => bugs2
2010-04-24 10:30 cth103 Category bugs2 => bugs
2020-04-19 20:14 system Note Added: 0021994
2020-04-19 20:14 system Status resolved => closed