View Issue Details

IDProjectCategoryView StatusLast Update
0002605ardourbugspublic2020-04-19 20:13
Reporternickm Assigned Topaul  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product VersionSVN/2.0-ongoing 
Summary0002605: [PATCH] Use file timestamp when importing broadcast wave files
DescriptionWhen importing a broadcast wave file with "use file timestamp", get the timecode from the file and use it when setting the position of generated regions.

NB: doesn't work for CoreAudio (no change from before)
NB: resampled import source will place the file in the wrong place (needs to account for sample rate change)
TagsNo tags attached.

Relationships

related to 0002633 closedpaul Timestamp not recognized when importing audio 

Activities

2009-03-30 01:00

 

2.0-ongoing-timestamp-2.patch (8,525 bytes)   
Index: gtk2_ardour/editor_audio_import.cc
===================================================================
--- gtk2_ardour/editor_audio_import.cc	(revision 4905)
+++ gtk2_ardour/editor_audio_import.cc	(working copy)
@@ -678,8 +678,11 @@
 	ustring region_name;
 	uint32_t input_chan = 0;
 	uint32_t output_chan = 0;
+	bool use_timestamp;
+	
+	use_timestamp = (pos == -1);
 
-	if (pos == -1) { // "use timestamp"
+	if (use_timestamp) {
 		if (sources[0]->natural_position() != 0) {
 			pos = sources[0]->natural_position();
 		} else {
@@ -692,11 +695,16 @@
 		/* take all the sources we have and package them up as a region */
 
 		region_name = region_name_from_path (paths.front(), (sources.size() > 1), false);
-		
-		regions.push_back (boost::dynamic_pointer_cast<AudioRegion> 
+		boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> 
 				   (RegionFactory::create (sources, 0, sources[0]->length(), region_name, 0,
-							   Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External))));
+							   Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)));
+							   
+        if (use_timestamp) {
+		    ar->special_set_position(sources[0]->natural_position());
+		}
 		
+		regions.push_back (ar);
+		
 	} else if (target_regions == -1 || target_regions > 1) {
 
 		/* take each source and create a region for each one */
@@ -713,11 +721,15 @@
 			boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*x);
 
 			region_name = region_name_from_path (afs->path(), false, true, sources.size(), n);
-
-			regions.push_back (boost::dynamic_pointer_cast<AudioRegion> 
+			boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> 
 					   (RegionFactory::create (just_one, 0, (*x)->length(), region_name, 0,
-								   Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External))));
+								   Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)));
 
+            if (use_timestamp) {
+    		    ar->special_set_position((*x)->natural_position());
+    		}
+
+			regions.push_back (ar);
 		}
 	}
 
Index: libs/ardour/ardour/sndfileimportable.h
===================================================================
--- libs/ardour/ardour/sndfileimportable.h	(revision 4905)
+++ libs/ardour/ardour/sndfileimportable.h	(working copy)
@@ -38,11 +38,13 @@
 	nframes_t length() const;
 	nframes_t samplerate() const;
 	void      seek (nframes_t pos);
+	nframes_t natural_position() const;
 
    protected:
 	SF_INFO sf_info;
 	boost::shared_ptr<SNDFILE> in;
-
+	nframes_t timecode;
+	int64_t get_timecode_info (SNDFILE*, SF_BROADCAST_INFO*, bool&);
 };
 
 }
Index: libs/ardour/ardour/importable_source.h
===================================================================
--- libs/ardour/ardour/importable_source.h	(revision 4905)
+++ libs/ardour/ardour/importable_source.h	(working copy)
@@ -36,6 +36,7 @@
 	virtual nframes_t length() const = 0;
 	virtual nframes_t samplerate() const = 0;
 	virtual void      seek (nframes_t pos) = 0;
+	virtual nframes_t natural_position() const = 0;
 };
 
 }
Index: libs/ardour/ardour/resampled_source.h
===================================================================
--- libs/ardour/ardour/resampled_source.h	(revision 4905)
+++ libs/ardour/ardour/resampled_source.h	(working copy)
@@ -40,6 +40,7 @@
 	nframes_t length() const { return source->length(); }
 	nframes_t samplerate() const { return source->samplerate(); }
 	void      seek (nframes_t pos) { source->seek (pos); }
