c1d51e11a45ebbd19fae5fffb1d9be2f1a1f99c5
[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                 nframes64_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 wave_name_exists = false;
222
223         for (SourceMap::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
224                 string tmp (Glib::path_get_basename (i->second->path()));
225                 if (tmp == wave_name) {
226                         wave_name_exists = true;
227                         break;
228                 }
229         }
230
231         int function = 1;
232
233         if (wave_name_exists) {
234                 string message;
235                 if (all_or_nothing) {
236                         // updating is still disabled
237                         //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);
238                         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);
239                 } else {
240                         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);
241
242                 }
243                 MessageDialog dialog(message, false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_NONE, true);
244
245                 if (all_or_nothing) {
246                         // disabled
247                         //dialog.add_button("Update", 0);
248                         dialog.add_button("Import", 1);
249                         dialog.add_button("Skip",   2);
250                 } else {
251                         dialog.add_button("Import", 1);
252                         dialog.add_button("Cancel", 2);
253                 }
254
255                 //dialog.add_button("Skip all", 4); // All or rest?
256
257                 dialog.show();
258
259                 function = dialog.run ();
260
261                 dialog.hide();
262         }
263
264         return function;
265 }
266
267 boost::shared_ptr<AudioTrack>
268 Editor::get_nth_selected_audio_track (int nth) const
269 {
270         AudioTimeAxisView* atv;
271         TrackSelection::iterator x;
272
273         for (x = selection->tracks.begin(); nth > 0 && x != selection->tracks.end(); ++x) {
274
275                 atv = dynamic_cast<AudioTimeAxisView*>(*x);
276
277                 if (!atv) {
278                         continue;
279                 } else if (atv->is_audio_track()) {
280                         --nth;
281                 }
282         }
283
284         if (x == selection->tracks.end()) {
285                 atv = dynamic_cast<AudioTimeAxisView*>(selection->tracks.back());
286         } else {
287                 atv = dynamic_cast<AudioTimeAxisView*>(*x);
288         }
289
290         if (!atv || !atv->is_audio_track()) {
291                 return boost::shared_ptr<AudioTrack>();
292         }
293
294         return atv->audio_track();
295 }
296
297 boost::shared_ptr<MidiTrack>
298 Editor::get_nth_selected_midi_track (int nth) const
299 {
300         MidiTimeAxisView* mtv;
301         TrackSelection::iterator x;
302
303         for (x = selection->tracks.begin(); nth > 0 && x != selection->tracks.end(); ++x) {
304
305                 mtv = dynamic_cast<MidiTimeAxisView*>(*x);
306
307                 if (!mtv) {
308                         continue;
309                 } else if (mtv->is_midi_track()) {
310                         --nth;
311                 }
312         }
313
314         if (x == selection->tracks.end()) {
315                 mtv = dynamic_cast<MidiTimeAxisView*>(selection->tracks.back());
316         } else {
317                 mtv = dynamic_cast<MidiTimeAxisView*>(*x);
318         }
319
320         if (!mtv || !mtv->is_midi_track()) {
321                 return boost::shared_ptr<MidiTrack>();
322         }
323
324         return mtv->midi_track();
325 }
326
327 void
328 Editor::do_import (vector<string> paths, ImportDisposition chns, ImportMode mode, SrcQuality quality, nframes64_t& pos)
329 {
330         boost::shared_ptr<Track> track;
331         vector<string> to_import;
332         int nth = 0;
333         bool use_timestamp = (pos == -1);
334
335         current_interthread_info = &import_status;
336         import_status.current = 1;
337         import_status.total = paths.size ();
338
339         ImportProgressWindow ipw (&import_status, _("Import"), _("Cancel Import"));
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                         import_sndfiles (paths, mode, quality, pos, 1, 1, track, false);
358                 }
359
360         } else {
361
362                 bool replace = false;
363                 bool ok = true;
364
365                 for (vector<string>::iterator a = paths.begin(); a != paths.end(); ++a) {
366
367                         const int check = check_whether_and_how_to_import (*a, true);
368                         
369                         switch (check) {
370                         case 2:
371                                 // user said skip
372                                 continue;
373                         case 0:
374                                 fatal << "Updating existing sources should be disabled!" << endmsg;
375                                 /* NOTREACHED*/
376                                 break;
377                         case 1:
378                                 replace = false;
379                                 break;
380                         default:
381                                 fatal << "Illegal return " << check <<  " from check_whether_and_how_to_import()!" << endmsg;
382                                 /* NOTREACHED*/
383                         }
384
385                         /* have to reset this for every file we handle */
386                         
387                         if (use_timestamp) {
388                                 pos = -1;
389                         }
390
391                         switch (chns) {
392                         case Editing::ImportDistinctFiles:
393                                 
394                                 to_import.clear ();
395                                 to_import.push_back (*a);
396                                 
397                                 if (mode == Editing::ImportToTrack) {
398                                         track = get_nth_selected_audio_track (nth++);
399                                 }
400                         
401                                 ok = (import_sndfiles (to_import, mode, quality, pos, 1, -1, track, replace) == 0);
402                                 break;
403                                 
404                         case Editing::ImportDistinctChannels:
405                                 
406                                 to_import.clear ();
407                                 to_import.push_back (*a);
408                                 
409                                 ok = (import_sndfiles (to_import, mode, quality, pos, -1, -1, track, replace) == 0);
410                                 break;
411                                 
412                         case Editing::ImportSerializeFiles:
413                                 
414                                 to_import.clear ();
415                                 to_import.push_back (*a);
416
417                                 ok = (import_sndfiles (to_import, mode, quality, pos, 1, 1, track, replace) == 0);
418                                 break;
419
420                         case Editing::ImportMergeFiles:
421                                 // Not entered, handled in earlier if() branch
422                                 break;
423                         }
424                 }
425         }
426 }
427
428 void
429 Editor::do_embed (vector<string> paths, ImportDisposition chns, ImportMode mode, nframes64_t& pos)
430 {
431         boost::shared_ptr<Track> track;
432         bool check_sample_rate = true;
433         bool ok = false;
434         vector<string> to_embed;
435         bool multi = paths.size() > 1;
436         int nth = 0;
437
438         switch (chns) {
439         case Editing::ImportDistinctFiles:
440                 for (vector<string>::iterator a = paths.begin(); a != paths.end(); ++a) {
441
442                         to_embed.clear ();
443                         to_embed.push_back (*a);
444
445                         if (mode == Editing::ImportToTrack) {
446                                 track = get_nth_selected_audio_track (nth++);
447                         }
448
449                         if (embed_sndfiles (to_embed, multi, check_sample_rate, mode, pos, 1, -1, track) < -1) {
450                                 goto out;
451                         }
452                 }
453                 break;
454
455         case Editing::ImportDistinctChannels:
456                 for (vector<string>::iterator a = paths.begin(); a != paths.end(); ++a) {
457
458                         to_embed.clear ();
459                         to_embed.push_back (*a);
460
461                         if (embed_sndfiles (to_embed, multi, check_sample_rate, mode, pos, -1, -1, track) < -1) {
462                                 goto out;
463                         }
464                 }
465                 break;
466
467         case Editing::ImportMergeFiles:
468                 if (embed_sndfiles (paths, multi, check_sample_rate, mode, pos, 1, 1, track) < -1) {
469                         goto out;
470                 }
471                 break;
472
473         case Editing::ImportSerializeFiles:
474                 for (vector<string>::iterator a = paths.begin(); a != paths.end(); ++a) {
475
476                         to_embed.clear ();
477                         to_embed.push_back (*a);
478
479                         if (embed_sndfiles (to_embed, multi, check_sample_rate, mode, pos, 1, 1, track) < -1) {
480                                 goto out;
481                         }
482                 }
483                 break;
484         }
485
486         ok = true;
487
488   out:
489         if (ok) {
490                 _session->save_state ("");
491         }
492 }
493
494 int
495 Editor::import_sndfiles (vector<string> paths, ImportMode mode, SrcQuality quality, nframes64_t& pos,
496                          int target_regions, int target_tracks, boost::shared_ptr<Track>& track, bool replace)
497 {
498         import_status.paths = paths;
499         import_status.done = false;
500         import_status.cancel = false;
501         import_status.freeze = false;
502         import_status.done = 0.0;
503         import_status.quality = quality;
504         import_status.replace_existing_source = replace;
505
506         import_status.mode = mode;
507         import_status.pos = pos;
508         import_status.target_tracks = target_tracks;
509         import_status.target_regions = target_regions;
510         import_status.track = track;
511         import_status.replace = replace;
512
513         track_canvas->get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
514         gdk_flush ();
515
516         /* start import thread for this spec. this will ultimately call Session::import_audiofiles()
517            which, if successful, will add the files as regions to the region list. its up to us
518            (the GUI) to direct additional steps after that.
519         */
520
521         pthread_create_and_store ("import", &import_status.thread, _import_thread, this);
522         pthread_detach (import_status.thread);
523
524         while (!import_status.done && !import_status.cancel) {
525                 gtk_main_iteration ();
526         }
527
528         import_status.done = true;
529
530         if (!import_status.cancel && !import_status.sources.empty()) {
531                 if (add_sources (import_status.paths,
532                                  import_status.sources,
533                                  import_status.pos,
534                                  import_status.mode,
535                                  import_status.target_regions,
536                                  import_status.target_tracks,
537                                  track, false) == 0) {
538                         _session->save_state ("");
539                 }
540
541                 /* update position from results */
542
543                 pos = import_status.pos;
544         }
545
546
547         track_canvas->get_window()->set_cursor (*current_canvas_cursor);
548         return 0;
549 }
550
551 int
552 Editor::embed_sndfiles (vector<string> paths, bool multifile,
553                         bool& check_sample_rate, ImportMode mode, nframes64_t& pos, int target_regions, int target_tracks,
554                         boost::shared_ptr<Track>& track)
555 {
556         boost::shared_ptr<AudioFileSource> source;
557         SourceList sources;
558         string linked_path;
559         SoundFileInfo finfo;
560         int ret = 0;
561         string path_to_use;
562
563         track_canvas->get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
564         gdk_flush ();
565
566         for (vector<string>::iterator p = paths.begin(); p != paths.end(); ++p) {
567
568                 string path = *p;
569
570                 if (Config->get_try_link_for_embed()) {
571
572                         /* lets see if we can link it into the session */
573                         
574                         sys::path tmp = _session->session_directory().sound_path() / Glib::path_get_basename(path);
575                         linked_path = tmp.to_string();
576                         
577                         path_to_use = linked_path;
578                         
579                         if (link (path.c_str(), linked_path.c_str()) == 0) {
580                                 
581                                 /* there are many reasons why link(2) might have failed.
582                                    but if it succeeds, we now have a link in the
583                                    session sound dir that will protect against
584                                    unlinking of the original path. nice.
585                                 */
586                                 
587                                 path = linked_path;
588                                 path_to_use = Glib::path_get_basename (path);
589                                 
590                         } else {
591
592                                 /* one possible reason is that its already linked */
593                                 
594                                 if (errno == EEXIST) {
595                                         struct stat sb;
596                                         
597                                         if (stat (linked_path.c_str(), &sb) == 0) {
598                                                 if (sb.st_nlink > 1) { // its a hard link, assume its the one we want
599                                                         path = linked_path;
600                                                         path_to_use = Glib::path_get_basename (path);
601                                                 }
602                                         }
603                                 }
604                         }
605                 }
606
607                 /* note that we temporarily truncated _id at the colon */
608
609                 string error_msg;
610
611                 if (!AudioFileSource::get_soundfile_info (path, finfo, error_msg)) {
612                         error << string_compose(_("Editor: cannot open file \"%1\", (%2)"), path, error_msg ) << endmsg;
613                         goto out;
614                 }
615
616                 if (check_sample_rate  && (finfo.samplerate != (int) _session->frame_rate())) {
617                         vector<string> choices;
618
619                         if (multifile) {
620                                 choices.push_back (_("Cancel entire import"));
621                                 choices.push_back (_("Don't embed it"));
622                                 choices.push_back (_("Embed all without questions"));
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!"),
627                                                         short_path (path, 40)),
628                                         choices, false
629                                         );
630
631                                 int resx = rate_choice.run ();
632
633                                 switch (resx) {
634                                 case 0: /* stop a multi-file import */
635                                         ret = -2;
636                                         goto out;
637                                 case 1: /* don't embed this one */
638                                         ret = -1;
639                                         goto out;
640                                 case 2: /* do it, and the rest without asking */
641                                         check_sample_rate = false;
642                                         break;
643                                 case 3: /* do it */
644                                         break;
645                                 default:
646                                         ret = -2;
647                                         goto out;
648                                 }
649                         } else {
650                                 choices.push_back (_("Cancel"));
651                                 choices.push_back (_("Embed it anyway"));
652
653                                 Gtkmm2ext::Choice rate_choice (
654                                         _("Sample rate"),
655                                         string_compose (_("%1\nThis audiofile's sample rate doesn't match the session sample rate!"), path),
656                                         choices, false
657                                         );
658
659                                 int resx = rate_choice.run ();
660
661                                 switch (resx) {
662                                 case 0: /* don't import */
663                                         ret = -1;
664                                         goto out;
665                                 case 1: /* do it */
666                                         break;
667                                 default:
668                                         ret = -2;
669                                         goto out;
670                                 }
671                         }
672                 }
673
674                 track_canvas->get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
675
676                 for (int n = 0; n < finfo.channels; ++n) {
677                         try {
678
679                                 /* check if we have this thing embedded already */
680
681                                 boost::shared_ptr<Source> s;
682
683                                 if ((s = _session->source_by_path_and_channel (path, n)) == 0) {
684
685                                         source = boost::dynamic_pointer_cast<AudioFileSource> (
686                                                 SourceFactory::createReadable (DataType::AUDIO, *_session,
687                                                                                path_to_use, n,
688                                                                                (mode == ImportAsTapeTrack
689                                                                                 ? Source::Destructive
690                                                                                 : Source::Flag (0)),
691                                                                         true, true));
692                                 } else {
693                                         source = boost::dynamic_pointer_cast<AudioFileSource> (s);
694                                 }
695
696                                 sources.push_back(source);
697                         }
698
699                         catch (failed_constructor& err) {
700                                 error << string_compose(_("could not open %1"), path) << endmsg;
701                                 goto out;
702                         }
703
704                         ARDOUR_UI::instance()->flush_pending ();
705                 }
706         }
707
708         if (sources.empty()) {
709                 goto out;
710         }
711
712         ret = add_sources (paths, sources, pos, mode, target_regions, target_tracks, track, true);
713
714   out:
715         track_canvas->get_window()->set_cursor (*current_canvas_cursor);
716         return ret;
717 }
718
719 int
720 Editor::add_sources (vector<string> paths, SourceList& sources, nframes64_t& pos, ImportMode mode,
721                      int target_regions, int target_tracks, boost::shared_ptr<Track>& track, bool /*add_channel_suffix*/)
722 {
723         vector<boost::shared_ptr<Region> > regions;
724         string region_name;
725         uint32_t input_chan = 0;
726         uint32_t output_chan = 0;
727         bool use_timestamp;
728
729         use_timestamp = (pos == -1);
730
731         // kludge (for MIDI we're abusing "channel" for "track" here)
732         if (SMFSource::safe_midi_file_extension (paths.front())) {
733                 target_regions = -1;
734         }
735
736         if (target_regions == 1) {
737
738                 /* take all the sources we have and package them up as a region */
739
740                 region_name = region_name_from_path (paths.front(), (sources.size() > 1), false);
741
742                 PropertyList plist; 
743                 
744                 plist.add (ARDOUR::Properties::start, 0);
745                 plist.add (ARDOUR::Properties::length, sources[0]->length (pos));
746                 plist.add (ARDOUR::Properties::name, region_name);
747                 plist.add (ARDOUR::Properties::layer, 0);
748                 plist.add (ARDOUR::Properties::whole_file, true);
749                 plist.add (ARDOUR::Properties::external, true);
750
751                 boost::shared_ptr<Region> r = RegionFactory::create (sources, plist);
752
753                 if (use_timestamp && boost::dynamic_pointer_cast<AudioRegion>(r)) {
754                         boost::dynamic_pointer_cast<AudioRegion>(r)->special_set_position(sources[0]->natural_position());
755                 }
756
757                 regions.push_back (r);
758
759
760         } else if (target_regions == -1 || target_regions > 1) {
761
762                 /* take each source and create a region for each one */
763
764                 SourceList just_one;
765                 SourceList::iterator x;
766                 uint32_t n;
767
768                 for (n = 0, x = sources.begin(); x != sources.end(); ++x, ++n) {
769
770                         just_one.clear ();
771                         just_one.push_back (*x);
772
773                         region_name = region_name_from_path ((*x)->path(), false, false, sources.size(), n);
774
775                         PropertyList plist; 
776                         
777                         plist.add (ARDOUR::Properties::start, 0);
778                         plist.add (ARDOUR::Properties::length, (*x)->length (pos));
779                         plist.add (ARDOUR::Properties::name, region_name);
780                         plist.add (ARDOUR::Properties::layer, 0);
781                         plist.add (ARDOUR::Properties::whole_file, true);
782                         plist.add (ARDOUR::Properties::external, true);
783
784                         boost::shared_ptr<Region> r = RegionFactory::create (just_one, plist);
785
786                         if (use_timestamp && boost::dynamic_pointer_cast<AudioRegion>(r)) {
787                                 boost::dynamic_pointer_cast<AudioRegion>(r)->special_set_position((*x)->natural_position());
788                         }
789
790                         regions.push_back (r);
791                 }
792         }
793
794         if (target_regions == 1) {
795                 input_chan = regions.front()->n_channels();
796         } else {
797                 if (target_tracks == 1) {
798                         input_chan = regions.size();
799                 } else {
800                         input_chan = 1;
801                 }
802         }
803
804         if (Config->get_output_auto_connect() & AutoConnectMaster) {
805                 output_chan = (_session->master_out() ? _session->master_out()->n_inputs().n_audio() : input_chan);
806         } else {
807                 output_chan = input_chan;
808         }
809
810         int n = 0;
811         framepos_t rlen = 0;
812
813         for (vector<boost::shared_ptr<Region> >::iterator r = regions.begin(); r != regions.end(); ++r, ++n) {
814                 
815                 boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (*r);
816                 
817                 if (use_timestamp && ar) {
818                         
819                         cerr << "Using timestamp to place region " << (*r)->name() << endl;
820                         
821                         /* get timestamp for this region */
822
823                         const boost::shared_ptr<Source> s (ar->sources().front());
824                         const boost::shared_ptr<AudioSource> as = boost::dynamic_pointer_cast<AudioSource> (s);
825                         
826                         assert (as);
827                         
828                         if (as->natural_position() != 0) {
829                                 pos = as->natural_position();
830                                 cerr << "\tgot " << pos << " from source TC info\n";
831                         } else if (target_tracks == 1) {
832                                 /* hmm, no timestamp available, put it after the previous region
833                                  */
834                                 if (n == 0) {
835                                         pos = get_preferred_edit_position ();
836                                         cerr << "\tno timestamp, first file, use edit pos = " << pos << endl;
837                                 } else {
838                                         pos += rlen;
839                                         cerr << "\tpacked-sequence-shuffle to " << pos << endl;
840                                 }
841                         } else {
842                                 pos = get_preferred_edit_position ();
843                                 cerr << "\tmultitracks, using edit position = " << pos << endl;
844                         }
845                                 
846                 }
847
848                 finish_bringing_in_material (*r, input_chan, output_chan, pos, mode, track);
849
850                 rlen = (*r)->length();
851                 
852                 if (target_tracks != 1) {
853                         track.reset ();
854                 } else { 
855                         if (!use_timestamp || !ar) {
856                                 /* line each one up right after the other */
857                                 pos += (*r)->length();
858                         }
859                 }
860         }
861
862         /* setup peak file building in another thread */
863
864         for (SourceList::iterator x = sources.begin(); x != sources.end(); ++x) {
865                 SourceFactory::setup_peakfile (*x, true);
866         }
867
868         return 0;
869 }
870
871 int
872 Editor::finish_bringing_in_material (boost::shared_ptr<Region> region, uint32_t in_chans, uint32_t out_chans, nframes64_t& pos,
873                                   ImportMode mode, boost::shared_ptr<Track>& existing_track)
874 {
875         boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(region);
876         boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(region);
877
878         switch (mode) {
879         case ImportAsRegion:
880                 /* relax, its been done */
881                 break;
882
883         case ImportToTrack:
884         {
885                 if (!existing_track) {
886
887                         if (ar) {
888                                 existing_track = get_nth_selected_audio_track (0);
889                         } else if (mr) {
890                                 existing_track = get_nth_selected_midi_track (0);
891                         }
892
893                         if (!existing_track) {
894                                 return -1;
895                         }
896                 }
897
898                 boost::shared_ptr<Playlist> playlist = existing_track->playlist();
899                 boost::shared_ptr<Region> copy (RegionFactory::create (region, region->properties()));
900                 begin_reversible_command (_("insert file"));
901                 playlist->clear_changes ();
902                 playlist->add_region (copy, pos);
903                 _session->add_command (new StatefulDiffCommand (playlist));
904                 commit_reversible_command ();
905                 break;
906         }
907
908         case ImportAsTrack:
909         {
910                 if (!existing_track) {
911                         if (ar) {
912                                 list<boost::shared_ptr<AudioTrack> > at (_session->new_audio_track (in_chans, out_chans, Normal, 0, 1));
913
914                                 if (at.empty()) {
915                                         return -1;
916                                 }
917
918                                 existing_track = at.front();
919                         } else if (mr) {
920                                 list<boost::shared_ptr<MidiTrack> > mt (_session->new_midi_track (Normal, 0, 1));
921
922                                 if (mt.empty()) {
923                                         return -1;
924                                 }
925
926                                 existing_track = mt.front();
927                         }
928
929                         existing_track->set_name (region->name());
930                 }
931
932                 boost::shared_ptr<Region> copy (RegionFactory::create (region));
933                 existing_track->playlist()->add_region (copy, pos);
934                 break;
935         }
936
937
938         case ImportAsTapeTrack:
939         {
940                 if (!ar)
941                         return -1;
942
943                 list<boost::shared_ptr<AudioTrack> > at (_session->new_audio_track (in_chans, out_chans, Destructive));
944                 if (!at.empty()) {
945                         boost::shared_ptr<Region> copy (RegionFactory::create (region));
946                         at.front()->set_name (basename_nosuffix (copy->name()));
947                         at.front()->playlist()->add_region (copy, pos);
948                 }
949                 break;
950         }
951         }
952
953         return 0;
954 }
955
956 void *
957 Editor::_import_thread (void *arg)
958 {
959         SessionEvent::create_per_thread_pool ("import events", 64);
960
961         Editor *ed = (Editor *) arg;
962         return ed->import_thread ();
963 }
964
965 void *
966 Editor::import_thread ()
967 {
968         _session->import_audiofiles (import_status);
969         pthread_exit_pbd (0);
970         /*NOTREACHED*/
971         return 0;
972 }