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