+	nframes_t natural_position() const { return source->natural_position(); }
 	
 	static const uint32_t blocksize;
 	
Index: libs/ardour/ardour/caimportable.h
===================================================================
--- libs/ardour/ardour/caimportable.h	(revision 4905)
+++ libs/ardour/ardour/caimportable.h	(working copy)
@@ -38,6 +38,7 @@
 	nframes_t length() const;
 	nframes_t samplerate() const;
 	void      seek (nframes_t pos);
+	nframes_t natural_position() const { return 0; }
 
    protected:
 	mutable CAAudioFile af;
Index: libs/ardour/ardour/audiofilesource.h
===================================================================
--- libs/ardour/ardour/audiofilesource.h	(revision 4905)
+++ libs/ardour/ardour/audiofilesource.h	(working copy)
@@ -125,6 +125,8 @@
 
 	bool can_be_analysed() const { return _length > 0; } 
 
+	virtual void set_timeline_position (int64_t pos);
+
   protected:
 	
 	/* constructor to be called for existing external-to-session files */
@@ -161,7 +163,6 @@
 
 	static uint64_t header_position_offset;
 
-	virtual void set_timeline_position (int64_t pos);
 	virtual void set_header_timeline_position () = 0;
 
 	bool find (Glib::ustring& path, bool must_exist, bool& is_new, uint16_t& chan);
Index: libs/ardour/sndfileimportable.cc
===================================================================
--- libs/ardour/sndfileimportable.cc	(revision 4905)
+++ libs/ardour/sndfileimportable.cc	(working copy)
@@ -1,14 +1,41 @@
 #include <ardour/sndfileimportable.h>
 #include <sndfile.h>
 #include <iostream>
+#include <cstring>
 
 using namespace ARDOUR;
 using namespace std;
 
+/* FIXME: this was copied from sndfilesource.cc, at some point these should be merged */
+int64_t
+SndFileImportableSource::get_timecode_info (SNDFILE* sf, SF_BROADCAST_INFO* binfo, bool& exists)
+{
+	if (sf_command (sf, SFC_GET_BROADCAST_INFO, binfo, sizeof (*binfo)) != SF_TRUE) {
+		exists = false;
+		return 0;
+	} 
+	
+	exists = true;
+	int64_t ret = (uint32_t) binfo->time_reference_high;
+	ret <<= 32;
+	ret |= (uint32_t) binfo->time_reference_low;
+	return ret;
+}
+
 SndFileImportableSource::SndFileImportableSource (const string& path)
 	: in (sf_open (path.c_str(), SFM_READ, &sf_info), sf_close)
 {
 	if (!in) throw failed_constructor();
+	
+	SF_BROADCAST_INFO binfo;
+	bool timecode_exists;
+
+	memset (&binfo, 0, sizeof (binfo));
+	timecode = get_timecode_info (in.get(), &binfo, timecode_exists);
+	
+	if (!timecode_exists) {
+		timecode = 0;
+	}
 }
 
 SndFileImportableSource::~SndFileImportableSource ()
@@ -46,3 +73,9 @@
 {
 	sf_seek (in.get(), 0, SEEK_SET);
 }
+
+nframes_t
+SndFileImportableSource::natural_position () const
+{
+	return timecode;
+}
Index: libs/ardour/import.cc
===================================================================
--- libs/ardour/import.cc	(revision 4905)
+++ libs/ardour/import.cc	(working copy)
@@ -193,8 +193,11 @@
 
 static bool
 create_mono_sources_for_writing (const vector<string>& new_paths, Session& sess,
-		uint samplerate, vector<boost::shared_ptr<AudioFileSource> >& newfiles)
+		uint samplerate, vector<boost::shared_ptr<AudioFileSource> >& newfiles,
+		nframes_t timeline_position)
 {
+    boost::shared_ptr<AudioFileSource> afs;
+    
 	for (vector<string>::const_iterator i = new_paths.begin();
 			i != new_paths.end(); ++i)
 	{
@@ -215,7 +218,9 @@
 			return false;
 		}
 
-		newfiles.push_back(boost::dynamic_pointer_cast<AudioFileSource>(source));
+		afs = boost::dynamic_pointer_cast<AudioFileSource>(source);
+		afs->set_timeline_position(timeline_position);
+		newfiles.push_back(afs);
 	}
 	return true;
 }
