From 7bb9d048591ecfab2b650784f8b45843773bbd41 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Thu, 12 Mar 2015 15:21:31 +0100 Subject: [PATCH 1/1] =?utf8?q?cont=E2=80=99d=20work=20on=20a16dd7c,=20fixe?= =?utf8?q?s=20#6170?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- libs/ardour/ardour/midi_ring_buffer.h | 1 + libs/ardour/midi_diskstream.cc | 4 +- libs/ardour/midi_ring_buffer.cc | 57 +++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/libs/ardour/ardour/midi_ring_buffer.h b/libs/ardour/ardour/midi_ring_buffer.h index 0d27de3c16..d89d85b2d7 100644 --- a/libs/ardour/ardour/midi_ring_buffer.h +++ b/libs/ardour/ardour/midi_ring_buffer.h @@ -49,6 +49,7 @@ public: inline bool read_contents(uint32_t size, uint8_t* buf); size_t read(MidiBuffer& dst, framepos_t start, framepos_t end, framecnt_t offset=0, bool stop_on_overflow_in_destination=false); + size_t skip_to(framepos_t start); void dump(std::ostream& dst); void flush (framepos_t start, framepos_t end); diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc index 80faab1f9d..cd7e530a42 100644 --- a/libs/ardour/midi_diskstream.cc +++ b/libs/ardour/midi_diskstream.cc @@ -621,7 +621,7 @@ MidiDiskstream::commit (framecnt_t playback_distance) * * In those cases the butler needs to be summed to refill the buffer (done now) * AND we need to skip (frames_read - frames_written). ie remove old events - * before playback_sample from the rinbuffer. (not yet done) + * before playback_sample from the rinbuffer. * * [1] one way to do so is described at #6170. * For me just popping up the context-menu on a MIDI-track header @@ -1440,6 +1440,8 @@ MidiDiskstream::get_playback (MidiBuffer& dst, framecnt_t nframes) size_t events_read = 0; + _playback_buf->skip_to (playback_sample); + if (loc) { framepos_t effective_start; diff --git a/libs/ardour/midi_ring_buffer.cc b/libs/ardour/midi_ring_buffer.cc index 9fbd9dfdff..5bd3f947e2 100644 --- a/libs/ardour/midi_ring_buffer.cc +++ b/libs/ardour/midi_ring_buffer.cc @@ -60,6 +60,10 @@ MidiRingBuffer::read(MidiBuffer& dst, framepos_t start, framepos_t end, frame ev_time = *(reinterpret_cast((uintptr_t)peekbuf)); ev_size = *(reinterpret_cast((uintptr_t)(peekbuf + sizeof(T) + sizeof (Evoral::EventType)))); + if (this->read_space() < ev_size) { + break;; + } + if (ev_time >= end) { DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("MRB event @ %1 past end @ %2\n", ev_time, end)); break; @@ -124,6 +128,59 @@ MidiRingBuffer::read(MidiBuffer& dst, framepos_t start, framepos_t end, frame return count; } +template +size_t +MidiRingBuffer::skip_to(framepos_t start) +{ + if (this->read_space() == 0) { + return 0; + } + + T ev_time; + uint32_t ev_size; + size_t count = 0; + const size_t prefix_size = sizeof(T) + sizeof(Evoral::EventType) + sizeof(uint32_t); + + while (this->read_space() >= prefix_size) { + + uint8_t peekbuf[prefix_size]; + this->peek (peekbuf, prefix_size); + + ev_time = *(reinterpret_cast((uintptr_t)peekbuf)); + ev_size = *(reinterpret_cast((uintptr_t)(peekbuf + sizeof(T) + sizeof (Evoral::EventType)))); + + if (ev_time >= start) { + return count; + } + + if (this->read_space() < ev_size) { + continue; + } + + this->increment_read_ptr (prefix_size); + + uint8_t status; + bool r = this->peek (&status, sizeof(uint8_t)); + assert (r); // If this failed, buffer is corrupt, all hope is lost + + ++count; + + if (ev_size < 8) { + this->increment_read_ptr (ev_size); + } else { + // we only track note on/off, 8 bytes are plenty. + uint8_t write_loc[8]; + bool success = read_contents (ev_size, write_loc); + if (success) { + _tracker.track(write_loc); + } + } + } + return count; +} + + + template void MidiRingBuffer::flush (framepos_t /*start*/, framepos_t end) -- 2.30.2