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();
238 boost::scoped_array<float> data(new float[nframes * channels]);
239 vector<boost::shared_array<Sample> > channel_data;
241 for (uint32_t n = 0; n < channels; ++n) {
242 channel_data.push_back(boost::shared_array<Sample>(new Sample[nframes]));
247 boost::shared_ptr<AudioSource> s = boost::dynamic_pointer_cast<AudioSource> (newfiles[0]);
250 status.progress = 0.0f;
251 float progress_multiplier = 1;
252 float progress_base = 0;
254 if (!source->clamped_at_unity() && s->clamped_at_unity()) {
256 /* The source we are importing from can return sample values with a magnitude greater than 1,
257 and the file we are writing the imported data to cannot handle such values. Compute the gain
258 factor required to normalize the input sources to have a magnitude of less than 1.
262 uint32_t read_count = 0;
264 while (!status.cancel) {
265 framecnt_t const nread = source->read (data.get(), nframes);
270 peak = compute_peak (data.get(), nread, peak);
273 status.progress = 0.5 * read_count / (source->ratio() * source->length() * channels);
277 /* we are out of range: compute a gain to fix it */
278 gain = (1 - FLT_EPSILON) / peak;
282 progress_multiplier = 0.5;
286 framecnt_t read_count = 0;
288 while (!status.cancel) {
290 framecnt_t nread, nfread;
294 if ((nread = source->read (data.get(), nframes)) == 0) {
295 #ifdef PLATFORM_WINDOWS
296 /* Flush the data once we've finished importing the file. Windows can */
297 /* cache the data for very long periods of time (perhaps not writing */
298 /* it to disk until Ardour closes). So let's force it to flush now. */
299 for (chn = 0; chn < channels; ++chn)
300 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(newfiles[chn])) != 0)
307 /* here is the gain fix for out-of-range sample values that we computed earlier */
308 apply_gain_to_buffer (data.get(), nread, gain);
311 nfread = nread / channels;
315 for (chn = 0; chn < channels; ++chn) {
318 for (x = chn, n = 0; n < nfread; x += channels, ++n) {
319 channel_data[chn][n] = (Sample) data[x];
325 for (chn = 0; chn < channels; ++chn) {
326 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(newfiles[chn])) != 0) {
327 afs->write (channel_data[chn].get(), nfread);
332 status.progress = progress_base + progress_multiplier * read_count / (source->ratio () * source->length() * channels);
337 write_midi_data_to_new_files (Evoral::SMF* source, ImportStatus& status,
338 vector<boost::shared_ptr<Source> >& newfiles)
340 uint32_t buf_size = 4;
341 uint8_t* buf = (uint8_t*) malloc (buf_size);
343 status.progress = 0.0f;
345 assert (newfiles.size() == source->num_tracks());
348 vector<boost::shared_ptr<Source> >::iterator s = newfiles.begin();
350 for (unsigned i = 1; i <= source->num_tracks(); ++i) {
352 boost::shared_ptr<SMFSource> smfs = boost::dynamic_pointer_cast<SMFSource> (*s);
355 source->seek_to_track (i);
358 uint32_t delta_t = 0;
362 while (!status.cancel) {
363 gint note_id_ignored; // imported files either don't have NoteID's or we ignore them.
367 int ret = source->read_event (&delta_t, &size, &buf, ¬e_id_ignored);
369 if (size > buf_size) {
373 if (ret < 0) { // EOT
379 if (ret == 0) { // Meta
384 smfs->mark_streaming_write_started ();
388 smfs->append_event_unlocked_beats(
389 Evoral::Event<double>(0,
390 (double)t / (double)source->ppqn(),
394 if (status.progress < 0.99) {
395 status.progress += 0.01;
401 /* we wrote something */
403 const framepos_t pos = 0;
404 const double length_beats = ceil(t / (double)source->ppqn());
405 BeatsFramesConverter converter(smfs->session().tempo_map(), pos);
406 smfs->update_length(pos + converter.to(length_beats));
407 smfs->mark_streaming_write_completed ();
413 warning << string_compose (_("Track %1 of %2 contained no usable MIDI data"), i, source->file_path()) << endmsg;
420 error << string_compose (_("MIDI file %1 was not readable (no reason available)"), source->file_path()) << endmsg;
429 remove_file_source (boost::shared_ptr<Source> source)
431 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
433 fs->DropReferences ();
436 ::g_unlink (fs->path().c_str());
440 // This function is still unable to cleanly update an existing source, even though
441 // it is possible to set the ImportStatus flag accordingly. The functinality
442 // is disabled at the GUI until the Source implementations are able to provide
443 // the necessary API.
445 Session::import_files (ImportStatus& status)
447 typedef vector<boost::shared_ptr<Source> > Sources;
448 Sources all_new_sources;
449 boost::shared_ptr<AudioFileSource> afs;
450 boost::shared_ptr<SMFSource> smfs;
451 uint32_t channels = 0;
453 status.sources.clear ();
455 for (vector<string>::iterator p = status.paths.begin();
456 p != status.paths.end() && !status.cancel;
459 boost::shared_ptr<ImportableSource> source;
460 std::auto_ptr<Evoral::SMF> smf_reader;
461 const DataType type = SMFSource::safe_midi_file_extension (*p) ? DataType::MIDI : DataType::AUDIO;
463 if (type == DataType::AUDIO) {
465 source = open_importable_source (*p, frame_rate(), status.quality);
466 channels = source->channels();
467 } catch (const failed_constructor& err) {
468 error << string_compose(_("Import: cannot open input sound file \"%1\""), (*p)) << endmsg;
469 status.done = status.cancel = true;
475 smf_reader = std::auto_ptr<Evoral::SMF>(new Evoral::SMF());
476 smf_reader->open(*p);
477 channels = smf_reader->num_tracks();
479 error << _("Import: error opening MIDI file") << endmsg;
480 status.done = status.cancel = true;
486 error << _("Import: file contains no channels.") << endmsg;
490 vector<string> new_paths = get_paths_for_new_sources (status.replace_existing_source, *p, channels);
492 framepos_t natural_position = source ? source->natural_position() : 0;
495 if (status.replace_existing_source) {
496 fatal << "THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" << endmsg;
497 status.cancel = !map_existing_mono_sources (new_paths, *this, frame_rate(), newfiles, this);
499 status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles, natural_position);
502 // copy on cancel/failure so that any files that were created will be removed below
503 std::copy (newfiles.begin(), newfiles.end(), std::back_inserter(all_new_sources));
509 for (Sources::iterator i = newfiles.begin(); i != newfiles.end(); ++i) {
510 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*i)) != 0) {
511 afs->prepare_for_peakfile_writes ();
515 if (source) { // audio
516 status.doing_what = compose_status_message (*p, source->samplerate(),
517 frame_rate(), status.current, status.total);
518 write_audio_data_to_new_files (source.get(), status, newfiles);
519 } else if (smf_reader.get()) { // midi
520 status.doing_what = string_compose(_("Loading MIDI file %1"), *p);
521 write_midi_data_to_new_files (smf_reader.get(), status, newfiles);
528 if (!status.cancel) {
532 now = localtime (&xnow);
533 status.freeze = true;
535 /* flush the final length(s) to the header(s) */
537 for (Sources::iterator x = all_new_sources.begin(); x != all_new_sources.end(); ) {
539 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*x)) != 0) {
540 afs->update_header((*x)->natural_position(), *now, xnow);
541 afs->done_with_peakfile_writes ();
543 /* now that there is data there, requeue the file for analysis */
545 if (Config->get_auto_analyse_audio()) {
546 Analyser::queue_source_for_analysis (boost::static_pointer_cast<Source>(*x), false);
550 /* imported, copied files cannot be written or removed
553 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource>(*x);
555 /* Only audio files should be marked as
556 immutable - we may need to rewrite MIDI
559 if (boost::dynamic_pointer_cast<AudioFileSource> (fs)) {
560 fs->mark_immutable ();
562 fs->mark_immutable_except_write ();
564 fs->mark_nonremovable ();
567 /* don't create tracks for empty MIDI sources (channels) */
569 if ((smfs = boost::dynamic_pointer_cast<SMFSource>(*x)) != 0 && smfs->is_empty()) {
570 x = all_new_sources.erase(x);
576 /* save state so that we don't lose these new Sources */
580 std::copy (all_new_sources.begin(), all_new_sources.end(), std::back_inserter(status.sources));
583 std::for_each (all_new_sources.begin(), all_new_sources.end(), remove_file_source);
585 error << _("Failed to remove some files after failed/cancelled import operation") << endmsg;