@@ -337,7 +342,7 @@
 			fatal << "THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" << endl;
 			status.cancel = !map_existing_mono_sources (new_paths, *this, frame_rate(), newfiles, this);
 		} else {
-			status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles);
+			status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles, source->natural_position());
 		}
 
 		// copy on cancel/failure so that any files that were created will be removed below
@@ -366,7 +371,7 @@
 
 		for (AudioSources::iterator x = all_new_sources.begin(); x != all_new_sources.end(); ++x)
 		{
-			(*x)->update_header(0, *now, xnow);
+			(*x)->update_header((*x)->natural_position(), *now, xnow);
 			(*x)->done_with_peakfile_writes ();
 			
 			/* now that there is data there, requeue the file for analysis */
Index: libs/ardour/sndfilesource.cc
===================================================================
--- libs/ardour/sndfilesource.cc	(revision 4905)
+++ libs/ardour/sndfilesource.cc	(working copy)
@@ -901,10 +901,6 @@
 		return (header_position_offset);
 	} 
 	
-	/* XXX 64 bit alert: when JACK switches to a 64 bit frame count, this needs to use the high bits
-	   of the time reference.
-	*/
-	
 	exists = true;
 	int64_t ret = (uint32_t) binfo->time_reference_high;
 	ret <<= 32;
2.0-ongoing-timestamp-2.patch (8,525 bytes)   

nickm

2009-07-08 18:06

reporter   ~0006404

Patch against 5338

2009-07-08 18:06

 

2.0-ongoing-import-timestamp-5338.patch (9,392 bytes)   
Index: 2.0-ongoing-import-timestamp/gtk2_ardour/editor_audio_import.cc
===================================================================
--- 2.0-ongoing-import-timestamp/gtk2_ardour/editor_audio_import.cc	(revision 5338)
+++ 2.0-ongoing-import-timestamp/gtk2_ardour/editor_audio_import.cc	(working copy)
@@ -683,8 +683,11 @@
 	ustring region_name;
 	uint32_t input_chan = 0;
 	uint32_t output_chan = 0;
+	bool use_timestamp;
+	
+	use_timestamp = (pos == -1);
 
-	if (pos == -1) { // "use timestamp"
+	if (use_timestamp) {
 		if (sources[0]->natural_position() != 0) {
 			pos = sources[0]->natural_position();
 		} else {
@@ -697,11 +700,16 @@
 		/* take all the sources we have and package them up as a region */
 
 		region_name = region_name_from_path (paths.front(), (sources.size() > 1), false);
-		
-		regions.push_back (boost::dynamic_pointer_cast<AudioRegion> 
+		boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> 
 				   (RegionFactory::create (sources, 0, sources[0]->length(), region_name, 0,
-							   Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External))));
+							   Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)));
+							   
+        if (use_timestamp) {
+		    ar->special_set_position(sources[0]->natural_position());
+		}
 		
+		regions.push_back (ar);
+		
 	} else if (target_regions == -1 || target_regions > 1) {
 
 		/* take each source and create a region for each one */
@@ -718,11 +726,15 @@
 			boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*x);
 
 			region_name = region_name_from_path (afs->path(), false, true, sources.size(), n);
-
-			regions.push_back (boost::dynamic_pointer_cast<AudioRegion> 
+			boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> 
 					   (RegionFactory::create (just_one, 0, (*x)->length(), region_name, 0,
-								   Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External))));
+								   Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)));
 
+            if (use_timestamp) {
+    		    ar->special_set_position((*x)->natural_position());
+    		}
+
+			regions.push_back (ar);
 		}
 	}
 
