Automation of LV2 plugin properties.
[ardour.git] / libs / ardour / smf_source.cc
1 /*
2     Copyright (C) 2006 Paul Davis
3     Author: David Robillard
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 */
20
21 #include <vector>
22
23 #include <sys/time.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26 #include <errno.h>
27 #include <regex.h>
28
29 #include "pbd/file_utils.h"
30 #include "pbd/stl_delete.h"
31 #include "pbd/strsplit.h"
32
33 #include <glib/gstdio.h>
34 #include <glibmm/miscutils.h>
35 #include <glibmm/fileutils.h>
36
37 #include "evoral/Control.hpp"
38 #include "evoral/SMF.hpp"
39
40 #include "ardour/midi_model.h"
41 #include "ardour/midi_ring_buffer.h"
42 #include "ardour/midi_state_tracker.h"
43 #include "ardour/parameter_types.h"
44 #include "ardour/session.h"
45 #include "ardour/smf_source.h"
46 #include "ardour/debug.h"
47
48 #include "i18n.h"
49
50 using namespace ARDOUR;
51 using namespace Glib;
52 using namespace PBD;
53 using namespace Evoral;
54
55 /** Constructor used for new internal-to-session files.  File cannot exist. */
56 SMFSource::SMFSource (Session& s, const string& path, Source::Flag flags)
57         : Source(s, DataType::MIDI, path, flags)
58         , MidiSource(s, path, flags)
59         , FileSource(s, DataType::MIDI, path, string(), flags)
60         , Evoral::SMF()
61         , _last_ev_time_beats(0.0)
62         , _last_ev_time_frames(0)
63         , _smf_last_read_end (0)
64         , _smf_last_read_time (0)
65 {
66         /* note that origin remains empty */
67
68         if (init (_path, false)) {
69                 throw failed_constructor ();
70         }
71  
72         assert (!Glib::file_test (_path, Glib::FILE_TEST_EXISTS));
73         existence_check ();
74
75         _flags = Source::Flag (_flags | Empty);
76
77         /* file is not opened until write */
78
79         if (flags & Writable) {
80                 return;
81         }
82
83         if (open (_path)) {
84                 throw failed_constructor ();
85         }
86
87         _open = true;
88 }
89
90 /** Constructor used for external-to-session files.  File must exist. */
91 SMFSource::SMFSource (Session& s, const string& path)
92         : Source(s, DataType::MIDI, path, Source::Flag (0))
93         , MidiSource(s, path, Source::Flag (0))
94         , FileSource(s, DataType::MIDI, path, string(), Source::Flag (0))
95         , Evoral::SMF()
96         , _last_ev_time_beats(0.0)
97         , _last_ev_time_frames(0)
98         , _smf_last_read_end (0)
99         , _smf_last_read_time (0)
100 {
101         /* note that origin remains empty */
102
103         if (init (_path, true)) {
104                 throw failed_constructor ();
105         }
106  
107         assert (Glib::file_test (_path, Glib::FILE_TEST_EXISTS));
108         existence_check ();
109
110         if (_flags & Writable) {
111                 /* file is not opened until write */
112                 return;
113         }
114
115         if (open (_path)) {
116                 throw failed_constructor ();
117         }
118
119         _open = true;
120 }
121
122 /** Constructor used for existing internal-to-session files. */
123 SMFSource::SMFSource (Session& s, const XMLNode& node, bool must_exist)
124         : Source(s, node)
125         , MidiSource(s, node)
126         , FileSource(s, node, must_exist)
127         , _last_ev_time_beats(0.0)
128         , _last_ev_time_frames(0)
129         , _smf_last_read_end (0)
130         , _smf_last_read_time (0)
131 {
132         if (set_state(node, Stateful::loading_state_version)) {
133                 throw failed_constructor ();
134         }
135
136         /* we expect the file to exist, but if no MIDI data was ever added
137            it will have been removed at last session close. so, we don't
138            require it to exist if it was marked Empty.
139         */
140
141         try {
142
143                 if (init (_path, true)) {
144                         throw failed_constructor ();
145                 }
146
147         } catch (MissingSource& err) {
148
149                 if (_flags & Source::Empty) {
150                         /* we don't care that the file was not found, because
151                            it was empty. But FileSource::init() will have
152                            failed to set our _path correctly, so we have to do
153                            this ourselves. Use the first entry in the search
154                            path for MIDI files, which is assumed to be the
155                            correct "main" location.
156                         */
157                         std::vector<string> sdirs = s.source_search_path (DataType::MIDI);
158                         _path = Glib::build_filename (sdirs.front(), _path);
159                         /* This might be important, too */
160                         _file_is_new = true;
161                 } else {
162                         /* pass it on */
163                         throw;
164                 }
165         }
166
167         if (!(_flags & Source::Empty)) {
168                 assert (Glib::file_test (_path, Glib::FILE_TEST_EXISTS));
169                 existence_check ();
170         } else {
171                 assert (_flags & Source::Writable);
172                 /* file will be opened on write */
173                 return;
174         }
175
176         if (open(_path)) {
177                 throw failed_constructor ();
178         }
179
180         _open = true;
181 }
182
183 SMFSource::~SMFSource ()
184 {
185         if (removable()) {
186                 ::g_unlink (_path.c_str());
187         }
188 }
189
190 int
191 SMFSource::open_for_write ()
192 {
193         if (create (_path)) {
194                 return -1;
195         }
196         _open = true;
197         return 0;
198 }
199
200 /** All stamps in audio frames */
201 framecnt_t
202 SMFSource::read_unlocked (Evoral::EventSink<framepos_t>& destination,
203                           framepos_t const               source_start,
204                           framepos_t                     start,
205                           framecnt_t                     duration,
206                           MidiStateTracker*              tracker) const
207 {
208         int      ret  = 0;
209         uint64_t time = 0; // in SMF ticks, 1 tick per _ppqn
210
211         if (writable() && !_open) {
212                 /* nothing to read since nothing has ben written */
213                 return duration;
214         }
215
216         DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF read_unlocked: start %1 duration %2\n", start, duration));
217
218         // Output parameters for read_event (which will allocate scratch in buffer as needed)
219         uint32_t ev_delta_t = 0;
220         uint32_t ev_type    = 0;
221         uint32_t ev_size    = 0;
222         uint8_t* ev_buffer  = 0;
223
224         size_t scratch_size = 0; // keep track of scratch to minimize reallocs
225
226         BeatsFramesConverter converter(_session.tempo_map(), source_start);
227
228         const uint64_t start_ticks = (uint64_t)(converter.from(start) * ppqn());
229         DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF read_unlocked: start in ticks %1\n", start_ticks));
230
231         if (_smf_last_read_end == 0 || start != _smf_last_read_end) {
232                 DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF read_unlocked: seek to %1\n", start));
233                 Evoral::SMF::seek_to_start();
234                 while (time < start_ticks) {
235                         gint ignored;
236
237                         ret = read_event(&ev_delta_t, &ev_size, &ev_buffer, &ignored);
238                         if (ret == -1) { // EOF
239                                 _smf_last_read_end = start + duration;
240                                 return duration;
241                         }
242                         time += ev_delta_t; // accumulate delta time
243                 }
244         } else {
245                 DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF read_unlocked: set time to %1\n", _smf_last_read_time));
246                 time = _smf_last_read_time;
247         }
248
249         _smf_last_read_end = start + duration;
250
251         while (true) {
252                 gint ignored; /* XXX don't ignore note id's ??*/
253
254                 ret = read_event(&ev_delta_t, &ev_size, &ev_buffer, &ignored);
255                 if (ret == -1) { // EOF
256                         break;
257                 }
258
259                 time += ev_delta_t; // accumulate delta time
260                 _smf_last_read_time = time;
261
262                 if (ret == 0) { // meta-event (skipped, just accumulate time)
263                         continue;
264                 }
265
266                 ev_type = midi_parameter_type(ev_buffer[0]);
267
268                 DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF read_unlocked delta %1, time %2, buf[0] %3, type %4\n",
269                                                                   ev_delta_t, time, ev_buffer[0], ev_type));
270
271                 assert(time >= start_ticks);
272
273                 /* Note that we add on the source start time (in session frames) here so that ev_frame_time
274                    is in session frames.
275                 */
276                 const framepos_t ev_frame_time = converter.to(time / (double)ppqn()) + source_start;
277
278                 if (ev_frame_time < start + duration) {
279                         destination.write (ev_frame_time, ev_type, ev_size, ev_buffer);
280
281                         if (tracker) {
282                                 if (ev_buffer[0] & MIDI_CMD_NOTE_ON) {
283                                         tracker->add (ev_buffer[1], ev_buffer[0] & 0xf);
284                                 } else if (ev_buffer[0] & MIDI_CMD_NOTE_OFF) {
285                                         tracker->remove (ev_buffer[1], ev_buffer[0] & 0xf);
286                                 }
287                         }
288                 } else {
289                         break;
290                 }
291
292                 if (ev_size > scratch_size) {
293                         scratch_size = ev_size;
294                 }
295                 ev_size = scratch_size; // ensure read_event only allocates if necessary
296         }
297
298         return duration;
299 }
300
301 framecnt_t
302 SMFSource::write_unlocked (MidiRingBuffer<framepos_t>& source,
303                            framepos_t                  position,
304                            framecnt_t                  cnt)
305 {
306         if (!_writing) {
307                 mark_streaming_write_started ();
308         }
309
310         framepos_t        time;
311         Evoral::EventType type;
312         uint32_t          size;
313
314         size_t   buf_capacity = 4;
315         uint8_t* buf          = (uint8_t*)malloc(buf_capacity);
316
317         if (_model && !_model->writing()) {
318                 _model->start_write();
319         }
320
321         Evoral::MIDIEvent<framepos_t> ev;
322         while (true) {
323                 /* Get the event time, in frames since session start but ignoring looping. */
324                 bool ret;
325                 if (!(ret = source.peek ((uint8_t*)&time, sizeof (time)))) {
326                         /* Ring is empty, no more events. */
327                         break;
328                 }
329
330                 if ((cnt != max_framecnt) &&
331                     (time > position + _capture_length + cnt)) {
332                         /* The diskstream doesn't want us to write everything, and this
333                            event is past the end of this block, so we're done for now. */
334                         break;
335                 }
336
337                 /* Read the time, type, and size of the event. */
338                 if (!(ret = source.read_prefix (&time, &type, &size))) {
339                         error << _("Unable to read event prefix, corrupt MIDI ring") << endmsg;
340                         break;
341                 }
342
343                 /* Enlarge body buffer if necessary now that we know the size. */
344                 if (size > buf_capacity) {
345                         buf_capacity = size;
346                         buf = (uint8_t*)realloc(buf, size);
347                 }
348
349                 /* Read the event body into buffer. */
350                 ret = source.read_contents(size, buf);
351                 if (!ret) {
352                         error << _("Event has time and size but no body, corrupt MIDI ring") << endmsg;
353                         break;
354                 }
355
356                 /* Convert event time from absolute to source relative. */
357                 if (time < position) {
358                         error << _("Event time is before MIDI source position") << endmsg;
359                         break;
360                 }
361                 time -= position;
362                         
363                 ev.set(buf, size, time);
364                 ev.set_event_type(midi_parameter_type(ev.buffer()[0]));
365                 ev.set_id(Evoral::next_event_id());
366
367                 if (!(ev.is_channel_event() || ev.is_smf_meta_event() || ev.is_sysex())) {
368                         continue;
369                 }
370
371                 append_event_unlocked_frames(ev, position);
372         }
373
374         Evoral::SMF::flush ();
375         free (buf);
376
377         return cnt;
378 }
379
380 /** Append an event with a timestamp in beats (double) */
381 void
382 SMFSource::append_event_unlocked_beats (const Evoral::Event<double>& ev)
383 {
384         if (!_writing || ev.size() == 0)  {
385                 return;
386         }
387
388         /*printf("SMFSource: %s - append_event_unlocked_beats ID = %d time = %lf, size = %u, data = ",
389                name().c_str(), ev.id(), ev.time(), ev.size());
390                for (size_t i = 0; i < ev.size(); ++i) printf("%X ", ev.buffer()[i]); printf("\n");*/
391
392         if (ev.time() < _last_ev_time_beats) {
393                 warning << string_compose(_("Skipping event with unordered time %1"), ev.time())
394                         << endmsg;
395                 return;
396         }
397
398         Evoral::event_id_t event_id;
399
400         if (ev.id() < 0) {
401                 event_id  = Evoral::next_event_id();
402         } else {
403                 event_id = ev.id();
404         }
405
406         if (_model) {
407                 _model->append (ev, event_id);
408         }
409
410         _length_beats = max(_length_beats, ev.time());
411
412         const double delta_time_beats   = ev.time() - _last_ev_time_beats;
413         const uint32_t delta_time_ticks = (uint32_t)lrint(delta_time_beats * (double)ppqn());
414
415         Evoral::SMF::append_event_delta(delta_time_ticks, ev.size(), ev.buffer(), event_id);
416         _last_ev_time_beats = ev.time();
417         _flags = Source::Flag (_flags & ~Empty);
418 }
419
420 /** Append an event with a timestamp in frames (framepos_t) */
421 void
422 SMFSource::append_event_unlocked_frames (const Evoral::Event<framepos_t>& ev, framepos_t position)
423 {
424         if (!_writing || ev.size() == 0)  {
425                 return;
426         }
427
428         // printf("SMFSource: %s - append_event_unlocked_frames ID = %d time = %u, size = %u, data = ",
429         // name().c_str(), ev.id(), ev.time(), ev.size());
430         // for (size_t i=0; i < ev.size(); ++i) printf("%X ", ev.buffer()[i]); printf("\n");
431
432         if (ev.time() < _last_ev_time_frames) {
433                 warning << string_compose(_("Skipping event with unordered time %1"), ev.time())
434                         << endmsg;
435                 return;
436         }
437
438         BeatsFramesConverter converter(_session.tempo_map(), position);
439         const double ev_time_beats = converter.from(ev.time());
440         Evoral::event_id_t event_id;
441
442         if (ev.id() < 0) {
443                 event_id  = Evoral::next_event_id();
444         } else {
445                 event_id = ev.id();
446         }
447
448         if (_model) {
449                 const Evoral::Event<double> beat_ev (ev.event_type(),
450                                                      ev_time_beats,
451                                                      ev.size(),
452                                                      const_cast<uint8_t*>(ev.buffer()));
453                 _model->append (beat_ev, event_id);
454         }
455
456         _length_beats = max(_length_beats, ev_time_beats);
457
458         const Evoral::MusicalTime last_time_beats  = converter.from (_last_ev_time_frames);
459         const Evoral::MusicalTime delta_time_beats = ev_time_beats - last_time_beats;
460         const uint32_t            delta_time_ticks = (uint32_t)(lrint(delta_time_beats * (double)ppqn()));
461
462         Evoral::SMF::append_event_delta(delta_time_ticks, ev.size(), ev.buffer(), event_id);
463         _last_ev_time_frames = ev.time();
464         _flags = Source::Flag (_flags & ~Empty);
465 }
466
467 XMLNode&
468 SMFSource::get_state ()
469 {
470         XMLNode& node = MidiSource::get_state();
471         node.add_property (X_("origin"), _origin);
472         return node;
473 }
474
475 int
476 SMFSource::set_state (const XMLNode& node, int version)
477 {
478         if (Source::set_state (node, version)) {
479                 return -1;
480         }
481
482         if (MidiSource::set_state (node, version)) {
483                 return -1;
484         }
485
486         if (FileSource::set_state (node, version)) {
487                 return -1;
488         }
489
490         return 0;
491 }
492
493 void
494 SMFSource::mark_streaming_midi_write_started (NoteMode mode)
495 {
496         /* CALLER MUST HOLD LOCK */
497
498         if (!_open && open_for_write()) {
499                 error << string_compose (_("cannot open MIDI file %1 for write"), _path) << endmsg;
500                 /* XXX should probably throw or return something */
501                 return;
502         }
503
504         MidiSource::mark_streaming_midi_write_started (mode);
505         Evoral::SMF::begin_write ();
506         _last_ev_time_beats = 0.0;
507         _last_ev_time_frames = 0;
508 }
509
510 void
511 SMFSource::mark_streaming_write_completed ()
512 {
513         mark_midi_streaming_write_completed (Evoral::Sequence<Evoral::MusicalTime>::DeleteStuckNotes);
514 }
515
516 void
517 SMFSource::mark_midi_streaming_write_completed (Evoral::Sequence<Evoral::MusicalTime>::StuckNoteOption stuck_notes_option, Evoral::MusicalTime when)
518 {
519         Glib::Threads::Mutex::Lock lm (_lock);
520         MidiSource::mark_midi_streaming_write_completed (stuck_notes_option, when);
521
522         if (!writable()) {
523                 warning << string_compose ("attempt to write to unwritable SMF file %1", _path) << endmsg;
524                 return;
525         }
526
527         if (_model) {
528                 _model->set_edited(false);
529         }
530
531         Evoral::SMF::end_write ();
532
533         /* data in the file now, not removable */
534
535         mark_nonremovable ();
536 }
537
538 bool
539 SMFSource::valid_midi_file (const string& file)
540 {
541         if (safe_midi_file_extension (file) ) {
542                 return (SMF::test (file) );
543         }
544         return false;
545 }
546
547 bool
548 SMFSource::safe_midi_file_extension (const string& file)
549 {
550         static regex_t compiled_pattern;
551         static bool compile = true;
552         const int nmatches = 2;
553         regmatch_t matches[nmatches];
554         
555         if (Glib::file_test (file, Glib::FILE_TEST_EXISTS)) {
556                 if (!Glib::file_test (file, Glib::FILE_TEST_IS_REGULAR)) {
557                         /* exists but is not a regular file */
558                         return false;
559                 }
560         }
561
562         if (compile && regcomp (&compiled_pattern, "\\.[mM][iI][dD][iI]?$", REG_EXTENDED)) {
563                 return false;
564         } else {
565                 compile = false;
566         }
567         
568         if (regexec (&compiled_pattern, file.c_str(), nmatches, matches, 0)) {
569                 return false;
570         }
571
572         return true;
573 }
574
575 static bool compare_eventlist (
576                 const std::pair< Evoral::Event<double>*, gint >& a,
577                 const std::pair< Evoral::Event<double>*, gint >& b) {
578         return ( a.first->time() < b.first->time() );
579 }
580
581 void
582 SMFSource::load_model (bool lock, bool force_reload)
583 {
584         if (_writing) {
585                 return;
586         }
587
588         boost::shared_ptr<Glib::Threads::Mutex::Lock> lm;
589         if (lock)
590                 lm = boost::shared_ptr<Glib::Threads::Mutex::Lock>(new Glib::Threads::Mutex::Lock(_lock));
591
592         if (_model && !force_reload) {
593                 return;
594         }
595
596         if (!_model) {
597                 _model = boost::shared_ptr<MidiModel> (new MidiModel (shared_from_this ()));
598         } else {
599                 _model->clear();
600         }
601
602         if (writable() && !_open) {
603                 return;
604         }
605
606         _model->start_write();
607         Evoral::SMF::seek_to_start();
608
609         uint64_t time = 0; /* in SMF ticks */
610         Evoral::Event<double> ev;
611
612         uint32_t scratch_size = 0; // keep track of scratch and minimize reallocs
613
614         uint32_t delta_t = 0;
615         uint32_t size    = 0;
616         uint8_t* buf     = NULL;
617         int ret;
618         gint event_id;
619         bool have_event_id;
620
621         // TODO simplify event allocation
622         std::list< std::pair< Evoral::Event<double>*, gint > > eventlist;
623
624         for (unsigned i = 1; i <= num_tracks(); ++i) {
625                 if (seek_to_track(i)) continue;
626
627                 time = 0;
628                 have_event_id = false;
629
630                 while ((ret = read_event (&delta_t, &size, &buf, &event_id)) >= 0) {
631
632                         time += delta_t;
633
634                         if (ret == 0) {
635                                 /* meta-event : did we get an event ID ?  */
636                                 if (event_id >= 0) {
637                                         have_event_id = true;
638                                 }
639                                 continue;
640                         }
641
642                         if (ret > 0) {
643                                 /* not a meta-event */
644
645                                 if (!have_event_id) {
646                                         event_id = Evoral::next_event_id();
647                                 }
648                                 uint32_t event_type = midi_parameter_type(buf[0]);
649                                 double   event_time = time / (double) ppqn();
650 #ifndef NDEBUG
651                                 std::string ss;
652
653                                 for (uint32_t xx = 0; xx < size; ++xx) {
654                                         char b[8];
655                                         snprintf (b, sizeof (b), "0x%x ", buf[xx]);
656                                         ss += b;
657                                 }
658
659                                 DEBUG_TRACE (DEBUG::MidiSourceIO, string_compose ("SMF %6 load model delta %1, time %2, size %3 buf %4, type %5\n",
660                                                         delta_t, time, size, ss , event_type, name()));
661 #endif
662
663                                 eventlist.push_back(make_pair (
664                                                         new Evoral::Event<double> (
665                                                                 event_type, event_time,
666                                                                 size, buf, true)
667                                                         , event_id));
668
669                                 // Set size to max capacity to minimize allocs in read_event
670                                 scratch_size = std::max(size, scratch_size);
671                                 size = scratch_size;
672
673                                 _length_beats = max(_length_beats, event_time);
674                         }
675
676                         /* event ID's must immediately precede the event they are for */
677                         have_event_id = false;
678                 }
679         }
680
681         eventlist.sort(compare_eventlist);
682
683         std::list< std::pair< Evoral::Event<double>*, gint > >::iterator it;
684         for (it=eventlist.begin(); it!=eventlist.end(); ++it) {
685                 _model->append (*it->first, it->second);
686                 delete it->first;
687         }
688
689         _model->end_write (Evoral::Sequence<Evoral::MusicalTime>::ResolveStuckNotes, _length_beats);
690         _model->set_edited (false);
691
692         _model_iter = _model->begin();
693
694         free(buf);
695 }
696
697 void
698 SMFSource::destroy_model ()
699 {
700         //cerr << _name << " destroying model " << _model.get() << endl;
701         _model.reset();
702 }
703
704 void
705 SMFSource::flush_midi ()
706 {
707         if (!writable() || _length_beats == 0.0) {
708                 return;
709         }
710
711         ensure_disk_file ();
712
713         Evoral::SMF::end_write ();
714         /* data in the file means its no longer removable */
715         mark_nonremovable ();
716 }
717
718 void
719 SMFSource::set_path (const string& p)
720 {
721         FileSource::set_path (p);
722         SMF::set_path (_path);
723 }
724
725 /** Ensure that this source has some file on disk, even if it's just a SMF header */
726 void
727 SMFSource::ensure_disk_file ()
728 {
729         if (!writable()) {
730                 return;
731         }
732
733         if (_model) {
734                 /* We have a model, so write it to disk; see MidiSource::session_saved
735                    for an explanation of what we are doing here.
736                 */
737                 boost::shared_ptr<MidiModel> mm = _model;
738                 _model.reset ();
739                 mm->sync_to_source ();
740                 _model = mm;
741         } else {
742                 /* No model; if it's not already open, it's an empty source, so create
743                    and open it for writing.
744                 */
745                 if (!_open) {
746                         open_for_write ();
747                 }
748         }
749 }
750
751 void
752 SMFSource::prevent_deletion ()
753 {
754         /* Unlike the audio case, the MIDI file remains mutable (because we can
755            edit MIDI data)
756         */
757   
758         _flags = Flag (_flags & ~(Removable|RemovableIfEmpty|RemoveAtDestroy));
759 }
760                 
761