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