diff --git a/libs/ardour/ardour/rt_midibuffer.h b/libs/ardour/ardour/rt_midibuffer.h index dfc4bd8c39..a317c6f4cf 100644 --- a/libs/ardour/ardour/rt_midibuffer.h +++ b/libs/ardour/ardour/rt_midibuffer.h @@ -52,6 +52,12 @@ class LIBARDOUR_API RTMidiBufferBase : public Evoral::EventSink RTMidiBufferBase (); ~RTMidiBufferBase (); + /* After calling convert(), this RTMidiBufferBase no longer owns or has + a reference to any data. The data is all "moved" to the returned + RTMidiBufferBase and timestamps modified to its time domain if nececssary. + */ + RTMidiBufferBase* convert (); + void clear(); void resize(size_t); size_t size() const { return _size; } @@ -112,6 +118,8 @@ class LIBARDOUR_API RTMidiBufferBase : public Evoral::EventSink private: friend struct WriteProtectRender; + /* any cousin of ours is a friend */ + template friend class RTMidiBufferBase; /* The main store. Holds Items (timestamp+up to 3 bytes of data OR * offset into secondary storage below) diff --git a/libs/ardour/rt_midibuffer.cc b/libs/ardour/rt_midibuffer.cc index 3ae401e53d..1b96ca8e17 100644 --- a/libs/ardour/rt_midibuffer.cc +++ b/libs/ardour/rt_midibuffer.cc @@ -533,6 +533,41 @@ RTMidiBufferBase::track_state (TimeType when, MidiStateTr } } +template +RTMidiBufferBase* +RTMidiBufferBase::convert() +{ + RTMidiBufferBase* beats = new RTMidiBufferBase(); + + /* Convert timestamps, taking advantage of the fact that beats and + * samples are both 64 bit integers, and thus Item::timestamp is the + * same size and type for both. + */ + + for (uint32_t n = 0; n < _size; ++n) { + auto item = &_data[n]; + Temporal::Beats b = timepos_t (item->timestamp).beats (); + item->timestamp = b.to_ticks (); + } + + /* Hand over all the data */ + + beats->_data = reinterpret_cast::Item*> (_data); + beats->_size = _size; + beats->_pool = _pool; + beats->_pool_size = _pool_size; + beats->_pool_size = _pool_size; + + _data = nullptr; + _pool = nullptr; + _size = 0; + _pool_size = 0; + _pool_capacity = 0; + + return beats; +} + + // Explicit instantiation template class RTMidiBufferBase;