64eadbb973d9685222bea58af89ff978aceae748
[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
21 #ifdef WAF_BUILD
22 #include "libardour-config.h"
23 #endif
24
25 #include <cstdio>
26 #include <cstdlib>
27 #include <string>
28 #include <climits>
29 #include <cerrno>
30 #include <unistd.h>
31 #include <sys/stat.h>
32 #include <time.h>
33 #include <stdint.h>
34
35 #include <sndfile.h>
36 #include <samplerate.h>
37
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/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, nframes_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 (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         const char* ext = (type == DataType::AUDIO) ? "wav" : "mid";
126
127         do {
128
129                 if (type == DataType::AUDIO && channels == 2) {
130                         if (channel == 0) {
131                                 snprintf (buf, sizeof(buf), "%s-L.wav", base.c_str());
132                         } else {
133                                 snprintf (buf, sizeof(buf), "%s-R.wav", base.c_str());
134                         }
135                 } else if (channels > 1) {
136                         snprintf (buf, sizeof(buf), "%s-c%d.%s", base.c_str(), channel, ext);
137                 } else {
138                         snprintf (buf, sizeof(buf), "%s.%s", base.c_str(), ext);
139                 }
140
141
142                 string tempname = destdir + "/" + buf;
143                 if (!allow_replacing && Glib::file_test (tempname, Glib::FILE_TEST_EXISTS)) {
144
145                         /* if the file already exists, we must come up with
146                          *  a new name for it.  for now we just keep appending
147                          *  _ to basename
148                          */
149
150                         base += "_";
151
152                 } else {
153
154                         goodfile = true;
155                 }
156
157         } while ( !goodfile);
158
159         return buf;
160 }
161
162 static vector<string>
163 get_paths_for_new_sources (const bool allow_replacing, const string& import_file_path, const string& session_dir, uint channels)
164 {
165         vector<string> new_paths;
166         const string basename = basename_nosuffix (import_file_path);
167
168         SessionDirectory sdir(session_dir);
169
170         for (uint n = 0; n < channels; ++n) {
171
172                 const DataType type = (import_file_path.rfind(".mid") != string::npos)
173                                 ? DataType::MIDI : DataType::AUDIO;
174
175                 std::string filepath = (type == DataType::MIDI)
176                                 ? sdir.midi_path().to_string() : sdir.sound_path().to_string();
177
178                 filepath += '/';
179                 filepath += get_non_existent_filename (type, allow_replacing, filepath, basename, n, channels);
180                 new_paths.push_back (filepath);
181         }
182
183         return new_paths;
184 }
185
186 static bool
187 map_existing_mono_sources (const vector<string>& new_paths, Session& /*sess*/,
188                            uint /*samplerate*/, vector<boost::shared_ptr<Source> >& newfiles, Session *session)
189 {
190         for (vector<string>::const_iterator i = new_paths.begin();
191                         i != new_paths.end(); ++i)
192         {
193                 boost::shared_ptr<Source> source = session->source_by_path_and_channel(*i, 0);
194
195                 if (source == 0) {
196                         error << string_compose(_("Could not find a source for %1 even though we are updating this file!"), (*i)) << endl;
197                         return false;
198                 }
199
200                 newfiles.push_back(boost::dynamic_pointer_cast<Source>(source));
201         }
202         return true;
203 }
204
205 static bool
206 create_mono_sources_for_writing (const vector<string>& new_paths, Session& sess,
207                                  uint samplerate, vector<boost::shared_ptr<Source> >& newfiles,
208                                  framepos_t timeline_position)
209 {
210         for (vector<string>::const_iterator i = new_paths.begin(); i != new_paths.end(); ++i)
211         {
212                 boost::shared_ptr<Source> source;
213
214                 try
215                 {
216                         const DataType type = ((*i).rfind(".mid") != string::npos)
217                                 ? DataType::MIDI : DataType::AUDIO;
218
219
220                         source = SourceFactory::createWritable (type, sess,
221                                         i->c_str(),
222                                         false, // destructive
223                                         samplerate);
224                 }
225                 catch (const failed_constructor& err)
226                 {
227                         error << string_compose (_("Unable to create file %1 during import"), *i) << endmsg;
228                         return false;
229                 }
230
231                 newfiles.push_back(boost::dynamic_pointer_cast<Source>(source));
232
233                 /* for audio files, reset the timeline position so that any BWF-ish
234                    information in the original files we are importing from is maintained.
235                 */
236
237                 boost::shared_ptr<AudioFileSource> afs;
238                 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
239                         afs->set_timeline_position(timeline_position);
240                 }
241         }
242         return true;
243 }
244
245 static Glib::ustring
246 compose_status_message (const string& path,
247                         uint file_samplerate,
248                         uint session_samplerate,
249                         uint current_file,
250                         uint total_files)
251 {
252         if (file_samplerate != session_samplerate) {
253                 return string_compose (_("<b>Resampling</b> from %1kHz to %2kHz.\n<i>%3</i>\n(%4 of %5)"),
254                                        file_samplerate/1000.0f,
255                                        session_samplerate/1000.0f,
256                                        Glib::path_get_basename (path),
257                                        current_file, total_files);
258         }
259
260         return string_compose (_("<b>Copying</b>\n<i>%1</i>\n(%2 of %3)"),
261                                Glib::path_get_basename (path),
262                                current_file, total_files);
263 }
264
265 static void
266 write_audio_data_to_new_files (ImportableSource* source, ImportStatus& status,
267                                vector<boost::shared_ptr<Source> >& newfiles)
268 {
269         const nframes_t nframes = ResampledImportableSource::blocksize;
270         boost::shared_ptr<AudioFileSource> afs;
271         uint channels = source->channels();
272
273         boost::scoped_array<float> data(new float[nframes * channels]);
274         vector<boost::shared_array<Sample> > channel_data;
275
276         for (uint n = 0; n < channels; ++n) {
277                 channel_data.push_back(boost::shared_array<Sample>(new Sample[nframes]));
278         }
279
280         float gain = 1;
281
282         boost::shared_ptr<AudioSource> s = boost::dynamic_pointer_cast<AudioSource> (newfiles[0]);
283         assert (s);
284
285         status.progress = 0.0f;
286         float progress_multiplier = 1;
287         float progress_base = 0;
288
289         if (!source->clamped_at_unity() && s->clamped_at_unity()) {
290
291                 /* The source we are importing from can return sample values with a magnitude greater than 1,
292                    and the file we are writing the imported data to cannot handle such values.  Compute the gain
293                    factor required to normalize the input sources to have a magnitude of less than 1.
294                 */
295                 
296                 float peak = 0;
297                 uint read_count = 0;
298                 
299                 while (!status.cancel) {
300                         nframes_t const nread = source->read (data.get(), nframes);
301                         if (nread == 0) {
302                                 break;
303                         }
304
305                         peak = compute_peak (data.get(), nread, peak);
306
307                         read_count += nread;
308                         status.progress = 0.5 * read_count / (source->ratio() * source->length() * channels);
309                 }
310
311                 if (peak >= 1) {
312                         /* we are out of range: compute a gain to fix it */
313                         gain = (1 - FLT_EPSILON) / peak;
314                 }
315                 
316                 source->seek (0);
317                 progress_multiplier = 0.5;
318                 progress_base = 0.5;
319         }
320
321         uint read_count = 0;
322
323         while (!status.cancel) {
324
325                 nframes_t nread, nfread;
326                 uint x;
327                 uint chn;
328
329                 if ((nread = source->read (data.get(), nframes)) == 0) {
330                         break;
331                 }
332
333                 if (gain != 1) {
334                         /* here is the gain fix for out-of-range sample values that we computed earlier */
335                         apply_gain_to_buffer (data.get(), nread, gain);
336                 }
337                 
338                 nfread = nread / channels;
339
340                 /* de-interleave */
341
342                 for (chn = 0; chn < channels; ++chn) {
343
344                         nframes_t n;
345                         for (x = chn, n = 0; n < nfread; x += channels, ++n) {
346                                 channel_data[chn][n] = (Sample) data[x];
347                         }
348                 }
349
350                 /* flush to disk */
351
352                 for (chn = 0; chn < channels; ++chn) {
353                         if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(newfiles[chn])) != 0) {
354                                 afs->write (channel_data[chn].get(), nfread);
355                         }
356                 }
357
358                 read_count += nread;
359                 status.progress = progress_base + progress_multiplier * read_count / (source->ratio () * source->length() * channels);
360         }
361 }
362
363 static void
364 write_midi_data_to_new_files (Evoral::SMF* source, ImportStatus& status,
365                               vector<boost::shared_ptr<Source> >& newfiles)
366 {
367         uint32_t buf_size = 4;
368         uint8_t* buf      = (uint8_t*)malloc(buf_size);
369
370         status.progress = 0.0f;
371
372         try {
373
374         for (unsigned i = 1; i <= source->num_tracks(); ++i) {
375                 boost::shared_ptr<SMFSource> smfs = boost::dynamic_pointer_cast<SMFSource>(newfiles[i-1]);
376                 smfs->drop_model();
377
378                 source->seek_to_track(i);
379
380                 uint64_t t       = 0;
381                 uint32_t delta_t = 0;
382                 uint32_t size    = 0;
383                 bool first = true;
384
385                 while (!status.cancel) {
386                         size = buf_size;
387
388                         int ret = source->read_event(&delta_t, &size, &buf);
389                         if (size > buf_size)
390                                 buf_size = size;
391
392                         if (ret < 0) { // EOT
393                                 break;
394                         }
395
396                         t += delta_t;
397
398                         if (ret == 0) { // Meta
399                                 continue;
400                         }
401                         
402                         if (first) {
403                                 smfs->mark_streaming_write_started ();
404                                 first = false;
405                         }
406
407                         smfs->append_event_unlocked_beats(Evoral::Event<double>(0,
408                                         (double)t / (double)source->ppqn(),
409                                         size,
410                                         buf));
411
412                         if (status.progress < 0.99)
413                                 status.progress += 0.01;
414                 }
415
416                 const nframes64_t pos = 0;
417                 const double length_beats = ceil(t / (double)source->ppqn());
418                 BeatsFramesConverter converter(smfs->session().tempo_map(), pos);
419                 smfs->update_length(pos, converter.to(length_beats));
420                 smfs->mark_streaming_write_completed ();
421
422                 if (status.cancel) {
423                         break;
424                 }
425         }
426
427         } catch (...) {
428                 error << "Corrupt MIDI file " << source->file_path() << endl;
429         }
430 }
431
432 static void
433 remove_file_source (boost::shared_ptr<Source> source)
434 {
435         ::unlink (source->path().c_str());
436 }
437
438 // This function is still unable to cleanly update an existing source, even though
439 // it is possible to set the ImportStatus flag accordingly. The functinality
440 // is disabled at the GUI until the Source implementations are able to provide
441 // the necessary API.
442 void
443 Session::import_audiofiles (ImportStatus& status)
444 {
445         typedef vector<boost::shared_ptr<Source> > Sources;
446         Sources all_new_sources;
447         boost::shared_ptr<AudioFileSource> afs;
448         boost::shared_ptr<SMFSource> smfs;
449         uint channels = 0;
450
451         status.sources.clear ();
452
453         for (vector<Glib::ustring>::iterator p = status.paths.begin();
454              p != status.paths.end() && !status.cancel;
455              ++p)
456         {
457                 boost::shared_ptr<ImportableSource> source;
458                 std::auto_ptr<Evoral::SMF>          smf_reader;
459                 const DataType type = ((*p).rfind(".mid") != string::npos) ?
460                         DataType::MIDI : DataType::AUDIO;
461
462                 if (type == DataType::AUDIO) {
463                         try {
464                                 source = open_importable_source (*p, frame_rate(), status.quality);
465                                 channels = source->channels();
466                         } catch (const failed_constructor& err) {
467                                 error << string_compose(_("Import: cannot open input sound file \"%1\""), (*p)) << endmsg;
468                                 status.done = status.cancel = true;
469                                 return;
470                         }
471
472                 } else {
473                         try {
474                                 smf_reader = std::auto_ptr<Evoral::SMF>(new Evoral::SMF());
475                                 smf_reader->open(*p);
476                                 channels = smf_reader->num_tracks();
477                         } catch (...) {
478                                 error << _("Import: error opening MIDI file") << endmsg;
479                                 status.done = status.cancel = true;
480                                 return;
481                         }
482                 }
483
484                 vector<string> new_paths = get_paths_for_new_sources (status.replace_existing_source, *p,
485                                                                       get_best_session_directory_for_new_source (),
486                                                                       channels);
487                 Sources newfiles;
488                 framepos_t natural_position = source ? source->natural_position() : 0;
489
490                 if (status.replace_existing_source) {
491                         fatal << "THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" << endmsg;
492                         status.cancel = !map_existing_mono_sources (new_paths, *this, frame_rate(), newfiles, this);
493                 } else {
494                         status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles, natural_position);
495                 }
496
497                 // copy on cancel/failure so that any files that were created will be removed below
498                 std::copy (newfiles.begin(), newfiles.end(), std::back_inserter(all_new_sources));
499
500                 if (status.cancel) {
501                         break;
502                 }
503
504                 for (Sources::iterator i = newfiles.begin(); i != newfiles.end(); ++i) {
505                         if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*i)) != 0) {
506                                 afs->prepare_for_peakfile_writes ();
507                         }
508                 }
509
510                 if (source) { // audio
511                         status.doing_what = compose_status_message (*p, source->samplerate(),
512                                                                     frame_rate(), status.current, status.total);
513                         write_audio_data_to_new_files (source.get(), status, newfiles);
514                 } else if (smf_reader.get()) { // midi
515                         status.doing_what = string_compose(_("Loading MIDI file %1"), *p);
516                         write_midi_data_to_new_files (smf_reader.get(), status, newfiles);
517                 }
518
519                 ++status.current;
520         }
521
522         if (!status.cancel) {
523                 struct tm* now;
524                 time_t xnow;
525                 time (&xnow);
526                 now = localtime (&xnow);
527                 status.freeze = true;
528
529                 /* flush the final length(s) to the header(s) */
530
531                 for (Sources::iterator x = all_new_sources.begin(); x != all_new_sources.end(); ) {
532                         if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*x)) != 0) {
533                                 afs->update_header((*x)->natural_position(), *now, xnow);
534                                 afs->done_with_peakfile_writes ();
535
536                                 /* now that there is data there, requeue the file for analysis */
537
538                                 if (Config->get_auto_analyse_audio()) {
539                                         Analyser::queue_source_for_analysis (boost::static_pointer_cast<Source>(*x), false);
540                                 }
541                         }
542
543                         /* don't create tracks for empty MIDI sources (channels) */
544
545                         if ((smfs = boost::dynamic_pointer_cast<SMFSource>(*x)) != 0 && smfs->is_empty()) {
546                                 x = all_new_sources.erase(x);
547                         } else {
548                                 ++x;
549                         }
550                 }
551
552                 /* save state so that we don't lose these new Sources */
553
554                 save_state (_name);
555
556                 std::copy (all_new_sources.begin(), all_new_sources.end(), std::back_inserter(status.sources));
557         } else {
558                 // this can throw...but it seems very unlikely
559                 std::for_each (all_new_sources.begin(), all_new_sources.end(), remove_file_source);
560         }
561
562         status.done = true;
563 }
564