Merge branch 'master' of git.ardour.org:ardour/ardour
[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 <glibmm.h>
38
39 #include <boost/scoped_array.hpp>
40 #include <boost/shared_array.hpp>
41
42 #include "pbd/basename.h"
43 #include "pbd/convert.h"
44
45 #include "evoral/SMF.hpp"
46
47 #include "ardour/analyser.h"
48 #include "ardour/ardour.h"
49 #include "ardour/audio_diskstream.h"
50 #include "ardour/audioengine.h"
51 #include "ardour/audioregion.h"
52 #include "ardour/import_status.h"
53 #include "ardour/region_factory.h"
54 #include "ardour/resampled_source.h"
55 #include "ardour/runtime_functions.h"
56 #include "ardour/session.h"
57 #include "ardour/session_directory.h"
58 #include "ardour/smf_source.h"
59 #include "ardour/sndfile_helpers.h"
60 #include "ardour/sndfileimportable.h"
61 #include "ardour/sndfilesource.h"
62 #include "ardour/source_factory.h"
63 #include "ardour/tempo.h"
64
65 #ifdef HAVE_COREAUDIO
66 #include "ardour/caimportable.h"
67 #endif
68
69 #include "i18n.h"
70
71 using namespace std;
72 using namespace ARDOUR;
73 using namespace PBD;
74
75 static boost::shared_ptr<ImportableSource>
76 open_importable_source (const string& path, framecnt_t samplerate, ARDOUR::SrcQuality quality)
77 {
78         /* try libsndfile first, because it can get BWF info from .wav, which ExtAudioFile cannot.
79            We don't necessarily need that information in an ImportableSource, but it keeps the
80            logic the same as in SourceFactory::create()
81         */
82
83         try {
84                 boost::shared_ptr<SndFileImportableSource> source(new SndFileImportableSource(path));
85
86                 if (source->samplerate() == samplerate) {
87                         return source;
88                 }
89
90                 /* rewrap as a resampled source */
91
92                 return boost::shared_ptr<ImportableSource>(new ResampledImportableSource(source, samplerate, quality));
93         }
94
95         catch (...) {
96
97 #ifdef HAVE_COREAUDIO
98
99                 /* libsndfile failed, see if we can use CoreAudio to handle the IO */
100
101                 CAImportableSource* src = new CAImportableSource(path);
102                 boost::shared_ptr<CAImportableSource> source (src);
103
104                 if (source->samplerate() == samplerate) {
105                         return source;
106                 }
107
108                 /* rewrap as a resampled source */
109
110                 return boost::shared_ptr<ImportableSource>(new ResampledImportableSource(source, samplerate, quality));
111
112 #else
113                 throw; // rethrow
114 #endif
115
116         }
117 }
118
119 static std::string
120 get_non_existent_filename (HeaderFormat hf, DataType type, const bool allow_replacing, const std::string& destdir, const std::string& basename, uint channel, uint channels)
121 {
122         char buf[PATH_MAX+1];
123         bool goodfile = false;
124         string base = basename;
125         string ext = native_header_format_extension (hf, type);
126         uint32_t cnt = 1;
127
128         do {
129
130                 if (type == DataType::AUDIO && channels == 2) {
131                         if (channel == 0) {
132                                 if (cnt == 1) {
133                                         snprintf (buf, sizeof(buf), "%s-L%s", base.c_str(), ext.c_str());
134                                 } else {
135                                         snprintf (buf, sizeof(buf), "%s-%d-L%s", base.c_str(), cnt, ext.c_str());
136                                 }
137                         } else {
138                                 if (cnt == 1) {
139                                         snprintf (buf, sizeof(buf), "%s-R%s", base.c_str(), ext.c_str());
140                                 } else {
141                                         snprintf (buf, sizeof(buf), "%s-%d-R%s", base.c_str(), cnt, ext.c_str());
142                                 }
143                         }
144                 } else if (channels > 1) {
145                         if (cnt == 1) {
146                                 snprintf (buf, sizeof(buf), "%s-c%d%s", base.c_str(), channel, ext.c_str());
147                         } else {
148                                 snprintf (buf, sizeof(buf), "%s-%d-c%d%s", base.c_str(), cnt, channel, ext.c_str());
149                         }
150                 } else {
151                         if (cnt == 1) {
152                                 snprintf (buf, sizeof(buf), "%s%s", base.c_str(), ext.c_str());
153                         } else {
154                                 snprintf (buf, sizeof(buf), "%s-%d%s", base.c_str(), cnt, ext.c_str());
155                         }
156                 }
157
158                 string tempname = destdir + "/" + buf;
159
160                 if (!allow_replacing && Glib::file_test (tempname, Glib::FILE_TEST_EXISTS)) {
161
162                         cnt++;
163
164                 } else {
165
166                         goodfile = true;
167                 }
168
169         } while (!goodfile);
170
171         return buf;
172 }
173
174 static vector<string>
175 get_paths_for_new_sources (HeaderFormat hf, const bool allow_replacing, const string& import_file_path, const string& session_dir, uint channels)
176 {
177         vector<string> new_paths;
178         const string basename = basename_nosuffix (import_file_path);
179
180         SessionDirectory sdir(session_dir);
181
182         for (uint n = 0; n < channels; ++n) {
183
184                 const DataType type = SMFSource::safe_midi_file_extension (import_file_path) ? DataType::MIDI : DataType::AUDIO;
185
186                 std::string filepath = (type == DataType::MIDI)
187                         ? sdir.midi_path() : sdir.sound_path();
188
189                 filepath = Glib::build_filename (filepath,
190                                                  get_non_existent_filename (hf, type, allow_replacing, filepath, basename, n, channels));
191                 new_paths.push_back (filepath);
192         }
193
194         return new_paths;
195 }
196
197 static bool
198 map_existing_mono_sources (const vector<string>& new_paths, Session& /*sess*/,
199                            uint /*samplerate*/, vector<boost::shared_ptr<Source> >& newfiles, Session *session)
200 {
201         for (vector<string>::const_iterator i = new_paths.begin();
202              i != new_paths.end(); ++i)
203         {
204                 boost::shared_ptr<Source> source = session->source_by_path_and_channel(*i, 0);
205
206                 if (source == 0) {
207                         error << string_compose(_("Could not find a source for %1 even though we are updating this file!"), (*i)) << endl;
208                         return false;
209                 }
210
211                 newfiles.push_back(boost::dynamic_pointer_cast<Source>(source));
212         }
213         return true;
214 }
215
216 static bool
217 create_mono_sources_for_writing (const string& origin,
218                                  const vector<string>& new_paths,
219                                  Session& sess, uint samplerate,
220                                  vector<boost::shared_ptr<Source> >& newfiles,
221                                  framepos_t timeline_position)
222 {
223         for (vector<string>::const_iterator i = new_paths.begin(); i != new_paths.end(); ++i) {
224
225                 boost::shared_ptr<Source> source;
226
227                 try {
228                         const DataType type = SMFSource::safe_midi_file_extension (*i) ? DataType::MIDI : DataType::AUDIO;
229
230                         source = SourceFactory::createWritable (type, sess,
231                                                                 i->c_str(),
232                                                                 origin,
233                                                                 false, // destructive
234                                                                 samplerate);
235                 }
236
237                 catch (const failed_constructor& err) {
238                         error << string_compose (_("Unable to create file %1 during import"), *i) << endmsg;
239                         return false;
240                 }
241
242                 newfiles.push_back(boost::dynamic_pointer_cast<Source>(source));
243
244                 /* for audio files, reset the timeline position so that any BWF-ish
245                    information in the original files we are importing from is maintained.
246                 */
247
248                 boost::shared_ptr<AudioFileSource> afs;
249                 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
250                         afs->set_timeline_position(timeline_position);
251                 }
252         }
253         return true;
254 }
255
256 static string
257 compose_status_message (const string& path,
258                         uint file_samplerate,
259                         uint session_samplerate,
260                         uint /* current_file */,
261                         uint /* total_files */)
262 {
263         if (file_samplerate != session_samplerate) {
264                 return string_compose (_("Resampling %1 from %2kHz to %3kHz"),
265                                        Glib::path_get_basename (path),
266                                        file_samplerate/1000.0f,
267                                        session_samplerate/1000.0f);
268         }
269
270         return string_compose (_("Copying %1"), Glib::path_get_basename (path));
271 }
272
273 static void
274 write_audio_data_to_new_files (ImportableSource* source, ImportStatus& status,
275                                vector<boost::shared_ptr<Source> >& newfiles)
276 {
277         const framecnt_t nframes = ResampledImportableSource::blocksize;
278         boost::shared_ptr<AudioFileSource> afs;
279         uint channels = source->channels();
280
281         boost::scoped_array<float> data(new float[nframes * channels]);
282         vector<boost::shared_array<Sample> > channel_data;
283
284         for (uint n = 0; n < channels; ++n) {
285                 channel_data.push_back(boost::shared_array<Sample>(new Sample[nframes]));
286         }
287
288         float gain = 1;
289
290         boost::shared_ptr<AudioSource> s = boost::dynamic_pointer_cast<AudioSource> (newfiles[0]);
291         assert (s);
292
293         status.progress = 0.0f;
294         float progress_multiplier = 1;
295         float progress_base = 0;
296
297         if (!source->clamped_at_unity() && s->clamped_at_unity()) {
298
299                 /* The source we are importing from can return sample values with a magnitude greater than 1,
300                    and the file we are writing the imported data to cannot handle such values.  Compute the gain
301                    factor required to normalize the input sources to have a magnitude of less than 1.
302                 */
303
304                 float peak = 0;
305                 uint read_count = 0;
306
307                 while (!status.cancel) {
308                         framecnt_t const nread = source->read (data.get(), nframes);
309                         if (nread == 0) {
310                                 break;
311                         }
312
313                         peak = compute_peak (data.get(), nread, peak);
314
315                         read_count += nread;
316                         status.progress = 0.5 * read_count / (source->ratio() * source->length() * channels);
317                 }
318
319                 if (peak >= 1) {
320                         /* we are out of range: compute a gain to fix it */
321                         gain = (1 - FLT_EPSILON) / peak;
322                 }
323
324                 source->seek (0);
325                 progress_multiplier = 0.5;
326                 progress_base = 0.5;
327         }
328
329         uint read_count = 0;
330
331         while (!status.cancel) {
332
333                 framecnt_t nread, nfread;
334                 uint x;
335                 uint chn;
336
337                 if ((nread = source->read (data.get(), nframes)) == 0) {
338                         break;
339                 }
340
341                 if (gain != 1) {
342                         /* here is the gain fix for out-of-range sample values that we computed earlier */
343                         apply_gain_to_buffer (data.get(), nread, gain);
344                 }
345
346                 nfread = nread / channels;
347
348                 /* de-interleave */
349
350                 for (chn = 0; chn < channels; ++chn) {
351
352                         framecnt_t n;
353                         for (x = chn, n = 0; n < nfread; x += channels, ++n) {
354                                 channel_data[chn][n] = (Sample) data[x];
355                         }
356                 }
357
358                 /* flush to disk */
359
360                 for (chn = 0; chn < channels; ++chn) {
361                         if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(newfiles[chn])) != 0) {
362                                 afs->write (channel_data[chn].get(), nfread);
363                         }
364                 }
365
366                 read_count += nread;
367                 status.progress = progress_base + progress_multiplier * read_count / (source->ratio () * source->length() * channels);
368         }
369 }
370
371 static void
372 write_midi_data_to_new_files (Evoral::SMF* source, ImportStatus& status,
373                               vector<boost::shared_ptr<Source> >& newfiles)
374 {
375         uint32_t buf_size = 4;
376         uint8_t* buf      = (uint8_t*) malloc (buf_size);
377
378         status.progress = 0.0f;
379
380         assert (newfiles.size() == source->num_tracks());
381
382         try {
383                 vector<boost::shared_ptr<Source> >::iterator s = newfiles.begin();
384
385                 for (unsigned i = 1; i <= source->num_tracks(); ++i) {
386
387                         boost::shared_ptr<SMFSource> smfs = boost::dynamic_pointer_cast<SMFSource> (*s);
388
389                         smfs->drop_model ();
390                         source->seek_to_track (i);
391
392                         uint64_t t       = 0;
393                         uint32_t delta_t = 0;
394                         uint32_t size    = 0;
395                         bool first = true;
396
397                         while (!status.cancel) {
398                                 gint note_id_ignored; // imported files either don't have NoteID's or we ignore them.
399
400                                 size = buf_size;
401
402                                 int ret = source->read_event (&delta_t, &size, &buf, &note_id_ignored);
403
404                                 if (size > buf_size) {
405                                         buf_size = size;
406                                 }
407
408                                 if (ret < 0) { // EOT
409                                         break;
410                                 }
411
412                                 t += delta_t;
413
414                                 if (ret == 0) { // Meta
415                                         continue;
416                                 }
417
418                                 if (first) {
419                                         smfs->mark_streaming_write_started ();
420                                         first = false;
421                                 }
422
423                                 smfs->append_event_unlocked_beats(
424                                         Evoral::Event<double>(0,
425                                                               (double)t / (double)source->ppqn(),
426                                                               size,
427                                                               buf));
428
429                                 if (status.progress < 0.99) {
430                                         status.progress += 0.01;
431                                 }
432                         }
433
434                         if (!first) {
435
436                                 /* we wrote something */
437
438                                 const framepos_t pos = 0;
439                                 const double length_beats = ceil(t / (double)source->ppqn());
440                                 BeatsFramesConverter converter(smfs->session().tempo_map(), pos);
441                                 smfs->update_length(pos + converter.to(length_beats));
442                                 smfs->mark_streaming_write_completed ();
443
444                                 if (status.cancel) {
445                                         break;
446                                 }
447                         } else {
448                                 warning << string_compose (_("Track %1 of %2 contained no usable MIDI data"), i, source->file_path()) << endmsg;
449                         }
450
451                         ++s; // next source
452                 }
453
454         } catch (...) {
455                 error << string_compose (_("MIDI file %1 was not readable (no reason available)"), source->file_path()) << endmsg;
456         }
457
458         if (buf) {
459                 free (buf);
460         }
461 }
462
463 static void
464 remove_file_source (boost::shared_ptr<Source> source)
465 {
466         boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
467
468         if (fs) {
469                 ::unlink (fs->path().c_str());
470         }
471 }
472
473 // This function is still unable to cleanly update an existing source, even though
474 // it is possible to set the ImportStatus flag accordingly. The functinality
475 // is disabled at the GUI until the Source implementations are able to provide
476 // the necessary API.
477 void
478 Session::import_files (ImportStatus& status)
479 {
480         typedef vector<boost::shared_ptr<Source> > Sources;
481         Sources all_new_sources;
482         boost::shared_ptr<AudioFileSource> afs;
483         boost::shared_ptr<SMFSource> smfs;
484         uint channels = 0;
485
486         status.sources.clear ();
487
488         for (vector<string>::iterator p = status.paths.begin();
489              p != status.paths.end() && !status.cancel;
490              ++p)
491         {
492                 boost::shared_ptr<ImportableSource> source;
493                 std::auto_ptr<Evoral::SMF>          smf_reader;
494                 const DataType type = SMFSource::safe_midi_file_extension (*p) ? DataType::MIDI : DataType::AUDIO;
495
496                 if (type == DataType::AUDIO) {
497                         try {
498                                 source = open_importable_source (*p, frame_rate(), status.quality);
499                                 channels = source->channels();
500                         } catch (const failed_constructor& err) {
501                                 error << string_compose(_("Import: cannot open input sound file \"%1\""), (*p)) << endmsg;
502                                 status.done = status.cancel = true;
503                                 return;
504                         }
505
506                 } else {
507                         try {
508                                 smf_reader = std::auto_ptr<Evoral::SMF>(new Evoral::SMF());
509                                 smf_reader->open(*p);
510                                 channels = smf_reader->num_tracks();
511                         } catch (...) {
512                                 error << _("Import: error opening MIDI file") << endmsg;
513                                 status.done = status.cancel = true;
514                                 return;
515                         }
516                 }
517
518                 vector<string> new_paths = get_paths_for_new_sources (config.get_native_file_header_format(),
519                                                                       status.replace_existing_source, *p,
520                                                                       get_best_session_directory_for_new_source (),
521                                                                       channels);
522                 Sources newfiles;
523                 framepos_t natural_position = source ? source->natural_position() : 0;
524
525
526                 if (status.replace_existing_source) {
527                         fatal << "THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" << endmsg;
528                         status.cancel = !map_existing_mono_sources (new_paths, *this, frame_rate(), newfiles, this);
529                 } else {
530                         status.cancel = !create_mono_sources_for_writing (*p, new_paths, *this, frame_rate(), newfiles, natural_position);
531                 }
532
533                 // copy on cancel/failure so that any files that were created will be removed below
534                 std::copy (newfiles.begin(), newfiles.end(), std::back_inserter(all_new_sources));
535
536                 if (status.cancel) {
537                         break;
538                 }
539
540                 for (Sources::iterator i = newfiles.begin(); i != newfiles.end(); ++i) {
541                         if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*i)) != 0) {
542                                 afs->prepare_for_peakfile_writes ();
543                         }
544                 }
545
546                 if (source) { // audio
547                         status.doing_what = compose_status_message (*p, source->samplerate(),
548                                                                     frame_rate(), status.current, status.total);
549                         write_audio_data_to_new_files (source.get(), status, newfiles);
550                 } else if (smf_reader.get()) { // midi
551                         status.doing_what = string_compose(_("Loading MIDI file %1"), *p);
552                         write_midi_data_to_new_files (smf_reader.get(), status, newfiles);
553                 }
554
555                 ++status.current;
556                 status.progress = 0;
557         }
558
559         if (!status.cancel) {
560                 struct tm* now;
561                 time_t xnow;
562                 time (&xnow);
563                 now = localtime (&xnow);
564                 status.freeze = true;
565
566                 /* flush the final length(s) to the header(s) */
567
568                 for (Sources::iterator x = all_new_sources.begin(); x != all_new_sources.end(); ) {
569
570                         if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*x)) != 0) {
571                                 afs->update_header((*x)->natural_position(), *now, xnow);
572                                 afs->done_with_peakfile_writes ();
573
574                                 /* now that there is data there, requeue the file for analysis */
575
576                                 if (Config->get_auto_analyse_audio()) {
577                                         Analyser::queue_source_for_analysis (boost::static_pointer_cast<Source>(*x), false);
578                                 }
579                         }
580                         
581                         /* imported, copied files cannot be written or removed
582                          */
583
584                         boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource>(*x);
585                         if (fs) {
586                                 /* Only audio files should be marked as
587                                    immutable - we may need to rewrite MIDI
588                                    files at any time.
589                                 */
590                                 if (boost::dynamic_pointer_cast<AudioFileSource> (fs)) {
591                                         fs->mark_immutable ();
592                                 } else {
593                                         fs->mark_immutable_except_write ();
594                                 }
595                                 fs->mark_nonremovable ();
596                         }
597
598                         /* don't create tracks for empty MIDI sources (channels) */
599
600                         if ((smfs = boost::dynamic_pointer_cast<SMFSource>(*x)) != 0 && smfs->is_empty()) {
601                                 x = all_new_sources.erase(x);
602                         } else {
603                                 ++x;
604                         }
605                 }
606
607                 /* save state so that we don't lose these new Sources */
608
609                 save_state (_name);
610
611                 std::copy (all_new_sources.begin(), all_new_sources.end(), std::back_inserter(status.sources));
612         } else {
613                 try {
614                         std::for_each (all_new_sources.begin(), all_new_sources.end(), remove_file_source);
615                 } catch (...) {
616                         error << _("Failed to remove some files after failed/cancelled import operation") << endmsg;
617                 }
618                                 
619         }
620
621         status.done = true;
622 }
623