handle multiple imports of the same file better (via better source naming); make...
[ardour.git] / gtk2_ardour / editor_audio_import.cc
1 /*
2     Copyright (C) 2000-2006 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <sys/time.h>
23 #include <errno.h>
24 #include <unistd.h>
25 #include <algorithm>
26
27 #include <sndfile.h>
28
29 #include "pbd/pthread_utils.h"
30 #include "pbd/basename.h"
31 #include "pbd/shortpath.h"
32 #include "pbd/stateful_diff_command.h"
33
34 #include <gtkmm2ext/choice.h>
35
36 #include "ardour/session.h"
37 #include "ardour/session_directory.h"
38 #include "ardour/audioplaylist.h"
39 #include "ardour/audioregion.h"
40 #include "ardour/audio_diskstream.h"
41 #include "ardour/midi_track.h"
42 #include "ardour/midi_region.h"
43 #include "ardour/utils.h"
44 #include "ardour/audio_track.h"
45 #include "ardour/audioplaylist.h"
46 #include "ardour/audiofilesource.h"
47 #include "ardour/region_factory.h"
48 #include "ardour/source_factory.h"
49 #include "ardour/session.h"
50 #include "ardour/smf_source.h"
51 #include "pbd/memento_command.h"
52
53 #include "ardour_ui.h"
54 #include "editor.h"
55 #include "sfdb_ui.h"
56 #include "editing.h"
57 #include "audio_time_axis.h"
58 #include "midi_time_axis.h"
59 #include "session_import_dialog.h"
60 #include "utils.h"
61 #include "gui_thread.h"
62 #include "interthread_progress_window.h"
63
64 #include "i18n.h"
65
66 using namespace std;
67 using namespace ARDOUR;
68 using namespace PBD;
69 using namespace Gtk;
70 using namespace Gtkmm2ext;
71 using namespace Editing;
72 using std::string;
73
74 /* Functions supporting the incorporation of external (non-captured) audio material into ardour */
75
76 void
77 Editor::add_external_audio_action (ImportMode mode_hint)
78 {
79         if (_session == 0) {
80                 MessageDialog msg (_("You can't import or embed an audiofile until you have a session loaded."));
81                 msg.run ();
82                 return;
83         }
84         
85         if (sfbrowser == 0) {
86                 sfbrowser = new SoundFileOmega (*this, _("Add Existing Media"), _session, 0, true, mode_hint);
87         } else {
88                 sfbrowser->set_mode (mode_hint);
89         }
90
91         external_audio_dialog ();
92 }
93
94 void
95 Editor::external_audio_dialog ()
96 {
97         vector<string> paths;
98         uint32_t track_cnt;
99
100         if (_session == 0) {
101                 MessageDialog msg (_("You can't import or embed an audiofile until you have a session loaded."));
102                 msg.run ();
103                 return;
104         }
105
106         track_cnt = 0;
107
108         for (TrackSelection::iterator x = selection->tracks.begin(); x != selection->tracks.end(); ++x) {
109                 AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(*x);
110
111                 if (!atv) {
112                         continue;
113                 } else if (atv->is_audio_track()) {
114                         track_cnt++;
115                 }
116         }
117
118         if (sfbrowser == 0) {
119                 sfbrowser = new SoundFileOmega (*this, _("Add Existing Media"), _session, track_cnt, true);
120         } else {
121                 sfbrowser->reset (track_cnt);
122         }
123
124         sfbrowser->show_all ();
125
126
127         bool keepRunning;
128
129         do {
130                 keepRunning = false;
131
132                 int response = sfbrowser->run ();
133
134                 switch (response) {
135                         case RESPONSE_APPLY:
136                                 // leave the dialog open
137                                 break;
138
139                         case RESPONSE_OK:
140                                 sfbrowser->hide ();
141                                 break;
142
143                         default:
144                                 // cancel from the browser - we are done
145                                 sfbrowser->hide ();
146                                 return;
147                 }
148
149                 /* lets do it */
150
151                 vector<string> upaths = sfbrowser->get_paths ();
152                 for (vector<string>::iterator x = upaths.begin(); x != upaths.end(); ++x) {
153                         paths.push_back (*x);
154                 }
155                 
156                 ImportPosition pos = sfbrowser->get_position ();
157                 ImportMode mode = sfbrowser->get_mode ();
158                 ImportDisposition chns = sfbrowser->get_channel_disposition ();
159                 framepos_t where;
160
161                 switch (pos) {
162                         case ImportAtEditPoint:
163                                 where = get_preferred_edit_position ();
164                                 break;
165                         case ImportAtTimestamp:
166                                 where = -1;
167                                 break;
168                         case ImportAtPlayhead:
169                                 where = playhead_cursor->current_frame;
170                                 break;
171                         case ImportAtStart:
172                                 where = _session->current_start_frame();
173                                 break;
174                 }
175
176                 SrcQuality quality = sfbrowser->get_src_quality();
177
178
179                 if (sfbrowser->copy_files_btn.get_active()) {
180                         do_import (paths, chns, mode, quality, where);
181                 } else {
182                         do_embed (paths, chns, mode, where);
183                 }
184
185                 if (response == RESPONSE_APPLY) {
186                         sfbrowser->clear_selection ();
187                         keepRunning = true;
188                 }
189
190         } while (keepRunning);
191 }
192
193 void
194 Editor::session_import_dialog ()
195 {
196         SessionImportDialog dialog (_session);
197         ensure_float (dialog);
198         dialog.run ();
199 }
200
201 typedef std::map<PBD::ID,boost::shared_ptr<ARDOUR::Source> > SourceMap;
202
203 /**
204  * Updating is still disabled, see note in libs/ardour/import.cc Session::import_audiofiles()
205  *
206  * all_or_nothing:
207  *   true  = show "Update", "Import" and "Skip"
208  *   false = show "Import", and "Cancel"
209  *
210  * Returns:
211  *     0  To update an existing source of the same name
212  *     1  To import/embed the file normally (make sure the new name will be unique)
213  *     2  If the user wants to skip this file
214  **/
215 int
216 Editor::check_whether_and_how_to_import(string path, bool all_or_nothing)
217 {
218         string wave_name (Glib::path_get_basename(path));
219
220         SourceMap all_sources = _session->get_sources();
221         bool already_exists = false;
222         uint32_t existing;
223
224         if ((existing = _session->count_sources_by_origin (path)) > 0) {
225                 already_exists = true;
226         }
227
228         int function = 1;
229
230         if (already_exists) {
231                 string message;
232                 if (all_or_nothing) {
233                         // updating is still disabled
234                         //message = string_compose(_("The session already contains a source file named %1. Do you want to update that file (and thus all regions using the file) or import this file as a new file?"),wave_name);
235                         message = string_compose (_("The session already contains a source file named %1.  Do you want to import %1 as a new file, or skip it?"), wave_name);
236                 } else {
237                         message = string_compose (_("The session already contains a source file named %1.  Do you want to import %2 as a new source, or skip it?"), wave_name, wave_name);
238
239                 }
240                 MessageDialog dialog(message, false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_NONE, true);
241
242                 if (all_or_nothing) {
243                         // disabled
244                         //dialog.add_button("Update", 0);
245                         dialog.add_button("Import", 1);
246                         dialog.add_button("Skip",   2);
247                 } else {
248                         dialog.add_button("Import", 1);
249                         dialog.add_button("Cancel", 2);
250                 }
251
252                 //dialog.add_button("Skip all", 4); // All or rest?
253
254                 dialog.show();
255
256                 function = dialog.run ();
257
258                 dialog.hide();
259         }
260
261         return function;
262 }
263
264 boost::shared_ptr<AudioTrack>
265 Editor::get_nth_selected_audio_track (int nth) const
266 {
267         AudioTimeAxisView* atv;
268         TrackSelection::iterator x;
269
270         for (x = selection->tracks.begin(); nth > 0 && x != selection->tracks.end(); ++x) {
271
272                 atv = dynamic_cast<AudioTimeAxisView*>(*x);
273
274                 if (!atv) {
275                         continue;
276                 } else if (atv->is_audio_track()) {
277                         --nth;
278                 }
279         }
280
281         if (x == selection->tracks.end()) {
282                 atv = dynamic_cast<AudioTimeAxisView*>(selection->tracks.back());
283         } else {
284                 atv = dynamic_cast<AudioTimeAxisView*>(*x);
285         }
286
287         if (!atv || !atv->is_audio_track()) {
288                 return boost::shared_ptr<AudioTrack>();
289         }
290
291         return atv->audio_track();
292 }
293
294 boost::shared_ptr<MidiTrack>
295 Editor::get_nth_selected_midi_track (int nth) const
296 {
297         MidiTimeAxisView* mtv;
298         TrackSelection::iterator x;
299
300         for (x = selection->tracks.begin(); nth > 0 && x != selection->tracks.end(); ++x) {
301
302                 mtv = dynamic_cast<MidiTimeAxisView*>(*x);
303
304                 if (!mtv) {
305                         continue;
306                 } else if (mtv->is_midi_track()) {
307                         --nth;
308                 }
309         }
310
311         if (x == selection->tracks.end()) {
312                 mtv = dynamic_cast<MidiTimeAxisView*>(selection->tracks.back());
313         } else {
314                 mtv = dynamic_cast<MidiTimeAxisView*>(*x);
315         }
316
317         if (!mtv || !mtv->is_midi_track()) {
318                 return boost::shared_ptr<MidiTrack>();
319         }
320
321         return mtv->midi_track();
322 }
323
324 void
325 Editor::do_import (vector<string> paths, ImportDisposition chns, ImportMode mode, SrcQuality quality, framepos_t& pos)
326 {
327         boost::shared_ptr<Track> track;
328         vector<string> to_import;
329         int nth = 0;
330         bool use_timestamp = (pos == -1);
331
332         current_interthread_info = &import_status;
333         import_status.current = 1;
334         import_status.total = paths.size ();
335         import_status.all_done = false;
336
337         ImportProgressWindow ipw (&import_status, _("Import"), _("Cancel Import"));
338
339         bool ok = true;
340
341         if (chns == Editing::ImportMergeFiles) {
342
343                 /* create 1 region from all paths, add to 1 track,
344                    ignore "track"
345                 */
346
347                 bool cancel = false;
348                 for (vector<string>::iterator a = paths.begin(); a != paths.end(); ++a) {
349                         int check = check_whether_and_how_to_import(*a, false);
350                         if (check == 2) {
351                                 cancel = true;
352                                 break;
353                         }
354                 }
355
356                 if (cancel) {
357                         ok = false;
358                 } else {
359                         ipw.show ();
360                         ok = (import_sndfiles (paths, mode, quality, pos, 1, 1, track, false) == 0);
361                 }
362
363         } else {
364
365                 bool replace = false;
366
367                 for (vector<string>::iterator a = paths.begin(); a != paths.end(); ++a) {
368
369                         const int check = check_whether_and_how_to_import (*a, true);
370                         
371                         switch (check) {
372                         case 2:
373                                 // user said skip
374                                 continue;
375                         case 0:
376                                 fatal << "Updating existing sources should be disabled!" << endmsg;
377                                 /* NOTREACHED*/
378                                 break;
379                         case 1:
380                                 replace = false;
381                                 break;
382                         default:
383                                 fatal << "Illegal return " << check <<  " from check_whether_and_how_to_import()!" << endmsg;
384                                 /* NOTREACHED*/
385                         }
386
387                         /* have to reset this for every file we handle */
388                         
389                         if (use_timestamp) {
390                                 pos = -1;
391                         }
392
393                         ipw.show ();
394                                 
395                         switch (chns) {
396                         case Editing::ImportDistinctFiles:
397                                 
398                                 to_import.clear ();
399                                 to_import.push_back (*a);
400                                 
401                                 if (mode == Editing::ImportToTrack) {
402                                         track = get_nth_selected_audio_track (nth++);
403                                 }
404                         
405                                 ok = (import_sndfiles (to_import, mode, quality, pos, 1, -1, track, replace) == 0);
406                                 break;
407                                 
408                         case Editing::ImportDistinctChannels:
409                                 
410                                 to_import.clear ();
411                                 to_import.push_back (*a);
412                                 
413                                 ok = (import_sndfiles (to_import, mode, quality, pos, -1, -1, track, replace) == 0);
414                                 break;
415                                 
416                         case Editing::ImportSerializeFiles:
417                                 
418                                 to_import.clear ();
419                                 to_import.push_back (*a);
420
421                                 ok = (import_sndfiles (to_import, mode, quality, pos, 1, 1, track, replace) == 0);
422                                 break;
423
424                         case Editing::ImportMergeFiles:
425                                 // Not entered, handled in earlier if() branch
426                                 break;
427                         }
428                 }
429         }
430
431         if (ok) {
432                 _session->save_state ("");
433         }
434
435         import_status.all_done = true;
436 }
437
438 void
439 Editor::do_embed (vector<string> paths, ImportDisposition chns, ImportMode mode, framepos_t& pos)
440 {
441         boost::shared_ptr<Track> track;
442         bool check_sample_rate = true;
443         bool ok = false;
444         vector<string> to_embed;
445         bool multi = paths.size() > 1;
446         int nth = 0;
447
448         switch (chns) {
449         case Editing::ImportDistinctFiles:
450                 for (vector<string>::iterator a = paths.begin(); a != paths.end(); ++a) {
451
452                         to_embed.clear ();
453                         to_embed.push_back (*a);
454
455                         if (mode == Editing::ImportToTrack) {
456                                 track = get_nth_selected_audio_track (nth++);
457                         }
458
459                         if (embed_sndfiles (to_embed, multi, check_sample_rate, mode, pos, 1, -1, track) < -1) {
460                                 goto out;
461                         }
462                 }
463                 break;
464
465         case Editing::ImportDistinctChannels:
466                 for (vector<string>::iterator a = paths.begin(); a != paths.end(); ++a) {
467
468                         to_embed.clear ();
469                         to_embed.push_back (*a);
470
471                         if (embed_sndfiles (to_embed, multi, check_sample_rate, mode, pos, -1, -1, track) < -1) {
472                                 goto out;
473                         }
474                 }
475                 break;
476
477         case Editing::ImportMergeFiles:
478                 if (embed_sndfiles (paths, multi, check_sample_rate, mode, pos, 1, 1, track) < -1) {
479                         goto out;
480                 }
481                 break;
482
483         case Editing::ImportSerializeFiles:
484                 for (vector<string>::iterator a = paths.begin(); a != paths.end(); ++a) {
485
486                         to_embed.clear ();
487                         to_embed.push_back (*a);
488
489                         if (embed_sndfiles (to_embed, multi, check_sample_rate, mode, pos, 1, 1, track) < -1) {
490                                 goto out;
491                         }
492                 }
493                 break;
494         }
495
496         ok = true;
497
498   out:
499         if (ok) {
500                 _session->save_state ("");
501         }
502 }
503
504 int
505 Editor::import_sndfiles (vector<string> paths, ImportMode mode, SrcQuality quality, framepos_t& pos,
506                          int target_regions, int target_tracks, boost::shared_ptr<Track>& track, bool replace)
507 {
508         import_status.paths = paths;
509         import_status.done = false;
510         import_status.cancel = false;
511         import_status.freeze = false;
512         import_status.quality = quality;
513         import_status.replace_existing_source = replace;
514
515         import_status.mode = mode;
516         import_status.pos = pos;
517         import_status.target_tracks = target_tracks;
518         import_status.target_regions = target_regions;
519         import_status.track = track;
520         import_status.replace = replace;
521         
522         set_canvas_cursor (wait_cursor);
523         gdk_flush ();
524
525         /* start import thread for this spec. this will ultimately call Session::import_audiofiles()
526            which, if successful, will add the files as regions to the region list. its up to us
527            (the GUI) to direct additional steps after that.
528         */
529
530         pthread_create_and_store ("import", &import_status.thread, _import_thread, this);
531         pthread_detach (import_status.thread);
532
533         while (!import_status.done && !import_status.cancel) {
534                 gtk_main_iteration ();
535         }
536
537         import_status.done = true;
538
539         int result = -1;
540
541         if (!import_status.cancel && !import_status.sources.empty()) {
542                 result = add_sources (
543                         import_status.paths,
544                         import_status.sources,
545                         import_status.pos,
546                         import_status.mode,
547                         import_status.target_regions,
548                         import_status.target_tracks,
549                         track, false
550                         );
551
552                 /* update position from results */
553
554                 pos = import_status.pos;
555         }
556
557         set_canvas_cursor (current_canvas_cursor);
558         return result;
559 }
560
561 int
562 Editor::embed_sndfiles (vector<string> paths, bool multifile,
563                         bool& check_sample_rate, ImportMode mode, framepos_t& pos, int target_regions, int target_tracks,
564                         boost::shared_ptr<Track>& track)
565 {
566         boost::shared_ptr<AudioFileSource> source;
567         SourceList sources;
568         string linked_path;
569         SoundFileInfo finfo;
570         int ret = 0;
571
572         set_canvas_cursor (wait_cursor);
573         gdk_flush ();
574
575         for (vector<string>::iterator p = paths.begin(); p != paths.end(); ++p) {
576
577                 string path = *p;
578                 string error_msg;
579
580                 /* note that we temporarily truncated _id at the colon */
581
582                 if (!AudioFileSource::get_soundfile_info (path, finfo, error_msg)) {
583                         error << string_compose(_("Editor: cannot open file \"%1\", (%2)"), path, error_msg ) << endmsg;
584                         goto out;
585                 }
586
587                 if (check_sample_rate  && (finfo.samplerate != (int) _session->frame_rate())) {
588                         vector<string> choices;
589
590                         if (multifile) {
591                                 choices.push_back (_("Cancel entire import"));
592                                 choices.push_back (_("Don't embed it"));
593                                 choices.push_back (_("Embed all without questions"));
594
595                                 Gtkmm2ext::Choice rate_choice (
596                                         _("Sample rate"),
597                                         string_compose (_("%1\nThis audiofile's sample rate doesn't match the session sample rate!"),
598                                                         short_path (path, 40)),
599                                         choices, false
600                                         );
601
602                                 int resx = rate_choice.run ();
603
604                                 switch (resx) {
605                                 case 0: /* stop a multi-file import */
606                                         ret = -2;
607                                         goto out;
608                                 case 1: /* don't embed this one */
609                                         ret = -1;
610                                         goto out;
611                                 case 2: /* do it, and the rest without asking */
612                                         check_sample_rate = false;
613                                         break;
614                                 case 3: /* do it */
615                                         break;
616                                 default:
617                                         ret = -2;
618                                         goto out;
619                                 }
620                         } else {
621                                 choices.push_back (_("Cancel"));
622                                 choices.push_back (_("Embed it anyway"));
623
624                                 Gtkmm2ext::Choice rate_choice (
625                                         _("Sample rate"),
626                                         string_compose (_("%1\nThis audiofile's sample rate doesn't match the session sample rate!"), path),
627                                         choices, false
628                                         );
629
630                                 int resx = rate_choice.run ();
631
632                                 switch (resx) {
633                                 case 0: /* don't import */
634                                         ret = -1;
635                                         goto out;
636                                 case 1: /* do it */
637                                         break;
638                                 default:
639                                         ret = -2;
640                                         goto out;
641                                 }
642                         }
643                 }
644
645                 set_canvas_cursor (wait_cursor);
646
647                 for (int n = 0; n < finfo.channels; ++n) {
648                         try {
649
650                                 /* check if we have this thing embedded already */
651
652                                 boost::shared_ptr<Source> s;
653
654                                 if ((s = _session->source_by_path_and_channel (path, n)) == 0) {
655
656                                         source = boost::dynamic_pointer_cast<AudioFileSource> (
657                                                 SourceFactory::createReadable (DataType::AUDIO, *_session,
658                                                                                path, n,
659                                                                                (mode == ImportAsTapeTrack
660                                                                                 ? Source::Destructive
661                                                                                 : Source::Flag (0)),
662                                                                         true, true));
663                                 } else {
664                                         source = boost::dynamic_pointer_cast<AudioFileSource> (s);
665                                 }
666
667                                 sources.push_back(source);
668                         }
669
670                         catch (failed_constructor& err) {
671                                 error << string_compose(_("could not open %1"), path) << endmsg;
672                                 goto out;
673                         }
674
675                         ARDOUR_UI::instance()->flush_pending ();
676                 }
677         }
678
679         if (sources.empty()) {
680                 goto out;
681         }
682
683         ret = add_sources (paths, sources, pos, mode, target_regions, target_tracks, track, true);
684
685   out:
686         set_canvas_cursor (current_canvas_cursor);
687         return ret;
688 }
689
690 int
691 Editor::add_sources (vector<string> paths, SourceList& sources, framepos_t& pos, ImportMode mode,
692                      int target_regions, int target_tracks, boost::shared_ptr<Track>& track, bool /*add_channel_suffix*/)
693 {
694         vector<boost::shared_ptr<Region> > regions;
695         string region_name;
696         uint32_t input_chan = 0;
697         uint32_t output_chan = 0;
698         bool use_timestamp;
699
700         use_timestamp = (pos == -1);
701
702         // kludge (for MIDI we're abusing "channel" for "track" here)
703         if (SMFSource::safe_midi_file_extension (paths.front())) {
704                 target_regions = -1;
705         }
706
707         if (target_regions == 1) {
708
709                 /* take all the sources we have and package them up as a region */
710
711                 region_name = region_name_from_path (paths.front(), (sources.size() > 1), false);
712
713                 /* we checked in import_sndfiles() that there were not too many */
714
715                 while (RegionFactory::region_by_name (region_name)) {
716                         region_name = bump_name_once (region_name, '.');
717                 }
718
719                 PropertyList plist; 
720                 
721                 plist.add (ARDOUR::Properties::start, 0);
722                 plist.add (ARDOUR::Properties::length, sources[0]->length (pos));
723                 plist.add (ARDOUR::Properties::name, region_name);
724                 plist.add (ARDOUR::Properties::layer, 0);
725                 plist.add (ARDOUR::Properties::whole_file, true);
726                 plist.add (ARDOUR::Properties::external, true);
727
728                 boost::shared_ptr<Region> r = RegionFactory::create (sources, plist);
729
730                 if (use_timestamp && boost::dynamic_pointer_cast<AudioRegion>(r)) {
731                         boost::dynamic_pointer_cast<AudioRegion>(r)->special_set_position(sources[0]->natural_position());
732                 }
733
734                 regions.push_back (r);
735
736
737         } else if (target_regions == -1 || target_regions > 1) {
738
739                 /* take each source and create a region for each one */
740
741                 SourceList just_one;
742                 SourceList::iterator x;
743                 uint32_t n;
744
745                 for (n = 0, x = sources.begin(); x != sources.end(); ++x, ++n) {
746
747                         just_one.clear ();
748                         just_one.push_back (*x);
749
750                         region_name = region_name_from_path ((*x)->path(), false, false, sources.size(), n);
751
752                         PropertyList plist; 
753                         
754                         plist.add (ARDOUR::Properties::start, 0);
755                         plist.add (ARDOUR::Properties::length, (*x)->length (pos));
756                         plist.add (ARDOUR::Properties::name, region_name);
757                         plist.add (ARDOUR::Properties::layer, 0);
758                         plist.add (ARDOUR::Properties::whole_file, true);
759                         plist.add (ARDOUR::Properties::external, true);
760
761                         boost::shared_ptr<Region> r = RegionFactory::create (just_one, plist);
762
763                         if (use_timestamp && boost::dynamic_pointer_cast<AudioRegion>(r)) {
764                                 boost::dynamic_pointer_cast<AudioRegion>(r)->special_set_position((*x)->natural_position());
765                         }
766
767                         regions.push_back (r);
768                 }
769         }
770
771         if (target_regions == 1) {
772                 input_chan = regions.front()->n_channels();
773         } else {
774                 if (target_tracks == 1) {
775                         input_chan = regions.size();
776                 } else {
777                         input_chan = 1;
778                 }
779         }
780
781         if (Config->get_output_auto_connect() & AutoConnectMaster) {
782                 output_chan = (_session->master_out() ? _session->master_out()->n_inputs().n_audio() : input_chan);
783         } else {
784                 output_chan = input_chan;
785         }
786
787         int n = 0;
788         framepos_t rlen = 0;
789
790         for (vector<boost::shared_ptr<Region> >::iterator r = regions.begin(); r != regions.end(); ++r, ++n) {
791                 
792                 boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (*r);
793                 
794                 if (use_timestamp && ar) {
795                         
796                         /* get timestamp for this region */
797
798                         const boost::shared_ptr<Source> s (ar->sources().front());
799                         const boost::shared_ptr<AudioSource> as = boost::dynamic_pointer_cast<AudioSource> (s);
800                         
801                         assert (as);
802                         
803                         if (as->natural_position() != 0) {
804                                 pos = as->natural_position();
805                         } else if (target_tracks == 1) {
806                                 /* hmm, no timestamp available, put it after the previous region
807                                  */
808                                 if (n == 0) {
809                                         pos = get_preferred_edit_position ();
810                                 } else {
811                                         pos += rlen;
812                                 }
813                         } else {
814                                 pos = get_preferred_edit_position ();
815                         }
816                                 
817                 }
818
819                 finish_bringing_in_material (*r, input_chan, output_chan, pos, mode, track);
820
821                 rlen = (*r)->length();
822                 
823                 if (target_tracks != 1) {
824                         track.reset ();
825                 } else { 
826                         if (!use_timestamp || !ar) {
827                                 /* line each one up right after the other */
828                                 pos += (*r)->length();
829                         }
830                 }
831         }
832
833         /* setup peak file building in another thread */
834
835         for (SourceList::iterator x = sources.begin(); x != sources.end(); ++x) {
836                 SourceFactory::setup_peakfile (*x, true);
837         }
838
839         return 0;
840 }
841
842 int
843 Editor::finish_bringing_in_material (boost::shared_ptr<Region> region, uint32_t in_chans, uint32_t out_chans, framepos_t& pos,
844                                   ImportMode mode, boost::shared_ptr<Track>& existing_track)
845 {
846         boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(region);
847         boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(region);
848
849         switch (mode) {
850         case ImportAsRegion:
851                 /* relax, its been done */
852                 break;
853
854         case ImportToTrack:
855         {
856                 if (!existing_track) {
857
858                         if (ar) {
859                                 existing_track = get_nth_selected_audio_track (0);
860                         } else if (mr) {
861                                 existing_track = get_nth_selected_midi_track (0);
862                         }
863
864                         if (!existing_track) {
865                                 return -1;
866                         }
867                 }
868
869                 boost::shared_ptr<Playlist> playlist = existing_track->playlist();
870                 boost::shared_ptr<Region> copy (RegionFactory::create (region, region->properties()));
871                 begin_reversible_command (_("insert file"));
872                 playlist->clear_changes ();
873                 playlist->add_region (copy, pos);
874                 _session->add_command (new StatefulDiffCommand (playlist));
875                 commit_reversible_command ();
876                 break;
877         }
878
879         case ImportAsTrack:
880         {
881                 if (!existing_track) {
882                         if (ar) {
883                                 list<boost::shared_ptr<AudioTrack> > at (_session->new_audio_track (in_chans, out_chans, Normal, 0, 1));
884
885                                 if (at.empty()) {
886                                         return -1;
887                                 }
888
889                                 existing_track = at.front();
890                         } else if (mr) {
891                                 list<boost::shared_ptr<MidiTrack> > mt (_session->new_midi_track (Normal, 0, 1));
892
893                                 if (mt.empty()) {
894                                         return -1;
895                                 }
896
897                                 existing_track = mt.front();
898                         }
899                         
900                         existing_track->set_name (region->name());
901                 }
902
903                 boost::shared_ptr<Region> copy (RegionFactory::create (region));
904                 existing_track->playlist()->add_region (copy, pos);
905                 break;
906         }
907
908
909         case ImportAsTapeTrack:
910         {
911                 if (!ar)
912                         return -1;
913
914                 list<boost::shared_ptr<AudioTrack> > at (_session->new_audio_track (in_chans, out_chans, Destructive));
915                 if (!at.empty()) {
916                         boost::shared_ptr<Region> copy (RegionFactory::create (region));
917                         at.front()->set_name (basename_nosuffix (copy->name()));
918                         at.front()->playlist()->add_region (copy, pos);
919                 }
920                 break;
921         }
922         }
923
924         return 0;
925 }
926
927 void *
928 Editor::_import_thread (void *arg)
929 {
930         SessionEvent::create_per_thread_pool ("import events", 64);
931
932         Editor *ed = (Editor *) arg;
933         return ed->import_thread ();
934 }
935
936 void *
937 Editor::import_thread ()
938 {
939         _session->import_audiofiles (import_status);
940         pthread_exit_pbd (0);
941         /*NOTREACHED*/
942         return 0;
943 }