ardour
editor_audio_import.cc
Go to the documentation of this file.
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"
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 "cursor_context.h"
50 #include "editor.h"
51 #include "sfdb_ui.h"
52 #include "editing.h"
53 #include "audio_time_axis.h"
54 #include "midi_time_axis.h"
55 #include "session_import_dialog.h"
56 #include "gui_thread.h"
58 #include "mouse_cursors.h"
59 #include "editor_cursors.h"
60 
61 #include "i18n.h"
62 
63 using namespace std;
64 using namespace ARDOUR;
65 using namespace PBD;
66 using namespace Gtk;
67 using namespace Gtkmm2ext;
68 using namespace Editing;
69 using std::string;
70 
71 /* Functions supporting the incorporation of external (non-captured) audio material into ardour */
72 
73 void
75 {
76  if (_session == 0) {
77  MessageDialog msg (_("You can't import or embed an audiofile until you have a session loaded."));
78  msg.run ();
79  return;
80  }
81 
82  if (sfbrowser == 0) {
83  sfbrowser = new SoundFileOmega (_("Add Existing Media"), _session, 0, true, mode_hint);
84  } else {
85  sfbrowser->set_mode (mode_hint);
86  }
87 
88  external_audio_dialog ();
89 }
90 
91 void
93 {
94  vector<string> paths;
95  uint32_t audio_track_cnt;
96  uint32_t midi_track_cnt;
97 
98  if (_session == 0) {
99  MessageDialog msg (_("You can't import or embed an audiofile until you have a session loaded."));
100  msg.run ();
101  return;
102  }
103 
104  audio_track_cnt = 0;
105  midi_track_cnt = 0;
106 
107  for (TrackSelection::iterator x = selection->tracks.begin(); x != selection->tracks.end(); ++x) {
108  AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(*x);
109 
110  if (atv) {
111  if (atv->is_audio_track()) {
112  audio_track_cnt++;
113  }
114 
115  } else {
116  MidiTimeAxisView* mtv = dynamic_cast<MidiTimeAxisView*>(*x);
117 
118  if (mtv) {
119  if (mtv->is_midi_track()) {
120  midi_track_cnt++;
121  }
122  }
123  }
124  }
125 
126  if (sfbrowser == 0) {
127  sfbrowser = new SoundFileOmega (_("Add Existing Media"), _session, audio_track_cnt, midi_track_cnt, true);
128  } else {
129  sfbrowser->reset (audio_track_cnt, midi_track_cnt);
130  }
131 
132  sfbrowser->show_all ();
133 }
134 
135 void
137 {
138  SessionImportDialog dialog (_session);
139  dialog.run ();
140 }
141 
142 typedef std::map<PBD::ID,boost::shared_ptr<ARDOUR::Source> > SourceMap;
143 
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 
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()) {
229  }
230 
231  return atv->audio_track();
232 }
233 
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()) {
259  }
260 
261  return mtv->midi_track();
262 }
263 
264 void
265 Editor::do_import (vector<string> paths,
266  ImportDisposition disposition,
267  ImportMode mode,
268  SrcQuality quality,
269  framepos_t& pos,
270  ARDOUR::PluginInfoPtr instrument)
271 {
273  vector<string> to_import;
274  int nth = 0;
275  bool use_timestamp = (pos == -1);
276 
277  current_interthread_info = &import_status;
278  import_status.current = 1;
279  import_status.total = paths.size ();
280  import_status.all_done = false;
281 
282  ImportProgressWindow ipw (&import_status, _("Import"), _("Cancel Import"));
283 
284  bool ok = true;
285 
286  if (disposition == Editing::ImportMergeFiles) {
287 
288  /* create 1 region from all paths, add to 1 track,
289  ignore "track"
290  */
291 
292  bool cancel = false;
293  for (vector<string>::iterator a = paths.begin(); a != paths.end(); ++a) {
294  int check = check_whether_and_how_to_import(*a, false);
295  if (check == 2) {
296  cancel = true;
297  break;
298  }
299  }
300 
301  if (cancel) {
302  ok = false;
303  } else {
304  ipw.show ();
305  ok = (import_sndfiles (paths, disposition, mode, quality, pos, 1, 1, track, false, instrument) == 0);
306  }
307 
308  } else {
309 
310  bool replace = false;
311 
312  for (vector<string>::iterator a = paths.begin(); a != paths.end(); ++a) {
313 
314  const int check = check_whether_and_how_to_import (*a, true);
315 
316  switch (check) {
317  case 2:
318  // user said skip
319  continue;
320  case 0:
321  fatal << "Updating existing sources should be disabled!" << endmsg;
322  abort(); /* NOTREACHED*/
323  break;
324  case 1:
325  replace = false;
326  break;
327  default:
328  fatal << "Illegal return " << check << " from check_whether_and_how_to_import()!" << endmsg;
329  abort(); /* NOTREACHED*/
330  }
331 
332  /* have to reset this for every file we handle */
333 
334  if (use_timestamp) {
335  pos = -1;
336  }
337 
338  ipw.show ();
339 
340  switch (disposition) {
341  case Editing::ImportDistinctFiles:
342 
343  to_import.clear ();
344  to_import.push_back (*a);
345 
346  if (mode == Editing::ImportToTrack) {
347  track = get_nth_selected_audio_track (nth++);
348  }
349 
350  ok = (import_sndfiles (to_import, disposition, mode, quality, pos, 1, -1, track, replace, instrument) == 0);
351  break;
352 
353  case Editing::ImportDistinctChannels:
354 
355  to_import.clear ();
356  to_import.push_back (*a);
357 
358  ok = (import_sndfiles (to_import, disposition, mode, quality, pos, -1, -1, track, replace, instrument) == 0);
359  break;
360 
361  case Editing::ImportSerializeFiles:
362 
363  to_import.clear ();
364  to_import.push_back (*a);
365 
366  ok = (import_sndfiles (to_import, disposition, mode, quality, pos, 1, 1, track, replace, instrument) == 0);
367  break;
368 
369  case Editing::ImportMergeFiles:
370  // Not entered, handled in earlier if() branch
371  break;
372  }
373  }
374  }
375 
376  if (ok) {
377  _session->save_state ("");
378  }
379 
380  import_status.all_done = true;
381 }
382 
383 void
384 Editor::do_embed (vector<string> paths, ImportDisposition import_as, ImportMode mode, framepos_t& pos, ARDOUR::PluginInfoPtr instrument)
385 {
387  bool check_sample_rate = true;
388  bool ok = false;
389  vector<string> to_embed;
390  bool multi = paths.size() > 1;
391  int nth = 0;
392  bool use_timestamp = (pos == -1);
393 
394  switch (import_as) {
395  case Editing::ImportDistinctFiles:
396  for (vector<string>::iterator a = paths.begin(); a != paths.end(); ++a) {
397 
398  /* have to reset this for every file we handle */
399  if (use_timestamp) {
400  pos = -1;
401  }
402 
403  to_embed.clear ();
404  to_embed.push_back (*a);
405 
406  if (mode == Editing::ImportToTrack) {
407  track = get_nth_selected_audio_track (nth++);
408  }
409 
410  if (embed_sndfiles (to_embed, multi, check_sample_rate, import_as, mode, pos, 1, -1, track, instrument) < -1) {
411  goto out;
412  }
413  }
414  break;
415 
416  case Editing::ImportDistinctChannels:
417  for (vector<string>::iterator a = paths.begin(); a != paths.end(); ++a) {
418 
419  /* have to reset this for every file we handle */
420  if (use_timestamp) {
421  pos = -1;
422  }
423 
424  to_embed.clear ();
425  to_embed.push_back (*a);
426 
427  if (embed_sndfiles (to_embed, multi, check_sample_rate, import_as, mode, pos, -1, -1, track, instrument) < -1) {
428  goto out;
429  }
430  }
431  break;
432 
433  case Editing::ImportMergeFiles:
434  if (embed_sndfiles (paths, multi, check_sample_rate, import_as, mode, pos, 1, 1, track, instrument) < -1) {
435  goto out;
436  }
437  break;
438 
439  case Editing::ImportSerializeFiles:
440  for (vector<string>::iterator a = paths.begin(); a != paths.end(); ++a) {
441 
442  /* have to reset this for every file we handle */
443  if (use_timestamp) {
444  pos = -1;
445  }
446 
447  to_embed.clear ();
448  to_embed.push_back (*a);
449 
450  if (embed_sndfiles (to_embed, multi, check_sample_rate, import_as, mode, pos, 1, 1, track, instrument) < -1) {
451  goto out;
452  }
453  }
454  break;
455  }
456 
457  ok = true;
458 
459  out:
460  if (ok) {
461  _session->save_state ("");
462  }
463 }
464 
465 int
466 Editor::import_sndfiles (vector<string> paths,
467  ImportDisposition disposition,
468  ImportMode mode,
469  SrcQuality quality,
470  framepos_t& pos,
471  int target_regions,
472  int target_tracks,
474  bool replace,
475  ARDOUR::PluginInfoPtr instrument)
476 {
477  import_status.paths = paths;
478  import_status.done = false;
479  import_status.cancel = false;
480  import_status.freeze = false;
481  import_status.quality = quality;
482  import_status.replace_existing_source = replace;
483 
484  import_status.mode = mode;
485  import_status.pos = pos;
486  import_status.target_tracks = target_tracks;
487  import_status.target_regions = target_regions;
488  import_status.track = track;
489  import_status.replace = replace;
490 
491  CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait);
492  gdk_flush ();
493 
494  /* start import thread for this spec. this will ultimately call Session::import_files()
495  which, if successful, will add the files as regions to the region list. its up to us
496  (the GUI) to direct additional steps after that.
497  */
498 
499  pthread_create_and_store ("import", &import_status.thread, _import_thread, this);
500  pthread_detach (import_status.thread);
501 
502  while (!import_status.done && !import_status.cancel) {
503  gtk_main_iteration ();
504  }
505 
506  import_status.done = true;
507 
508  int result = -1;
509 
510  if (!import_status.cancel && !import_status.sources.empty()) {
511  result = add_sources (
512  import_status.paths,
513  import_status.sources,
514  import_status.pos,
515  disposition,
516  import_status.mode,
517  import_status.target_regions,
518  import_status.target_tracks,
519  track, false, instrument
520  );
521 
522  /* update position from results */
523 
524  pos = import_status.pos;
525  }
526 
527  import_status.sources.clear();
528  return result;
529 }
530 
531 int
532 Editor::embed_sndfiles (vector<string> paths,
533  bool multifile,
534  bool& check_sample_rate,
535  ImportDisposition disposition,
536  ImportMode mode,
537  framepos_t& pos,
538  int target_regions,
539  int target_tracks,
541  ARDOUR::PluginInfoPtr instrument)
542 {
544  SourceList sources;
545  string linked_path;
546  SoundFileInfo finfo;
547 
548  CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait);
549  gdk_flush ();
550 
551  for (vector<string>::iterator p = paths.begin(); p != paths.end(); ++p) {
552 
553  string path = *p;
554  string error_msg;
555 
556  /* note that we temporarily truncated _id at the colon */
557 
558  if (!AudioFileSource::get_soundfile_info (path, finfo, error_msg)) {
559  error << string_compose(_("Editor: cannot open file \"%1\", (%2)"), path, error_msg ) << endmsg;
560  return -3;
561  }
562 
563  if (check_sample_rate && (finfo.samplerate != (int) _session->frame_rate())) {
564  vector<string> choices;
565 
566  if (multifile) {
567  choices.push_back (_("Cancel entire import"));
568  choices.push_back (_("Don't embed it"));
569  choices.push_back (_("Embed all without questions"));
570 
571  Gtkmm2ext::Choice rate_choice (
572  _("Sample rate"),
573  string_compose (_("%1\nThis audiofile's sample rate doesn't match the session sample rate!"),
574  short_path (path, 40)),
575  choices, false
576  );
577 
578  int resx = rate_choice.run ();
579 
580  switch (resx) {
581  case 0: /* stop a multi-file import */
582  return -2;
583  case 1: /* don't embed this one */
584  return -1;
585  case 2: /* do it, and the rest without asking */
586  check_sample_rate = false;
587  break;
588  case 3: /* do it */
589  break;
590  default:
591  return -2;
592  }
593  } else {
594  choices.push_back (_("Cancel"));
595  choices.push_back (_("Embed it anyway"));
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!"), path),
600  choices, false
601  );
602 
603  int resx = rate_choice.run ();
604 
605  switch (resx) {
606  case 0: /* don't import */
607  return -1;
608  case 1: /* do it */
609  break;
610  default:
611  return -2;
612  }
613  }
614  }
615 
616  for (int n = 0; n < finfo.channels; ++n) {
617 
618  try {
619 
620  /* check if we have this thing embedded already */
621 
623 
624  if ((s = _session->audio_source_by_path_and_channel (path, n)) == 0) {
625 
627  SourceFactory::createExternal (DataType::AUDIO, *_session,
628  path, n,
629  (mode == ImportAsTapeTrack
631  : Source::Flag (0)),
632  true, true));
633  } else {
635  }
636 
637  sources.push_back(source);
638  }
639 
640  catch (failed_constructor& err) {
641  error << string_compose(_("could not open %1"), path) << endmsg;
642  return -3;
643  }
644 
645  gtk_main_iteration();
646  }
647  }
648 
649  if (!sources.empty()) {
650  return add_sources (paths, sources, pos, disposition, mode, target_regions, target_tracks, track, true, instrument);
651  }
652 
653  return 0;
654 }
655 
656 int
657 Editor::add_sources (vector<string> paths,
658  SourceList& sources,
659  framepos_t& pos,
660  ImportDisposition disposition,
661  ImportMode mode,
662  int target_regions,
663  int target_tracks,
665  bool /*add_channel_suffix*/,
666  ARDOUR::PluginInfoPtr instrument)
667 {
668  vector<boost::shared_ptr<Region> > regions;
669  string region_name;
670  uint32_t input_chan = 0;
671  uint32_t output_chan = 0;
672  bool use_timestamp;
673  vector<string> track_names;
674 
675  use_timestamp = (pos == -1);
676 
677  // kludge (for MIDI we're abusing "channel" for "track" here)
678  if (SMFSource::safe_midi_file_extension (paths.front())) {
679  target_regions = -1;
680  }
681 
682  if (target_regions == 1) {
683 
684  /* take all the sources we have and package them up as a region */
685 
686  region_name = region_name_from_path (paths.front(), (sources.size() > 1), false);
687 
688  /* we checked in import_sndfiles() that there were not too many */
689 
690  while (RegionFactory::region_by_name (region_name)) {
691  region_name = bump_name_once (region_name, '.');
692  }
693 
694  PropertyList plist;
695 
696  plist.add (ARDOUR::Properties::start, 0);
697  plist.add (ARDOUR::Properties::length, sources[0]->length (pos));
698  plist.add (ARDOUR::Properties::name, region_name);
699  plist.add (ARDOUR::Properties::layer, 0);
700  plist.add (ARDOUR::Properties::whole_file, true);
701  plist.add (ARDOUR::Properties::external, true);
702 
703  boost::shared_ptr<Region> r = RegionFactory::create (sources, plist);
704 
705  if (use_timestamp && boost::dynamic_pointer_cast<AudioRegion>(r)) {
706  boost::dynamic_pointer_cast<AudioRegion>(r)->special_set_position(sources[0]->natural_position());
707  }
708 
709  regions.push_back (r);
710 
711  /* if we're creating a new track, name it after the cleaned-up
712  * and "merged" region name.
713  */
714 
715  track_names.push_back (region_name);
716 
717  } else if (target_regions == -1 || target_regions > 1) {
718 
719  /* take each source and create a region for each one */
720 
721  SourceList just_one;
722  SourceList::iterator x;
723  uint32_t n;
724 
725  for (n = 0, x = sources.begin(); x != sources.end(); ++x, ++n) {
726 
727  just_one.clear ();
728  just_one.push_back (*x);
729 
731 
732  if (sources.size() > 1 && disposition == ImportDistinctChannels) {
733 
734  /* generate a per-channel region name so that things work as
735  * intended
736  */
737 
738  string path;
739 
740  if (fs) {
741  region_name = basename_nosuffix (fs->path());
742  } else {
743  region_name = (*x)->name();
744  }
745 
746  if (sources.size() == 2) {
747  if (n == 0) {
748  region_name += "-L";
749  } else {
750  region_name += "-R";
751  }
752  } else if (sources.size() > 2) {
753  region_name += string_compose ("-%1", n+1);
754  }
755 
756  track_names.push_back (region_name);
757 
758  } else {
759  if (fs) {
760  region_name = region_name_from_path (fs->path(), false, false, sources.size(), n);
761  } else {
762  region_name = (*x)->name();
763  }
764 
765  if (SMFSource::safe_midi_file_extension (paths.front())) {
766  string track_name = string_compose ("%1-t%2", PBD::basename_nosuffix (fs->path()), (n + 1));
767  track_names.push_back (track_name);
768  } else {
769  track_names.push_back (PBD::basename_nosuffix (paths[n]));
770  }
771  }
772 
773  PropertyList plist;
774 
775  /* Fudge region length to ensure it is non-zero; make it 1 beat at 120bpm
776  for want of a better idea. It can't be too small, otherwise if this
777  is a MIDI region the conversion from frames -> beats -> frames will
778  round it back down to 0 again.
779  */
780  framecnt_t len = (*x)->length (pos);
781  if (len == 0) {
782  len = (60.0 / 120.0) * _session->frame_rate ();
783  }
784 
785  plist.add (ARDOUR::Properties::start, 0);
786  plist.add (ARDOUR::Properties::length, len);
787  plist.add (ARDOUR::Properties::name, region_name);
788  plist.add (ARDOUR::Properties::layer, 0);
789  plist.add (ARDOUR::Properties::whole_file, true);
790  plist.add (ARDOUR::Properties::external, true);
791 
792  boost::shared_ptr<Region> r = RegionFactory::create (just_one, plist);
793 
794  if (use_timestamp && boost::dynamic_pointer_cast<AudioRegion>(r)) {
795  boost::dynamic_pointer_cast<AudioRegion>(r)->special_set_position((*x)->natural_position());
796  }
797 
798  regions.push_back (r);
799  }
800  }
801 
802  if (target_regions == 1) {
803  input_chan = regions.front()->n_channels();
804  } else {
805  if (target_tracks == 1) {
806  input_chan = regions.size();
807  } else {
808  input_chan = 1;
809  }
810  }
811 
812  if (Config->get_output_auto_connect() & AutoConnectMaster) {
813  output_chan = (_session->master_out() ? _session->master_out()->n_inputs().n_audio() : input_chan);
814  } else {
815  output_chan = input_chan;
816  }
817 
818  int n = 0;
819  framepos_t rlen = 0;
820 
821  begin_reversible_command (Operations::insert_file);
822 
823  /* we only use tracks names when importing to new tracks, but we
824  * require that one is defined for every region, just to keep
825  * the API simpler.
826  */
827  assert (regions.size() == track_names.size());
828 
829  for (vector<boost::shared_ptr<Region> >::iterator r = regions.begin(); r != regions.end(); ++r, ++n) {
831 
832  if (use_timestamp) {
833  if (ar) {
834 
835  /* get timestamp for this region */
836 
837  const boost::shared_ptr<Source> s (ar->sources().front());
839 
840  assert (as);
841 
842  if (as->natural_position() != 0) {
843  pos = as->natural_position();
844  } else if (target_tracks == 1) {
845  /* hmm, no timestamp available, put it after the previous region
846  */
847  if (n == 0) {
848  pos = get_preferred_edit_position ();
849  } else {
850  pos += rlen;
851  }
852  } else {
853  pos = get_preferred_edit_position ();
854  }
855  } else {
856  /* should really get first position in MIDI file, but for now, use edit position*/
857  pos = get_preferred_edit_position ();
858  }
859  }
860 
861  finish_bringing_in_material (*r, input_chan, output_chan, pos, mode, track, track_names[n], instrument);
862 
863  rlen = (*r)->length();
864 
865  if (target_tracks != 1) {
866  track.reset ();
867  } else {
868  if (!use_timestamp || !ar) {
869  /* line each one up right after the other */
870  pos += (*r)->length();
871  }
872  }
873  }
874 
875  commit_reversible_command ();
876 
877  /* setup peak file building in another thread */
878 
879  for (SourceList::iterator x = sources.begin(); x != sources.end(); ++x) {
880  SourceFactory::setup_peakfile (*x, true);
881  }
882 
883  return 0;
884 }
885 
886 int
888  uint32_t in_chans,
889  uint32_t out_chans,
890  framepos_t& pos,
891  ImportMode mode,
892  boost::shared_ptr<Track>& existing_track,
893  const string& new_track_name,
894  ARDOUR::PluginInfoPtr instrument)
895 {
898 
899  switch (mode) {
900  case ImportAsRegion:
901  /* relax, its been done */
902  break;
903 
904  case ImportToTrack:
905  {
906  if (!existing_track) {
907 
908  if (ar) {
909  existing_track = get_nth_selected_audio_track (0);
910  } else if (mr) {
911  existing_track = get_nth_selected_midi_track (0);
912  }
913 
914  if (!existing_track) {
915  return -1;
916  }
917  }
918 
919  boost::shared_ptr<Playlist> playlist = existing_track->playlist();
920  boost::shared_ptr<Region> copy (RegionFactory::create (region, region->properties()));
921  playlist->clear_changes ();
922  playlist->add_region (copy, pos);
923  if (Config->get_edit_mode() == Ripple)
924  playlist->ripple (pos, copy->length(), copy);
925 
926  _session->add_command (new StatefulDiffCommand (playlist));
927  break;
928  }
929 
930  case ImportAsTrack:
931  {
932  if (!existing_track) {
933  if (ar) {
934  list<boost::shared_ptr<AudioTrack> > at (_session->new_audio_track (in_chans, out_chans, Normal, 0, 1));
935 
936  if (at.empty()) {
937  return -1;
938  }
939 
940  existing_track = at.front();
941  } else if (mr) {
942  list<boost::shared_ptr<MidiTrack> > mt (
943  _session->new_midi_track (ChanCount (DataType::MIDI, 1),
944  ChanCount (DataType::MIDI, 1),
945  instrument,
946  Normal, 0, 1));
947 
948  if (mt.empty()) {
949  return -1;
950  }
951 
952  existing_track = mt.front();
953  }
954 
955  if (!new_track_name.empty()) {
956  existing_track->set_name (new_track_name);
957  } else {
958  existing_track->set_name (region->name());
959  }
960  }
961 
962  boost::shared_ptr<Playlist> playlist = existing_track->playlist();
963  boost::shared_ptr<Region> copy (RegionFactory::create (region, true));
964  playlist->clear_changes ();
965  playlist->add_region (copy, pos);
966  _session->add_command (new StatefulDiffCommand (playlist));
967  break;
968  }
969 
970  case ImportAsTapeTrack:
971  {
972  if (!ar) {
973  return -1;
974  }
975 
976  list<boost::shared_ptr<AudioTrack> > at (_session->new_audio_track (in_chans, out_chans, Destructive));
977  if (!at.empty()) {
978  boost::shared_ptr<Playlist> playlist = at.front()->playlist();
979  boost::shared_ptr<Region> copy (RegionFactory::create (region, true));
980  playlist->clear_changes ();
981  playlist->add_region (copy, pos);
982  _session->add_command (new StatefulDiffCommand (playlist));
983  }
984  break;
985  }
986  }
987 
988  return 0;
989 }
990 
991 void *
993 {
994  SessionEvent::create_per_thread_pool ("import events", 64);
995 
996  Editor *ed = (Editor *) arg;
997  return ed->import_thread ();
998 }
999 
1000 void *
1002 {
1003  _session->import_files (import_status);
1004  return 0;
1005 }
void do_import(std::vector< std::string > paths, Editing::ImportDisposition disposition, Editing::ImportMode mode, ARDOUR::SrcQuality quality, framepos_t &pos, boost::shared_ptr< ARDOUR::PluginInfo > instrument=boost::shared_ptr< ARDOUR::PluginInfo >())
LIBPBD_API Transmitter fatal
void ripple(framepos_t at, framecnt_t distance, RegionList *exclude)
Definition: playlist.cc:2812
std::map< PBD::ID, boost::shared_ptr< ARDOUR::Source > > SourceMap
boost::shared_ptr< ARDOUR::MidiTrack > midi_track() const
Definition: route_ui.cc:1762
bool is_midi_track() const
Definition: route_ui.cc:1756
LIBARDOUR_API PBD::PropertyDescriptor< layer_t > layer
Definition: region.cc:67
bool is_audio_track() const
Definition: route_ui.cc:1744
Definition: ardour_ui.h:130
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r)
Definition: shared_ptr.hpp:396
LIBARDOUR_API PBD::PropertyDescriptor< std::string > name
int embed_sndfiles(std::vector< std::string > paths, bool multiple_files, bool &check_sample_rate, Editing::ImportDisposition disposition, Editing::ImportMode mode, framepos_t &pos, int target_regions, int target_tracks, boost::shared_ptr< ARDOUR::Track > &track, boost::shared_ptr< ARDOUR::PluginInfo > instrument=boost::shared_ptr< ARDOUR::PluginInfo >())
void add_command(Command *const cmd)
Definition: session.h:787
const SourceList & sources() const
Definition: region.h:261
uint32_t n_audio() const
Definition: chan_count.h:63
Definition: Beats.hpp:239
LIBPBD_API Transmitter error
int import_sndfiles(std::vector< std::string > paths, Editing::ImportDisposition disposition, Editing::ImportMode mode, ARDOUR::SrcQuality quality, framepos_t &pos, int target_regions, int target_tracks, boost::shared_ptr< ARDOUR::Track > &track, bool replace, boost::shared_ptr< ARDOUR::PluginInfo > instrument=boost::shared_ptr< ARDOUR::PluginInfo >())
SrcQuality
Definition: types.h:522
std::ostream & endmsg(std::ostream &ostr)
Definition: transmitter.h:71
boost::shared_ptr< ARDOUR::MidiTrack > get_nth_selected_midi_track(int nth) const
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > start
Definition: region.cc:63
framecnt_t frame_rate() const
Definition: session.h:365
static void * _import_thread(void *)
void * import_thread()
LIBARDOUR_API GQuark insert_file
Definition: operations.cc:27
static Handle create(Editor &editor, Gdk::Cursor *cursor)
boost::shared_ptr< AudioFileSource > audio_source_by_path_and_channel(const std::string &, uint16_t) const
Definition: session.cc:3684
#define _(Text)
Definition: i18n.h:11
void add_region(boost::shared_ptr< Region >, framepos_t position, float times=1, bool auto_partition=false)
Definition: playlist.cc:668
int64_t framecnt_t
Definition: types.h:76
LIBARDOUR_API RCConfiguration * Config
Definition: globals.cc:119
uint32_t count_sources_by_origin(const std::string &)
Definition: session.cc:3728
void session_import_dialog()
Definition: amp.h:29
boost::shared_ptr< Route > master_out() const
Definition: session.h:718
boost::shared_ptr< Playlist > playlist()
Definition: track.cc:590
void do_embed(std::vector< std::string > paths, Editing::ImportDisposition disposition, Editing::ImportMode mode, framepos_t &pos, boost::shared_ptr< ARDOUR::PluginInfo > instrument=boost::shared_ptr< ARDOUR::PluginInfo >())
int64_t framepos_t
Definition: types.h:66
LIBARDOUR_API PBD::PropertyDescriptor< bool > external
Definition: region.cc:56
void add_external_audio_action(Editing::ImportMode)
ImportMode
Definition: editing.h:148
const OwnedPropertyList & properties() const
Definition: stateful.h:56
ChanCount n_inputs() const
Definition: route.h:92
LIBARDOUR_API PBD::PropertyDescriptor< bool > regions
Definition: playlist.cc:51
LIBARDOUR_API std::string bump_name_once(const std::string &s, char delimiter)
Definition: utils.cc:158
boost::shared_ptr< ARDOUR::AudioTrack > get_nth_selected_audio_track(int nth) const
LIBPBD_API Glib::ustring basename_nosuffix(Glib::ustring)
const std::string & path() const
Definition: file_source.h:49
int finish_bringing_in_material(boost::shared_ptr< ARDOUR::Region > region, uint32_t in_chans, uint32_t out_chans, framepos_t &pos, Editing::ImportMode mode, boost::shared_ptr< ARDOUR::Track > &existing_track, const std::string &new_track_name, boost::shared_ptr< ARDOUR::PluginInfo > instrument)
Definition: editor.h:134
uint32_t n_channels() const
Definition: region.h:259
ImportDisposition
Definition: editing.h:168
std::list< boost::shared_ptr< AudioTrack > > new_audio_track(int input_channels, int output_channels, TrackMode mode=Normal, RouteGroup *route_group=0, uint32_t how_many=1, std::string name_template="")
Definition: session.cc:2361
std::string name() const
Definition: debug.h:30
int add_sources(std::vector< std::string > paths, ARDOUR::SourceList &sources, framepos_t &pos, Editing::ImportDisposition disposition, Editing::ImportMode mode, int target_regions, int target_tracks, boost::shared_ptr< ARDOUR::Track > &track, bool add_channel_suffix, boost::shared_ptr< ARDOUR::PluginInfo > instrument=boost::shared_ptr< ARDOUR::PluginInfo >())
std::list< boost::shared_ptr< MidiTrack > > new_midi_track(const ChanCount &input, const ChanCount &output, boost::shared_ptr< PluginInfo > instrument=boost::shared_ptr< PluginInfo >(), TrackMode mode=Normal, RouteGroup *route_group=0, uint32_t how_many=1, std::string name_template="")
Definition: session.cc:2117
void import_files(ImportStatus &)
Definition: import.cc:452
LIBPBD_API Glib::ustring short_path(const Glib::ustring &path, Glib::ustring::size_type target_characters)
framecnt_t length() const
Definition: region.h:114
int save_state(std::string snapshot_name, bool pending=false, bool switch_to_snapshot=false, bool template_only=false)
bool set_name(const std::string &str)
Definition: track.cc:316
boost::shared_ptr< ARDOUR::AudioTrack > audio_track() const
Definition: route_ui.cc:1750
int check_whether_and_how_to_import(std::string, bool all_or_nothing=true)
void clear_changes()
Definition: stateful.cc:184
virtual framepos_t natural_position() const
Definition: source.h:70
LIBPBD_API int pthread_create_and_store(std::string name, pthread_t *thread, void *(*start_routine)(void *), void *arg)
std::vector< boost::shared_ptr< Source > > SourceList
Definition: types.h:520
LIBARDOUR_API std::string region_name_from_path(std::string path, bool strip_channels, bool add_channel_suffix=false, uint32_t total=0, uint32_t this_one=0)
bool add(PropertyBase *prop)
ARDOUR::Session * _session
LIBARDOUR_API PBD::PropertyDescriptor< bool > whole_file
Definition: region.cc:54
std::string string_compose(const std::string &fmt, const T1 &o1)
Definition: compose.h:208
LIBARDOUR_API PBD::PropertyDescriptor< framecnt_t > length
Definition: region.cc:64
void external_audio_dialog()