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