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