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