Index: 2.0-ongoing-import-timestamp/libs/ardour/ardour/sndfileimportable.h
===================================================================
--- 2.0-ongoing-import-timestamp/libs/ardour/ardour/sndfileimportable.h	(revision 5338)
+++ 2.0-ongoing-import-timestamp/libs/ardour/ardour/sndfileimportable.h	(working copy)
@@ -38,11 +38,13 @@
 	nframes_t length() const;
 	nframes_t samplerate() const;
 	void      seek (nframes_t pos);
+	nframes_t natural_position() const;
 
    protected:
 	SF_INFO sf_info;
 	boost::shared_ptr<SNDFILE> in;
-
+	nframes_t timecode;
+	int64_t get_timecode_info (SNDFILE*, SF_BROADCAST_INFO*, bool&);
 };
 
 }
Index: 2.0-ongoing-import-timestamp/libs/ardour/ardour/importable_source.h
===================================================================
--- 2.0-ongoing-import-timestamp/libs/ardour/ardour/importable_source.h	(revision 5338)
+++ 2.0-ongoing-import-timestamp/libs/ardour/ardour/importable_source.h	(working copy)
@@ -36,6 +36,7 @@
 	virtual nframes_t length() const = 0;
 	virtual nframes_t samplerate() const = 0;
 	virtual void      seek (nframes_t pos) = 0;
+	virtual nframes_t natural_position() const = 0;
 };
 
 }
Index: 2.0-ongoing-import-timestamp/libs/ardour/ardour/resampled_source.h
===================================================================
--- 2.0-ongoing-import-timestamp/libs/ardour/ardour/resampled_source.h	(revision 5338)
+++ 2.0-ongoing-import-timestamp/libs/ardour/ardour/resampled_source.h	(working copy)
@@ -40,6 +40,7 @@
 	nframes_t length() const { return source->length(); }
 	nframes_t samplerate() const { return source->samplerate(); }
 	void      seek (nframes_t pos) { source->seek (pos); }
+	nframes_t natural_position() const { return source->natural_position(); }
 	
 	static const uint32_t blocksize;
 	
Index: 2.0-ongoing-import-timestamp/libs/ardour/ardour/caimportable.h
===================================================================
--- 2.0-ongoing-import-timestamp/libs/ardour/ardour/caimportable.h	(revision 5338)
+++ 2.0-ongoing-import-timestamp/libs/ardour/ardour/caimportable.h	(working copy)
@@ -38,6 +38,7 @@
 	nframes_t length() const;
 	nframes_t samplerate() const;
 	void      seek (nframes_t pos);
+	nframes_t natural_position() const { return 0; }
 
    protected:
 	mutable CAAudioFile af;
Index: 2.0-ongoing-import-timestamp/libs/ardour/ardour/audiofilesource.h
===================================================================
--- 2.0-ongoing-import-timestamp/libs/ardour/ardour/audiofilesource.h	(revision 5338)
+++ 2.0-ongoing-import-timestamp/libs/ardour/ardour/audiofilesource.h	(working copy)
@@ -125,6 +125,8 @@
 
 	bool can_be_analysed() const { return _length > 0; } 
 
+	virtual void set_timeline_position (int64_t pos);
+
 	static bool find (Glib::ustring path, bool must_exist, bool embedded, bool& is_new, uint16_t& chan,
 			  Glib::ustring& found_path, std::string& found_name);
 
@@ -164,7 +166,6 @@
 
 	static uint64_t header_position_offset;
 
-	virtual void set_timeline_position (int64_t pos);
 	virtual void set_header_timeline_position () = 0;
 
 	bool removable() const;
Index: 2.0-ongoing-import-timestamp/libs/ardour/sndfileimportable.cc
===================================================================
--- 2.0-ongoing-import-timestamp/libs/ardour/sndfileimportable.cc	(revision 5338)
+++ 2.0-ongoing-import-timestamp/libs/ardour/sndfileimportable.cc	(working copy)
@@ -1,16 +1,43 @@
 #include <ardour/sndfileimportable.h>
 #include <sndfile.h>
 #include <iostream>
+#include <cstring>
 #include <string.h>
 
 using namespace ARDOUR;
 using namespace std;
 
