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