1 /*
2  * Copyright (C) 2006-2014 David Robillard <d@drobilla.net>
3  * Copyright (C) 2006-2017 Paul Davis <paul@linuxaudiosystems.com>
4  * Copyright (C) 2006 Taybin Rutkin <taybin@taybin.com>
5  * Copyright (C) 2007 Tim Mayberry <mojofunk@gmail.com>
6  * Copyright (C) 2009-2012 Carl Hetherington <carl@carlh.net>
7  * Copyright (C) 2012-2019 Robin Gareus <robin@gareus.org>
8  * Copyright (C) 2013-2014 Colin Fletcher <colin.m.fletcher@googlemail.com>
9  * Copyright (C) 2015-2017 Nick Mainsbridge <mainsbridge@gmail.com>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25 
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <sys/time.h>
29 #include <errno.h>
30 #include <unistd.h>
31 #include <algorithm>
32 
33 #include <sndfile.h>
34 
35 #include "pbd/pthread_utils.h"
36 #include "pbd/basename.h"
37 #include "pbd/shortpath.h"
38 #include "pbd/stateful_diff_command.h"
39 
40 #include "widgets/choice.h"
41 
42 #include "ardour/audio_track.h"
43 #include "ardour/audiofilesource.h"
44 #include "ardour/audioregion.h"
45 #include "ardour/midi_region.h"
46 #include "ardour/midi_track.h"
47 #include "ardour/operations.h"
48 #include "ardour/profile.h"
49 #include "ardour/region_factory.h"
50 #include "ardour/smf_source.h"
51 #include "ardour/source_factory.h"
52 #include "ardour/utils.h"
53 #include "pbd/memento_command.h"
54 
55 #include "ardour_message.h"
56 #include "ardour_ui.h"
57 #include "cursor_context.h"
58 #include "editor.h"
59 #include "sfdb_ui.h"
60 #include "editing.h"
61 #include "audio_time_axis.h"
62 #include "midi_time_axis.h"
63 #include "session_import_dialog.h"
64 #include "gui_thread.h"
65 #include "interthread_progress_window.h"
66 #include "mouse_cursors.h"
67 #include "editor_cursors.h"
68 
69 #include "pbd/i18n.h"
70 
71 using namespace std;
72 using namespace ARDOUR;
73 using namespace PBD;
74 using namespace Gtk;
75 using namespace Gtkmm2ext;
76 using namespace Editing;
77 using std::string;
78 
79 /* Functions supporting the incorporation of external (non-captured) audio material into ardour */
80 
81 void
add_external_audio_action(ImportMode mode_hint)82 Editor::add_external_audio_action (ImportMode mode_hint)
83 {
84 	if (_session == 0) {
85 		ArdourMessageDialog msg (_("You can't import or embed an audiofile until you have a session loaded."));
86 		msg.run ();
87 		return;
88 	}
89 
90 	if (sfbrowser == 0) {
91 		sfbrowser = new SoundFileOmega (_("Add Existing Media"), _session, 0, 0, true, mode_hint);
92 	} else {
93 		sfbrowser->set_mode (mode_hint);
94 	}
95 
96 	external_audio_dialog ();
97 }
98 
99 void
external_audio_dialog()100 Editor::external_audio_dialog ()
101 {
102 	vector<string> paths;
103 	uint32_t audio_track_cnt;
104 	uint32_t midi_track_cnt;
105 
106 	if (_session == 0) {
107 		ArdourMessageDialog msg (_("You can't import or embed an audiofile until you have a session loaded."));
108 		msg.run ();
109 		return;
110 	}
111 
112 	audio_track_cnt = 0;
113 	midi_track_cnt = 0;
114 
115 	for (TrackSelection::iterator x = selection->tracks.begin(); x != selection->tracks.end(); ++x) {
116 		AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(*x);
117 
118 		if (atv) {
119 			if (atv->is_audio_track()) {
120 				audio_track_cnt++;
121 			}
122 
123 		} else {
124 			MidiTimeAxisView* mtv = dynamic_cast<MidiTimeAxisView*>(*x);
125 
126 			if (mtv) {
127 				if (mtv->is_midi_track()) {
128 					midi_track_cnt++;
129 				}
130 			}
131 		}
132 	}
133 
134 	if (sfbrowser == 0) {
135 		sfbrowser = new SoundFileOmega (_("Add Existing Media"), _session, audio_track_cnt, midi_track_cnt, true);
136 	} else {
137 		sfbrowser->reset (audio_track_cnt, midi_track_cnt);
138 	}
139 
140 	sfbrowser->show_all ();
141 }
142 
143 void
session_import_dialog()144 Editor::session_import_dialog ()
145 {
146 	SessionImportDialog dialog (_session);
147 	dialog.run ();
148 }
149 
150 typedef std::map<PBD::ID,boost::shared_ptr<ARDOUR::Source> > SourceMap;
151 
152 /**
153  * Updating is still disabled, see note in libs/ardour/import.cc Session::import_files()
154  *
155  * all_or_nothing:
156  *   true  = show "Update", "Import" and "Skip"
157  *   false = show "Import", and "Cancel"
158  *
159  * Returns:
160  *     0  To update an existing source of the same name
161  *     1  To import/embed the file normally (make sure the new name will be unique)
162  *     2  If the user wants to skip this file
163  **/
164 int
check_whether_and_how_to_import(string path,bool all_or_nothing)165 Editor::check_whether_and_how_to_import(string path, bool all_or_nothing)
166 {
167 	string wave_name (Glib::path_get_basename(path));
168 
169 	bool already_exists = false;
170 	uint32_t existing;
171 
172 	if ((existing = _session->count_sources_by_origin (path)) > 0) {
173 		already_exists = true;
174 	}
175 
176 	int function = 1;
177 
178 	if (already_exists) {
179 		string message;
180 		if (all_or_nothing) {
181 			// updating is still disabled
182 			//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);
183 			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);
184 		} else {
185 			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);
186 
187 		}
188 		ArdourMessageDialog dialog(message, false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_NONE, true);
189 
190 		if (all_or_nothing) {
191 			// disabled
192 			//dialog.add_button("Update", 0);
193 			dialog.add_button("Import", 1);
194 			dialog.add_button("Skip",   2);
195 		} else {
196 			dialog.add_button("Import", 1);
197 			dialog.add_button("Cancel", 2);
198 		}
199 
200 		//dialog.add_button("Skip all", 4); // All or rest?
201 
202 		function = dialog.run ();
203 		dialog.hide();
204 	}
205 
206 	return function;
207 }
208 
209 boost::shared_ptr<AudioTrack>
get_nth_selected_audio_track(int nth) const210 Editor::get_nth_selected_audio_track (int nth) const
211 {
212 	AudioTimeAxisView* atv;
213 	TrackSelection::iterator x;
214 
215 	for (x = selection->tracks.begin(); nth > 0 && x != selection->tracks.end(); ++x) {
216 
217 		atv = dynamic_cast<AudioTimeAxisView*>(*x);
218 
219 		if (!atv) {
220 			continue;
221 		} else if (atv->is_audio_track()) {
222 			--nth;
223 		}
224 	}
225 
226 	if (x == selection->tracks.end()) {
227 		atv = dynamic_cast<AudioTimeAxisView*>(selection->tracks.back());
228 	} else {
229 		atv = dynamic_cast<AudioTimeAxisView*>(*x);
230 	}
231 
232 	if (!atv || !atv->is_audio_track()) {
233 		return boost::shared_ptr<AudioTrack>();
234 	}
235 
236 	return atv->audio_track();
237 }
238 
239 boost::shared_ptr<MidiTrack>
get_nth_selected_midi_track(int nth) const240 Editor::get_nth_selected_midi_track (int nth) const
241 {
242 	MidiTimeAxisView* mtv;
243 	TrackSelection::iterator x;
244 
245 	for (x = selection->tracks.begin(); nth > 0 && x != selection->tracks.end(); ++x) {
246 
247 		mtv = dynamic_cast<MidiTimeAxisView*>(*x);
248 
249 		if (!mtv) {
250 			continue;
251 		} else if (mtv->is_midi_track()) {
252 			--nth;
253 		}
254 	}
255 
256 	if (x == selection->tracks.end()) {
257 		mtv = dynamic_cast<MidiTimeAxisView*>(selection->tracks.back());
258 	} else {
259 		mtv = dynamic_cast<MidiTimeAxisView*>(*x);
260 	}
261 
262 	if (!mtv || !mtv->is_midi_track()) {
263 		return boost::shared_ptr<MidiTrack>();
264 	}
265 
266 	return mtv->midi_track();
267 }
268 
269 void
import_smf_tempo_map(Evoral::SMF const & smf,samplepos_t pos)270 Editor::import_smf_tempo_map (Evoral::SMF const & smf, samplepos_t pos)
271 {
272 	if (!_session) {
273 		return;
274 	}
275 
276 	const size_t num_tempos = smf.num_tempos ();
277 
278 	if (num_tempos == 0) {
279 		return;
280 	}
281 
282 	const samplecnt_t sample_rate = _session->sample_rate ();
283 	TempoMap new_map (sample_rate);
284 	Meter last_meter (4.0, 4.0);
285 	bool have_initial_meter = false;
286 
287 	for (size_t n = 0; n < num_tempos; ++n) {
288 
289 		Evoral::SMF::Tempo* t = smf.nth_tempo (n);
290 		assert (t);
291 
292 		Tempo tempo (t->tempo(), 32.0 / (double) t->notes_per_note);
293 		Meter meter (t->numerator, t->denominator);
294 		Timecode::BBT_Time bbt; /* 1|1|0 which is correct for the no-meter case */
295 
296 		if (have_initial_meter) {
297 			new_map.add_tempo (tempo, t->time_pulses/ (double)smf.ppqn() / 4.0, 0, MusicTime);
298 			if (!(meter == last_meter)) {
299 				bbt = new_map.bbt_at_quarter_note (t->time_pulses/(double)smf.ppqn());
300 				new_map.add_meter (meter, bbt, 0, MusicTime);
301 			}
302 
303 		} else {
304 			new_map.replace_meter (new_map.meter_section_at_sample (0), meter, bbt, pos, AudioTime);
305 			new_map.replace_tempo (new_map.tempo_section_at_sample (0), tempo, 0.0, pos, AudioTime);
306 			have_initial_meter = true;
307 
308 		}
309 
310 		last_meter = meter;
311 	}
312 
313 	_session->tempo_map() = new_map;
314 }
315 
316 void
import_smf_markers(Evoral::SMF & smf,samplepos_t pos)317 Editor::import_smf_markers (Evoral::SMF & smf, samplepos_t pos)
318 {
319 	if (!_session) {
320 		return;
321 	}
322 
323 	smf.load_markers ();
324 
325 	Evoral::SMF::Markers const & markers = smf.markers();
326 
327 	if (markers.empty()) {
328 		return;
329 	}
330 
331 	/* XXX in nutempo2 just add location using Beats */
332 
333 	for (Evoral::SMF::Markers::const_iterator m = markers.begin(); m != markers.end(); ++m) {
334 		// Temporal::Beats beat_pos (m->time_pulses / (double) smf.ppqn() / 4.0);
335 		double beat = m->time_pulses / (double) smf.ppqn();
336 		samplepos_t samplepos = pos + _session->tempo_map().sample_at_beat (beat);
337 		Location* loc = new Location (*_session, samplepos, samplepos_t (0), m->text, Location::IsMark, 0);
338 		_session->locations()->add (loc);
339 	}
340 
341 }
342 
343 void
do_import(vector<string> paths,ImportDisposition disposition,ImportMode mode,SrcQuality quality,MidiTrackNameSource midi_track_name_source,MidiTempoMapDisposition smf_tempo_disposition,samplepos_t & pos,ARDOUR::PluginInfoPtr instrument,bool with_markers)344 Editor::do_import (vector<string>          paths,
345                    ImportDisposition       disposition,
346                    ImportMode              mode,
347                    SrcQuality              quality,
348                    MidiTrackNameSource     midi_track_name_source,
349                    MidiTempoMapDisposition smf_tempo_disposition,
350                    samplepos_t&            pos,
351                    ARDOUR::PluginInfoPtr   instrument,
352                    bool                    with_markers)
353 {
354 	boost::shared_ptr<Track> track;
355 	vector<string> to_import;
356 	int nth = 0;
357 	bool use_timestamp = (pos == -1);
358 
359 	/* XXX nutempo2: we will import markers using music (beat) time, which
360 	   will make any imported tempo map irrelevant. Not doing that (in 6.7,
361 	   before nutempo2) is much more complicated because we don't know
362 	   which file may have the tempo map, and if we're importing that
363 	   it will change the marker positions. So for now, there's an implicit
364 	   limitation that if you import more than 1 MIDI file and the first
365 	   has markers but the second has the tempo map, the markers could be
366 	   in the wrong position.
367 	*/
368 
369 	if (with_markers || (smf_tempo_disposition == SMFTempoUse)) {
370 
371 		bool tempo_map_done = false;
372 
373 		for (vector<string>::iterator a = paths.begin(); a != paths.end(); ++a) {
374 
375 			Evoral::SMF smf;
376 
377 			if (smf.open (*a)) {
378 				continue;
379 			}
380 
381 			/* Find the first MIDI file with a tempo map, and import it
382 			   before we do anything else.
383 			*/
384 			if (!tempo_map_done && smf_tempo_disposition == SMFTempoUse) {
385 				if (smf.num_tempos() > 0) {
386 					import_smf_tempo_map (smf, pos);
387 					tempo_map_done = true;
388 				}
389 			}
390 
391 			if (with_markers) {
392 
393 				import_smf_markers (smf, pos);
394 			}
395 
396 			smf.close ();
397 		}
398 	}
399 
400 	current_interthread_info = &import_status;
401 	import_status.current = 1;
402 	import_status.total = paths.size ();
403 	import_status.all_done = false;
404 	import_status.midi_track_name_source = midi_track_name_source;
405 
406 	ImportProgressWindow ipw (&import_status, _("Import"), _("Cancel Import"));
407 
408 	if (disposition == Editing::ImportMergeFiles) {
409 
410 		/* create 1 region from all paths, add to 1 track,
411 		   ignore "track"
412 		*/
413 
414 		bool cancel = false;
415 		for (vector<string>::iterator a = paths.begin(); a != paths.end(); ++a) {
416 			int check = check_whether_and_how_to_import(*a, false);
417 			if (check == 2) {
418 				cancel = true;
419 				break;
420 			}
421 		}
422 
423 		if (!cancel) {
424 			ipw.show ();
425 			import_sndfiles (paths, disposition, mode, quality, pos, 1, 1, track, false, instrument);
426 			import_status.clear();
427 		}
428 
429 	} else {
430 
431 		bool replace = false;
432 
433 		for (vector<string>::iterator a = paths.begin(); a != paths.end() && !import_status.cancel; ++a) {
434 
435 			const int check = check_whether_and_how_to_import (*a, true);
436 
437 			switch (check) {
438 			case 2:
439 				// user said skip
440 				continue;
441 			case 0:
442 				fatal << "Updating existing sources should be disabled!" << endmsg;
443 				abort(); /* NOTREACHED*/
444 				break;
445 			case 1:
446 				replace = false;
447 				break;
448 			default:
449 				fatal << "Illegal return " << check <<  " from check_whether_and_how_to_import()!" << endmsg;
450 				abort(); /* NOTREACHED*/
451 			}
452 
453 			/* have to reset this for every file we handle */
454 
455 			if (use_timestamp) {
456 				pos = -1;
457 			}
458 
459 			ipw.show ();
460 
461 			switch (disposition) {
462 			case Editing::ImportDistinctFiles:
463 
464 				to_import.clear ();
465 				to_import.push_back (*a);
466 
467 				if (mode == Editing::ImportToTrack) {
468 					track = get_nth_selected_audio_track (nth++);
469 				}
470 
471 				import_sndfiles (to_import, disposition, mode, quality, pos, 1, -1, track, replace, instrument);
472 				import_status.clear();
473 				break;
474 
475 			case Editing::ImportDistinctChannels:
476 
477 				to_import.clear ();
478 				to_import.push_back (*a);
479 
480 				import_sndfiles (to_import, disposition, mode, quality, pos, -1, -1, track, replace, instrument);
481 				import_status.clear();
482 				break;
483 
484 			case Editing::ImportSerializeFiles:
485 
486 				to_import.clear ();
487 				to_import.push_back (*a);
488 
489 				import_sndfiles (to_import, disposition, mode, quality, pos, 1, 1, track, replace, instrument);
490 				import_status.clear();
491 				break;
492 
493 			case Editing::ImportMergeFiles:
494 				// Not entered, handled in earlier if() branch
495 				break;
496 			}
497 		}
498 	}
499 
500 	import_status.all_done = true;
501 }
502 
503 void
do_embed(vector<string> paths,ImportDisposition import_as,ImportMode mode,samplepos_t & pos,ARDOUR::PluginInfoPtr instrument)504 Editor::do_embed (vector<string> paths, ImportDisposition import_as, ImportMode mode, samplepos_t& pos, ARDOUR::PluginInfoPtr instrument)
505 {
506 	boost::shared_ptr<Track> track;
507 	bool check_sample_rate = true;
508 	vector<string> to_embed;
509 	bool multi = paths.size() > 1;
510 	int nth = 0;
511 	bool use_timestamp = (pos == -1);
512 
513 	switch (import_as) {
514 	case Editing::ImportDistinctFiles:
515 		for (vector<string>::iterator a = paths.begin(); a != paths.end(); ++a) {
516 
517 			/* have to reset this for every file we handle */
518 			if (use_timestamp) {
519 				pos = -1;
520 			}
521 
522 			to_embed.clear ();
523 			to_embed.push_back (*a);
524 
525 			if (mode == Editing::ImportToTrack) {
526 				track = get_nth_selected_audio_track (nth++);
527 			}
528 
529 			if (embed_sndfiles (to_embed, multi, check_sample_rate, import_as, mode, pos, 1, -1, track, instrument) < -1) {
530 				/* error, bail out */
531 				return;
532 			}
533 		}
534 		break;
535 
536 	case Editing::ImportDistinctChannels:
537 		for (vector<string>::iterator a = paths.begin(); a != paths.end(); ++a) {
538 
539 			/* have to reset this for every file we handle */
540 			if (use_timestamp) {
541 				pos = -1;
542 			}
543 
544 			to_embed.clear ();
545 			to_embed.push_back (*a);
546 
547 			if (embed_sndfiles (to_embed, multi, check_sample_rate, import_as, mode, pos, -1, -1, track, instrument) < -1) {
548 				/* error, bail out */
549 				return;
550 			}
551 		}
552 		break;
553 
554 	case Editing::ImportMergeFiles:
555 		if (embed_sndfiles (paths, multi, check_sample_rate, import_as, mode, pos, 1, 1, track, instrument) < -1) {
556 			/* error, bail out */
557 			return;
558 		}
559 		break;
560 
561 	case Editing::ImportSerializeFiles:
562 		for (vector<string>::iterator a = paths.begin(); a != paths.end(); ++a) {
563 
564 			/* have to reset this for every file we handle */
565 			if (use_timestamp) {
566 				pos = -1;
567 			}
568 
569 			to_embed.clear ();
570 			to_embed.push_back (*a);
571 
572 			if (embed_sndfiles (to_embed, multi, check_sample_rate, import_as, mode, pos, 1, 1, track, instrument) < -1) {
573 				/* error, bail out */
574 				return;
575 			}
576 		}
577 		break;
578 	}
579 }
580 
581 int
import_sndfiles(vector<string> paths,ImportDisposition disposition,ImportMode mode,SrcQuality quality,samplepos_t & pos,int target_regions,int target_tracks,boost::shared_ptr<Track> & track,bool replace,ARDOUR::PluginInfoPtr instrument)582 Editor::import_sndfiles (vector<string>            paths,
583                          ImportDisposition         disposition,
584                          ImportMode                mode,
585                          SrcQuality                quality,
586                          samplepos_t&              pos,
587                          int                       target_regions,
588                          int                       target_tracks,
589                          boost::shared_ptr<Track>& track,
590                          bool                      replace,
591                          ARDOUR::PluginInfoPtr     instrument)
592 {
593 	/* skip periodic saves while importing */
594 	Session::StateProtector sp (_session);
595 
596 	import_status.paths = paths;
597 	import_status.done = false;
598 	import_status.freeze = false;
599 	import_status.quality = quality;
600 	import_status.replace_existing_source = replace;
601 	import_status.split_midi_channels = (disposition == Editing::ImportDistinctChannels);
602 
603 	import_status.mode = mode;
604 	import_status.pos = pos;
605 	import_status.target_tracks = target_tracks;
606 	import_status.target_regions = target_regions;
607 	import_status.track = track;
608 	import_status.replace = replace;
609 
610 	CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait);
611 	gdk_flush ();
612 
613 	/* start import thread for this spec. this will ultimately call Session::import_files()
614 	   which, if successful, will add the files as regions to the region list. its up to us
615 	   (the GUI) to direct additional steps after that.
616 	*/
617 
618 	pthread_create_and_store ("import", &import_status.thread, _import_thread, this);
619 	pthread_detach (import_status.thread);
620 
621 	while (!import_status.done && !import_status.cancel) {
622 		gtk_main_iteration ();
623 	}
624 
625 	// wait for thread to terminate
626 	while (!import_status.done) {
627 		gtk_main_iteration ();
628 	}
629 
630 	int result = -1;
631 
632 	if (!import_status.cancel && !import_status.sources.empty()) {
633 		result = add_sources (
634 			import_status.paths,
635 			import_status.sources,
636 			import_status.pos,
637 			disposition,
638 			import_status.mode,
639 			import_status.target_regions,
640 			import_status.target_tracks,
641 			track, false, instrument
642 			);
643 
644 		/* update position from results */
645 
646 		pos = import_status.pos;
647 	}
648 
649 	return result;
650 }
651 
652 int
embed_sndfiles(vector<string> paths,bool multifile,bool & check_sample_rate,ImportDisposition disposition,ImportMode mode,samplepos_t & pos,int target_regions,int target_tracks,boost::shared_ptr<Track> & track,ARDOUR::PluginInfoPtr instrument)653 Editor::embed_sndfiles (vector<string>            paths,
654                         bool                      multifile,
655                         bool&                     check_sample_rate,
656                         ImportDisposition         disposition,
657                         ImportMode                mode,
658                         samplepos_t&              pos,
659                         int                       target_regions,
660                         int                       target_tracks,
661                         boost::shared_ptr<Track>& track,
662                         ARDOUR::PluginInfoPtr     instrument)
663 {
664 	boost::shared_ptr<AudioFileSource> source;
665 	SourceList sources;
666 	string linked_path;
667 	SoundFileInfo finfo;
668 
669 	/* skip periodic saves while importing */
670 	Session::StateProtector sp (_session);
671 
672 	CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait);
673 	gdk_flush ();
674 
675 	for (vector<string>::iterator p = paths.begin(); p != paths.end(); ++p) {
676 
677 		string path = *p;
678 		string error_msg;
679 
680 		/* note that we temporarily truncated _id at the colon */
681 
682 		if (!AudioFileSource::get_soundfile_info (path, finfo, error_msg)) {
683 			error << string_compose(_("Editor: cannot open file \"%1\", (%2)"), path, error_msg ) << endmsg;
684 			return -3;
685 		}
686 
687 		if (!finfo.seekable) {
688 			ArdourMessageDialog msg (string_compose (_("%1\nThis audiofile cannot be embedded. It must be imported!"), short_path (path, 40)), false, Gtk::MESSAGE_ERROR);
689 			msg.run ();
690 			return -2;
691 		}
692 
693 		if (check_sample_rate  && (finfo.samplerate != (int) _session->sample_rate())) {
694 			vector<string> choices;
695 
696 			if (multifile) {
697 				choices.push_back (_("Cancel entire import"));
698 				choices.push_back (_("Don't embed it"));
699 				choices.push_back (_("Embed all without questions"));
700 
701 				ArdourWidgets::Choice rate_choice (
702 					_("Sample rate"),
703 					string_compose (_("%1\nThis audiofile's sample rate doesn't match the session sample rate!"),
704 							short_path (path, 40)),
705 					choices, false
706 					);
707 
708 				int resx = rate_choice.run ();
709 
710 				switch (resx) {
711 				case 0: /* stop a multi-file import */
712 					return -2;
713 				case 1: /* don't embed this one */
714 					return -1;
715 				case 2: /* do it, and the rest without asking */
716 					check_sample_rate = false;
717 					break;
718 				case 3: /* do it */
719 					break;
720 				default:
721 					return -2;
722 				}
723 			} else {
724 				choices.push_back (_("Cancel"));
725 				choices.push_back (_("Embed it anyway"));
726 
727 				ArdourWidgets::Choice rate_choice (
728 					_("Sample rate"),
729 					string_compose (_("%1\nThis audiofile's sample rate doesn't match the session sample rate!"), path),
730 					choices, false
731 					);
732 
733 				int resx = rate_choice.run ();
734 
735 				switch (resx) {
736 				case 0: /* don't import */
737 					return -1;
738 				case 1: /* do it */
739 					break;
740 				default:
741 					return -2;
742 				}
743 			}
744 		}
745 
746 		for (int n = 0; n < finfo.channels; ++n) {
747 
748 			try {
749 
750 				/* check if we have this thing embedded already */
751 
752 				boost::shared_ptr<Source> s;
753 
754 				if ((s = _session->audio_source_by_path_and_channel (path, n)) == 0) {
755 
756 					source = boost::dynamic_pointer_cast<AudioFileSource> (
757 						SourceFactory::createExternal (DataType::AUDIO, *_session,
758 									       path, n,
759 						                               Source::Flag (0),
760 									true, true));
761 				} else {
762 					source = boost::dynamic_pointer_cast<AudioFileSource> (s);
763 				}
764 
765 				sources.push_back(source);
766 			}
767 
768 			catch (failed_constructor& err) {
769 				error << string_compose(_("could not open %1"), path) << endmsg;
770 				return -3;
771 			}
772 
773 			gtk_main_iteration();
774 		}
775 	}
776 
777 	if (!sources.empty()) {
778 		return add_sources (paths, sources, pos, disposition, mode, target_regions, target_tracks, track, true, instrument);
779 	}
780 
781 	return 0;
782 }
783 
784 int
add_sources(vector<string> paths,SourceList & sources,samplepos_t & pos,ImportDisposition disposition,ImportMode mode,int target_regions,int target_tracks,boost::shared_ptr<Track> & track,bool,ARDOUR::PluginInfoPtr instrument)785 Editor::add_sources (vector<string>            paths,
786                      SourceList&               sources,
787                      samplepos_t&              pos,
788                      ImportDisposition         disposition,
789                      ImportMode                mode,
790                      int                       target_regions,
791                      int                       target_tracks,
792                      boost::shared_ptr<Track>& track,
793                      bool                      /*add_channel_suffix*/,
794                      ARDOUR::PluginInfoPtr     instrument)
795 {
796 	vector<boost::shared_ptr<Region> > regions;
797 	string region_name;
798 	uint32_t input_chan = 0;
799 	uint32_t output_chan = 0;
800 	bool use_timestamp;
801 	vector<string> track_names;
802 
803 	use_timestamp = (pos == -1);
804 
805 	// kludge (for MIDI we're abusing "channel" for "track" here)
806 	if (SMFSource::safe_midi_file_extension (paths.front())) {
807 		target_regions = -1;
808 	}
809 
810 	if (target_regions == 1) {
811 
812 		/* take all the sources we have and package them up as a region */
813 
814 		region_name = region_name_from_path (paths.front(), (sources.size() > 1), false);
815 
816 		/* we checked in import_sndfiles() that there were not too many */
817 
818 		while (RegionFactory::region_by_name (region_name)) {
819 			region_name = bump_name_once (region_name, '.');
820 		}
821 
822 		PropertyList plist;
823 
824 		plist.add (ARDOUR::Properties::start, 0);
825 		plist.add (ARDOUR::Properties::length, sources[0]->length (pos));
826 		plist.add (ARDOUR::Properties::name, region_name);
827 		plist.add (ARDOUR::Properties::layer, 0);
828 		plist.add (ARDOUR::Properties::whole_file, true);
829 		plist.add (ARDOUR::Properties::external, true);
830 
831 		boost::shared_ptr<Region> r = RegionFactory::create (sources, plist);
832 
833 		if (boost::dynamic_pointer_cast<AudioRegion>(r)) {
834 			boost::dynamic_pointer_cast<AudioRegion>(r)->special_set_position(sources[0]->natural_position());
835 		}
836 
837 		regions.push_back (r);
838 
839 		/* if we're creating a new track, name it after the cleaned-up
840 		 * and "merged" region name.
841 		 */
842 
843 		track_names.push_back (region_name);
844 
845 	} else if (target_regions == -1 || target_regions > 1) {
846 
847 		/* take each source and create a region for each one */
848 
849 		SourceList just_one;
850 		SourceList::iterator x;
851 		uint32_t n;
852 
853 		for (n = 0, x = sources.begin(); x != sources.end(); ++x, ++n) {
854 
855 			just_one.clear ();
856 			just_one.push_back (*x);
857 
858 			boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (*x);
859 
860 			if (sources.size() > 1 && disposition == ImportDistinctChannels) {
861 
862 				/* generate a per-channel region name so that things work as
863 				 * intended
864 				 */
865 
866 				string path;
867 
868 				if (fs) {
869 					region_name = basename_nosuffix (fs->path());
870 				} else {
871 					region_name = (*x)->name();
872 				}
873 
874 				if (sources.size() == 2) {
875 					if (n == 0) {
876 						region_name += "-L";
877 					} else {
878 						region_name += "-R";
879 					}
880 				} else if (sources.size() > 2) {
881 					region_name += string_compose ("-%1", n+1);
882 				}
883 
884 				track_names.push_back (region_name);
885 
886 			} else {
887 				if (fs) {
888 					region_name = region_name_from_path (fs->path(), false, false, sources.size(), n);
889 				} else {
890 					region_name = (*x)->name();
891 				}
892 
893 				if (SMFSource::safe_midi_file_extension (paths.front())) {
894 					string track_name = string_compose ("%1-t%2", PBD::basename_nosuffix (fs->path()), (n + 1));
895 					track_names.push_back (track_name);
896 				} else {
897 					track_names.push_back (PBD::basename_nosuffix (paths[n]));
898 				}
899 			}
900 
901 			PropertyList plist;
902 
903 			/* Fudge region length to ensure it is non-zero; make it 1 beat at 120bpm
904 			   for want of a better idea.  It can't be too small, otherwise if this
905 			   is a MIDI region the conversion from samples -> beats -> samples will
906 			   round it back down to 0 again.
907 			*/
908 			samplecnt_t len = (*x)->length (pos);
909 			if (len == 0) {
910 				len = (60.0 / 120.0) * _session->sample_rate ();
911 			}
912 
913 			plist.add (ARDOUR::Properties::start, 0);
914 			plist.add (ARDOUR::Properties::length, len);
915 			plist.add (ARDOUR::Properties::name, region_name);
916 			plist.add (ARDOUR::Properties::layer, 0);
917 			plist.add (ARDOUR::Properties::whole_file, true);
918 			plist.add (ARDOUR::Properties::external, true);
919 
920 			boost::shared_ptr<Region> r = RegionFactory::create (just_one, plist);
921 
922 			if (boost::dynamic_pointer_cast<AudioRegion>(r)) {
923 				boost::dynamic_pointer_cast<AudioRegion>(r)->special_set_position((*x)->natural_position());
924 			}
925 
926 			regions.push_back (r);
927 		}
928 	}
929 
930 	if (target_regions == 1) {
931 		input_chan = regions.front()->n_channels();
932 	} else {
933 		if (target_tracks == 1) {
934 			input_chan = regions.size();
935 		} else {
936 			input_chan = 1;
937 		}
938 	}
939 
940 	if (Config->get_output_auto_connect() & AutoConnectMaster) {
941 		output_chan = (_session->master_out() ? _session->master_out()->n_inputs().n_audio() : input_chan);
942 	} else {
943 		output_chan = input_chan;
944 	}
945 
946 	int n = 0;
947 	samplepos_t rlen = 0;
948 
949 	begin_reversible_command (Operations::insert_file);
950 
951 	/* we only use tracks names when importing to new tracks, but we
952 	 * require that one is defined for every region, just to keep
953 	 * the API simpler.
954 	 */
955 	assert (regions.size() == track_names.size());
956 
957 	for (vector<boost::shared_ptr<Region> >::iterator r = regions.begin(); r != regions.end(); ++r, ++n) {
958 		boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (*r);
959 
960 		if (use_timestamp) {
961 			if (ar) {
962 
963 				/* get timestamp for this region */
964 
965 				const boost::shared_ptr<Source> s (ar->sources().front());
966 				const boost::shared_ptr<AudioSource> as = boost::dynamic_pointer_cast<AudioSource> (s);
967 
968 				assert (as);
969 
970 				if (as->natural_position() != 0) {
971 					pos = as->natural_position();
972 				} else if (target_tracks == 1) {
973 					/* hmm, no timestamp available, put it after the previous region
974 					 */
975 					if (n == 0) {
976 						pos = get_preferred_edit_position ();
977 					} else {
978 						pos += rlen;
979 					}
980 				} else {
981 					pos = get_preferred_edit_position ();
982 				}
983 			} else {
984 				/* should really get first position in MIDI file, but for now, use edit position*/
985 				pos = get_preferred_edit_position ();
986 			}
987 		}
988 
989 		finish_bringing_in_material (*r, input_chan, output_chan, pos, mode, track, track_names[n], instrument);
990 
991 		rlen = (*r)->length();
992 
993 		if (target_tracks != 1) {
994 			track.reset ();
995 		} else {
996 			if (!use_timestamp || !ar) {
997 				/* line each one up right after the other */
998 				pos += (*r)->length();
999 			}
1000 		}
1001 	}
1002 
1003 	commit_reversible_command ();
1004 
1005 	/* setup peak file building in another thread */
1006 
1007 	for (SourceList::iterator x = sources.begin(); x != sources.end(); ++x) {
1008 		SourceFactory::setup_peakfile (*x, true);
1009 	}
1010 
1011 	return 0;
1012 }
1013 
1014 int
finish_bringing_in_material(boost::shared_ptr<Region> region,uint32_t in_chans,uint32_t out_chans,samplepos_t & pos,ImportMode mode,boost::shared_ptr<Track> & existing_track,const string & new_track_name,ARDOUR::PluginInfoPtr instrument)1015 Editor::finish_bringing_in_material (boost::shared_ptr<Region> region,
1016                                      uint32_t                  in_chans,
1017                                      uint32_t                  out_chans,
1018                                      samplepos_t&               pos,
1019                                      ImportMode                mode,
1020                                      boost::shared_ptr<Track>& existing_track,
1021                                      const string&             new_track_name,
1022                                      ARDOUR::PluginInfoPtr     instrument)
1023 {
1024 	boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(region);
1025 	boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(region);
1026 
1027 	switch (mode) {
1028 	case ImportAsRegion:
1029 		/* relax, its been done */
1030 		break;
1031 
1032 	case ImportToTrack:
1033 	{
1034 		if (!existing_track) {
1035 
1036 			if (ar) {
1037 				existing_track = get_nth_selected_audio_track (0);
1038 			} else if (mr) {
1039 				existing_track = get_nth_selected_midi_track (0);
1040 			}
1041 
1042 			if (!existing_track) {
1043 				return -1;
1044 			}
1045 		}
1046 
1047 		boost::shared_ptr<Playlist> playlist = existing_track->playlist();
1048 		boost::shared_ptr<Region> copy (RegionFactory::create (region, region->properties()));
1049 		playlist->clear_changes ();
1050 		playlist->clear_owned_changes ();
1051 		playlist->add_region (copy, pos);
1052 		if (Config->get_edit_mode() == Ripple) {
1053 			playlist->ripple (pos, copy->length(), copy);
1054 
1055 			/* recusive diff of rippled regions */
1056 			vector<Command*> cmds;
1057 			playlist->rdiff (cmds);
1058 			_session->add_commands (cmds);
1059 		}
1060 
1061 		_session->add_command (new StatefulDiffCommand (playlist));
1062 		break;
1063 	}
1064 
1065 	case ImportAsTrack:
1066 	{
1067 		if (!existing_track) {
1068 			if (ar) {
1069 				list<boost::shared_ptr<AudioTrack> > at (_session->new_audio_track (in_chans, out_chans, 0, 1, string(), PresentationInfo::max_order, Normal));
1070 
1071 				if (at.empty()) {
1072 					return -1;
1073 				}
1074 				if (Config->get_strict_io ()) {
1075 					for (list<boost::shared_ptr<AudioTrack> >::iterator i = at.begin(); i != at.end(); ++i) {
1076 						(*i)->set_strict_io (true);
1077 					}
1078 				}
1079 
1080 				existing_track = at.front();
1081 			} else if (mr) {
1082 				list<boost::shared_ptr<MidiTrack> > mt (
1083 					_session->new_midi_track (ChanCount (DataType::MIDI, 1),
1084 						                  ChanCount (DataType::MIDI, 1),
1085 					                          Config->get_strict_io () || Profile->get_mixbus (),
1086 					                          instrument, (Plugin::PresetRecord*) 0,
1087 					                          (RouteGroup*) 0,
1088 					                          1,
1089 					                          string(),
1090 					                          PresentationInfo::max_order));
1091 
1092 				if (mt.empty()) {
1093 					return -1;
1094 				}
1095 
1096 				// TODO set strict_io from preferences
1097 				existing_track = mt.front();
1098 			}
1099 
1100 			if (!new_track_name.empty()) {
1101 				existing_track->set_name (new_track_name);
1102 			} else {
1103 				existing_track->set_name (region->name());
1104 			}
1105 		}
1106 
1107 		boost::shared_ptr<Playlist> playlist = existing_track->playlist();
1108 		boost::shared_ptr<Region> copy (RegionFactory::create (region, true));
1109 		playlist->clear_changes ();
1110 		playlist->add_region (copy, pos);
1111 		_session->add_command (new StatefulDiffCommand (playlist));
1112 		break;
1113 	}
1114 
1115 	}
1116 
1117 	return 0;
1118 }
1119 
1120 void *
_import_thread(void * arg)1121 Editor::_import_thread (void *arg)
1122 {
1123 	SessionEvent::create_per_thread_pool ("import events", 64);
1124 
1125 	Editor *ed = (Editor *) arg;
1126 	return ed->import_thread ();
1127 }
1128 
1129 void *
import_thread()1130 Editor::import_thread ()
1131 {
1132 	_session->import_files (import_status);
1133 	return 0;
1134 }
1135