+/* FIXME: this was copied from sndfilesource.cc, at some point these should be merged */
+int64_t
+SndFileImportableSource::get_timecode_info (SNDFILE* sf, SF_BROADCAST_INFO* binfo, bool& exists)
+{
+	if (sf_command (sf, SFC_GET_BROADCAST_INFO, binfo, sizeof (*binfo)) != SF_TRUE) {
+		exists = false;
+		return 0;
+	} 
+	
+	exists = true;
+	int64_t ret = (uint32_t) binfo->time_reference_high;
+	ret <<= 32;
+	ret |= (uint32_t) binfo->time_reference_low;
+	return ret;
+}
+
 SndFileImportableSource::SndFileImportableSource (const string& path)
 {
 	memset(&sf_info, 0 , sizeof(sf_info));
 	in.reset( sf_open(path.c_str(), SFM_READ, &sf_info), sf_close);
 	if (!in) throw failed_constructor();
+	
+	SF_BROADCAST_INFO binfo;
+	bool timecode_exists;
+
+	memset (&binfo, 0, sizeof (binfo));
+	timecode = get_timecode_info (in.get(), &binfo, timecode_exists);
+	
+	if (!timecode_exists) {
+		timecode = 0;
+	}
 }
 
 SndFileImportableSource::~SndFileImportableSource ()
@@ -48,3 +75,9 @@
 {
 	sf_seek (in.get(), 0, SEEK_SET);
 }
+
+nframes_t
+SndFileImportableSource::natural_position () const
+{
+	return timecode;
+}
Index: 2.0-ongoing-import-timestamp/libs/ardour/import.cc
===================================================================
--- 2.0-ongoing-import-timestamp/libs/ardour/import.cc	(revision 5338)
+++ 2.0-ongoing-import-timestamp/libs/ardour/import.cc	(working copy)
@@ -193,8 +193,11 @@
 
 static bool
 create_mono_sources_for_writing (const vector<string>& new_paths, Session& sess,
-		uint samplerate, vector<boost::shared_ptr<AudioFileSource> >& newfiles)
+		uint samplerate, vector<boost::shared_ptr<AudioFileSource> >& newfiles,
+		nframes_t timeline_position)
 {
+    boost::shared_ptr<AudioFileSource> afs;
+    
 	for (vector<string>::const_iterator i = new_paths.begin();
 			i != new_paths.end(); ++i)
 	{
@@ -215,7 +218,9 @@
 			return false;
 		}
 
-		newfiles.push_back(boost::dynamic_pointer_cast<AudioFileSource>(source));
+		afs = boost::dynamic_pointer_cast<AudioFileSource>(source);
+		afs->set_timeline_position(timeline_position);
+		newfiles.push_back(afs);
 	}
 	return true;
 }
@@ -337,7 +342,7 @@
 			fatal << "THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" << endl;
 			status.cancel = !map_existing_mono_sources (new_paths, *this, frame_rate(), newfiles, this);
 		} else {
-			status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles);
+			status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles, source->natural_position());
 		}
 
 		// copy on cancel/failure so that any files that were created will be removed below
@@ -366,7 +371,7 @@
 
 		for (AudioSources::iterator x = all_new_sources.begin(); x != all_new_sources.end(); ++x)
 		{
-			(*x)->update_header(0, *now, xnow);
+			(*x)->update_header((*x)->natural_position(), *now, xnow);
 			(*x)->done_with_peakfile_writes ();
 			
 			/* now that there is data there, requeue the file for analysis */
Index: 2.0-ongoing-import-timestamp/libs/ardour/sndfilesource.cc
===================================================================
--- 2.0-ongoing-import-timestamp/libs/ardour/sndfilesource.cc	(revision 5338)
+++ 2.0-ongoing-import-timestamp/libs/ardour/sndfilesource.cc	(working copy)
@@ -901,10 +901,6 @@
 		return (header_position_offset);
 	} 
 	
-	/* XXX 64 bit alert: when JACK switches to a 64 bit frame count, this needs to use the high bits
-	   of the time reference.
-	*/
-	
 	exists = true;
 	int64_t ret = (uint32_t) binfo->time_reference_high;
 	ret <<= 32;

