View Issue Details

IDProjectCategoryView StatusLast Update
0001533ardourbugspublic2007-09-05 09:11
Reporteroofus Assigned Tocth103  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
PlatformCentrino 1.6GHz LaptopOSLinuxOS VersionMandriva 2007
Summary0001533: Adding existing audio to tracks puts all of the selected files on the the first track of the range selected.
DescriptionWhen trying to embed multiple files at the same time, the regions representing the files all end up on the same track. I think the regions should be spread across the selected tracks.
Steps To Reproduce1. Select a range of track headers, say tracks 1-8.
2. From the Session menu, select Add existing audio -> to tracks.
3. From the resulting file browser, select 8 files to embed.
4. Click embed.
5. The regions representing the selected files will now all be on track 1 located at their time stamp position, if the files have time stamps.
TagsNo tags attached.

Activities

2007-03-07 17:20

 

mult-import-1 (10,657 bytes)   
Index: gtk2_ardour/editor_audio_import.cc
===================================================================
--- gtk2_ardour/editor_audio_import.cc	(revision 1560)
+++ gtk2_ardour/editor_audio_import.cc	(working copy)
@@ -57,20 +57,27 @@
 Editor::add_external_audio_action (ImportMode mode)
 {
 	nframes_t& pos = edit_cursor->current_frame;
-	AudioTrack* track = 0;
 
-	if (!selection->tracks.empty()) {
-		AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(selection->tracks.front());
+	/* list of audio tracks and the next position on each track to place a new sound file */
+	list<ImportTargetTrack> tracks;
+
+	for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
+		AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(*i);
 		if (atv) {
-			track = atv->audio_track();
+			tracks.push_back (make_pair (atv->audio_track(), pos));
 		}
 	}
 
-	bring_in_external_audio (mode, track, pos, false);
+	if (tracks.empty()) {
+		/* there aren't any tracks, so insert a dummy null one */
+		tracks.push_back (make_pair ( (AudioTrack *) 0, pos));
+	}
+
+	bring_in_external_audio (mode, tracks, false);
 }
 
 void
