Wrap MusicalTime in a class.
[ardour.git] / libs / ardour / import.cc
1 /*
2   Copyright (C) 2000 Paul Davis
3
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.
8
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.
13
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.
17
18 */
19
20 #ifdef WAF_BUILD
21 #include "libardour-config.h"
22 #endif
23
24 #include <cstdio>
25 #include <cstdlib>
26 #include <string>
27 #include <climits>
28 #include <cerrno>
29 #include <unistd.h>
30 #include <sys/stat.h>
31 #include <time.h>
32 #include <stdint.h>
33
34 #include <sndfile.h>
35 #include <samplerate.h>
36
37 #include <glib/gstdio.h>
38 #include <glibmm.h>
39
40 #include <boost/scoped_array.hpp>
41 #include <boost/shared_array.hpp>
42
43 #include "pbd/basename.h"
44 #include "pbd/convert.h"
45
46 #include "evoral/SMF.hpp"
47
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"
65
66 #ifdef HAVE_COREAUDIO
67 #include "ardour/caimportable.h"
68 #endif
69
70 #include "i18n.h"
71
72 using namespace std;
73 using namespace ARDOUR;
74 using namespace PBD;
75
76 static boost::shared_ptr<ImportableSource>
77 open_importable_source (const string& path, framecnt_t samplerate, ARDOUR::SrcQuality quality)
78 {
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()
82         */
83
84         try {
85                 boost::shared_ptr<SndFileImportableSource> source(new SndFileImportableSource(path));
86
87                 if (source->samplerate() == samplerate) {
88                         return source;
89                 }
90
91                 /* rewrap as a resampled source */
92
93                 return boost::shared_ptr<ImportableSource>(new ResampledImportableSource(source, samplerate, quality));
94         }
95
96         catch (...) {
97
98 #ifdef HAVE_COREAUDIO
99
100                 /* libsndfile failed, see if we can use CoreAudio to handle the IO */
101
102                 CAImportableSource* src = new CAImportableSource(path);
103                 boost::shared_ptr<CAImportableSource> source (src);
104
105                 if (source->samplerate() == samplerate) {
106                         return source;
107                 }
108
109                 /* rewrap as a resampled source */
110
111                 return boost::shared_ptr<ImportableSource>(new ResampledImportableSource(source, samplerate, quality));
112
113 #else
114                 throw; // rethrow
115 #endif
116
117         }
118 }
119
120 vector<string>
121 Session::get_paths_for_new_sources (bool /*allow_replacing*/, const string& import_file_path, uint32_t channels)
122 {
123         vector<string> new_paths;
124         const string basename = basename_nosuffix (import_file_path);
125
126         for (uint32_t n = 0; n < channels; ++n) {
127
128                 const DataType type = SMFSource::safe_midi_file_extension (import_file_path) ? DataType::MIDI : DataType::AUDIO;
129                 string filepath;
130
131                 switch (type) {
132                   case DataType::MIDI:
133                                 if (channels > 1) {
134                                         string mchn_name = string_compose ("%1-t%2", basename, n);
135                                         filepath = new_midi_source_path (mchn_name);
136                                 } else {
137                                         filepath = new_midi_source_path (basename);
138                                 }
139                         break;
140                 case DataType::AUDIO:
141                         filepath = new_audio_source_path (basename, channels, n, false, false);
142                         break;
143                 }
144
145                 if (filepath.empty()) {
146                         error << string_compose (_("Cannot find new filename for imported file %1"), import_file_path) << endmsg;
147                         return vector<string>();
148                 }
149
150                 new_paths.push_back (filepath);
151         }
152
153         return new_paths;
154 }
155
156 static bool
157 map_existing_mono_sources (const vector<string>& new_paths, Session& /*sess*/,
158                            uint32_t /*samplerate*/, vector<boost::shared_ptr<Source> >& newfiles, Session *session)
159 {
160         for (vector<string>::const_iterator i = new_paths.begin();
161              i != new_paths.end(); ++i)
162         {
163                 boost::shared_ptr<Source> source = session->audio_source_by_path_and_channel(*i, 0);
164
165                 if (source == 0) {
166                         error << string_compose(_("Could not find a source for %1 even though we are updating this file!"), (*i)) << endl;
167                         return false;
168                 }
169
170                 newfiles.push_back(boost::dynamic_pointer_cast<Source>(source));
171         }
172         return true;
173 }
174
175 static bool
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)
180 {
181         for (vector<string>::const_iterator i = new_paths.begin(); i != new_paths.end(); ++i) {
182
183                 boost::shared_ptr<Source> source;
184
185                 try {
186                         const DataType type = SMFSource::safe_midi_file_extension (*i) ? DataType::MIDI : DataType::AUDIO;
187
188                         source = SourceFactory::createWritable (type, sess,
189                                                                 i->c_str(),
190                                                                 false, // destructive
191                                                                 samplerate);
192                 }
193
194                 catch (const failed_constructor& err) {
195                         error << string_compose (_("Unable to create file %1 during import"), *i) << endmsg;
196                         return false;
197                 }
198
199                 newfiles.push_back(boost::dynamic_pointer_cast<Source>(source));
200
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.
203                 */
204
205                 boost::shared_ptr<AudioFileSource> afs;
206                 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
207                         afs->set_timeline_position(timeline_position);
208                 }
209         }
210         return true;
211 }
212
213 static string
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 */)
219 {
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);
225         }
226
227         return string_compose (_("Copying %1"), Glib::path_get_basename (path));
228 }
229
230 static void
231 write_audio_data_to_new_files (ImportableSource* source, ImportStatus& status,
232                                vector<boost::shared_ptr<Source> >& newfiles)
233 {
234         const framecnt_t nframes = ResampledImportableSource::blocksize;
235         boost::shared_ptr<AudioFileSource> afs;
236         uint32_t channels = source->channels();
237         if (channels == 0) {
238                 return;
239         }
240
241         boost::scoped_array<float> data(new float[nframes * channels]);
242         vector<boost::shared_array<Sample> > channel_data;
243
244         for (uint32_t n = 0; n < channels; ++n) {
245                 channel_data.push_back(boost::shared_array<Sample>(new Sample[nframes]));
246         }
247
248         float gain = 1;
249
250         boost::shared_ptr<AudioSource> s = boost::dynamic_pointer_cast<AudioSource> (newfiles[0]);
251         assert (s);
252
253         status.progress = 0.0f;
254         float progress_multiplier = 1;
255         float progress_base = 0;
256
257         if (!source->clamped_at_unity() && s->clamped_at_unity()) {
258
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.
262                 */
263
264                 float peak = 0;
265                 uint32_t read_count = 0;
266
267                 while (!status.cancel) {
268                         framecnt_t const nread = source->read (data.get(), nframes);
269                         if (nread == 0) {
270                                 break;
271                         }
272
273                         peak = compute_peak (data.get(), nread, peak);
274
275                         read_count += nread;
276                         status.progress = 0.5 * read_count / (source->ratio() * source->length() * channels);
277                 }
278
279                 if (peak >= 1) {
280                         /* we are out of range: compute a gain to fix it */
281                         gain = (1 - FLT_EPSILON) / peak;
282                 }
283
284                 source->seek (0);
285                 progress_multiplier = 0.5;
286                 progress_base = 0.5;
287         }
288
289         framecnt_t read_count = 0;
290
291         while (!status.cancel) {
292
293                 framecnt_t nread, nfread;
294                 uint32_t x;
295                 uint32_t chn;
296
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)
304                                         afs->flush ();
305 #endif
306                         break;
307                 }
308
309                 if (gain != 1) {
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);
312                 }
313
314                 nfread = nread / channels;
315
316                 /* de-interleave */
317
318                 for (chn = 0; chn < channels; ++chn) {
319
320                         framecnt_t n;
321                         for (x = chn, n = 0; n < nfread; x += channels, ++n) {
322                                 channel_data[chn][n] = (Sample) data[x];
323                         }
324                 }
325
326                 /* flush to disk */
327
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);
331                         }
332                 }
333
334                 read_count += nread;
335                 status.progress = progress_base + progress_multiplier * read_count / (source->ratio () * source->length() * channels);
336         }
337 }
338
339 static void
340 write_midi_data_to_new_files (Evoral::SMF* source, ImportStatus& status,
341                               vector<boost::shared_ptr<Source> >& newfiles)
342 {
343         uint32_t buf_size = 4;
344         uint8_t* buf      = (uint8_t*) malloc (buf_size);
345
346         status.progress = 0.0f;
347
348         assert (newfiles.size() == source->num_tracks());
349
350         try {
351                 vector<boost::shared_ptr<Source> >::iterator s = newfiles.begin();
352
353                 for (unsigned i = 1; i <= source->num_tracks(); ++i) {
354
355                         boost::shared_ptr<SMFSource> smfs = boost::dynamic_pointer_cast<SMFSource> (*s);
356
357                         smfs->drop_model ();
358                         source->seek_to_track (i);
359
360                         uint64_t t       = 0;
361                         uint32_t delta_t = 0;
362                         uint32_t size    = 0;
363                         bool first = true;
364
365                         while (!status.cancel) {
366                                 gint note_id_ignored; // imported files either don't have NoteID's or we ignore them.
367
368                                 size = buf_size;
369
370                                 int ret = source->read_event (&delta_t, &size, &buf, &note_id_ignored);
371
372                                 if (size > buf_size) {
373                                         buf_size = size;
374                                 }
375
376                                 if (ret < 0) { // EOT
377                                         break;
378                                 }
379
380                                 t += delta_t;
381
382                                 if (ret == 0) { // Meta
383                                         continue;
384                                 }
385
386                                 if (first) {
387                                         smfs->mark_streaming_write_started ();
388                                         first = false;
389                                 }
390
391                                 smfs->append_event_unlocked_beats(
392                                         Evoral::Event<Evoral::MusicalTime>(
393                                                 0,
394                                                 Evoral::MusicalTime::ticks_at_rate(t, source->ppqn()),
395                                                 size,
396                                                 buf));
397
398                                 if (status.progress < 0.99) {
399                                         status.progress += 0.01;
400                                 }
401                         }
402
403                         if (!first) {
404
405                                 /* we wrote something */
406
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 ();
412
413                                 if (status.cancel) {
414                                         break;
415                                 }
416                         } else {
417                                 warning << string_compose (_("Track %1 of %2 contained no usable MIDI data"), i, source->file_path()) << endmsg;
418                         }
419
420                         ++s; // next source
421                 }
422
423         } catch (...) {
424                 error << string_compose (_("MIDI file %1 was not readable (no reason available)"), source->file_path()) << endmsg;
425         }
426
427         if (buf) {
428                 free (buf);
429         }
430 }
431
432 static void
433 remove_file_source (boost::shared_ptr<Source> source)
434 {
435         boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
436
437         fs->DropReferences ();
438
439         if (fs) {
440                 ::g_unlink (fs->path().c_str());
441         }
442 }
443
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.
448 void
449 Session::import_files (ImportStatus& status)
450 {
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;
456
457         status.sources.clear ();
458
459         for (vector<string>::iterator p = status.paths.begin();
460              p != status.paths.end() && !status.cancel;
461              ++p)
462         {
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;
466
467                 if (type == DataType::AUDIO) {
468                         try {
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;
474                                 return;
475                         }
476
477                 } else {
478                         try {
479                                 smf_reader = std::auto_ptr<Evoral::SMF>(new Evoral::SMF());
480                                 smf_reader->open(*p);
481                                 channels = smf_reader->num_tracks();
482                         } catch (...) {
483                                 error << _("Import: error opening MIDI file") << endmsg;
484                                 status.done = status.cancel = true;
485                                 return;
486                         }
487                 }
488                 
489                 if (channels == 0) {
490                         error << _("Import: file contains no channels.") << endmsg;
491                         continue;
492                 }
493
494                 vector<string> new_paths = get_paths_for_new_sources (status.replace_existing_source, *p, channels);
495                 Sources newfiles;
496                 framepos_t natural_position = source ? source->natural_position() : 0;
497
498
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);
502                 } else {
503                         status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles, natural_position);
504                 }
505
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));
508
509                 if (status.cancel) {
510                         break;
511                 }
512
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 ();
516                         }
517                 }
518
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);
526                 }
527
528                 ++status.current;
529                 status.progress = 0;
530         }
531
532         if (!status.cancel) {
533                 struct tm* now;
534                 time_t xnow;
535                 time (&xnow);
536                 now = localtime (&xnow);
537                 status.freeze = true;
538
539                 /* flush the final length(s) to the header(s) */
540
541                 for (Sources::iterator x = all_new_sources.begin(); x != all_new_sources.end(); ) {
542
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 ();
546
547                                 /* now that there is data there, requeue the file for analysis */
548
549                                 if (Config->get_auto_analyse_audio()) {
550                                         Analyser::queue_source_for_analysis (boost::static_pointer_cast<Source>(*x), false);
551                                 }
552                         }
553                         
554                         /* imported, copied files cannot be written or removed
555                          */
556
557                         boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource>(*x);
558                         if (fs) {
559                                 /* Only audio files should be marked as
560                                    immutable - we may need to rewrite MIDI
561                                    files at any time.
562                                 */
563                                 if (boost::dynamic_pointer_cast<AudioFileSource> (fs)) {
564                                         fs->mark_immutable ();
565                                 } else {
566                                         fs->mark_immutable_except_write ();
567                                 }
568                                 fs->mark_nonremovable ();
569                         }
570
571                         /* don't create tracks for empty MIDI sources (channels) */
572
573                         if ((smfs = boost::dynamic_pointer_cast<SMFSource>(*x)) != 0 && smfs->is_empty()) {
574                                 x = all_new_sources.erase(x);
575                         } else {
576                                 ++x;
577                         }
578                 }
579
580                 /* save state so that we don't lose these new Sources */
581
582                 save_state (_name);
583
584                 std::copy (all_new_sources.begin(), all_new_sources.end(), std::back_inserter(status.sources));
585         } else {
586                 try {
587                         std::for_each (all_new_sources.begin(), all_new_sources.end(), remove_file_source);
588                 } catch (...) {
589                         error << _("Failed to remove some files after failed/cancelled import operation") << endmsg;
590                 }
591                                 
592         }
593
594         status.done = true;
595 }
596