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 Session::get_paths_for_new_sources (bool /*allow_replacing*/, const string& import_file_path, uint32_t channels)
122 vector<string> new_paths;
123 const string basename = basename_nosuffix (import_file_path);
125 for (uint n = 0; n < channels; ++n) {
127 const DataType type = SMFSource::safe_midi_file_extension (import_file_path) ? DataType::MIDI : DataType::AUDIO;
132 filepath = new_midi_source_path (basename);
134 case DataType::AUDIO:
135 filepath = new_audio_source_path (basename, channels, n, false, false);
139 if (filepath.empty()) {
140 error << string_compose (_("Cannot find new filename for imported file %1"), import_file_path) << endmsg;
141 return vector<string>();
144 new_paths.push_back (filepath);
151 map_existing_mono_sources (const vector<string>& new_paths, Session& /*sess*/,
152 uint /*samplerate*/, vector<boost::shared_ptr<Source> >& newfiles, Session *session)
154 for (vector<string>::const_iterator i = new_paths.begin();
155 i != new_paths.end(); ++i)
157 boost::shared_ptr<Source> source = session->audio_source_by_path_and_channel(*i, 0);
160 error << string_compose(_("Could not find a source for %1 even though we are updating this file!"), (*i)) << endl;
164 newfiles.push_back(boost::dynamic_pointer_cast<Source>(source));
170 create_mono_sources_for_writing (const vector<string>& new_paths,
171 Session& sess, uint samplerate,
172 vector<boost::shared_ptr<Source> >& newfiles,
173 framepos_t timeline_position)
175 for (vector<string>::const_iterator i = new_paths.begin(); i != new_paths.end(); ++i) {
177 boost::shared_ptr<Source> source;
180 const DataType type = SMFSource::safe_midi_file_extension (*i) ? DataType::MIDI : DataType::AUDIO;
182 source = SourceFactory::createWritable (type, sess,
184 false, // destructive
188 catch (const failed_constructor& err) {
189 error << string_compose (_("Unable to create file %1 during import"), *i) << endmsg;
193 newfiles.push_back(boost::dynamic_pointer_cast<Source>(source));
195 /* for audio files, reset the timeline position so that any BWF-ish
196 information in the original files we are importing from is maintained.
199 boost::shared_ptr<AudioFileSource> afs;
200 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
201 afs->set_timeline_position(timeline_position);
208 compose_status_message (const string& path,
209 uint file_samplerate,
210 uint session_samplerate,
211 uint /* current_file */,
212 uint /* total_files */)
214 if (file_samplerate != session_samplerate) {
215 return string_compose (_("Resampling %1 from %2kHz to %3kHz"),
216 Glib::path_get_basename (path),
217 file_samplerate/1000.0f,
218 session_samplerate/1000.0f);
221 return string_compose (_("Copying %1"), Glib::path_get_basename (path));
225 write_audio_data_to_new_files (ImportableSource* source, ImportStatus& status,
226 vector<boost::shared_ptr<Source> >& newfiles)
228 const framecnt_t nframes = ResampledImportableSource::blocksize;
229 boost::shared_ptr<AudioFileSource> afs;
230 uint32_t channels = source->channels();
232 boost::scoped_array<float> data(new float[nframes * channels]);
233 vector<boost::shared_array<Sample> > channel_data;
235 for (uint32_t n = 0; n < channels; ++n) {
236 channel_data.push_back(boost::shared_array<Sample>(new Sample[nframes]));
241 boost::shared_ptr<AudioSource> s = boost::dynamic_pointer_cast<AudioSource> (newfiles[0]);
244 status.progress = 0.0f;
245 float progress_multiplier = 1;
246 float progress_base = 0;
248 if (!source->clamped_at_unity() && s->clamped_at_unity()) {
250 /* The source we are importing from can return sample values with a magnitude greater than 1,
251 and the file we are writing the imported data to cannot handle such values. Compute the gain
252 factor required to normalize the input sources to have a magnitude of less than 1.
258 while (!status.cancel) {
259 framecnt_t const nread = source->read (data.get(), nframes);
264 peak = compute_peak (data.get(), nread, peak);
267 status.progress = 0.5 * read_count / (source->ratio() * source->length() * channels);
271 /* we are out of range: compute a gain to fix it */
272 gain = (1 - FLT_EPSILON) / peak;
276 progress_multiplier = 0.5;
280 framecnt_t read_count = 0;
282 while (!status.cancel) {
284 framecnt_t nread, nfread;
288 if ((nread = source->read (data.get(), nframes)) == 0) {
293 /* here is the gain fix for out-of-range sample values that we computed earlier */
294 apply_gain_to_buffer (data.get(), nread, gain);
297 nfread = nread / channels;
301 for (chn = 0; chn < channels; ++chn) {
304 for (x = chn, n = 0; n < nfread; x += channels, ++n) {
305 channel_data[chn][n] = (Sample) data[x];
311 for (chn = 0; chn < channels; ++chn) {
312 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(newfiles[chn])) != 0) {
313 afs->write (channel_data[chn].get(), nfread);
318 status.progress = progress_base + progress_multiplier * read_count / (source->ratio () * source->length() * channels);
323 write_midi_data_to_new_files (Evoral::SMF* source, ImportStatus& status,
324 vector<boost::shared_ptr<Source> >& newfiles)
326 uint32_t buf_size = 4;
327 uint8_t* buf = (uint8_t*) malloc (buf_size);
329 status.progress = 0.0f;
331 assert (newfiles.size() == source->num_tracks());
334 vector<boost::shared_ptr<Source> >::iterator s = newfiles.begin();
336 for (unsigned i = 1; i <= source->num_tracks(); ++i) {
338 boost::shared_ptr<SMFSource> smfs = boost::dynamic_pointer_cast<SMFSource> (*s);
341 source->seek_to_track (i);
344 uint32_t delta_t = 0;
348 while (!status.cancel) {
349 gint note_id_ignored; // imported files either don't have NoteID's or we ignore them.
353 int ret = source->read_event (&delta_t, &size, &buf, ¬e_id_ignored);
355 if (size > buf_size) {
359 if (ret < 0) { // EOT
365 if (ret == 0) { // Meta
370 smfs->mark_streaming_write_started ();
374 smfs->append_event_unlocked_beats(
375 Evoral::Event<double>(0,
376 (double)t / (double)source->ppqn(),
380 if (status.progress < 0.99) {
381 status.progress += 0.01;
387 /* we wrote something */
389 const framepos_t pos = 0;
390 const double length_beats = ceil(t / (double)source->ppqn());
391 BeatsFramesConverter converter(smfs->session().tempo_map(), pos);
392 smfs->update_length(pos + converter.to(length_beats));
393 smfs->mark_streaming_write_completed ();
399 warning << string_compose (_("Track %1 of %2 contained no usable MIDI data"), i, source->file_path()) << endmsg;
406 error << string_compose (_("MIDI file %1 was not readable (no reason available)"), source->file_path()) << endmsg;
415 remove_file_source (boost::shared_ptr<Source> source)
417 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
420 ::unlink (fs->path().c_str());
424 // This function is still unable to cleanly update an existing source, even though
425 // it is possible to set the ImportStatus flag accordingly. The functinality
426 // is disabled at the GUI until the Source implementations are able to provide
427 // the necessary API.
429 Session::import_files (ImportStatus& status)
431 typedef vector<boost::shared_ptr<Source> > Sources;
432 Sources all_new_sources;
433 boost::shared_ptr<AudioFileSource> afs;
434 boost::shared_ptr<SMFSource> smfs;
437 status.sources.clear ();
439 for (vector<string>::iterator p = status.paths.begin();
440 p != status.paths.end() && !status.cancel;
443 boost::shared_ptr<ImportableSource> source;
444 std::auto_ptr<Evoral::SMF> smf_reader;
445 const DataType type = SMFSource::safe_midi_file_extension (*p) ? DataType::MIDI : DataType::AUDIO;
447 if (type == DataType::AUDIO) {
449 source = open_importable_source (*p, frame_rate(), status.quality);
450 channels = source->channels();
451 } catch (const failed_constructor& err) {
452 error << string_compose(_("Import: cannot open input sound file \"%1\""), (*p)) << endmsg;
453 status.done = status.cancel = true;
459 smf_reader = std::auto_ptr<Evoral::SMF>(new Evoral::SMF());
460 smf_reader->open(*p);
461 channels = smf_reader->num_tracks();
463 error << _("Import: error opening MIDI file") << endmsg;
464 status.done = status.cancel = true;
469 vector<string> new_paths = get_paths_for_new_sources (status.replace_existing_source, *p, channels);
471 framepos_t natural_position = source ? source->natural_position() : 0;
474 if (status.replace_existing_source) {
475 fatal << "THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" << endmsg;
476 status.cancel = !map_existing_mono_sources (new_paths, *this, frame_rate(), newfiles, this);
478 status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles, natural_position);
481 // copy on cancel/failure so that any files that were created will be removed below
482 std::copy (newfiles.begin(), newfiles.end(), std::back_inserter(all_new_sources));
488 for (Sources::iterator i = newfiles.begin(); i != newfiles.end(); ++i) {
489 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*i)) != 0) {
490 afs->prepare_for_peakfile_writes ();
494 if (source) { // audio
495 status.doing_what = compose_status_message (*p, source->samplerate(),
496 frame_rate(), status.current, status.total);
497 write_audio_data_to_new_files (source.get(), status, newfiles);
498 } else if (smf_reader.get()) { // midi
499 status.doing_what = string_compose(_("Loading MIDI file %1"), *p);
500 write_midi_data_to_new_files (smf_reader.get(), status, newfiles);
507 if (!status.cancel) {
511 now = localtime (&xnow);
512 status.freeze = true;
514 /* flush the final length(s) to the header(s) */
516 for (Sources::iterator x = all_new_sources.begin(); x != all_new_sources.end(); ) {
518 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*x)) != 0) {
519 afs->update_header((*x)->natural_position(), *now, xnow);
520 afs->done_with_peakfile_writes ();
522 /* now that there is data there, requeue the file for analysis */
524 if (Config->get_auto_analyse_audio()) {
525 Analyser::queue_source_for_analysis (boost::static_pointer_cast<Source>(*x), false);
529 /* imported, copied files cannot be written or removed
532 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource>(*x);
534 /* Only audio files should be marked as
535 immutable - we may need to rewrite MIDI
538 if (boost::dynamic_pointer_cast<AudioFileSource> (fs)) {
539 fs->mark_immutable ();
541 fs->mark_immutable_except_write ();
543 fs->mark_nonremovable ();
546 /* don't create tracks for empty MIDI sources (channels) */
548 if ((smfs = boost::dynamic_pointer_cast<SMFSource>(*x)) != 0 && smfs->is_empty()) {
549 x = all_new_sources.erase(x);
555 /* save state so that we don't lose these new Sources */
559 std::copy (all_new_sources.begin(), all_new_sources.end(), std::back_inserter(status.sources));
562 std::for_each (all_new_sources.begin(), all_new_sources.end(), remove_file_source);
564 error << _("Failed to remove some files after failed/cancelled import operation") << endmsg;