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