minor translation fixes/typos from edogawa
[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(Evoral::Event<double>(0,
424                                                                                         (double)t / (double)source->ppqn(),
425                                                                                         size,
426                                                                                         buf));
427
428                                 if (status.progress < 0.99) {
429                                         status.progress += 0.01;
430                                 }
431                         }
432
433                         if (!first) {
434
435                                 /* we wrote something */
436
437                                 const framepos_t pos = 0;
438                                 const double length_beats = ceil(t / (double)source->ppqn());
439                                 BeatsFramesConverter converter(smfs->session().tempo_map(), pos);
440                                 smfs->update_length(pos + converter.to(length_beats));
441                                 smfs->mark_streaming_write_completed ();
442
443                                 if (status.cancel) {
444                                         break;
445                                 }
446                         } else {
447                                 warning << string_compose (_("Track %1 of %2 contained no usable MIDI data"), i, source->file_path()) << endmsg;
448                         }
449
450                         ++s; // next source
451                 }
452
453         } catch (...) {
454                 error << string_compose (_("MIDI file %1 was not readable (no reason available)"), source->file_path()) << endmsg;
455         }
456
457         if (buf) {
458                 free (buf);
459         }
460 }
461
462 static void
463 remove_file_source (boost::shared_ptr<Source> source)
464 {
465         boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (source);
466
467         if (fs) {
468                 ::unlink (fs->path().c_str());
469         }
470 }
471
472 // This function is still unable to cleanly update an existing source, even though
473 // it is possible to set the ImportStatus flag accordingly. The functinality
474 // is disabled at the GUI until the Source implementations are able to provide
475 // the necessary API.
476 void
477 Session::import_files (ImportStatus& status)
478 {
479         typedef vector<boost::shared_ptr<Source> > Sources;
480         Sources all_new_sources;
481         boost::shared_ptr<AudioFileSource> afs;
482         boost::shared_ptr<SMFSource> smfs;
483         uint channels = 0;
484
485         status.sources.clear ();
486
487         for (vector<string>::iterator p = status.paths.begin();
488              p != status.paths.end() && !status.cancel;
489              ++p)
490         {
491                 boost::shared_ptr<ImportableSource> source;
492                 std::auto_ptr<Evoral::SMF>          smf_reader;
493                 const DataType type = SMFSource::safe_midi_file_extension (*p) ? DataType::MIDI : DataType::AUDIO;
494
495                 if (type == DataType::AUDIO) {
496                         try {
497                                 source = open_importable_source (*p, frame_rate(), status.quality);
498                                 channels = source->channels();
499                         } catch (const failed_constructor& err) {
500                                 error << string_compose(_("Import: cannot open input sound file \"%1\""), (*p)) << endmsg;
501                                 status.done = status.cancel = true;
502                                 return;
503                         }
504
505                 } else {
506                         try {
507                                 smf_reader = std::auto_ptr<Evoral::SMF>(new Evoral::SMF());
508                                 smf_reader->open(*p);
509                                 channels = smf_reader->num_tracks();
510                         } catch (...) {
511                                 error << _("Import: error opening MIDI file") << endmsg;
512                                 status.done = status.cancel = true;
513                                 return;
514                         }
515                 }
516
517                 vector<string> new_paths = get_paths_for_new_sources (config.get_native_file_header_format(),
518                                                                       status.replace_existing_source, *p,
519                                                                       get_best_session_directory_for_new_source (),
520                                                                       channels);
521                 Sources newfiles;
522                 framepos_t natural_position = source ? source->natural_position() : 0;
523
524
525                 if (status.replace_existing_source) {
526                         fatal << "THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" << endmsg;
527                         status.cancel = !map_existing_mono_sources (new_paths, *this, frame_rate(), newfiles, this);
528                 } else {
529                         status.cancel = !create_mono_sources_for_writing (*p, new_paths, *this, frame_rate(), newfiles, natural_position);
530                 }
531
532                 // copy on cancel/failure so that any files that were created will be removed below
533                 std::copy (newfiles.begin(), newfiles.end(), std::back_inserter(all_new_sources));
534
535                 if (status.cancel) {
536                         break;
537                 }
538
539                 for (Sources::iterator i = newfiles.begin(); i != newfiles.end(); ++i) {
540                         if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*i)) != 0) {
541                                 afs->prepare_for_peakfile_writes ();
542                         }
543                 }
544
545                 if (source) { // audio
546                         status.doing_what = compose_status_message (*p, source->samplerate(),
547                                                                     frame_rate(), status.current, status.total);
548                         write_audio_data_to_new_files (source.get(), status, newfiles);
549                 } else if (smf_reader.get()) { // midi
550                         status.doing_what = string_compose(_("Loading MIDI file %1"), *p);
551                         write_midi_data_to_new_files (smf_reader.get(), status, newfiles);
552                 }
553
554                 ++status.current;
555                 status.progress = 0;
556         }
557
558         if (!status.cancel) {
559                 struct tm* now;
560                 time_t xnow;
561                 time (&xnow);
562                 now = localtime (&xnow);
563                 status.freeze = true;
564
565                 /* flush the final length(s) to the header(s) */
566
567                 for (Sources::iterator x = all_new_sources.begin(); x != all_new_sources.end(); ) {
568
569                         if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*x)) != 0) {
570                                 afs->update_header((*x)->natural_position(), *now, xnow);
571                                 afs->done_with_peakfile_writes ();
572
573                                 /* now that there is data there, requeue the file for analysis */
574
575                                 if (Config->get_auto_analyse_audio()) {
576                                         Analyser::queue_source_for_analysis (boost::static_pointer_cast<Source>(*x), false);
577                                 }
578                         }
579                         
580                         /* imported, copied files cannot be written or removed
581                          */
582
583                         boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource>(*x);
584                         if (fs) {
585                                 /* Only audio files should be marked as
586                                    immutable - we may need to rewrite MIDI
587                                    files at any time.
588                                 */
589                                 if (boost::dynamic_pointer_cast<AudioFileSource> (fs)) {
590                                         fs->mark_immutable ();
591                                 } else {
592                                         fs->mark_immutable_except_write ();
593                                 }
594                                 fs->mark_nonremovable ();
595                         }
596
597                         /* don't create tracks for empty MIDI sources (channels) */
598
599                         if ((smfs = boost::dynamic_pointer_cast<SMFSource>(*x)) != 0 && smfs->is_empty()) {
600                                 x = all_new_sources.erase(x);
601                         } else {
602                                 ++x;
603                         }
604                 }
605
606                 /* save state so that we don't lose these new Sources */
607
608                 save_state (_name);
609
610                 std::copy (all_new_sources.begin(), all_new_sources.end(), std::back_inserter(status.sources));
611         } else {
612                 try {
613                         std::for_each (all_new_sources.begin(), all_new_sources.end(), remove_file_source);
614                 } catch (...) {
615                         error << _("Failed to remove some files after failed/cancelled import operation") << endmsg;
616                 }
617                                 
618         }
619
620         status.done = true;
621 }
622