Fix progress report when resampling to fixed-point on import
[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 "pbd/gstdio_compat.h"
38 #include <glibmm.h>
39
40 #include <boost/scoped_array.hpp>
41 #include <boost/scoped_ptr.hpp>
42 #include <boost/shared_array.hpp>
43
44 #include "pbd/basename.h"
45 #include "pbd/convert.h"
46
47 #include "evoral/SMF.hpp"
48
49 #include "ardour/analyser.h"
50 #include "ardour/ardour.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 "pbd/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, samplecnt_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                                     vector<string> const & smf_track_names)
123
124 {
125         vector<string> new_paths;
126         const string basename = basename_nosuffix (import_file_path);
127
128         for (uint32_t n = 0; n < channels; ++n) {
129
130                 const DataType type = SMFSource::safe_midi_file_extension (import_file_path) ? DataType::MIDI : DataType::AUDIO;
131                 string filepath;
132
133                 switch (type) {
134                 case DataType::MIDI:
135                         assert (smf_track_names.empty() || smf_track_names.size() == channels);
136                         if (channels > 1) {
137                                 string mchn_name;
138                                 if (smf_track_names.empty() || smf_track_names[n].empty()) {
139                                         mchn_name = string_compose ("%1-t%2", basename, n);
140                                 } else {
141                                         mchn_name = string_compose ("%1-%2", basename, smf_track_names[n]);
142                                 }
143                                 filepath = new_midi_source_path (mchn_name);
144                         } else {
145                                 filepath = new_midi_source_path (basename);
146                         }
147                         break;
148                 case DataType::AUDIO:
149                         filepath = new_audio_source_path (basename, channels, n, false, false);
150                         break;
151                 }
152
153                 if (filepath.empty()) {
154                         error << string_compose (_("Cannot find new filename for imported file %1"), import_file_path) << endmsg;
155                         return vector<string>();
156                 }
157
158                 new_paths.push_back (filepath);
159         }
160
161         return new_paths;
162 }
163
164 static bool
165 map_existing_mono_sources (const vector<string>& new_paths, Session& /*sess*/,
166                            uint32_t /*samplerate*/, vector<boost::shared_ptr<Source> >& newfiles, Session *session)
167 {
168         for (vector<string>::const_iterator i = new_paths.begin();
169              i != new_paths.end(); ++i)
170         {
171                 boost::shared_ptr<Source> source = session->audio_source_by_path_and_channel(*i, 0);
172
173                 if (source == 0) {
174                         error << string_compose(_("Could not find a source for %1 even though we are updating this file!"), (*i)) << endl;
175                         return false;
176                 }
177
178                 newfiles.push_back(boost::dynamic_pointer_cast<Source>(source));
179         }
180         return true;
181 }
182
183 static bool
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                                  samplepos_t timeline_position)
188 {
189         for (vector<string>::const_iterator i = new_paths.begin(); i != new_paths.end(); ++i) {
190
191                 boost::shared_ptr<Source> source;
192
193                 try {
194                         const DataType type = SMFSource::safe_midi_file_extension (*i) ? DataType::MIDI : DataType::AUDIO;
195
196                         source = SourceFactory::createWritable (type, sess,
197                                                                 i->c_str(),
198                                                                 false, // destructive
199                                                                 samplerate);
200                 }
201
202                 catch (const failed_constructor& err) {
203                         error << string_compose (_("Unable to create file %1 during import"), *i) << endmsg;
204                         return false;
205                 }
206
207                 newfiles.push_back(boost::dynamic_pointer_cast<Source>(source));
208
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.
211                 */
212
213                 boost::shared_ptr<AudioFileSource> afs;
214                 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
215                         afs->set_timeline_position(timeline_position);
216                 }
217         }
218         return true;
219 }
220
221 static string
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 */)
227 {
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);
233         }
234
235         return string_compose (_("Copying %1"), Glib::path_get_basename (path));
236 }
237
238 static void
239 write_audio_data_to_new_files (ImportableSource* source, ImportStatus& status,
240                                vector<boost::shared_ptr<Source> >& newfiles)
241 {
242         const samplecnt_t nframes = ResampledImportableSource::blocksize;
243         boost::shared_ptr<AudioFileSource> afs;
244         uint32_t channels = source->channels();
245         if (channels == 0) {
246                 return;
247         }
248
249         boost::scoped_array<float> data(new float[nframes * channels]);
250         vector<boost::shared_array<Sample> > channel_data;
251
252         for (uint32_t n = 0; n < channels; ++n) {
253                 channel_data.push_back(boost::shared_array<Sample>(new Sample[nframes]));
254         }
255
256         float gain = 1;
257
258         boost::shared_ptr<AudioSource> s = boost::dynamic_pointer_cast<AudioSource> (newfiles[0]);
259         assert (s);
260
261         status.progress = 0.0f;
262         float progress_multiplier = 1;
263         float progress_base = 0;
264         const float progress_length = source->ratio() * source->length();
265
266         if (!source->clamped_at_unity() && s->clamped_at_unity()) {
267
268                 /* The source we are importing from can return sample values with a magnitude greater than 1,
269                    and the file we are writing the imported data to cannot handle such values.  Compute the gain
270                    factor required to normalize the input sources to have a magnitude of less than 1.
271                 */
272
273                 float peak = 0;
274                 uint32_t read_count = 0;
275
276                 while (!status.cancel) {
277                         samplecnt_t const nread = source->read (data.get(), nframes * channels);
278                         if (nread == 0) {
279                                 break;
280                         }
281
282                         peak = compute_peak (data.get(), nread, peak);
283
284                         read_count += nread / channels;
285                         status.progress = 0.5 * read_count / progress_length;
286                 }
287
288                 if (peak >= 1) {
289                         /* we are out of range: compute a gain to fix it */
290                         gain = (1 - FLT_EPSILON) / peak;
291                 }
292
293                 source->seek (0);
294                 progress_multiplier = 0.5;
295                 progress_base = 0.5;
296         }
297
298         samplecnt_t read_count = 0;
299
300         while (!status.cancel) {
301
302                 samplecnt_t nread, nfread;
303                 uint32_t x;
304                 uint32_t chn;
305
306                 if ((nread = source->read (data.get(), nframes * channels)) == 0) {
307 #ifdef PLATFORM_WINDOWS
308                         /* Flush the data once we've finished importing the file. Windows can  */
309                         /* cache the data for very long periods of time (perhaps not writing   */
310                         /* it to disk until Ardour closes). So let's force it to flush now.    */
311                         for (chn = 0; chn < channels; ++chn)
312                                 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(newfiles[chn])) != 0)
313                                         afs->flush ();
314 #endif
315                         break;
316                 }
317
318                 if (gain != 1) {
319                         /* here is the gain fix for out-of-range sample values that we computed earlier */
320                         apply_gain_to_buffer (data.get(), nread, gain);
321                 }
322
323                 nfread = nread / channels;
324
325                 /* de-interleave */
326
327                 for (chn = 0; chn < channels; ++chn) {
328
329                         samplecnt_t n;
330                         for (x = chn, n = 0; n < nfread; x += channels, ++n) {
331                                 channel_data[chn][n] = (Sample) data[x];
332                         }
333                 }
334
335                 /* flush to disk */
336
337                 for (chn = 0; chn < channels; ++chn) {
338                         if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(newfiles[chn])) != 0) {
339                                 afs->write (channel_data[chn].get(), nfread);
340                         }
341                 }
342
343                 read_count += nfread;
344                 status.progress = progress_base + progress_multiplier * read_count / progress_length;
345         }
346 }
347
348 static void
349 write_midi_data_to_new_files (Evoral::SMF* source, ImportStatus& status,
350                               vector<boost::shared_ptr<Source> >& newfiles,
351                               bool split_type0)
352 {
353         uint32_t buf_size = 4;
354         uint8_t* buf      = (uint8_t*) malloc (buf_size);
355
356         status.progress = 0.0f;
357         uint16_t num_tracks;
358         bool type0 = source->is_type0 () && split_type0;
359         const std::set<uint8_t>& chn = source->channels ();
360
361         if (type0) {
362                 num_tracks = source->channels().size();
363         } else {
364                 num_tracks = source->num_tracks();
365         }
366         assert (newfiles.size() == num_tracks);
367
368         try {
369                 vector<boost::shared_ptr<Source> >::iterator s = newfiles.begin();
370                 std::set<uint8_t>::const_iterator cur_chan = chn.begin();
371
372                 for (unsigned i = 1; i <= num_tracks; ++i) {
373
374                         boost::shared_ptr<SMFSource> smfs = boost::dynamic_pointer_cast<SMFSource> (*s);
375
376                         Glib::Threads::Mutex::Lock source_lock(smfs->mutex());
377
378                         smfs->drop_model (source_lock);
379                         if (type0) {
380                                 source->seek_to_start ();
381                         } else {
382                                 source->seek_to_track (i);
383                         }
384
385                         uint64_t t       = 0;
386                         uint32_t delta_t = 0;
387                         uint32_t size    = 0;
388                         bool first = true;
389
390                         while (!status.cancel) {
391                                 gint note_id_ignored; // imported files either don't have NoteID's or we ignore them.
392
393                                 size = buf_size;
394
395                                 int ret = source->read_event (&delta_t, &size, &buf, &note_id_ignored);
396
397                                 if (size > buf_size) {
398                                         buf_size = size;
399                                 }
400
401                                 if (ret < 0) { // EOT
402                                         break;
403                                 }
404
405                                 t += delta_t;
406
407                                 if (ret == 0) { // Meta
408                                         continue;
409                                 }
410
411                                 // type-0 files separate by channel
412                                 if (type0) {
413                                         uint8_t type = buf[0] & 0xf0;
414                                         uint8_t chan = buf[0] & 0x0f;
415                                         if (type >= 0x80 && type <= 0xE0) {
416                                                 if (chan != *cur_chan) {
417                                                         continue;
418                                                 }
419                                         }
420                                 }
421
422                                 if (first) {
423                                         smfs->mark_streaming_write_started (source_lock);
424                                         first = false;
425                                 }
426
427                                 smfs->append_event_beats(
428                                         source_lock,
429                                         Evoral::Event<Temporal::Beats>(
430                                                 Evoral::MIDI_EVENT,
431                                                 Temporal::Beats::ticks_at_rate(t, source->ppqn()),
432                                                 size,
433                                                 buf));
434
435                                 if (status.progress < 0.99) {
436                                         status.progress += 0.01;
437                                 }
438                         }
439
440                         if (!first) {
441
442                                 /* we wrote something */
443
444                                 const samplepos_t     pos          = 0;
445                                 const Temporal::Beats  length_beats = Temporal::Beats::ticks_at_rate(t, source->ppqn());
446                                 BeatsSamplesConverter converter(smfs->session().tempo_map(), pos);
447                                 smfs->update_length(pos + converter.to(length_beats.round_up_to_beat()));
448                                 smfs->mark_streaming_write_completed (source_lock);
449
450                                 if (status.cancel) {
451                                         break;
452                                 }
453                         } else {
454                                 info << string_compose (_("Track %1 of %2 contained no usable MIDI data"), i, num_tracks) << endmsg;
455                         }
456
457                         ++s; // next source
458                         if (type0) {
459                                 ++cur_chan;
460                         }
461                 }
462
463         } catch (exception& e) {
464                 error << string_compose (_("MIDI file could not be written (best guess: %1)"), e.what()) << endmsg;
465         }
466
467         if (buf) {
468                 free (buf);
469         }
470 }
471
472 static void
473 remove_file_source (boost::shared_ptr<Source> source)
474 {
475         boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
476
477         fs->DropReferences ();
478
479         if (fs) {
480                 ::g_unlink (fs->path().c_str());
481         }
482 }
483
484 // This function is still unable to cleanly update an existing source, even though
485 // it is possible to set the ImportStatus flag accordingly. The functinality
486 // is disabled at the GUI until the Source implementations are able to provide
487 // the necessary API.
488 void
489 Session::import_files (ImportStatus& status)
490 {
491         typedef vector<boost::shared_ptr<Source> > Sources;
492         Sources all_new_sources;
493         boost::shared_ptr<AudioFileSource> afs;
494         boost::shared_ptr<SMFSource> smfs;
495         uint32_t channels = 0;
496         vector<string> smf_names;
497
498         status.sources.clear ();
499
500         for (vector<string>::const_iterator p = status.paths.begin();
501              p != status.paths.end() && !status.cancel;
502              ++p)
503         {
504                 boost::shared_ptr<ImportableSource> source;
505
506                 const DataType type = SMFSource::safe_midi_file_extension (*p) ? DataType::MIDI : DataType::AUDIO;
507                 boost::scoped_ptr<Evoral::SMF> smf_reader;
508
509                 if (type == DataType::AUDIO) {
510                         try {
511                                 source = open_importable_source (*p, sample_rate(), status.quality);
512                                 channels = source->channels();
513                         } catch (const failed_constructor& err) {
514                                 error << string_compose(_("Import: cannot open input sound file \"%1\""), (*p)) << endmsg;
515                                 status.done = status.cancel = true;
516                                 return;
517                         }
518
519                 } else {
520                         try {
521                                 smf_reader.reset (new Evoral::SMF());
522
523                                 if (smf_reader->open(*p)) {
524                                         throw Evoral::SMF::FileError (*p);
525                                 }
526
527                                 if (smf_reader->is_type0 () && status.split_midi_channels) {
528                                         channels = smf_reader->channels().size();
529                                 } else {
530                                         channels = smf_reader->num_tracks();
531                                         switch (status.midi_track_name_source) {
532                                         case SMFTrackNumber:
533                                                 break;
534                                         case SMFTrackName:
535                                                 smf_reader->track_names (smf_names);
536                                                 break;
537                                         case SMFInstrumentName:
538                                                 smf_reader->instrument_names (smf_names);
539                                                 break;
540                                         }
541                                 }
542                         } catch (...) {
543                                 error << _("Import: error opening MIDI file") << endmsg;
544                                 status.done = status.cancel = true;
545                                 return;
546                         }
547                 }
548
549                 if (channels == 0) {
550                         error << _("Import: file contains no channels.") << endmsg;
551                         continue;
552                 }
553
554                 vector<string> new_paths = get_paths_for_new_sources (status.replace_existing_source, *p, channels, smf_names);
555                 Sources newfiles;
556                 samplepos_t natural_position = source ? source->natural_position() : 0;
557
558
559                 if (status.replace_existing_source) {
560                         fatal << "THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" << endmsg;
561                         status.cancel = !map_existing_mono_sources (new_paths, *this, sample_rate(), newfiles, this);
562                 } else {
563                         status.cancel = !create_mono_sources_for_writing (new_paths, *this, sample_rate(), newfiles, natural_position);
564                 }
565
566                 // copy on cancel/failure so that any files that were created will be removed below
567                 std::copy (newfiles.begin(), newfiles.end(), std::back_inserter(all_new_sources));
568
569                 if (status.cancel) {
570                         break;
571                 }
572
573                 for (Sources::iterator i = newfiles.begin(); i != newfiles.end(); ++i) {
574                         if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*i)) != 0) {
575                                 afs->prepare_for_peakfile_writes ();
576                         }
577                 }
578
579                 if (source) { // audio
580                         status.doing_what = compose_status_message (*p, source->samplerate(),
581                                                                     sample_rate(), status.current, status.total);
582                         write_audio_data_to_new_files (source.get(), status, newfiles);
583                 } else if (smf_reader) { // midi
584                         status.doing_what = string_compose(_("Loading MIDI file %1"), *p);
585                         write_midi_data_to_new_files (smf_reader.get(), status, newfiles, status.split_midi_channels);
586                 }
587
588                 ++status.current;
589                 status.progress = 0;
590         }
591
592         if (!status.cancel) {
593                 struct tm* now;
594                 time_t xnow;
595                 time (&xnow);
596                 now = localtime (&xnow);
597                 status.freeze = true;
598
599                 /* flush the final length(s) to the header(s) */
600
601                 for (Sources::iterator x = all_new_sources.begin(); x != all_new_sources.end(); ) {
602
603                         if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*x)) != 0) {
604                                 afs->update_header((*x)->natural_position(), *now, xnow);
605                                 afs->done_with_peakfile_writes ();
606
607                                 /* now that there is data there, requeue the file for analysis */
608
609                                 if (Config->get_auto_analyse_audio()) {
610                                         Analyser::queue_source_for_analysis (boost::static_pointer_cast<Source>(*x), false);
611                                 }
612                         }
613
614                         /* imported, copied files cannot be written or removed
615                          */
616
617                         boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource>(*x);
618                         if (fs) {
619                                 /* Only audio files should be marked as
620                                    immutable - we may need to rewrite MIDI
621                                    files at any time.
622                                 */
623                                 if (boost::dynamic_pointer_cast<AudioFileSource> (fs)) {
624                                         fs->mark_immutable ();
625                                 } else {
626                                         fs->mark_immutable_except_write ();
627                                 }
628                                 fs->mark_nonremovable ();
629                         }
630
631                         /* don't create tracks for empty MIDI sources (channels) */
632
633                         if ((smfs = boost::dynamic_pointer_cast<SMFSource>(*x)) != 0 && smfs->is_empty()) {
634                                 x = all_new_sources.erase(x);
635                         } else {
636                                 ++x;
637                         }
638                 }
639
640                 /* save state so that we don't lose these new Sources */
641
642                 save_state (_name);
643
644                 std::copy (all_new_sources.begin(), all_new_sources.end(), std::back_inserter(status.sources));
645         } else {
646                 try {
647                         std::for_each (all_new_sources.begin(), all_new_sources.end(), remove_file_source);
648                 } catch (...) {
649                         error << _("Failed to remove some files after failed/cancelled import operation") << endmsg;
650                 }
651
652         }
653
654         status.done = true;
655 }
656