Add "session rate" as a possible sample rate for export formats
[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, 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().to_string() : sdir.sound_path().to_string();
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         try {
381
382         for (unsigned i = 1; i <= source->num_tracks(); ++i) {
383                 boost::shared_ptr<SMFSource> smfs = boost::dynamic_pointer_cast<SMFSource>(newfiles[i-1]);
384                 smfs->drop_model();
385
386                 source->seek_to_track(i);
387
388                 uint64_t t       = 0;
389                 uint32_t delta_t = 0;
390                 uint32_t size    = 0;
391                 bool first = true;
392
393                 while (!status.cancel) {
394                         gint ignored; // imported files either don't have NoteID's or
395                                       // we ignore them.
396
397                         size = buf_size;
398                         
399                         int ret = source->read_event(&delta_t, &size, &buf, &ignored);
400                         if (size > buf_size)
401                                 buf_size = size;
402
403                         if (ret < 0) { // EOT
404                                 break;
405                         }
406
407                         t += delta_t;
408
409                         if (ret == 0) { // Meta
410                                 continue;
411                         }
412                         
413                         if (first) {
414                                 smfs->mark_streaming_write_started ();
415                                 first = false;
416                         }
417
418                         smfs->append_event_unlocked_beats(Evoral::Event<double>(0,
419                                         (double)t / (double)source->ppqn(),
420                                         size,
421                                         buf));
422
423                         if (status.progress < 0.99)
424                                 status.progress += 0.01;
425                 }
426
427                 const framepos_t pos = 0;
428                 const double length_beats = ceil(t / (double)source->ppqn());
429                 BeatsFramesConverter converter(smfs->session().tempo_map(), pos);
430                 smfs->update_length(pos, converter.to(length_beats));
431                 smfs->mark_streaming_write_completed ();
432
433                 if (status.cancel) {
434                         break;
435                 }
436         }
437
438         } catch (...) {
439                 error << "Corrupt MIDI file " << source->file_path() << endl;
440         }
441 }
442
443 static void
444 remove_file_source (boost::shared_ptr<Source> source)
445 {
446         ::unlink (source->path().c_str());
447 }
448
449 // This function is still unable to cleanly update an existing source, even though
450 // it is possible to set the ImportStatus flag accordingly. The functinality
451 // is disabled at the GUI until the Source implementations are able to provide
452 // the necessary API.
453 void
454 Session::import_audiofiles (ImportStatus& status)
455 {
456         typedef vector<boost::shared_ptr<Source> > Sources;
457         Sources all_new_sources;
458         boost::shared_ptr<AudioFileSource> afs;
459         boost::shared_ptr<SMFSource> smfs;
460         uint channels = 0;
461
462         status.sources.clear ();
463
464         for (vector<string>::iterator p = status.paths.begin();
465              p != status.paths.end() && !status.cancel;
466              ++p)
467         {
468                 boost::shared_ptr<ImportableSource> source;
469                 std::auto_ptr<Evoral::SMF>          smf_reader;
470                 const DataType type = SMFSource::safe_midi_file_extension (*p) ? DataType::MIDI : DataType::AUDIO;
471
472                 if (type == DataType::AUDIO) {
473                         try {
474                                 source = open_importable_source (*p, frame_rate(), status.quality);
475                                 channels = source->channels();
476                         } catch (const failed_constructor& err) {
477                                 error << string_compose(_("Import: cannot open input sound file \"%1\""), (*p)) << endmsg;
478                                 status.done = status.cancel = true;
479                                 return;
480                         }
481
482                 } else {
483                         try {
484                                 smf_reader = std::auto_ptr<Evoral::SMF>(new Evoral::SMF());
485                                 smf_reader->open(*p);
486                                 channels = smf_reader->num_tracks();
487                         } catch (...) {
488                                 error << _("Import: error opening MIDI file") << endmsg;
489                                 status.done = status.cancel = true;
490                                 return;
491                         }
492                 }
493
494                 vector<string> new_paths = get_paths_for_new_sources (config.get_native_file_header_format(),
495                                                                       status.replace_existing_source, *p,
496                                                                       get_best_session_directory_for_new_source (),
497                                                                       channels);
498                 Sources newfiles;
499                 framepos_t natural_position = source ? source->natural_position() : 0;
500
501                 if (status.replace_existing_source) {
502                         fatal << "THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" << endmsg;
503                         status.cancel = !map_existing_mono_sources (new_paths, *this, frame_rate(), newfiles, this);
504                 } else {
505                         status.cancel = !create_mono_sources_for_writing (*p, new_paths, *this, frame_rate(), newfiles, natural_position);
506                 }
507
508                 // copy on cancel/failure so that any files that were created will be removed below
509                 std::copy (newfiles.begin(), newfiles.end(), std::back_inserter(all_new_sources));
510
511                 if (status.cancel) {
512                         break;
513                 }
514
515                 for (Sources::iterator i = newfiles.begin(); i != newfiles.end(); ++i) {
516                         if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*i)) != 0) {
517                                 afs->prepare_for_peakfile_writes ();
518                         }
519                 }
520
521                 if (source) { // audio
522                         status.doing_what = compose_status_message (*p, source->samplerate(),
523                                                                     frame_rate(), status.current, status.total);
524                         write_audio_data_to_new_files (source.get(), status, newfiles);
525                 } else if (smf_reader.get()) { // midi
526                         status.doing_what = string_compose(_("Loading MIDI file %1"), *p);
527                         write_midi_data_to_new_files (smf_reader.get(), status, newfiles);
528                 }
529
530                 ++status.current;
531                 status.progress = 0;
532         }
533
534         if (!status.cancel) {
535                 struct tm* now;
536                 time_t xnow;
537                 time (&xnow);
538                 now = localtime (&xnow);
539                 status.freeze = true;
540
541                 /* flush the final length(s) to the header(s) */
542
543                 for (Sources::iterator x = all_new_sources.begin(); x != all_new_sources.end(); ) {
544                         if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*x)) != 0) {
545                                 afs->update_header((*x)->natural_position(), *now, xnow);
546                                 afs->done_with_peakfile_writes ();
547
548                                 /* now that there is data there, requeue the file for analysis */
549
550                                 if (Config->get_auto_analyse_audio()) {
551                                         Analyser::queue_source_for_analysis (boost::static_pointer_cast<Source>(*x), false);
552                                 }
553                         }
554
555                         /* don't create tracks for empty MIDI sources (channels) */
556
557                         if ((smfs = boost::dynamic_pointer_cast<SMFSource>(*x)) != 0 && smfs->is_empty()) {
558                                 x = all_new_sources.erase(x);
559                         } else {
560                                 ++x;
561                         }
562                 }
563
564                 /* save state so that we don't lose these new Sources */
565
566                 save_state (_name);
567
568                 std::copy (all_new_sources.begin(), all_new_sources.end(), std::back_inserter(status.sources));
569         } else {
570                 // this can throw...but it seems very unlikely
571                 std::for_each (all_new_sources.begin(), all_new_sources.end(), remove_file_source);
572         }
573
574         status.done = true;
575 }
576