2009-07-08 18:14

 

2.0-ongoing-import-timestamp-5338-v2.patch (8,818 bytes)   
Index: 2.0-ongoing-import-timestamp/gtk2_ardour/editor_audio_import.cc
===================================================================
--- 2.0-ongoing-import-timestamp/gtk2_ardour/editor_audio_import.cc	(revision 5338)
+++ 2.0-ongoing-import-timestamp/gtk2_ardour/editor_audio_import.cc	(working copy)
@@ -683,8 +683,11 @@
 	ustring region_name;
 	uint32_t input_chan = 0;
 	uint32_t output_chan = 0;
+	bool use_timestamp;
+	
+	use_timestamp = (pos == -1);
 
-	if (pos == -1) { // "use timestamp"
+	if (use_timestamp) {
 		if (sources[0]->natural_position() != 0) {
 			pos = sources[0]->natural_position();
 		} else {
@@ -697,11 +700,16 @@
 		/* take all the sources we have and package them up as a region */
 
 		region_name = region_name_from_path (paths.front(), (sources.size() > 1), false);
-		
-		regions.push_back (boost::dynamic_pointer_cast<AudioRegion> 
+		boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> 
 				   (RegionFactory::create (sources, 0, sources[0]->length(), region_name, 0,
-							   Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External))));
+							   Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)));
+							   
+        if (use_timestamp) {
+		    ar->special_set_position(sources[0]->natural_position());
+		}
 		
+		regions.push_back (ar);
+		
 	} else if (target_regions == -1 || target_regions > 1) {
 
 		/* take each source and create a region for each one */
@@ -718,11 +726,15 @@
 			boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*x);
 
 			region_name = region_name_from_path (afs->path(), false, true, sources.size(), n);
-
-			regions.push_back (boost::dynamic_pointer_cast<AudioRegion> 
+			boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> 
 					   (RegionFactory::create (just_one, 0, (*x)->length(), region_name, 0,
-								   Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External))));
+								   Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)));
 
+            if (use_timestamp) {
+    		    ar->special_set_position((*x)->natural_position());
+    		}
+
+			regions.push_back (ar);
 		}
 	}
 
Index: 2.0-ongoing-import-timestamp/libs/ardour/ardour/sndfileimportable.h
===================================================================
--- 2.0-ongoing-import-timestamp/libs/ardour/ardour/sndfileimportable.h	(revision 5338)
+++ 2.0-ongoing-import-timestamp/libs/ardour/ardour/sndfileimportable.h	(working copy)
@@ -38,11 +38,13 @@
 	nframes_t length() const;
 	nframes_t samplerate() const;
 	void      seek (nframes_t pos);
+	nframes_t natural_position() const;
 
    protected:
 	SF_INFO sf_info;
 	boost::shared_ptr<SNDFILE> in;
-
+	nframes_t timecode;
+	int64_t get_timecode_info (SNDFILE*, SF_BROADCAST_INFO*, bool&);
 };
 
 }
Index: 2.0-ongoing-import-timestamp/libs/ardour/ardour/importable_source.h
===================================================================
--- 2.0-ongoing-import-timestamp/libs/ardour/ardour/importable_source.h	(revision 5338)
+++ 2.0-ongoing-import-timestamp/libs/ardour/ardour/importable_source.h	(working copy)
@@ -36,6 +36,7 @@
 	virtual nframes_t length() const = 0;
 	virtual nframes_t samplerate() const = 0;
 	virtual void      seek (nframes_t pos) = 0;
+	virtual nframes_t natural_position() const = 0;
 };
 
 }
Index: 2.0-ongoing-import-timestamp/libs/ardour/ardour/resampled_source.h
===================================================================
--- 2.0-ongoing-import-timestamp/libs/ardour/ardour/resampled_source.h	(revision 5338)
+++ 2.0-ongoing-import-timestamp/libs/ardour/ardour/resampled_source.h	(working copy)
@@ -40,6 +40,7 @@
 	nframes_t length() const { return source->length(); }
 	nframes_t samplerate() const { return source->samplerate(); }
 	void      seek (nframes_t pos) { source->seek (pos); }
