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 Session::get_paths_for_new_sources (bool /*allow_replacing*/, const string& import_file_path, uint32_t channels)
123 vector<string> new_paths;
124 const string basename = basename_nosuffix (import_file_path);
126 for (uint32_t n = 0; n < channels; ++n) {
128 const DataType type = SMFSource::safe_midi_file_extension (import_file_path) ? DataType::MIDI : DataType::AUDIO;
134 string mchn_name = string_compose ("%1-t%2", basename, n);
135 filepath = new_midi_source_path (mchn_name);
137 filepath = new_midi_source_path (basename);
140 case DataType::AUDIO:
141 filepath = new_audio_source_path (basename, channels, n, false, false);
145 if (filepath.empty()) {
146 error << string_compose (_("Cannot find new filename for imported file %1"), import_file_path) << endmsg;
147 return vector<string>();
150 new_paths.push_back (filepath);
157 map_existing_mono_sources (const vector<string>& new_paths, Session& /*sess*/,
158 uint32_t /*samplerate*/, vector<boost::shared_ptr<Source> >& newfiles, Session *session)
160 for (vector<string>::const_iterator i = new_paths.begin();
161 i != new_paths.end(); ++i)
163 boost::shared_ptr<Source> source = session->audio_source_by_path_and_channel(*i, 0);
166 error << string_compose(_("Could not find a source for %1 even though we are updating this file!"), (*i)) << endl;
170 newfiles.push_back(boost::dynamic_pointer_cast<Source>(source));
176 create_mono_sources_for_writing (const vector<string>& new_paths,
177 Session& sess, uint32_t samplerate,
178 vector<boost::shared_ptr<Source> >& newfiles,
179 framepos_t timeline_position)
181 for (vector<string>::const_iterator i = new_paths.begin(); i != new_paths.end(); ++i) {
183 boost::shared_ptr<Source> source;
186 const DataType type = SMFSource::safe_midi_file_extension (*i) ? DataType::MIDI : DataType::AUDIO;
188 source = SourceFactory::createWritable (type, sess,
190 false, // destructive
194 catch (const failed_constructor& err) {
195 error << string_compose (_("Unable to create file %1 during import"), *i) << endmsg;
199 newfiles.push_back(boost::dynamic_pointer_cast<Source>(source));
201 /* for audio files, reset the timeline position so that any BWF-ish
202 information in the original files we are importing from is maintained.
205 boost::shared_ptr<AudioFileSource> afs;
206 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
207 afs->set_timeline_position(timeline_position);
214 compose_status_message (const string& path,
215 uint32_t file_samplerate,
216 uint32_t session_samplerate,
217 uint32_t /* current_file */,
218 uint32_t /* total_files */)
220 if (file_samplerate != session_samplerate) {
221 return string_compose (_("Resampling %1 from %2kHz to %3kHz"),
222 Glib::path_get_basename (path),
223 file_samplerate/1000.0f,
224 session_samplerate/1000.0f);
227 return string_compose (_("Copying %1"), Glib::path_get_basename (path));
231 write_audio_data_to_new_files (ImportableSource* source, ImportStatus& status,
232 vector<boost::shared_ptr<Source> >& newfiles)
234 const framecnt_t nframes = ResampledImportableSource::blocksize;
235 boost::shared_ptr<AudioFileSource> afs;
236 uint32_t channels = source->channels();
241 boost::scoped_array<float> data(new float[nframes * channels]);
242 vector<boost::shared_array<Sample> > channel_data;
244 for (uint32_t n = 0; n < channels; ++n) {
245 channel_data.push_back(boost::shared_array<Sample>(new Sample[nframes]));
250 boost::shared_ptr<AudioSource> s = boost::dynamic_pointer_cast<AudioSource> (newfiles[0]);
253 status.progress = 0.0f;
254 float progress_multiplier = 1;
255 float progress_base = 0;
257 if (!source->clamped_at_unity() && s->clamped_at_unity()) {
259 /* The source we are importing from can return sample values with a magnitude greater than 1,
260 and the file we are writing the imported data to cannot handle such values. Compute the gain
261 factor required to normalize the input sources to have a magnitude of less than 1.
265 uint32_t read_count = 0;
267 while (!status.cancel) {
268 framecnt_t const nread = source->read (data.get(), nframes);
273 peak = compute_peak (data.get(), nread, peak);
276 status.progress = 0.5 * read_count / (source->ratio() * source->length() * channels);
280 /* we are out of range: compute a gain to fix it */
281 gain = (1 - FLT_EPSILON) / peak;
285 progress_multiplier = 0.5;
289 framecnt_t read_count = 0;
291 while (!status.cancel) {
293 framecnt_t nread, nfread;
297 if ((nread = source->read (data.get(), nframes)) == 0) {
298 #ifdef PLATFORM_WINDOWS
299 /* Flush the data once we've finished importing the file. Windows can */
300 /* cache the data for very long periods of time (perhaps not writing */
301 /* it to disk until Ardour closes). So let's force it to flush now. */
302 for (chn = 0; chn < channels; ++chn)
303 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(newfiles[chn])) != 0)
310 /* here is the gain fix for out-of-range sample values that we computed earlier */
311 apply_gain_to_buffer (data.get(), nread, gain);
314 nfread = nread / channels;
318 for (chn = 0; chn < channels; ++chn) {
321 for (x = chn, n = 0; n < nfread; x += channels, ++n) {
322 channel_data[chn][n] = (Sample) data[x];
328 for (chn = 0; chn < channels; ++chn) {
329 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(newfiles[chn])) != 0) {
330 afs->write (channel_data[chn].get(), nfread);
335 status.progress = progress_base + progress_multiplier * read_count / (source->ratio () * source->length() * channels);
340 write_midi_data_to_new_files (Evoral::SMF* source, ImportStatus& status,
341 vector<boost::shared_ptr<Source> >& newfiles)
343 uint32_t buf_size = 4;
344 uint8_t* buf = (uint8_t*) malloc (buf_size);
346 status.progress = 0.0f;
348 assert (newfiles.size() == source->num_tracks());
351 vector<boost::shared_ptr<Source> >::iterator s = newfiles.begin();
353 for (unsigned i = 1; i <= source->num_tracks(); ++i) {
355 boost::shared_ptr<SMFSource> smfs = boost::dynamic_pointer_cast<SMFSource> (*s);
358 source->seek_to_track (i);
361 uint32_t delta_t = 0;
365 while (!status.cancel) {
366 gint note_id_ignored; // imported files either don't have NoteID's or we ignore them.
370 int ret = source->read_event (&delta_t, &size, &buf, ¬e_id_ignored);
372 if (size > buf_size) {
376 if (ret < 0) { // EOT
382 if (ret == 0) { // Meta
387 smfs->mark_streaming_write_started ();
391 smfs->append_event_unlocked_beats(
392 Evoral::Event<Evoral::MusicalTime>(
394 Evoral::MusicalTime::ticks_at_rate(t, source->ppqn()),
398 if (status.progress < 0.99) {
399 status.progress += 0.01;
405 /* we wrote something */
407 const framepos_t pos = 0;
408 const Evoral::MusicalTime length_beats = Evoral::MusicalTime::ticks_at_rate(t, source->ppqn());
409 BeatsFramesConverter converter(smfs->session().tempo_map(), pos);
410 smfs->update_length(pos + converter.to(length_beats.round_up_to_beat()));
411 smfs->mark_streaming_write_completed ();
417 warning << string_compose (_("Track %1 of %2 contained no usable MIDI data"), i, source->file_path()) << endmsg;
424 error << string_compose (_("MIDI file %1 was not readable (no reason available)"), source->file_path()) << endmsg;
433 remove_file_source (boost::shared_ptr<Source> source)
435 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
437 fs->DropReferences ();
440 ::g_unlink (fs->path().c_str());
444 // This function is still unable to cleanly update an existing source, even though
445 // it is possible to set the ImportStatus flag accordingly. The functinality
446 // is disabled at the GUI until the Source implementations are able to provide
447 // the necessary API.
449 Session::import_files (ImportStatus& status)
451 typedef vector<boost::shared_ptr<Source> > Sources;
452 Sources all_new_sources;
453 boost::shared_ptr<AudioFileSource> afs;
454 boost::shared_ptr<SMFSource> smfs;
455 uint32_t channels = 0;
457 status.sources.clear ();
459 for (vector<string>::iterator p = status.paths.begin();
460 p != status.paths.end() && !status.cancel;
463 boost::shared_ptr<ImportableSource> source;
464 std::auto_ptr<Evoral::SMF> smf_reader;
465 const DataType type = SMFSource::safe_midi_file_extension (*p) ? DataType::MIDI : DataType::AUDIO;
467 if (type == DataType::AUDIO) {
469 source = open_importable_source (*p, frame_rate(), status.quality);
470 channels = source->channels();
471 } catch (const failed_constructor& err) {
472 error << string_compose(_("Import: cannot open input sound file \"%1\""), (*p)) << endmsg;
473 status.done = status.cancel = true;
479 smf_reader = std::auto_ptr<Evoral::SMF>(new Evoral::SMF());
480 smf_reader->open(*p);
481 channels = smf_reader->num_tracks();
483 error << _("Import: error opening MIDI file") << endmsg;
484 status.done = status.cancel = true;
490 error << _("Import: file contains no channels.") << endmsg;
494 vector<string> new_paths = get_paths_for_new_sources (status.replace_existing_source, *p, channels);
496 framepos_t natural_position = source ? source->natural_position() : 0;
499 if (status.replace_existing_source) {
500 fatal << "THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" << endmsg;
501 status.cancel = !map_existing_mono_sources (new_paths, *this, frame_rate(), newfiles, this);
503 status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles, natural_position);
506 // copy on cancel/failure so that any files that were created will be removed below
507 std::copy (newfiles.begin(), newfiles.end(), std::back_inserter(all_new_sources));
513 for (Sources::iterator i = newfiles.begin(); i != newfiles.end(); ++i) {
514 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*i)) != 0) {
515 afs->prepare_for_peakfile_writes ();
519 if (source) { // audio
520 status.doing_what = compose_status_message (*p, source->samplerate(),
521 frame_rate(), status.current, status.total);
522 write_audio_data_to_new_files (source.get(), status, newfiles);
523 } else if (smf_reader.get()) { // midi
524 status.doing_what = string_compose(_("Loading MIDI file %1"), *p);
525 write_midi_data_to_new_files (smf_reader.get(), status, newfiles);
532 if (!status.cancel) {
536 now = localtime (&xnow);
537 status.freeze = true;
539 /* flush the final length(s) to the header(s) */
541 for (Sources::iterator x = all_new_sources.begin(); x != all_new_sources.end(); ) {
543 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*x)) != 0) {
544 afs->update_header((*x)->natural_position(), *now, xnow);
545 afs->done_with_peakfile_writes ();
547 /* now that there is data there, requeue the file for analysis */
549 if (Config->get_auto_analyse_audio()) {
550 Analyser::queue_source_for_analysis (boost::static_pointer_cast<Source>(*x), false);
554 /* imported, copied files cannot be written or removed
557 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource>(*x);
559 /* Only audio files should be marked as
560 immutable - we may need to rewrite MIDI
563 if (boost::dynamic_pointer_cast<AudioFileSource> (fs)) {
564 fs->mark_immutable ();
566 fs->mark_immutable_except_write ();
568 fs->mark_nonremovable ();
571 /* don't create tracks for empty MIDI sources (channels) */
573 if ((smfs = boost::dynamic_pointer_cast<SMFSource>(*x)) != 0 && smfs->is_empty()) {
574 x = all_new_sources.erase(x);
580 /* save state so that we don't lose these new Sources */
584 std::copy (all_new_sources.begin(), all_new_sources.end(), std::back_inserter(status.sources));
587 std::for_each (all_new_sources.begin(), all_new_sources.end(), remove_file_source);
589 error << _("Failed to remove some files after failed/cancelled import operation") << endmsg;