13
0

provide an interesting method to convert an RTMidiBuffer<samples> to RTMidiBuffer<beats> without any memory reallocation

This commit is contained in:
Paul Davis 2024-09-23 12:53:43 -06:00
parent 88c326aee0
commit 86b01a5d2f
2 changed files with 43 additions and 0 deletions

View File

@ -52,6 +52,12 @@ class LIBARDOUR_API RTMidiBufferBase : public Evoral::EventSink<TimeType>
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<Temporal::Beats,Temporal::Beats>* convert ();
void clear();
void resize(size_t);
size_t size() const { return _size; }
@ -112,6 +118,8 @@ class LIBARDOUR_API RTMidiBufferBase : public Evoral::EventSink<TimeType>
private:
friend struct WriteProtectRender;
/* any cousin of ours is a friend */
template<typename T, typename D> friend class RTMidiBufferBase;
/* The main store. Holds Items (timestamp+up to 3 bytes of data OR
* offset into secondary storage below)

View File

@ -533,6 +533,41 @@ RTMidiBufferBase<TimeType,DistanceType>::track_state (TimeType when, MidiStateTr
}
}
template<class TimeType, class DistanceType>
RTMidiBufferBase<Temporal::Beats,Temporal::Beats>*
RTMidiBufferBase<TimeType,DistanceType>::convert()
{
RTMidiBufferBase<Temporal::Beats,Temporal::Beats>* beats = new RTMidiBufferBase<Temporal::Beats,Temporal::Beats>();
/* 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<RTMidiBufferBase<Temporal::Beats,Temporal::Beats>::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<samplepos_t,samplecnt_t>;