+	nframes_t natural_position() const { return source->natural_position(); }
 	
 	static const uint32_t blocksize;
 	
Index: 2.0-ongoing-import-timestamp/libs/ardour/ardour/caimportable.h
===================================================================
--- 2.0-ongoing-import-timestamp/libs/ardour/ardour/caimportable.h	(revision 5338)
+++ 2.0-ongoing-import-timestamp/libs/ardour/ardour/caimportable.h	(working copy)
@@ -38,6 +38,7 @@
 	nframes_t length() const;
 	nframes_t samplerate() const;
 	void      seek (nframes_t pos);
+	nframes_t natural_position() const { return 0; }
 
    protected:
 	mutable CAAudioFile af;
Index: 2.0-ongoing-import-timestamp/libs/ardour/ardour/audiofilesource.h
===================================================================
--- 2.0-ongoing-import-timestamp/libs/ardour/ardour/audiofilesource.h	(revision 5338)
+++ 2.0-ongoing-import-timestamp/libs/ardour/ardour/audiofilesource.h	(working copy)
@@ -125,6 +125,8 @@
 
 	bool can_be_analysed() const { return _length > 0; } 
 
+	virtual void set_timeline_position (int64_t pos);
+
 	static bool find (Glib::ustring path, bool must_exist, bool embedded, bool& is_new, uint16_t& chan,
 			  Glib::ustring& found_path, std::string& found_name);
 
@@ -164,7 +166,6 @@
 
 	static uint64_t header_position_offset;
 
-	virtual void set_timeline_position (int64_t pos);
 	virtual void set_header_timeline_position () = 0;
 
 	bool removable() const;
Index: 2.0-ongoing-import-timestamp/libs/ardour/sndfileimportable.cc
===================================================================
--- 2.0-ongoing-import-timestamp/libs/ardour/sndfileimportable.cc	(revision 5338)
+++ 2.0-ongoing-import-timestamp/libs/ardour/sndfileimportable.cc	(working copy)
@@ -1,16 +1,43 @@
 #include <ardour/sndfileimportable.h>
 #include <sndfile.h>
 #include <iostream>
+#include <cstring>
 #include <string.h>
 
 using namespace ARDOUR;
 using namespace std;
 
+/* FIXME: this was copied from sndfilesource.cc, at some point these should be merged */
+int64_t
+SndFileImportableSource::get_timecode_info (SNDFILE* sf, SF_BROADCAST_INFO* binfo, bool& exists)
+{
+	if (sf_command (sf, SFC_GET_BROADCAST_INFO, binfo, sizeof (*binfo)) != SF_TRUE) {
+		exists = false;
+		return 0;
+	} 
+	
+	exists = true;
+	int64_t ret = (uint32_t) binfo->time_reference_high;
+	ret <<= 32;
+	ret |= (uint32_t) binfo->time_reference_low;
+	return ret;
+}
+
 SndFileImportableSource::SndFileImportableSource (const string& path)
 {
 	memset(&sf_info, 0 , sizeof(sf_info));
 	in.reset( sf_open(path.c_str(), SFM_READ, &sf_info), sf_close);
 	if (!in) throw failed_constructor();
+	
+	SF_BROADCAST_INFO binfo;
+	bool timecode_exists;
+
+	memset (&binfo, 0, sizeof (binfo));
+	timecode = get_timecode_info (in.get(), &binfo, timecode_exists);
+	
+	if (!timecode_exists) {
+		timecode = 0;
+	}
 }
 
 SndFileImportableSource::~SndFileImportableSource ()
@@ -48,3 +75,9 @@
 {
 	sf_seek (in.get(), 0, SEEK_SET);
 }