-Editor::bring_in_external_audio (ImportMode mode, AudioTrack* track, nframes_t& pos, bool prompt)
+Editor::bring_in_external_audio (ImportMode mode, list<ImportTargetTrack>& tracks, bool prompt)
 {
 	if (session == 0) {
 		MessageDialog msg (0, _("You can't import or embed an audiofile until you have a session loaded."));
@@ -83,11 +90,11 @@
 
 	switch (sfdb.run()) {
 	case SoundFileOmega::ResponseImport:
-		do_import (sfdb.get_paths(), sfdb.get_split(), sfdb.get_mode(), track, pos, prompt);
+		do_import (sfdb.get_paths(), sfdb.get_split(), sfdb.get_mode(), tracks, prompt);
 		break;
 		
 	case SoundFileOmega::ResponseEmbed:
-		do_embed (sfdb.get_paths(), sfdb.get_split(), sfdb.get_mode(), track, pos, prompt);
+		do_embed (sfdb.get_paths(), sfdb.get_split(), sfdb.get_mode(), tracks, prompt);
 		break;
 
 	default:
@@ -96,7 +103,7 @@
 }
 
 void
-Editor::do_import (vector<ustring> paths, bool split, ImportMode mode, AudioTrack* track, nframes_t& pos, bool prompt)
+Editor::do_import (vector<ustring> paths, bool split, ImportMode mode, list<ImportTargetTrack>& tracks, bool prompt)
 {
 	/* SFDB sets "multichan" to true to indicate "split channels"
 	   so reverse the setting to match the way libardour
@@ -111,24 +118,47 @@
 
 	vector<ustring> to_import;
 
+	list<ImportTargetTrack>::iterator track = tracks.begin();
 	for (vector<ustring>::iterator a = paths.begin(); a != paths.end(); ++a) {
 
 		to_import.clear ();
 		to_import.push_back (*a);
 
-		import_sndfile (to_import, mode, track, pos);
+		import_sndfile (to_import, mode, track);
+
+		list<ImportTargetTrack>::iterator tmp = track;
+		tmp++;
+		if (tmp != tracks.end()) {
+			track = tmp;
+		}
 	}
 
 	interthread_progress_window->hide_all ();
 }
 
+
+/**
+ *    Front end for main do_embed () for convenience to some callers.
+ */
+
 void
 Editor::do_embed (vector<ustring> paths, bool split, ImportMode mode, AudioTrack* track, nframes_t& pos, bool prompt)
 {
+	list<ImportTargetTrack> t;
+	t.push_back (make_pair (track, pos));
+	do_embed (paths, split, mode, t, prompt);
+	pos = t.front().second;
+}
+
+
+void
+Editor::do_embed (vector<ustring> paths, bool split, ImportMode mode, std::list<ImportTargetTrack>& tracks, bool prompt)
+{
 	bool multiple_files = paths.size() > 1;
 	bool check_sample_rate = true;
 	vector<ustring>::iterator a;
 
+	std::list<ImportTargetTrack>::iterator track = tracks.begin();
 	for (a = paths.begin(); a != paths.end(); ) {
 
 		cerr << "Considering embed of " << (*a) << endl;
@@ -178,7 +208,7 @@
 				
 				/* keep them paired */
 
-				if (embed_sndfile (to_embed, split, multiple_files, check_sample_rate, mode, track, pos, prompt) < -1) {
+				if (embed_sndfile (to_embed, split, multiple_files, check_sample_rate, mode, track, prompt) < -1) {
 					break;
 				}
 
@@ -193,7 +223,7 @@
 					foo.clear ();
 					foo.push_back (*x);
 
-					if (embed_sndfile (foo, split, multiple_files, check_sample_rate, mode, track, pos, prompt) < -1) {
+					if (embed_sndfile (foo, split, multiple_files, check_sample_rate, mode, track, prompt) < -1) {
 						break;
 					}
 				}
@@ -201,10 +231,18 @@
 
 		} else {
 			
-			if (embed_sndfile (to_embed, split, multiple_files, check_sample_rate, mode, track, pos, prompt) < -1) {
+			if (embed_sndfile (to_embed, split, multiple_files, check_sample_rate, mode, track, prompt) < -1) {
 				break;
 			}
 		}
+
+		list<ImportTargetTrack>::iterator tmp = track;
+		tmp++;
+		if (tmp != tracks.end()) {
+			track = tmp;
+		}
+
+		
 	}
 	
 	if (a == paths.end()) {
@@ -213,7 +251,7 @@
 }
 
 int
-Editor::import_sndfile (vector<ustring> paths, ImportMode mode, AudioTrack* track, nframes_t& pos)
+Editor::import_sndfile (vector<ustring> paths, ImportMode mode, std::list<ImportTargetTrack>::iterator track)
 {
 	interthread_progress_window->set_title (string_compose (_("ardour: importing %1"), paths.front()));
 	interthread_progress_window->set_position (Gtk::WIN_POS_MOUSE);
@@ -254,7 +292,7 @@
 	
 	if (!import_status.new_regions.empty()) {
 		boost::shared_ptr<AudioRegion> region (import_status.new_regions.front());
-		finish_bringing_in_audio (region, region->n_channels(), region->n_channels(), track, pos, mode);
+		finish_bringing_in_audio (region, region->n_channels(), region->n_channels(), track, mode);
 	}
 
 	track_canvas.get_window()->set_cursor (*current_canvas_cursor);
@@ -263,7 +301,7 @@
 
 int
 Editor::embed_sndfile (vector<Glib::ustring> paths, bool split, bool multiple_files, bool& check_sample_rate, ImportMode mode, 
-		       AudioTrack* track, nframes_t& pos, bool prompt)
+		       list<ImportTargetTrack>::iterator track, bool prompt)
 {
 	boost::shared_ptr<AudioFileSource> source;
 	SourceList sources;
@@ -393,7 +431,7 @@
 	}
 
 	if (sources[0]->natural_position() != 0) {
-		pos = sources[0]->natural_position();
+		track->second = sources[0]->natural_position();
 	} 
 
 	region_name = region_name_from_path (paths.front(), (sources.size() > 1));
@@ -407,7 +445,7 @@
 		output_chan = input_chan;
 	}
 
-	finish_bringing_in_audio (region, input_chan, output_chan, track, pos, mode);
+	finish_bringing_in_audio (region, input_chan, output_chan, track, mode);
 	
   out:
 	track_canvas.get_window()->set_cursor (*current_canvas_cursor);
@@ -415,7 +453,7 @@
 }
 
 int
-Editor::finish_bringing_in_audio (boost::shared_ptr<AudioRegion> region, uint32_t in_chans, uint32_t out_chans, AudioTrack* track, nframes_t& pos, ImportMode mode)
+Editor::finish_bringing_in_audio (boost::shared_ptr<AudioRegion> region, uint32_t in_chans, uint32_t out_chans, std::list<ImportTargetTrack>::iterator track, ImportMode mode)
 {
 	switch (mode) {
 	case ImportAsRegion:
@@ -423,17 +461,17 @@
 		break;
 		
 	case ImportToTrack:
-		if (track) {
-			boost::shared_ptr<Playlist> playlist = track->diskstream()->playlist();
+		if (track->first) {
+			boost::shared_ptr<Playlist> playlist = track->first->diskstream()->playlist();
 			
 			boost::shared_ptr<AudioRegion> copy (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region)));
 			begin_reversible_command (_("insert sndfile"));
                         XMLNode &before = playlist->get_state();
-			playlist->add_region (copy, pos);
+			playlist->add_region (copy, track->second);
 			session->add_command (new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
 			commit_reversible_command ();
 
-			pos += region->length();
+			track->second += region->length();
 		}
 		break;
 		
@@ -442,7 +480,7 @@
 		list<boost::shared_ptr<AudioTrack> > at (session->new_audio_track (in_chans, out_chans, Normal, 1));
 		if (!at.empty()) {
 			boost::shared_ptr<AudioRegion> copy (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region)));
-			at.front()->diskstream()->playlist()->add_region (copy, pos);
+			at.front()->diskstream()->playlist()->add_region (copy, track->second);
 		}
 		break;
 	}
@@ -452,7 +490,7 @@
 		list<boost::shared_ptr<AudioTrack> > at (session->new_audio_track (in_chans, out_chans, Destructive));
 		if (!at.empty()) {
 			boost::shared_ptr<AudioRegion> copy (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region)));
-			at.front()->diskstream()->playlist()->add_region (copy, pos);
+			at.front()->diskstream()->playlist()->add_region (copy, track->second);
 		}
 		break;
 	}
