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