+
+nframes_t
+SndFileImportableSource::natural_position () const
+{
+	return timecode;
+}
Index: 2.0-ongoing-import-timestamp/libs/ardour/import.cc
===================================================================
--- 2.0-ongoing-import-timestamp/libs/ardour/import.cc	(revision 5338)
+++ 2.0-ongoing-import-timestamp/libs/ardour/import.cc	(working copy)
@@ -193,8 +193,11 @@
 
 static bool
 create_mono_sources_for_writing (const vector<string>& new_paths, Session& sess,
-		uint samplerate, vector<boost::shared_ptr<AudioFileSource> >& newfiles)
+		uint samplerate, vector<boost::shared_ptr<AudioFileSource> >& newfiles,
+		nframes_t timeline_position)
 {
+    boost::shared_ptr<AudioFileSource> afs;
+    
 	for (vector<string>::const_iterator i = new_paths.begin();
 			i != new_paths.end(); ++i)
 	{
@@ -215,7 +218,9 @@
 			return false;
 		}
 
-		newfiles.push_back(boost::dynamic_pointer_cast<AudioFileSource>(source));
+		afs = boost::dynamic_pointer_cast<AudioFileSource>(source);
+		afs->set_timeline_position(timeline_position);
+		newfiles.push_back(afs);
 	}
 	return true;
 }
@@ -337,7 +342,7 @@
 			fatal << "THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" << endl;
 			status.cancel = !map_existing_mono_sources (new_paths, *this, frame_rate(), newfiles, this);
 		} else {
-			status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles);
+			status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles, source->natural_position());
 		}
 
 		// copy on cancel/failure so that any files that were created will be removed below
@@ -366,7 +371,7 @@
 
 		for (AudioSources::iterator x = all_new_sources.begin(); x != all_new_sources.end(); ++x)
 		{
-			(*x)->update_header(0, *now, xnow);
+			(*x)->update_header((*x)->natural_position(), *now, xnow);
 			(*x)->done_with_peakfile_writes ();
 			
 			/* now that there is data there, requeue the file for analysis */

nickm

2009-07-08 18:14

reporter   ~0006405

New version that removes a spurious hunk

seablade

2009-07-08 18:48

manager   ~0006408

Assigned this one to Paul as well, thanks;)

    Seablade

paul

2009-07-09 12:20

administrator   ~0006411

nick - could you outline what you believe this fixes? i have reports of people importing @ file timestamp without problems, yet a casual reading of the patch suggests that it simply would not work at all without the fix.

nickm

2009-07-09 17:55

reporter   ~0006415

The motivation for this was importing wave files from a Pro Tools session. The files had a file timestamp that was visible in the import dialog - yet they would always end up at zero on the timeline.

I don't see how it could work without my patch as there are parts of the original code that were explicitly setting positions to zero eg

(*x)->update_header(0, *now, xnow);

in import.cc.

I tried to make it so that the created sources had the same natural position as the imported files, as if they had been recorded in ardour itself.

I can write a more detailed description if you want but it might take me a while to figure all this stuff out again :)

paul

2009-10-01 17:58

administrator   ~0006675

committed for 2.0-ongoing but needs reworking for 3.0

system

2020-04-19 20:13

developer   ~0021885

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-03-30 01:00 nickm New Issue
2009-03-30 01:00 nickm File Added: 2.0-ongoing-timestamp-2.patch
2009-07-08 18:06 nickm Note Added: 0006404
2009-07-08 18:06 nickm File Added: 2.0-ongoing-import-timestamp-5338.patch
2009-07-08 18:14 nickm File Added: 2.0-ongoing-import-timestamp-5338-v2.patch
2009-07-08 18:14 nickm Note Added: 0006405
2009-07-08 18:48 seablade Status new => assigned
2009-07-08 18:48 seablade Assigned To => paul
2009-07-08 18:48 seablade Note Added: 0006408
2009-07-09 12:20 paul Note Added: 0006411
2009-07-09 17:55 nickm Note Added: 0006415
2009-10-01 17:58 paul cost => 0.00
2009-10-01 17:58 paul Note Added: 0006675
2009-10-01 17:58 paul Status assigned => resolved
2009-10-01 17:58 paul Resolution open => fixed
2010-04-18 00:14 cth103 Relationship added related to 0002633
2010-04-24 10:28 cth103 Category bugs => bugs2
2010-04-24 10:31 cth103 Category bugs2 => bugs
2020-04-19 20:13 system Note Added: 0021885
2020-04-19 20:13 system Status resolved => closed