Index: gtk2_ardour/editor.h
===================================================================
--- gtk2_ardour/editor.h	(revision 1560)
+++ gtk2_ardour/editor.h	(working copy)
@@ -76,6 +76,7 @@
 	class Session;
 	class AudioFilter;
 	class Crossfade;
+	class AudioTrack;
 }
 
 namespace LADSPA {
@@ -955,13 +956,16 @@
 
 	void add_external_audio_action (Editing::ImportMode);
 
-	void bring_in_external_audio (Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes_t& pos, bool prompt);
-	void do_import (vector<Glib::ustring> paths, bool split, Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes_t&, bool);
-	void do_embed (vector<Glib::ustring> paths, bool split, Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes_t&, bool);
-	int  import_sndfile (vector<Glib::ustring> paths, Editing::ImportMode mode, ARDOUR::AudioTrack* track, nframes_t& pos);
+	typedef std::pair<ARDOUR::AudioTrack*, nframes_t> ImportTargetTrack;
+
+	void bring_in_external_audio (Editing::ImportMode mode, std::list<ImportTargetTrack>&, bool prompt);
+	void do_import (vector<Glib::ustring> paths, bool split, Editing::ImportMode mode, std::list<ImportTargetTrack>&, bool);
+	void do_embed (vector<Glib::ustring> paths, bool split, Editing::ImportMode mode, std::list<ImportTargetTrack>&, bool);
+	void do_embed (vector<Glib::ustring> paths, bool split, Editing::ImportMode mode, ARDOUR::AudioTrack* track, nframes_t& pos, bool);
+	int  import_sndfile (vector<Glib::ustring> paths, Editing::ImportMode mode, std::list<ImportTargetTrack>::iterator track);
 	int  embed_sndfile (vector<Glib::ustring> paths, bool split, bool multiple_files, bool& check_sample_rate, Editing::ImportMode mode, 
-			    ARDOUR::AudioTrack* track, nframes_t& pos, bool prompt);
-	int finish_bringing_in_audio (boost::shared_ptr<ARDOUR::AudioRegion> region, uint32_t, uint32_t, ARDOUR::AudioTrack* track, nframes_t& pos, Editing::ImportMode mode);
+			    std::list<ImportTargetTrack>::iterator track, bool prompt);
+	int finish_bringing_in_audio (boost::shared_ptr<ARDOUR::AudioRegion> region, uint32_t, uint32_t, std::list<ImportTargetTrack>::iterator track, Editing::ImportMode mode);
 
 	/* generic interthread progress window */
