2 Copyright (C) 2000 Paul Davis
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.
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.
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.
21 #include "libardour-config.h"
35 #include <samplerate.h>
39 #include <boost/scoped_array.hpp>
40 #include <boost/shared_array.hpp>
42 #include "pbd/basename.h"
43 #include "pbd/convert.h"
45 #include "evoral/SMF.hpp"
47 #include "ardour/analyser.h"
48 #include "ardour/ardour.h"
49 #include "ardour/audio_diskstream.h"
50 #include "ardour/audioengine.h"
51 #include "ardour/audioregion.h"
52 #include "ardour/import_status.h"
53 #include "ardour/region_factory.h"
54 #include "ardour/resampled_source.h"
55 #include "ardour/runtime_functions.h"
56 #include "ardour/session.h"
57 #include "ardour/session_directory.h"
58 #include "ardour/smf_source.h"
59 #include "ardour/sndfile_helpers.h"
60 #include "ardour/sndfileimportable.h"
61 #include "ardour/sndfilesource.h"
62 #include "ardour/source_factory.h"
63 #include "ardour/tempo.h"
66 #include "ardour/caimportable.h"
72 using namespace ARDOUR;
75 static boost::shared_ptr<ImportableSource>
76 open_importable_source (const string& path, framecnt_t samplerate, ARDOUR::SrcQuality quality)
78 /* try libsndfile first, because it can get BWF info from .wav, which ExtAudioFile cannot.
79 We don't necessarily need that information in an ImportableSource, but it keeps the
80 logic the same as in SourceFactory::create()
84 boost::shared_ptr<SndFileImportableSource> source(new SndFileImportableSource(path));
86 if (source->samplerate() == samplerate) {
90 /* rewrap as a resampled source */
92 return boost::shared_ptr<ImportableSource>(new ResampledImportableSource(source, samplerate, quality));
99 /* libsndfile failed, see if we can use CoreAudio to handle the IO */
101 CAImportableSource* src = new CAImportableSource(path);
102 boost::shared_ptr<CAImportableSource> source (src);
104 if (source->samplerate() == samplerate) {
108 /* rewrap as a resampled source */
110 return boost::shared_ptr<ImportableSource>(new ResampledImportableSource(source, samplerate, quality));
120 get_non_existent_filename (HeaderFormat hf, DataType type, const bool allow_replacing, const std::string& destdir, const std::string& basename, uint channel, uint channels)
122 char buf[PATH_MAX+1];
123 bool goodfile = false;
124 string base = basename;
125 string ext = native_header_format_extension (hf, type);
130 if (type == DataType::AUDIO && channels == 2) {
133 snprintf (buf, sizeof(buf), "%s-L%s", base.c_str(), ext.c_str());
135 snprintf (buf, sizeof(buf), "%s-%d-L%s", base.c_str(), cnt, ext.c_str());
139 snprintf (buf, sizeof(buf), "%s-R%s", base.c_str(), ext.c_str());
141 snprintf (buf, sizeof(buf), "%s-%d-R%s", base.c_str(), cnt, ext.c_str());
144 } else if (channels > 1) {
146 snprintf (buf, sizeof(buf), "%s-c%d%s", base.c_str(), channel, ext.c_str());
148 snprintf (buf, sizeof(buf), "%s-%d-c%d%s", base.c_str(), cnt, channel, ext.c_str());
152 snprintf (buf, sizeof(buf), "%s%s", base.c_str(), ext.c_str());
154 snprintf (buf, sizeof(buf), "%s-%d%s", base.c_str(), cnt, ext.c_str());
158 string tempname = destdir + "/" + buf;
160 if (!allow_replacing && Glib::file_test (tempname, Glib::FILE_TEST_EXISTS)) {
174 static vector<string>
175 get_paths_for_new_sources (HeaderFormat hf, const bool allow_replacing, const string& import_file_path, const string& session_dir, uint channels)
177 vector<string> new_paths;
178 const string basename = basename_nosuffix (import_file_path);
180 SessionDirectory sdir(session_dir);
182 for (uint n = 0; n < channels; ++n) {
184 const DataType type = SMFSource::safe_midi_file_extension (import_file_path) ? DataType::MIDI : DataType::AUDIO;
186 std::string filepath = (type == DataType::MIDI)
187 ? sdir.midi_path() : sdir.sound_path();
189 filepath = Glib::build_filename (filepath,
190 get_non_existent_filename (hf, type, allow_replacing, filepath, basename, n, channels));
191 new_paths.push_back (filepath);
198 map_existing_mono_sources (const vector<string>& new_paths, Session& /*sess*/,
199 uint /*samplerate*/, vector<boost::shared_ptr<Source> >& newfiles, Session *session)
201 for (vector<string>::const_iterator i = new_paths.begin();
202 i != new_paths.end(); ++i)
204 boost::shared_ptr<Source> source = session->source_by_path_and_channel(*i, 0);
207 error << string_compose(_("Could not find a source for %1 even though we are updating this file!"), (*i)) << endl;
211 newfiles.push_back(boost::dynamic_pointer_cast<Source>(source));
217 create_mono_sources_for_writing (const vector<string>& new_paths,
218 Session& sess, uint samplerate,
219 vector<boost::shared_ptr<Source> >& newfiles,
220 framepos_t timeline_position)
222 for (vector<string>::const_iterator i = new_paths.begin(); i != new_paths.end(); ++i) {
224 boost::shared_ptr<Source> source;
227 const DataType type = SMFSource::safe_midi_file_extension (*i) ? DataType::MIDI : DataType::AUDIO;
229 source = SourceFactory::createWritable (type, sess,
231 false, // destructive
235 catch (const failed_constructor& err) {
236 error << string_compose (_("Unable to create file %1 during import"), *i) << endmsg;
240 newfiles.push_back(boost::dynamic_pointer_cast<Source>(source));
242 /* for audio files, reset the timeline position so that any BWF-ish
243 information in the original files we are importing from is maintained.
246 boost::shared_ptr<AudioFileSource> afs;
247 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
248 afs->set_timeline_position(timeline_position);
255 compose_status_message (const string& path,
256 uint file_samplerate,
257 uint session_samplerate,
258 uint /* current_file */,
259 uint /* total_files */)
261 if (file_samplerate != session_samplerate) {
262 return string_compose (_("Resampling %1 from %2kHz to %3kHz"),
263 Glib::path_get_basename (path),
264 file_samplerate/1000.0f,
265 session_samplerate/1000.0f);
268 return string_compose (_("Copying %1"), Glib::path_get_basename (path));
272 write_audio_data_to_new_files (ImportableSource* source, ImportStatus& status,
273 vector<boost::shared_ptr<Source> >& newfiles)
275 const framecnt_t nframes = ResampledImportableSource::blocksize;
276 boost::shared_ptr<AudioFileSource> afs;
277 uint channels = source->channels();
279 boost::scoped_array<float> data(new float[nframes * channels]);
280 vector<boost::shared_array<Sample> > channel_data;
282 for (uint n = 0; n < channels; ++n) {
283 channel_data.push_back(boost::shared_array<Sample>(new Sample[nframes]));
288 boost::shared_ptr<AudioSource> s = boost::dynamic_pointer_cast<AudioSource> (newfiles[0]);
291 status.progress = 0.0f;
292 float progress_multiplier = 1;
293 float progress_base = 0;
295 if (!source->clamped_at_unity() && s->clamped_at_unity()) {
297 /* The source we are importing from can return sample values with a magnitude greater than 1,
298 and the file we are writing the imported data to cannot handle such values. Compute the gain
299 factor required to normalize the input sources to have a magnitude of less than 1.
305 while (!status.cancel) {
306 framecnt_t const nread = source->read (data.get(), nframes);
311 peak = compute_peak (data.get(), nread, peak);
314 status.progress = 0.5 * read_count / (source->ratio() * source->length() * channels);
318 /* we are out of range: compute a gain to fix it */
319 gain = (1 - FLT_EPSILON) / peak;
323 progress_multiplier = 0.5;
329 while (!status.cancel) {
331 framecnt_t nread, nfread;
335 if ((nread = source->read (data.get(), nframes)) == 0) {
340 /* here is the gain fix for out-of-range sample values that we computed earlier */
341 apply_gain_to_buffer (data.get(), nread, gain);
344 nfread = nread / channels;
348 for (chn = 0; chn < channels; ++chn) {
351 for (x = chn, n = 0; n < nfread; x += channels, ++n) {
352 channel_data[chn][n] = (Sample) data[x];
358 for (chn = 0; chn < channels; ++chn) {
359 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(newfiles[chn])) != 0) {
360 afs->write (channel_data[chn].get(), nfread);
365 status.progress = progress_base + progress_multiplier * read_count / (source->ratio () * source->length() * channels);
370 write_midi_data_to_new_files (Evoral::SMF* source, ImportStatus& status,
371 vector<boost::shared_ptr<Source> >& newfiles)
373 uint32_t buf_size = 4;
374 uint8_t* buf = (uint8_t*) malloc (buf_size);
376 status.progress = 0.0f;
378 assert (newfiles.size() == source->num_tracks());
381 vector<boost::shared_ptr<Source> >::iterator s = newfiles.begin();
383 for (unsigned i = 1; i <= source->num_tracks(); ++i) {
385 boost::shared_ptr<SMFSource> smfs = boost::dynamic_pointer_cast<SMFSource> (*s);
388 source->seek_to_track (i);
391 uint32_t delta_t = 0;
395 while (!status.cancel) {
396 gint note_id_ignored; // imported files either don't have NoteID's or we ignore them.
400 int ret = source->read_event (&delta_t, &size, &buf, ¬e_id_ignored);
402 if (size > buf_size) {
406 if (ret < 0) { // EOT
412 if (ret == 0) { // Meta
417 smfs->mark_streaming_write_started ();
421 smfs->append_event_unlocked_beats(
422 Evoral::Event<double>(0,
423 (double)t / (double)source->ppqn(),
427 if (status.progress < 0.99) {
428 status.progress += 0.01;
434 /* we wrote something */
436 const framepos_t pos = 0;
437 const double length_beats = ceil(t / (double)source->ppqn());
438 BeatsFramesConverter converter(smfs->session().tempo_map(), pos);
439 smfs->update_length(pos + converter.to(length_beats));
440 smfs->mark_streaming_write_completed ();
446 warning << string_compose (_("Track %1 of %2 contained no usable MIDI data"), i, source->file_path()) << endmsg;
453 error << string_compose (_("MIDI file %1 was not readable (no reason available)"), source->file_path()) << endmsg;
462 remove_file_source (boost::shared_ptr<Source> source)
464 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
467 ::unlink (fs->path().c_str());
471 // This function is still unable to cleanly update an existing source, even though
472 // it is possible to set the ImportStatus flag accordingly. The functinality
473 // is disabled at the GUI until the Source implementations are able to provide
474 // the necessary API.
476 Session::import_files (ImportStatus& status)
478 typedef vector<boost::shared_ptr<Source> > Sources;
479 Sources all_new_sources;
480 boost::shared_ptr<AudioFileSource> afs;
481 boost::shared_ptr<SMFSource> smfs;
484 status.sources.clear ();
486 for (vector<string>::iterator p = status.paths.begin();
487 p != status.paths.end() && !status.cancel;
490 boost::shared_ptr<ImportableSource> source;
491 std::auto_ptr<Evoral::SMF> smf_reader;
492 const DataType type = SMFSource::safe_midi_file_extension (*p) ? DataType::MIDI : DataType::AUDIO;
494 if (type == DataType::AUDIO) {
496 source = open_importable_source (*p, frame_rate(), status.quality);
497 channels = source->channels();
498 } catch (const failed_constructor& err) {
499 error << string_compose(_("Import: cannot open input sound file \"%1\""), (*p)) << endmsg;
500 status.done = status.cancel = true;
506 smf_reader = std::auto_ptr<Evoral::SMF>(new Evoral::SMF());
507 smf_reader->open(*p);
508 channels = smf_reader->num_tracks();
510 error << _("Import: error opening MIDI file") << endmsg;
511 status.done = status.cancel = true;
516 vector<string> new_paths = get_paths_for_new_sources (config.get_native_file_header_format(),
517 status.replace_existing_source, *p,
518 get_best_session_directory_for_new_source (),
521 framepos_t natural_position = source ? source->natural_position() : 0;
524 if (status.replace_existing_source) {
525 fatal << "THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" << endmsg;
526 status.cancel = !map_existing_mono_sources (new_paths, *this, frame_rate(), newfiles, this);
528 status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles, natural_position);
531 // copy on cancel/failure so that any files that were created will be removed below
532 std::copy (newfiles.begin(), newfiles.end(), std::back_inserter(all_new_sources));
538 for (Sources::iterator i = newfiles.begin(); i != newfiles.end(); ++i) {
539 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*i)) != 0) {
540 afs->prepare_for_peakfile_writes ();
544 if (source) { // audio
545 status.doing_what = compose_status_message (*p, source->samplerate(),
546 frame_rate(), status.current, status.total);
547 write_audio_data_to_new_files (source.get(), status, newfiles);
548 } else if (smf_reader.get()) { // midi
549 status.doing_what = string_compose(_("Loading MIDI file %1"), *p);
550 write_midi_data_to_new_files (smf_reader.get(), status, newfiles);
557 if (!status.cancel) {
561 now = localtime (&xnow);
562 status.freeze = true;
564 /* flush the final length(s) to the header(s) */
566 for (Sources::iterator x = all_new_sources.begin(); x != all_new_sources.end(); ) {
568 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*x)) != 0) {
569 afs->update_header((*x)->natural_position(), *now, xnow);
570 afs->done_with_peakfile_writes ();
572 /* now that there is data there, requeue the file for analysis */
574 if (Config->get_auto_analyse_audio()) {
575 Analyser::queue_source_for_analysis (boost::static_pointer_cast<Source>(*x), false);
579 /* imported, copied files cannot be written or removed
582 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource>(*x);
584 /* Only audio files should be marked as
585 immutable - we may need to rewrite MIDI
588 if (boost::dynamic_pointer_cast<AudioFileSource> (fs)) {
589 fs->mark_immutable ();
591 fs->mark_immutable_except_write ();
593 fs->mark_nonremovable ();
596 /* don't create tracks for empty MIDI sources (channels) */
598 if ((smfs = boost::dynamic_pointer_cast<SMFSource>(*x)) != 0 && smfs->is_empty()) {
599 x = all_new_sources.erase(x);
605 /* save state so that we don't lose these new Sources */
609 std::copy (all_new_sources.begin(), all_new_sources.end(), std::back_inserter(status.sources));
612 std::for_each (all_new_sources.begin(), all_new_sources.end(), remove_file_source);
614 error << _("Failed to remove some files after failed/cancelled import operation") << endmsg;