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