mult-import-1 (10,657 bytes)   

cth103

2007-03-07 17:21

administrator   ~0003529

Hi,

The attached patch should fix this, so that imported audio files are added to as many tracks as are selected. Would you like to give it a try and see what you think?

Carl

paul

2007-03-09 13:26

administrator   ~0003544

carl, not sure why you wanted to pair up (track,position) pairs ...

the patch looks ok, although the null pointer trick worries me just a little. this is probably fine, since in the near term future i'd like to change the workflow for import/embed anyway so that it will not be possible to get to that point without knowing which tracks are the target.

chris, will wait for your confirmation on this one.

cth103

2007-03-09 13:44

administrator   ~0003549

I think the pairing of ( track, position ) was the neatest way I could think of to cope with the fact that if there are enough tracks you'll want to put each new region at the same time on each track, but if there aren't enough you'll want to put the regions one after another on the same track. As it has turned out you probably don't need a position per track, but instead you need to know when updating pos whether or not you've got enough tracks.

Hmm.

I agree that the null pointer trick is quite unpleasant; it would perhaps be neater if you had the tracks ready before doing the import, but then I suppose if the import subsequently fails you end up with empty tracks lying about. The null pointer in the list is basically an extension of how things used to be done, passing a null pointer in to signify "no selected track".

oofus

2007-03-10 14:34

developer   ~0003554

I haven't tried the patch yet, but .......
From my point of view (and I could just be being selfish !) If I selected more files than tracks then only the number of files equalling the number of selected tracks should be embedded, each onto one of the selected tracks. Any more files are just ignored. If the files have no time stamp, then they should be positioned at the Edit Cursor. I wouldn't want the files embedded one after the other on the same track. Somebody else may though. If Importing/Embedding is to change in the future, then these options could be considered.

If only one track has been selected, then I suppose multiple files could be embedded one after the other on the same track. But, as soon as more than one track is selected files shouldn't be embedded one after the other (ignore more files, as described above).

oofus

2007-09-05 09:11

developer   ~0004335

A new import dialogue has been implemented. This problem is no longer relevant.

Issue History

Date Modified Username Field Change
2007-03-06 10:21 oofus New Issue
2007-03-07 17:20 cth103 File Added: mult-import-1
2007-03-07 17:20 cth103 Status new => assigned
2007-03-07 17:20 cth103 Assigned To => cth103
2007-03-07 17:21 cth103 Note Added: 0003529
2007-03-07 17:21 cth103 Status assigned => feedback
2007-03-09 13:26 paul Note Added: 0003544
2007-03-09 13:44 cth103 Note Added: 0003549
2007-03-10 14:34 oofus Note Added: 0003554
2007-09-05 09:11 oofus Status feedback => closed
2007-09-05 09:11 oofus Note Added: 0004335
2007-09-05 09:11 oofus Resolution open => fixed