4880b5a04dcd0c5b7d741fa26ce753058637f874
[ardour.git] / libs / evoral / src / Sequence.cpp
1 /* This file is part of Evoral.
2  * Copyright (C) 2008 Dave Robillard <http://drobilla.net>
3  * Copyright (C) 2000-2008 Paul Davis
4  * 
5  * Evoral is free software; you can redistribute it and/or modify it under the
6  * terms of the GNU General Public License as published by the Free Software
7  * Foundation; either version 2 of the License, or (at your option) any later
8  * version.
9  * 
10  * Evoral is distributed in the hope that it will be useful, but WITHOUT ANY
11  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for details.
13  * 
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18
19 #define __STDC_LIMIT_MACROS 1
20
21 #include <iostream>
22 #include <algorithm>
23 #include <stdexcept>
24 #include <stdint.h>
25 #include <evoral/Sequence.hpp>
26 #include <evoral/ControlList.hpp>
27 #include <evoral/Control.hpp>
28 #include <evoral/ControlSet.hpp>
29 #include <evoral/EventSink.hpp>
30 #include <evoral/MIDIParameters.hpp>
31
32 using namespace std;
33
34 namespace Evoral {
35
36 void Sequence::write_lock() {
37         _lock.writer_lock();
38         _control_lock.lock();
39 }
40
41 void Sequence::write_unlock() {
42         _lock.writer_unlock();
43         _control_lock.unlock();
44 }
45
46 void Sequence::read_lock() const {
47         _lock.reader_lock();
48 }
49
50 void Sequence::read_unlock() const {
51         _lock.reader_unlock();
52 }
53
54 // Read iterator (const_iterator)
55
56 Sequence::const_iterator::const_iterator(const Sequence& seq, double t)
57         : _seq(&seq)
58         , _is_end( (t == DBL_MAX) || seq.empty() )
59         , _locked( !_is_end )
60 {
61         //cerr << "Created MIDI iterator @ " << t << " (is end: " << _is_end << ")" << endl;
62
63         if (_is_end) {
64                 return;
65         }
66
67         seq.read_lock();
68
69         _note_iter = seq.notes().end();
70         // find first note which begins after t
71         for (Sequence::Notes::const_iterator i = seq.notes().begin(); i != seq.notes().end(); ++i) {
72                 if ((*i)->time() >= t) {
73                         _note_iter = i;
74                         break;
75                 }
76         }
77
78         ControlIterator earliest_control(boost::shared_ptr<ControlList>(), DBL_MAX, 0.0);
79
80         _control_iters.reserve(seq.controls().size());
81         
82         // find the earliest control event available
83         for (Controls::const_iterator i = seq.controls().begin(); i != seq.controls().end(); ++i) {
84                 double x, y;
85                 bool ret = i->second->list()->rt_safe_earliest_event_unlocked(t, DBL_MAX, x, y);
86                 if (!ret) {
87                         //cerr << "MIDI Iterator: CC " << i->first.id() << " (size " << i->second->list()->size()
88                         //      << ") has no events past " << t << endl;
89                         continue;
90                 }
91
92                 assert(x >= 0);
93
94                 if (y < i->first.min() || y > i->first.max()) {
95                         cerr << "ERROR: Controller (" << i->first.type() << ") value '" << y
96                                 << "' out of range [" << i->first.min() << "," << i->first.max()
97                                 << "], event ignored" << endl;
98                         continue;
99                 }
100
101                 const ControlIterator new_iter(i->second->list(), x, y);
102
103                 //cerr << "MIDI Iterator: CC " << i->first.id() << " added (" << x << ", " << y << ")" << endl;
104                 _control_iters.push_back(new_iter);
105
106                 // if the x of the current control is less than earliest_control
107                 // we have a new earliest_control
108                 if (x < earliest_control.x) {
109                         earliest_control = new_iter;
110                         _control_iter = _control_iters.end();
111                         --_control_iter;
112                         // now _control_iter points to the last Element in _control_iters
113                 }
114         }
115
116         if (_note_iter != seq.notes().end()) {
117                 _event = boost::shared_ptr<Event>(new Event((*_note_iter)->on_event(), true));
118         }
119
120         double time = DBL_MAX;
121         // in case we have no notes in the region, we still want to get controller messages
122         if (_event.get()) {
123                 time = _event->time();
124                 // if the note is going to make it this turn, advance _note_iter
125                 if (earliest_control.x > time) {
126                         _active_notes.push(*_note_iter);
127                         ++_note_iter;
128                 }
129         }
130         
131         // <=, because we probably would want to send control events first 
132         if (earliest_control.list.get() && earliest_control.x <= time) {
133                 seq.control_to_midi_event(_event, earliest_control);
134         } else {
135                 _control_iter = _control_iters.end();
136         }
137
138         if ( (! _event.get()) || _event->size() == 0) {
139                 //cerr << "Created MIDI iterator @ " << t << " is at end." << endl;
140                 _is_end = true;
141
142                 // eliminate possible race condition here (ugly)
143                 static Glib::Mutex mutex;
144                 Glib::Mutex::Lock lock(mutex);
145                 if (_locked) {
146                         _seq->read_unlock();
147                         _locked = false;
148                 }
149         } else {
150                 //printf("New MIDI Iterator = %X @ %lf\n", _event->type(), _event->time());
151         }
152
153         assert(_is_end || (_event->buffer() && _event->buffer()[0] != '\0'));
154 }
155
156 Sequence::const_iterator::~const_iterator()
157 {
158         if (_locked) {
159                 _seq->read_unlock();
160         }
161 }
162
163 const Sequence::const_iterator& Sequence::const_iterator::operator++()
164 {
165         if (_is_end) {
166                 throw std::logic_error("Attempt to iterate past end of Sequence");
167         }
168         
169         assert(_event->buffer() && _event->buffer()[0] != '\0');
170
171         /*cerr << "const_iterator::operator++: " << _event->to_string() << endl;*/
172
173         if (! (_event->is_note() || _event->is_cc() || _event->is_pgm_change() || _event->is_pitch_bender() || _event->is_channel_aftertouch()) ) {
174                 cerr << "FAILED event buffer: " << hex << int(_event->buffer()[0]) << int(_event->buffer()[1]) << int(_event->buffer()[2]) << endl;
175         }
176         assert((_event->is_note() || _event->is_cc() || _event->is_pgm_change() || _event->is_pitch_bender() || _event->is_channel_aftertouch()));
177
178         // Increment past current control event
179         if (!_event->is_note() && _control_iter != _control_iters.end() && _control_iter->list.get()) {
180                 double x = 0.0, y = 0.0;
181                 const bool ret = _control_iter->list->rt_safe_earliest_event_unlocked(
182                                 _control_iter->x, DBL_MAX, x, y, false);
183
184                 if (ret) {
185                         _control_iter->x = x;
186                         _control_iter->y = y;
187                 } else {
188                         _control_iter->list.reset();
189                         _control_iter->x = DBL_MAX;
190                 }
191         }
192
193         const std::vector<ControlIterator>::iterator old_control_iter = _control_iter;
194         _control_iter = _control_iters.begin();
195
196         // find the _control_iter with the earliest event time
197         for (std::vector<ControlIterator>::iterator i = _control_iters.begin();
198                         i != _control_iters.end(); ++i) {
199                 if (i->x < _control_iter->x) {
200                         _control_iter = i;
201                 }
202         }
203
204         enum Type {NIL, NOTE_ON, NOTE_OFF, AUTOMATION};
205
206         Type type = NIL;
207         double t = 0;
208
209         // Next earliest note on
210         if (_note_iter != _seq->notes().end()) {
211                 type = NOTE_ON;
212                 t = (*_note_iter)->time();
213         }
214
215         // Use the next earliest note off iff it's earlier than the note on
216         if (!_seq->percussive() && (! _active_notes.empty())) {
217                 if (type == NIL || _active_notes.top()->end_time() <= (*_note_iter)->time()) {
218                         type = NOTE_OFF;
219                         t = _active_notes.top()->end_time();
220                 }
221         }
222
223         // Use the next earliest controller iff it's earlier than the note event
224         if (_control_iter != _control_iters.end() && _control_iter->x != DBL_MAX /*&& _control_iter != old_control_iter */) {
225                 if (type == NIL || _control_iter->x < t) {
226                         type = AUTOMATION;
227                 }
228         }
229
230         if (type == NOTE_ON) {
231                 //cerr << "********** MIDI Iterator = note on" << endl;
232                 *_event = (*_note_iter)->on_event();
233                 _active_notes.push(*_note_iter);
234                 ++_note_iter;
235         } else if (type == NOTE_OFF) {
236                 //cerr << "********** MIDI Iterator = note off" << endl;
237                 *_event = _active_notes.top()->off_event();
238                 _active_notes.pop();
239         } else if (type == AUTOMATION) {
240                 //cerr << "********** MIDI Iterator = Automation" << endl;
241                 _seq->control_to_midi_event(_event, *_control_iter);
242         } else {
243                 //cerr << "********** MIDI Iterator = End" << endl;
244                 _is_end = true;
245         }
246
247         assert(_is_end || _event->size() > 0);
248
249         return *this;
250 }
251
252 bool Sequence::const_iterator::operator==(const const_iterator& other) const
253 {
254         if (_is_end || other._is_end) {
255                 return (_is_end == other._is_end);
256         } else {
257                 return (_event == other._event);
258         }
259 }
260
261 Sequence::const_iterator& Sequence::const_iterator::operator=(const const_iterator& other)
262 {
263         if (_locked && _seq != other._seq) {
264                 _seq->read_unlock();
265         }
266
267         _seq           = other._seq;
268         _active_notes  = other._active_notes;
269         _is_end        = other._is_end;
270         _locked        = other._locked;
271         _note_iter     = other._note_iter;
272         _control_iters = other._control_iters;
273         size_t index   = other._control_iter - other._control_iters.begin();
274         _control_iter  = _control_iters.begin() + index;
275         
276         if (!_is_end) {
277                 _event =  boost::shared_ptr<Event>(new Event(*other._event, true));
278         }
279
280         return *this;
281 }
282
283 // Sequence
284
285 Sequence::Sequence(size_t size)
286         : _read_iter(*this, DBL_MAX)
287         , _edited(false)
288         , _notes(size)
289         , _writing(false)
290         , _end_iter(*this, DBL_MAX)
291         , _next_read(UINT32_MAX)
292         , _percussive(false)
293 {
294         assert(_end_iter._is_end);
295         assert( ! _end_iter._locked);
296 }
297
298 /** Read events in frame range \a start .. \a start+cnt into \a dst,
299  * adding \a offset to each event's timestamp.
300  * \return number of events written to \a dst
301  */
302 size_t Sequence::read(EventSink& dst, timestamp_t start, timestamp_t nframes, timedur_t offset) const
303 {
304         //cerr << this << " MM::read @ " << start << " frames: " << nframes << " -> " << stamp_offset << endl;
305         //cerr << this << " MM # notes: " << n_notes() << endl;
306
307         size_t read_events = 0;
308
309         if (start != _next_read) {
310                 _read_iter = const_iterator(*this, (double)start);
311                 //cerr << "Repositioning iterator from " << _next_read << " to " << start << endl;
312         } else {
313                 //cerr << "Using cached iterator at " << _next_read << endl;
314         }
315
316         _next_read = start + nframes;
317
318         while (_read_iter != end() && _read_iter->time() < start + nframes) {
319                 assert(_read_iter->size() > 0);
320                 assert(_read_iter->buffer());
321                 dst.write(_read_iter->time() + offset,
322                           _read_iter->size(), 
323                           _read_iter->buffer());
324                 
325                  /*cerr << this << " Sequence::read event @ " << _read_iter->time()  
326                  << " type: " << hex << int(_read_iter->type()) << dec 
327                  << " note: " << int(_read_iter->note()) 
328                  << " velocity: " << int(_read_iter->velocity()) 
329                  << endl;*/
330                 
331                 ++_read_iter;
332                 ++read_events;
333         }
334
335         return read_events;
336 }
337
338 /** Write the controller event pointed to by \a iter to \a ev.
339  * The buffer of \a ev will be allocated or resized as necessary.
340  * \return true on success
341  */
342 bool
343 Sequence::control_to_midi_event(boost::shared_ptr<Event>& ev, const ControlIterator& iter) const
344 {
345         assert(iter.list.get());
346         if (!ev) {
347                 ev = boost::shared_ptr<Event>(new Event(0, 3, NULL, true));
348         }
349         
350         switch (iter.list->parameter().type()) {
351         case midi_cc_type:
352                 assert(iter.list.get());
353                 assert(iter.list->parameter().channel() < 16);
354                 assert(iter.list->parameter().id() <= INT8_MAX);
355                 assert(iter.y <= INT8_MAX);
356                 
357                 ev->time() = iter.x;
358                 ev->realloc(3);
359                 ev->buffer()[0] = MIDI_CMD_CONTROL + iter.list->parameter().channel();
360                 ev->buffer()[1] = (uint8_t)iter.list->parameter().id();
361                 ev->buffer()[2] = (uint8_t)iter.y;
362                 break;
363
364         case midi_pc_type:
365                 assert(iter.list.get());
366                 assert(iter.list->parameter().channel() < 16);
367                 assert(iter.list->parameter().id() == 0);
368                 assert(iter.y <= INT8_MAX);
369                 
370                 ev->time() = iter.x;
371                 ev->realloc(2);
372                 ev->buffer()[0] = MIDI_CMD_PGM_CHANGE + iter.list->parameter().channel();
373                 ev->buffer()[1] = (uint8_t)iter.y;
374                 break;
375
376         case midi_pb_type:
377                 assert(iter.list.get());
378                 assert(iter.list->parameter().channel() < 16);
379                 assert(iter.list->parameter().id() == 0);
380                 assert(iter.y < (1<<14));
381                 
382                 ev->time() = iter.x;
383                 ev->realloc(3);
384                 ev->buffer()[0] = MIDI_CMD_BENDER + iter.list->parameter().channel();
385                 ev->buffer()[1] = uint16_t(iter.y) & 0x7F; // LSB
386                 ev->buffer()[2] = (uint16_t(iter.y) >> 7) & 0x7F; // MSB
387                 break;
388
389         case midi_ca_type:
390                 assert(iter.list.get());
391                 assert(iter.list->parameter().channel() < 16);
392                 assert(iter.list->parameter().id() == 0);
393                 assert(iter.y <= INT8_MAX);
394
395                 ev->time() = iter.x;
396                 ev->realloc(2);
397                 ev->buffer()[0] = MIDI_CMD_CHANNEL_PRESSURE + iter.list->parameter().channel();
398                 ev->buffer()[1] = (uint8_t)iter.y;
399                 break;
400
401         default:
402                 return false;
403         }
404
405         return true;
406 }
407
408
409 /** Clear all events from the model.
410  */
411 void Sequence::clear()
412 {
413         _lock.writer_lock();
414         _notes.clear();
415         for (Controls::iterator li = _controls.begin(); li != _controls.end(); ++li)
416                 li->second->list()->clear();
417         _next_read = 0;
418         _read_iter = end();
419         _lock.writer_unlock();
420 }
421
422
423 /** Begin a write of events to the model.
424  *
425  * If \a mode is Sustained, complete notes with duration are constructed as note
426  * on/off events are received.  Otherwise (Percussive), only note on events are
427  * stored; note off events are discarded entirely and all contained notes will
428  * have duration 0.
429  */
430 void Sequence::start_write()
431 {
432         //cerr << "MM " << this << " START WRITE, PERCUSSIVE = " << _percussive << endl;
433         write_lock();
434         _writing = true;
435         for (int i = 0; i < 16; ++i)
436                 _write_notes[i].clear();
437         
438         _dirty_controls.clear();
439         write_unlock();
440 }
441
442 /** Finish a write of events to the model.
443  *
444  * If \a delete_stuck is true and the current mode is Sustained, note on events
445  * that were never resolved with a corresonding note off will be deleted.
446  * Otherwise they will remain as notes with duration 0.
447  */
448 void Sequence::end_write(bool delete_stuck)
449 {
450         write_lock();
451         assert(_writing);
452
453         //cerr << "MM " << this << " END WRITE: " << _notes.size() << " NOTES\n";
454
455         if (!_percussive && delete_stuck) {
456                 for (Notes::iterator n = _notes.begin(); n != _notes.end() ;) {
457                         if ((*n)->duration() == 0) {
458                                 cerr << "WARNING: Stuck note lost: " << (*n)->note() << endl;
459                                 n = _notes.erase(n);
460                                 // we have to break here because erase invalidates the iterator
461                                 break;
462                         } else {
463                                 ++n;
464                         }
465                 }
466         }
467
468         for (int i = 0; i < 16; ++i) {
469                 if (!_write_notes[i].empty()) {
470                         cerr << "WARNING: Sequence::end_write: Channel " << i << " has "
471                                         << _write_notes[i].size() << " stuck notes" << endl;
472                 }
473                 _write_notes[i].clear();
474         }
475
476         for (ControlLists::const_iterator i = _dirty_controls.begin(); i != _dirty_controls.end(); ++i) {
477                 (*i)->mark_dirty();
478         }
479         
480         _writing = false;
481         write_unlock();
482 }
483
484 /** Append \a ev to model.  NOT realtime safe.
485  *
486  * Timestamps of events in \a buf are expected to be relative to
487  * the start of this model (t=0) and MUST be monotonically increasing
488  * and MUST be >= the latest event currently in the model.
489  */
490 void Sequence::append(const Event& ev)
491 {
492         write_lock();
493         _edited = true;
494
495         assert(_notes.empty() || ev.time() >= _notes.back()->time());
496         assert(_writing);
497
498         if (ev.is_note_on()) {
499                 append_note_on_unlocked(ev.channel(), ev.time(), ev.note(),
500                                 ev.velocity());
501         } else if (ev.is_note_off()) {
502                 append_note_off_unlocked(ev.channel(), ev.time(), ev.note());
503         } else if (ev.is_cc()) {
504                 append_control_unlocked(
505                                 Evoral::MIDI::ContinuousController(midi_cc_type, ev.cc_number(), ev.channel()),
506                                 ev.time(), ev.cc_value());
507         } else if (ev.is_pgm_change()) {
508                 append_control_unlocked(
509                                 Evoral::MIDI::ProgramChange(midi_pc_type, ev.channel()),
510                                 ev.time(), ev.pgm_number());
511         } else if (ev.is_pitch_bender()) {
512                 append_control_unlocked(
513                                 Evoral::MIDI::PitchBender(midi_pb_type, ev.channel()),
514                                 ev.time(), double(  (0x7F & ev.pitch_bender_msb()) << 7
515                                                   | (0x7F & ev.pitch_bender_lsb()) ));
516         } else if (ev.is_channel_aftertouch()) {
517                 append_control_unlocked(
518                                 Evoral::MIDI::ChannelAftertouch(midi_ca_type, ev.channel()),
519                                 ev.time(), ev.channel_aftertouch());
520         } else {
521                 printf("WARNING: Sequence: Unknown event type %X\n", ev.type());
522         }
523
524         write_unlock();
525 }
526
527 void Sequence::append_note_on_unlocked(uint8_t chan, double time,
528                 uint8_t note_num, uint8_t velocity)
529 {
530         /*cerr << "Sequence " << this << " chan " << (int)chan <<
531          " note " << (int)note_num << " on @ " << time << endl;*/
532
533         assert(note_num <= 127);
534         assert(chan < 16);
535         assert(_writing);
536         _edited = true;
537
538         boost::shared_ptr<Note> new_note(new Note(chan, time, 0, note_num, velocity));
539         _notes.push_back(new_note);
540         if (!_percussive) {
541                 //cerr << "MM Sustained: Appending active note on " << (unsigned)(uint8_t)note_num << endl;
542                 _write_notes[chan].push_back(_notes.size() - 1);
543         }/* else {
544          cerr << "MM Percussive: NOT appending active note on" << endl;
545          }*/
546 }
547
548 void Sequence::append_note_off_unlocked(uint8_t chan, double time,
549                 uint8_t note_num)
550 {
551         /*cerr << "Sequence " << this << " chan " << (int)chan <<
552          " note " << (int)note_num << " off @ " << time << endl;*/
553
554         assert(note_num <= 127);
555         assert(chan < 16);
556         assert(_writing);
557         _edited = true;
558
559         if (_percussive) {
560                 cerr << "Sequence Ignoring note off (percussive mode)" << endl;
561                 return;
562         }
563
564         /* FIXME: make _write_notes fixed size (127 noted) for speed */
565
566         /* FIXME: note off velocity for that one guy out there who actually has
567          * keys that send it */
568
569         bool resolved = false;
570
571         for (WriteNotes::iterator n = _write_notes[chan].begin(); n
572                         != _write_notes[chan].end(); ++n) {
573                 Note& note = *_notes[*n].get();
574                 if (note.note() == note_num) {
575                         assert(time >= note.time());
576                         note.set_duration(time - note.time());
577                         _write_notes[chan].erase(n);
578                         //cerr << "MM resolved note, duration: " << note.duration() << endl;
579                         resolved = true;
580                         break;
581                 }
582         }
583
584         if (!resolved) {
585                 cerr << "Sequence " << this << " spurious note off chan " << (int)chan
586                                 << ", note " << (int)note_num << " @ " << time << endl;
587         }
588 }
589
590 void Sequence::append_control_unlocked(const Parameter& param, double time, double value)
591 {
592         control(param, true)->list()->rt_add(time, value);
593 }
594
595
596 void Sequence::add_note_unlocked(const boost::shared_ptr<Note> note)
597 {
598         //cerr << "Sequence " << this << " add note " << (int)note.note() << " @ " << note.time() << endl;
599         _edited = true;
600         Notes::iterator i = upper_bound(_notes.begin(), _notes.end(), note,
601                         note_time_comparator);
602         _notes.insert(i, note);
603 }
604
605 void Sequence::remove_note_unlocked(const boost::shared_ptr<const Note> note)
606 {
607         _edited = true;
608         //cerr << "Sequence " << this << " remove note " << (int)note.note() << " @ " << note.time() << endl;
609         for (Notes::iterator n = _notes.begin(); n != _notes.end(); ++n) {
610                 Note& _n = *(*n);
611                 const Note& _note = *note;
612                 // TODO: There is still the issue, that after restarting ardour
613                 // persisted undo does not work, because of rounding errors in the
614                 // event times after saving/restoring to/from MIDI files
615                 /*cerr << "======================================= " << endl;
616                 cerr << int(_n.note()) << "@" << int(_n.time()) << "[" << int(_n.channel()) << "] --" << int(_n.duration()) << "-- #" << int(_n.velocity()) << endl;
617                 cerr << int(_note.note()) << "@" << int(_note.time()) << "[" << int(_note.channel()) << "] --" << int(_note.duration()) << "-- #" << int(_note.velocity()) << endl;
618                 cerr << "Equal: " << bool(_n == _note) << endl;
619                 cerr << endl << endl;*/
620                 if (_n == _note) {
621                         _notes.erase(n);
622                         // we have to break here, because erase invalidates all iterators, ie. n itself
623                         break;
624                 }
625         }
626 }
627
628 /** Slow!  for debugging only. */
629 #ifndef NDEBUG
630 bool Sequence::is_sorted() const {
631         bool t = 0;
632         for (Notes::const_iterator n = _notes.begin(); n != _notes.end(); ++n)
633                 if ((*n)->time() < t)
634                         return false;
635                 else
636                         t = (*n)->time();
637
638         return true;
639 }
640 #endif
641
642 } // namespace Evoral
643