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