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>
37 #include <glib/gstdio.h>
40 #include <boost/scoped_array.hpp>
41 #include <boost/shared_array.hpp>
43 #include "pbd/basename.h"
44 #include "pbd/convert.h"
46 #include "evoral/SMF.hpp"
48 #include "ardour/analyser.h"
49 #include "ardour/ardour.h"
50 #include "ardour/audio_diskstream.h"
51 #include "ardour/audioengine.h"
52 #include "ardour/audioregion.h"
53 #include "ardour/import_status.h"
54 #include "ardour/region_factory.h"
55 #include "ardour/resampled_source.h"
56 #include "ardour/runtime_functions.h"
57 #include "ardour/session.h"
58 #include "ardour/session_directory.h"
59 #include "ardour/smf_source.h"
60 #include "ardour/sndfile_helpers.h"
61 #include "ardour/sndfileimportable.h"
62 #include "ardour/sndfilesource.h"
63 #include "ardour/source_factory.h"
64 #include "ardour/tempo.h"
67 #include "ardour/caimportable.h"
73 using namespace ARDOUR;
76 static boost::shared_ptr<ImportableSource>
77 open_importable_source (const string& path, framecnt_t samplerate, ARDOUR::SrcQuality quality)
79 /* try libsndfile first, because it can get BWF info from .wav, which ExtAudioFile cannot.
80 We don't necessarily need that information in an ImportableSource, but it keeps the
81 logic the same as in SourceFactory::create()
85 boost::shared_ptr<SndFileImportableSource> source(new SndFileImportableSource(path));
87 if (source->samplerate() == samplerate) {
91 /* rewrap as a resampled source */
93 return boost::shared_ptr<ImportableSource>(new ResampledImportableSource(source, samplerate, quality));
100 /* libsndfile failed, see if we can use CoreAudio to handle the IO */
102 CAImportableSource* src = new CAImportableSource(path);
103 boost::shared_ptr<CAImportableSource> source (src);
105 if (source->samplerate() == samplerate) {
109 /* rewrap as a resampled source */
111 return boost::shared_ptr<ImportableSource>(new ResampledImportableSource(source, samplerate, quality));
121 get_non_existent_filename (HeaderFormat hf, DataType type, const bool allow_replacing, const std::string& destdir, const std::string& basename, uint32_t channel, uint32_t channels)
123 char buf[PATH_MAX+1];
124 bool goodfile = false;
125 string base = basename;
126 string ext = native_header_format_extension (hf, type);
131 if (type == DataType::AUDIO && channels == 2) {
134 snprintf (buf, sizeof(buf), "%s-L%s", base.c_str(), ext.c_str());
136 snprintf (buf, sizeof(buf), "%s-%d-L%s", base.c_str(), cnt, ext.c_str());
140 snprintf (buf, sizeof(buf), "%s-R%s", base.c_str(), ext.c_str());
142 snprintf (buf, sizeof(buf), "%s-%d-R%s", base.c_str(), cnt, ext.c_str());
145 } else if (channels > 1) {
147 snprintf (buf, sizeof(buf), "%s-c%d%s", base.c_str(), channel, ext.c_str());
149 snprintf (buf, sizeof(buf), "%s-%d-c%d%s", base.c_str(), cnt, channel, ext.c_str());
153 snprintf (buf, sizeof(buf), "%s%s", base.c_str(), ext.c_str());
155 snprintf (buf, sizeof(buf), "%s-%d%s", base.c_str(), cnt, ext.c_str());
159 string tempname = destdir + "/" + buf;
161 if (!allow_replacing && Glib::file_test (tempname, Glib::FILE_TEST_EXISTS)) {
175 static vector<string>
176 get_paths_for_new_sources (HeaderFormat hf, const bool allow_replacing, const string& import_file_path, const string& session_dir, uint32_t channels)
178 vector<string> new_paths;
179 const string basename = basename_nosuffix (import_file_path);
181 SessionDirectory sdir(session_dir);
183 for (uint32_t n = 0; n < channels; ++n) {
185 const DataType type = SMFSource::safe_midi_file_extension (import_file_path) ? DataType::MIDI : DataType::AUDIO;
187 std::string filepath = (type == DataType::MIDI)
188 ? sdir.midi_path() : sdir.sound_path();
190 filepath = Glib::build_filename (filepath,
191 get_non_existent_filename (hf, type, allow_replacing, filepath, basename, n, channels));
192 new_paths.push_back (filepath);
199 map_existing_mono_sources (const vector<string>& new_paths, Session& /*sess*/,
200 uint32_t /*samplerate*/, vector<boost::shared_ptr<Source> >& newfiles, Session *session)
202 for (vector<string>::const_iterator i = new_paths.begin();
203 i != new_paths.end(); ++i)
205 boost::shared_ptr<Source> source = session->source_by_path_and_channel(*i, 0);
208 error << string_compose(_("Could not find a source for %1 even though we are updating this file!"), (*i)) << endl;
212 newfiles.push_back(boost::dynamic_pointer_cast<Source>(source));
218 create_mono_sources_for_writing (const vector<string>& new_paths,
219 Session& sess, uint32_t samplerate,
220 vector<boost::shared_ptr<Source> >& newfiles,
221 framepos_t timeline_position)
223 for (vector<string>::const_iterator i = new_paths.begin(); i != new_paths.end(); ++i) {
225 boost::shared_ptr<Source> source;
228 const DataType type = SMFSource::safe_midi_file_extension (*i) ? DataType::MIDI : DataType::AUDIO;
230 source = SourceFactory::createWritable (type, sess,
232 false, // destructive
236 catch (const failed_constructor& err) {
237 error << string_compose (_("Unable to create file %1 during import"), *i) << endmsg;
241 newfiles.push_back(boost::dynamic_pointer_cast<Source>(source));
243 /* for audio files, reset the timeline position so that any BWF-ish
244 information in the original files we are importing from is maintained.
247 boost::shared_ptr<AudioFileSource> afs;
248 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
249 afs->set_timeline_position(timeline_position);
256 compose_status_message (const string& path,
257 uint32_t file_samplerate,
258 uint32_t session_samplerate,
259 uint32_t /* current_file */,
260 uint32_t /* total_files */)
262 if (file_samplerate != session_samplerate) {
263 return string_compose (_("Resampling %1 from %2kHz to %3kHz"),
264 Glib::path_get_basename (path),
265 file_samplerate/1000.0f,
266 session_samplerate/1000.0f);
269 return string_compose (_("Copying %1"), Glib::path_get_basename (path));
273 write_audio_data_to_new_files (ImportableSource* source, ImportStatus& status,
274 vector<boost::shared_ptr<Source> >& newfiles)
276 const framecnt_t nframes = ResampledImportableSource::blocksize;
277 boost::shared_ptr<AudioFileSource> afs;
278 uint32_t channels = source->channels();
280 boost::scoped_array<float> data(new float[nframes * channels]);
281 vector<boost::shared_array<Sample> > channel_data;
283 for (uint32_t n = 0; n < channels; ++n) {
284 channel_data.push_back(boost::shared_array<Sample>(new Sample[nframes]));
289 boost::shared_ptr<AudioSource> s = boost::dynamic_pointer_cast<AudioSource> (newfiles[0]);
292 status.progress = 0.0f;
293 float progress_multiplier = 1;
294 float progress_base = 0;
296 if (!source->clamped_at_unity() && s->clamped_at_unity()) {
298 /* The source we are importing from can return sample values with a magnitude greater than 1,
299 and the file we are writing the imported data to cannot handle such values. Compute the gain
300 factor required to normalize the input sources to have a magnitude of less than 1.
304 uint32_t read_count = 0;
306 while (!status.cancel) {
307 framecnt_t const nread = source->read (data.get(), nframes);
312 peak = compute_peak (data.get(), nread, peak);
315 status.progress = 0.5 * read_count / (source->ratio() * source->length() * channels);
319 /* we are out of range: compute a gain to fix it */
320 gain = (1 - FLT_EPSILON) / peak;
324 progress_multiplier = 0.5;
328 uint32_t read_count = 0;
330 while (!status.cancel) {
332 framecnt_t nread, nfread;
336 if ((nread = source->read (data.get(), nframes)) == 0) {
337 #ifdef PLATFORM_WINDOWS
338 /* Flush the data once we've finished importing the file. Windows can */
339 /* cache the data for very long periods of time (perhaps not writing */
340 /* it to disk until Ardour closes). So let's force it to flush now. */
341 for (chn = 0; chn < channels; ++chn)
342 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(newfiles[chn])) != 0)
349 /* here is the gain fix for out-of-range sample values that we computed earlier */
350 apply_gain_to_buffer (data.get(), nread, gain);
353 nfread = nread / channels;
357 for (chn = 0; chn < channels; ++chn) {
360 for (x = chn, n = 0; n < nfread; x += channels, ++n) {
361 channel_data[chn][n] = (Sample) data[x];
367 for (chn = 0; chn < channels; ++chn) {
368 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(newfiles[chn])) != 0) {
369 afs->write (channel_data[chn].get(), nfread);
374 status.progress = progress_base + progress_multiplier * read_count / (source->ratio () * source->length() * channels);
379 write_midi_data_to_new_files (Evoral::SMF* source, ImportStatus& status,
380 vector<boost::shared_ptr<Source> >& newfiles)
382 uint32_t buf_size = 4;
383 uint8_t* buf = (uint8_t*) malloc (buf_size);
385 status.progress = 0.0f;
387 assert (newfiles.size() == source->num_tracks());
390 vector<boost::shared_ptr<Source> >::iterator s = newfiles.begin();
392 for (unsigned i = 1; i <= source->num_tracks(); ++i) {
394 boost::shared_ptr<SMFSource> smfs = boost::dynamic_pointer_cast<SMFSource> (*s);
397 source->seek_to_track (i);
400 uint32_t delta_t = 0;
404 while (!status.cancel) {
405 gint note_id_ignored; // imported files either don't have NoteID's or we ignore them.
409 int ret = source->read_event (&delta_t, &size, &buf, ¬e_id_ignored);
411 if (size > buf_size) {
415 if (ret < 0) { // EOT
421 if (ret == 0) { // Meta
426 smfs->mark_streaming_write_started ();
430 smfs->append_event_unlocked_beats(
431 Evoral::Event<double>(0,
432 (double)t / (double)source->ppqn(),
436 if (status.progress < 0.99) {
437 status.progress += 0.01;
443 /* we wrote something */
445 const framepos_t pos = 0;
446 const double length_beats = ceil(t / (double)source->ppqn());
447 BeatsFramesConverter converter(smfs->session().tempo_map(), pos);
448 smfs->update_length(pos + converter.to(length_beats));
449 smfs->mark_streaming_write_completed ();
455 warning << string_compose (_("Track %1 of %2 contained no usable MIDI data"), i, source->file_path()) << endmsg;
462 error << string_compose (_("MIDI file %1 was not readable (no reason available)"), source->file_path()) << endmsg;
471 remove_file_source (boost::shared_ptr<Source> source)
473 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
476 ::g_unlink (fs->path().c_str());
480 // This function is still unable to cleanly update an existing source, even though
481 // it is possible to set the ImportStatus flag accordingly. The functinality
482 // is disabled at the GUI until the Source implementations are able to provide
483 // the necessary API.
485 Session::import_files (ImportStatus& status)
487 typedef vector<boost::shared_ptr<Source> > Sources;
488 Sources all_new_sources;
489 boost::shared_ptr<AudioFileSource> afs;
490 boost::shared_ptr<SMFSource> smfs;
491 uint32_t channels = 0;
493 status.sources.clear ();
495 for (vector<string>::iterator p = status.paths.begin();
496 p != status.paths.end() && !status.cancel;
499 boost::shared_ptr<ImportableSource> source;
500 std::auto_ptr<Evoral::SMF> smf_reader;
501 const DataType type = SMFSource::safe_midi_file_extension (*p) ? DataType::MIDI : DataType::AUDIO;
503 if (type == DataType::AUDIO) {
505 source = open_importable_source (*p, frame_rate(), status.quality);
506 channels = source->channels();
507 } catch (const failed_constructor& err) {
508 error << string_compose(_("Import: cannot open input sound file \"%1\""), (*p)) << endmsg;
509 status.done = status.cancel = true;
515 smf_reader = std::auto_ptr<Evoral::SMF>(new Evoral::SMF());
516 smf_reader->open(*p);
517 channels = smf_reader->num_tracks();
519 error << _("Import: error opening MIDI file") << endmsg;
520 status.done = status.cancel = true;
525 vector<string> new_paths = get_paths_for_new_sources (config.get_native_file_header_format(),
526 status.replace_existing_source, *p,
527 get_best_session_directory_for_new_source (),
530 framepos_t natural_position = source ? source->natural_position() : 0;
533 if (status.replace_existing_source) {
534 fatal << "THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" << endmsg;
535 status.cancel = !map_existing_mono_sources (new_paths, *this, frame_rate(), newfiles, this);
537 status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles, natural_position);
540 // copy on cancel/failure so that any files that were created will be removed below
541 std::copy (newfiles.begin(), newfiles.end(), std::back_inserter(all_new_sources));
547 for (Sources::iterator i = newfiles.begin(); i != newfiles.end(); ++i) {
548 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*i)) != 0) {
549 afs->prepare_for_peakfile_writes ();
553 if (source) { // audio
554 status.doing_what = compose_status_message (*p, source->samplerate(),
555 frame_rate(), status.current, status.total);
556 write_audio_data_to_new_files (source.get(), status, newfiles);
557 } else if (smf_reader.get()) { // midi
558 status.doing_what = string_compose(_("Loading MIDI file %1"), *p);
559 write_midi_data_to_new_files (smf_reader.get(), status, newfiles);
566 if (!status.cancel) {
570 now = localtime (&xnow);
571 status.freeze = true;
573 /* flush the final length(s) to the header(s) */
575 for (Sources::iterator x = all_new_sources.begin(); x != all_new_sources.end(); ) {
577 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*x)) != 0) {
578 afs->update_header((*x)->natural_position(), *now, xnow);
579 afs->done_with_peakfile_writes ();
581 /* now that there is data there, requeue the file for analysis */
583 if (Config->get_auto_analyse_audio()) {
584 Analyser::queue_source_for_analysis (boost::static_pointer_cast<Source>(*x), false);
588 /* imported, copied files cannot be written or removed
591 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource>(*x);
593 /* Only audio files should be marked as
594 immutable - we may need to rewrite MIDI
597 if (boost::dynamic_pointer_cast<AudioFileSource> (fs)) {
598 fs->mark_immutable ();
600 fs->mark_immutable_except_write ();
602 fs->mark_nonremovable ();
605 /* don't create tracks for empty MIDI sources (channels) */
607 if ((smfs = boost::dynamic_pointer_cast<SMFSource>(*x)) != 0 && smfs->is_empty()) {
608 x = all_new_sources.erase(x);
614 /* save state so that we don't lose these new Sources */
618 std::copy (all_new_sources.begin(), all_new_sources.end(), std::back_inserter(status.sources));
621 std::for_each (all_new_sources.begin(), all_new_sources.end(), remove_file_source);
623 error << _("Failed to remove some files after failed/cancelled import operation") << endmsg;