diff --git a/libs/ardour/ardour/midi_buffer.h b/libs/ardour/ardour/midi_buffer.h index 53be5a8c63..67d512b4f8 100644 --- a/libs/ardour/ardour/midi_buffer.h +++ b/libs/ardour/ardour/midi_buffer.h @@ -43,6 +43,7 @@ public: MidiBuffer(size_t capacity); ~MidiBuffer(); + void clear(); void silence (samplecnt_t nframes, samplecnt_t offset = 0); void read_from (const Buffer& src, samplecnt_t nframes, sampleoffset_t dst_offset = 0, sampleoffset_t src_offset = 0); void merge_from (const Buffer& src, samplecnt_t nframes, sampleoffset_t dst_offset = 0, sampleoffset_t src_offset = 0); @@ -152,8 +153,9 @@ public: size_t total_data_deleted = align32 (sizeof(TimeType) + sizeof (Evoral::EventType) + event_size); - if (i.offset + total_data_deleted > _size) { + if (i.offset + total_data_deleted >= _size) { _size = 0; + _silent = true; return end(); } @@ -167,6 +169,8 @@ public: _size -= total_data_deleted; + assert (_size > 0); + /* all subsequent iterators are now invalid, and the one we * return should refer to the event we copied, which was after * the one we just erased. diff --git a/libs/ardour/midi_buffer.cc b/libs/ardour/midi_buffer.cc index d75e516776..751cec1eca 100644 --- a/libs/ardour/midi_buffer.cc +++ b/libs/ardour/midi_buffer.cc @@ -96,7 +96,6 @@ MidiBuffer::copy(MidiBuffer const * const copy) memcpy(_data, copy->_data, _size); } - void MidiBuffer::read_from (const Buffer& src, samplecnt_t nframes, sampleoffset_t dst_offset, sampleoffset_t src_offset) { @@ -107,21 +106,13 @@ MidiBuffer::read_from (const Buffer& src, samplecnt_t nframes, sampleoffset_t ds assert (_capacity >= msrc.size()); - clear (); - assert (_size == 0); + MidiBuffer::silence (nframes, dst_offset); for (MidiBuffer::const_iterator i = msrc.begin(); i != msrc.end(); ++i) { const Evoral::Event ev(*i, false); if (ev.time() >= src_offset && ev.time() < nframes + src_offset) { push_back (ev.time() + dst_offset - src_offset, ev.event_type (), ev.size(), ev.buffer()); - } else { - cerr << "\t!!!! MIDI event @ " << ev.time() - << " skipped, not within range. nframes: " << nframes - << " src_offset: " << src_offset - << " dst_offset: " << dst_offset - << "\n"; - PBD::stacktrace (cerr, 30); } } @@ -299,18 +290,34 @@ MidiBuffer::reserve(TimeType time, Evoral::EventType event_type, size_t size) return write_loc; } - void -MidiBuffer::silence (samplecnt_t /*nframes*/, samplecnt_t /*offset*/) +MidiBuffer::clear () { - /* XXX iterate over existing events, find all in range given by offset & nframes, - and delete them. - */ - _size = 0; _silent = true; } +void +MidiBuffer::silence (samplecnt_t nframes, samplecnt_t offset) +{ + /* iterate over existing events, find all in range given by offset & nframes, + * and delete them. + */ + if (nframes == _capacity && offset == 0) { + MidiBuffer::clear (); + return; + } + + for (MidiBuffer::iterator i = begin(); i != end();) { + const Evoral::Event ev(*i, false); + if (ev.time() >= offset && ev.time() < nframes + offset) { + i = erase (i); + } else { + ++i; + } + } +} + bool MidiBuffer::second_simultaneous_midi_byte_is_first (uint8_t a, uint8_t b) {