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 "pbd/gstdio_compat.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,
122 vector<string> const & smf_track_names)
125 vector<string> new_paths;
126 const string basename = basename_nosuffix (import_file_path);
128 for (uint32_t n = 0; n < channels; ++n) {
130 const DataType type = SMFSource::safe_midi_file_extension (import_file_path) ? DataType::MIDI : DataType::AUDIO;
135 assert (smf_track_names.empty() || smf_track_names.size() == channels);
138 if (smf_track_names.empty() || smf_track_names[n].empty()) {
139 mchn_name = string_compose ("%1-t%2", basename, n);
141 mchn_name = string_compose ("%1-%2", basename, smf_track_names[n]);
143 filepath = new_midi_source_path (mchn_name);
145 filepath = new_midi_source_path (basename);
148 case DataType::AUDIO:
149 filepath = new_audio_source_path (basename, channels, n, false, false);
153 if (filepath.empty()) {
154 error << string_compose (_("Cannot find new filename for imported file %1"), import_file_path) << endmsg;
155 return vector<string>();
158 new_paths.push_back (filepath);
165 map_existing_mono_sources (const vector<string>& new_paths, Session& /*sess*/,
166 uint32_t /*samplerate*/, vector<boost::shared_ptr<Source> >& newfiles, Session *session)
168 for (vector<string>::const_iterator i = new_paths.begin();
169 i != new_paths.end(); ++i)
171 boost::shared_ptr<Source> source = session->audio_source_by_path_and_channel(*i, 0);
174 error << string_compose(_("Could not find a source for %1 even though we are updating this file!"), (*i)) << endl;
178 newfiles.push_back(boost::dynamic_pointer_cast<Source>(source));
184 create_mono_sources_for_writing (const vector<string>& new_paths,
185 Session& sess, uint32_t samplerate,
186 vector<boost::shared_ptr<Source> >& newfiles,
187 framepos_t timeline_position)
189 for (vector<string>::const_iterator i = new_paths.begin(); i != new_paths.end(); ++i) {
191 boost::shared_ptr<Source> source;
194 const DataType type = SMFSource::safe_midi_file_extension (*i) ? DataType::MIDI : DataType::AUDIO;
196 source = SourceFactory::createWritable (type, sess,
198 false, // destructive
202 catch (const failed_constructor& err) {
203 error << string_compose (_("Unable to create file %1 during import"), *i) << endmsg;
207 newfiles.push_back(boost::dynamic_pointer_cast<Source>(source));
209 /* for audio files, reset the timeline position so that any BWF-ish
210 information in the original files we are importing from is maintained.
213 boost::shared_ptr<AudioFileSource> afs;
214 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
215 afs->set_timeline_position(timeline_position);
222 compose_status_message (const string& path,
223 uint32_t file_samplerate,
224 uint32_t session_samplerate,
225 uint32_t /* current_file */,
226 uint32_t /* total_files */)
228 if (file_samplerate != session_samplerate) {
229 return string_compose (_("Resampling %1 from %2kHz to %3kHz"),
230 Glib::path_get_basename (path),
231 file_samplerate/1000.0f,
232 session_samplerate/1000.0f);
235 return string_compose (_("Copying %1"), Glib::path_get_basename (path));
239 write_audio_data_to_new_files (ImportableSource* source, ImportStatus& status,
240 vector<boost::shared_ptr<Source> >& newfiles)
242 const framecnt_t nframes = ResampledImportableSource::blocksize;
243 boost::shared_ptr<AudioFileSource> afs;
244 uint32_t channels = source->channels();
249 boost::scoped_array<float> data(new float[nframes * channels]);
250 vector<boost::shared_array<Sample> > channel_data;
252 for (uint32_t n = 0; n < channels; ++n) {
253 channel_data.push_back(boost::shared_array<Sample>(new Sample[nframes]));
258 boost::shared_ptr<AudioSource> s = boost::dynamic_pointer_cast<AudioSource> (newfiles[0]);
261 status.progress = 0.0f;
262 float progress_multiplier = 1;
263 float progress_base = 0;
265 if (!source->clamped_at_unity() && s->clamped_at_unity()) {
267 /* The source we are importing from can return sample values with a magnitude greater than 1,
268 and the file we are writing the imported data to cannot handle such values. Compute the gain
269 factor required to normalize the input sources to have a magnitude of less than 1.
273 uint32_t read_count = 0;
275 while (!status.cancel) {
276 framecnt_t const nread = source->read (data.get(), nframes * channels);
281 peak = compute_peak (data.get(), nread * channels, peak);
283 read_count += nread / channels;
284 status.progress = 0.5 * read_count / (source->ratio() * source->length() * channels);
288 /* we are out of range: compute a gain to fix it */
289 gain = (1 - FLT_EPSILON) / peak;
293 progress_multiplier = 0.5;
297 framecnt_t read_count = 0;
299 while (!status.cancel) {
301 framecnt_t nread, nfread;
305 if ((nread = source->read (data.get(), nframes * channels)) == 0) {
306 #ifdef PLATFORM_WINDOWS
307 /* Flush the data once we've finished importing the file. Windows can */
308 /* cache the data for very long periods of time (perhaps not writing */
309 /* it to disk until Ardour closes). So let's force it to flush now. */
310 for (chn = 0; chn < channels; ++chn)
311 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(newfiles[chn])) != 0)
318 /* here is the gain fix for out-of-range sample values that we computed earlier */
319 apply_gain_to_buffer (data.get(), nread, gain);
322 nfread = nread / channels;
326 for (chn = 0; chn < channels; ++chn) {
329 for (x = chn, n = 0; n < nfread; x += channels, ++n) {
330 channel_data[chn][n] = (Sample) data[x];
336 for (chn = 0; chn < channels; ++chn) {
337 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(newfiles[chn])) != 0) {
338 afs->write (channel_data[chn].get(), nfread);
343 status.progress = progress_base + progress_multiplier * read_count / (source->ratio () * source->length() * channels);
348 write_midi_data_to_new_files (Evoral::SMF* source, ImportStatus& status,
349 vector<boost::shared_ptr<Source> >& newfiles,
352 uint32_t buf_size = 4;
353 uint8_t* buf = (uint8_t*) malloc (buf_size);
355 status.progress = 0.0f;
357 bool type0 = source->is_type0 () && split_type0;
358 const std::set<uint8_t>& chn = source->channels ();
361 num_tracks = source->channels().size();
363 num_tracks = source->num_tracks();
365 assert (newfiles.size() == num_tracks);
368 vector<boost::shared_ptr<Source> >::iterator s = newfiles.begin();
369 std::set<uint8_t>::const_iterator cur_chan = chn.begin();
371 for (unsigned i = 1; i <= num_tracks; ++i) {
373 boost::shared_ptr<SMFSource> smfs = boost::dynamic_pointer_cast<SMFSource> (*s);
375 Glib::Threads::Mutex::Lock source_lock(smfs->mutex());
377 smfs->drop_model (source_lock);
379 source->seek_to_start ();
381 source->seek_to_track (i);
385 uint32_t delta_t = 0;
389 while (!status.cancel) {
390 gint note_id_ignored; // imported files either don't have NoteID's or we ignore them.
394 int ret = source->read_event (&delta_t, &size, &buf, ¬e_id_ignored);
396 if (size > buf_size) {
400 if (ret < 0) { // EOT
406 if (ret == 0) { // Meta
410 // type-0 files separate by channel
412 uint8_t type = buf[0] & 0xf0;
413 uint8_t chan = buf[0] & 0x0f;
414 if (type >= 0x80 && type <= 0xE0) {
415 if (chan != *cur_chan) {
422 smfs->mark_streaming_write_started (source_lock);
426 smfs->append_event_beats(
428 Evoral::Event<Evoral::Beats>(
430 Evoral::Beats::ticks_at_rate(t, source->ppqn()),
434 if (status.progress < 0.99) {
435 status.progress += 0.01;
441 /* we wrote something */
443 const framepos_t pos = 0;
444 const Evoral::Beats length_beats = Evoral::Beats::ticks_at_rate(t, source->ppqn());
445 BeatsFramesConverter converter(smfs->session().tempo_map(), pos);
446 smfs->update_length(pos + converter.to(length_beats.round_up_to_beat()));
447 smfs->mark_streaming_write_completed (source_lock);
453 info << string_compose (_("Track %1 of %2 contained no usable MIDI data"), i, num_tracks) << endmsg;
462 } catch (exception& e) {
463 error << string_compose (_("MIDI file could not be written (best guess: %1)"), e.what()) << endmsg;
472 remove_file_source (boost::shared_ptr<Source> source)
474 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
476 fs->DropReferences ();
479 ::g_unlink (fs->path().c_str());
483 // This function is still unable to cleanly update an existing source, even though
484 // it is possible to set the ImportStatus flag accordingly. The functinality
485 // is disabled at the GUI until the Source implementations are able to provide
486 // the necessary API.
488 Session::import_files (ImportStatus& status)
490 typedef vector<boost::shared_ptr<Source> > Sources;
491 Sources all_new_sources;
492 boost::shared_ptr<AudioFileSource> afs;
493 boost::shared_ptr<SMFSource> smfs;
494 uint32_t channels = 0;
495 vector<string> smf_names;
497 status.sources.clear ();
499 for (vector<string>::const_iterator p = status.paths.begin();
500 p != status.paths.end() && !status.cancel;
503 boost::shared_ptr<ImportableSource> source;
504 std::auto_ptr<Evoral::SMF> smf_reader;
505 const DataType type = SMFSource::safe_midi_file_extension (*p) ? DataType::MIDI : DataType::AUDIO;
507 if (type == DataType::AUDIO) {
509 source = open_importable_source (*p, frame_rate(), status.quality);
510 channels = source->channels();
511 } catch (const failed_constructor& err) {
512 error << string_compose(_("Import: cannot open input sound file \"%1\""), (*p)) << endmsg;
513 status.done = status.cancel = true;
519 smf_reader = std::auto_ptr<Evoral::SMF>(new Evoral::SMF());
521 if (smf_reader->open(*p)) {
522 throw Evoral::SMF::FileError (*p);
525 if (smf_reader->is_type0 () && status.split_midi_channels) {
526 channels = smf_reader->channels().size();
528 channels = smf_reader->num_tracks();
529 switch (status.midi_track_name_source) {
533 smf_reader->track_names (smf_names);
535 case SMFInstrumentName:
536 smf_reader->instrument_names (smf_names);
541 error << _("Import: error opening MIDI file") << endmsg;
542 status.done = status.cancel = true;
548 error << _("Import: file contains no channels.") << endmsg;
552 vector<string> new_paths = get_paths_for_new_sources (status.replace_existing_source, *p, channels, smf_names);
554 framepos_t natural_position = source ? source->natural_position() : 0;
557 if (status.replace_existing_source) {
558 fatal << "THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" << endmsg;
559 status.cancel = !map_existing_mono_sources (new_paths, *this, frame_rate(), newfiles, this);
561 status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles, natural_position);
564 // copy on cancel/failure so that any files that were created will be removed below
565 std::copy (newfiles.begin(), newfiles.end(), std::back_inserter(all_new_sources));
571 for (Sources::iterator i = newfiles.begin(); i != newfiles.end(); ++i) {
572 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*i)) != 0) {
573 afs->prepare_for_peakfile_writes ();
577 if (source) { // audio
578 status.doing_what = compose_status_message (*p, source->samplerate(),
579 frame_rate(), status.current, status.total);
580 write_audio_data_to_new_files (source.get(), status, newfiles);
581 } else if (smf_reader.get()) { // midi
582 status.doing_what = string_compose(_("Loading MIDI file %1"), *p);
583 write_midi_data_to_new_files (smf_reader.get(), status, newfiles, status.split_midi_channels);
590 if (!status.cancel) {
594 now = localtime (&xnow);
595 status.freeze = true;
597 /* flush the final length(s) to the header(s) */
599 for (Sources::iterator x = all_new_sources.begin(); x != all_new_sources.end(); ) {
601 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*x)) != 0) {
602 afs->update_header((*x)->natural_position(), *now, xnow);
603 afs->done_with_peakfile_writes ();
605 /* now that there is data there, requeue the file for analysis */
607 if (Config->get_auto_analyse_audio()) {
608 Analyser::queue_source_for_analysis (boost::static_pointer_cast<Source>(*x), false);
612 /* imported, copied files cannot be written or removed
615 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource>(*x);
617 /* Only audio files should be marked as
618 immutable - we may need to rewrite MIDI
621 if (boost::dynamic_pointer_cast<AudioFileSource> (fs)) {
622 fs->mark_immutable ();
624 fs->mark_immutable_except_write ();
626 fs->mark_nonremovable ();
629 /* don't create tracks for empty MIDI sources (channels) */
631 if ((smfs = boost::dynamic_pointer_cast<SMFSource>(*x)) != 0 && smfs->is_empty()) {
632 x = all_new_sources.erase(x);
638 /* save state so that we don't lose these new Sources */
642 std::copy (all_new_sources.begin(), all_new_sources.end(), std::back_inserter(status.sources));
645 std::for_each (all_new_sources.begin(), all_new_sources.end(), remove_file_source);
647 error << _("Failed to remove some files after failed/cancelled import operation") << endmsg;