Update MIDI buffer implementation to retain EventType

This commit is contained in:
Robin Gareus 2020-09-19 22:36:17 +02:00
parent 472fe2b556
commit 7c37a18b75
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
5 changed files with 51 additions and 34 deletions

View File

@ -53,9 +53,9 @@ public:
void skip_to (TimeType when);
bool push_back(const Evoral::Event<TimeType>& event);
bool push_back(TimeType time, size_t size, const uint8_t* data);
bool push_back(TimeType time, size_t size, const uint8_t* data, Evoral::EventType event_type = Evoral::MIDI_EVENT);
uint8_t* reserve(TimeType time, size_t size);
uint8_t* reserve(TimeType time, Evoral::EventType event_type, size_t size);
void resize(size_t);
size_t size() const { return _size; }
@ -86,19 +86,21 @@ public:
}
inline EventType operator*() const {
uint8_t* ev_start = buffer->_data + offset + sizeof(TimeType);
uint8_t* ev_start = buffer->_data + offset + sizeof(TimeType) + sizeof (Evoral::EventType);
int event_size = Evoral::midi_event_size(ev_start);
assert(event_size >= 0);
return EventType(midi_parameter_type(*ev_start),
return EventType(
*((Evoral::EventType*)(buffer->_data + offset + sizeof(TimeType))),
*((TimeType*)(buffer->_data + offset)),
event_size, ev_start);
}
inline EventType operator*() {
uint8_t* ev_start = buffer->_data + offset + sizeof(TimeType);
uint8_t* ev_start = buffer->_data + offset + sizeof(TimeType) + sizeof (Evoral::EventType);
int event_size = Evoral::midi_event_size(ev_start);
assert(event_size >= 0);
return EventType(Evoral::MIDI_EVENT,
return EventType(
*(reinterpret_cast<Evoral::EventType*>((uintptr_t)(buffer->_data + offset + sizeof(TimeType)))),
*(reinterpret_cast<TimeType*>((uintptr_t)(buffer->_data + offset))),
event_size, ev_start);
}
@ -107,11 +109,15 @@ public:
return reinterpret_cast<TimeType*>((uintptr_t)(buffer->_data + offset));
}
inline Evoral::EventType * event_type_ptr() {
return reinterpret_cast<Evoral::EventType*>((uintptr_t)(buffer->_data + offset + sizeof(TimeType)));
}
inline iterator_base<BufferType, EventType>& operator++() {
uint8_t* ev_start = buffer->_data + offset + sizeof(TimeType);
uint8_t* ev_start = buffer->_data + offset + sizeof(TimeType) + sizeof (Evoral::EventType);
int event_size = Evoral::midi_event_size(ev_start);
assert(event_size >= 0);
offset += sizeof(TimeType) + event_size;
offset += sizeof(TimeType) + sizeof (Evoral::EventType) + event_size;
return *this;
}
@ -138,7 +144,7 @@ public:
iterator erase(const iterator& i) {
assert (i.buffer == this);
uint8_t* ev_start = _data + i.offset + sizeof (TimeType);
uint8_t* ev_start = _data + i.offset + sizeof (TimeType) + sizeof (Evoral::EventType);
int event_size = Evoral::midi_event_size (ev_start);
if (event_size < 0) {
@ -146,7 +152,7 @@ public:
return end();
}
size_t total_data_deleted = sizeof(TimeType) + event_size;
size_t total_data_deleted = sizeof(TimeType) + sizeof (Evoral::EventType) + event_size;
if (i.offset + total_data_deleted > _size) {
_size = 0;
@ -182,7 +188,7 @@ private:
friend class iterator_base< MidiBuffer, Evoral::Event<TimeType> >;
friend class iterator_base< const MidiBuffer, const Evoral::Event<TimeType> >;
uint8_t* _data; ///< timestamp, event, timestamp, event, ...
uint8_t* _data; ///< [timestamp, event-type, event]*
pframes_t _size;
};

View File

@ -83,7 +83,7 @@ AsyncMIDIPort::flush_output_fifo (MIDI::pframes_t nframes)
assert (evp->buffer());
for (size_t n = 0; n < vec.len[0]; ++n, ++evp) {
if (mb.push_back (evp->time(), evp->size(), evp->buffer())) {
if (mb.push_back (evp->time(), evp->size(), evp->buffer(), evp->event_type ())) {
written++;
}
}
@ -96,7 +96,7 @@ AsyncMIDIPort::flush_output_fifo (MIDI::pframes_t nframes)
assert (evp->buffer());
for (size_t n = 0; n < vec.len[1]; ++n, ++evp) {
if (mb.push_back (evp->time(), evp->size(), evp->buffer())) {
if (mb.push_back (evp->time(), evp->size(), evp->buffer(), evp->event_type ())) {
written++;
}
}

View File

@ -2731,7 +2731,7 @@ LuaBindings::dsp (lua_State* L)
.addFunction ("resize", &MidiBuffer::resize)
.addFunction ("copy", (void (MidiBuffer::*)(MidiBuffer const * const))&MidiBuffer::copy)
.addFunction ("push_event", (bool (MidiBuffer::*)(const Evoral::Event<samplepos_t>&))&MidiBuffer::push_back)
.addFunction ("push_back", (bool (MidiBuffer::*)(samplepos_t, size_t, const uint8_t*))&MidiBuffer::push_back)
.addFunction ("push_back", (bool (MidiBuffer::*)(samplepos_t, size_t, const uint8_t*, Evoral::EventType))&MidiBuffer::push_back)
// TODO iterators..
.addExtCFunction ("table", &luabridge::CFunc::listToTable<const Evoral::Event<samplepos_t>, MidiBuffer>)
.endClass()

View File

@ -115,7 +115,7 @@ MidiBuffer::read_from (const Buffer& src, samplecnt_t nframes, sampleoffset_t ds
const Evoral::Event<TimeType> ev(*i, false);
if (ev.time() >= 0 && ev.time() < nframes) {
push_back (ev.time(), ev.size(), ev.buffer());
push_back (ev.time(), ev.size(), ev.buffer(), ev.event_type ());
} else {
cerr << "\t!!!! MIDI event @ " << ev.time() << " skipped, not within range 0 .. " << nframes << endl;
PBD::stacktrace (cerr, 30);
@ -146,7 +146,7 @@ MidiBuffer::merge_from (const Buffer& src, samplecnt_t /*nframes*/, sampleoffset
bool
MidiBuffer::push_back(const Evoral::Event<TimeType>& ev)
{
return push_back (ev.time(), ev.size(), ev.buffer());
return push_back (ev.time(), ev.size(), ev.buffer(), ev.event_type ());
}
@ -158,9 +158,10 @@ MidiBuffer::push_back(const Evoral::Event<TimeType>& ev)
* @return false if operation failed (not enough room)
*/
bool
MidiBuffer::push_back(TimeType time, size_t size, const uint8_t* data)
MidiBuffer::push_back(TimeType time, size_t size, const uint8_t* data, Evoral::EventType event_type)
{
const size_t stamp_size = sizeof(TimeType);
const size_t etype_size = sizeof(Evoral::EventType);
#ifndef NDEBUG
if (DEBUG_ENABLED(DEBUG::MidiIO)) {
@ -177,7 +178,7 @@ MidiBuffer::push_back(TimeType time, size_t size, const uint8_t* data)
}
#endif
if (_size + stamp_size + size >= _capacity) {
if (_size + stamp_size + etype_size + size >= _capacity) {
return false;
}
@ -187,9 +188,10 @@ MidiBuffer::push_back(TimeType time, size_t size, const uint8_t* data)
uint8_t* const write_loc = _data + _size;
*(reinterpret_cast<TimeType*>((uintptr_t)write_loc)) = time;
memcpy(write_loc + stamp_size, data, size);
*(reinterpret_cast<Evoral::EventType*>((uintptr_t)(write_loc + stamp_size))) = event_type;
memcpy(write_loc + stamp_size + etype_size, data, size);
_size += stamp_size + size;
_size += stamp_size + etype_size + size;
_silent = false;
return true;
@ -205,7 +207,9 @@ MidiBuffer::insert_event(const Evoral::Event<TimeType>& ev)
}
const size_t stamp_size = sizeof(TimeType);
const size_t bytes_to_merge = stamp_size + ev.size();
const size_t etype_size = sizeof(Evoral::EventType);
const size_t bytes_to_merge = stamp_size + etype_size + ev.size();
if (_size + bytes_to_merge >= _capacity) {
cerr << string_compose ("MidiBuffer::push_back failed (buffer is full: size: %1 capacity %2 new bytes %3)", _size, _capacity, bytes_to_merge) << endl;
@ -243,7 +247,8 @@ MidiBuffer::insert_event(const Evoral::Event<TimeType>& ev)
uint8_t* const write_loc = _data + insert_offset;
*(reinterpret_cast<TimeType*>((uintptr_t)write_loc)) = t;
memcpy(write_loc + stamp_size, ev.buffer(), ev.size());
*(reinterpret_cast<Evoral::EventType*>((uintptr_t)(write_loc + stamp_size))) = ev.event_type ();
memcpy(write_loc + stamp_size + etype_size, ev.buffer(), ev.size());
_size += bytes_to_merge;
@ -265,21 +270,23 @@ MidiBuffer::write(TimeType time, Evoral::EventType type, uint32_t size, const ui
* location, or the buffer will be corrupted and very nasty things will happen.
*/
uint8_t*
MidiBuffer::reserve(TimeType time, size_t size)
MidiBuffer::reserve(TimeType time, Evoral::EventType event_type, size_t size)
{
const size_t stamp_size = sizeof(TimeType);
if (_size + stamp_size + size >= _capacity) {
const size_t etype_size = sizeof(Evoral::EventType);
if (_size + stamp_size + etype_size + size >= _capacity) {
return 0;
}
// write timestamp
// write timestamp and event-type
uint8_t* write_loc = _data + _size;
*(reinterpret_cast<TimeType*>((uintptr_t)write_loc)) = time;
*(reinterpret_cast<Evoral::EventType*>((uintptr_t)(write_loc + stamp_size))) = event_type;
// move write_loc to begin of MIDI buffer data to write to
write_loc += stamp_size;
write_loc += stamp_size + etype_size;
_size += stamp_size + size;
_size += stamp_size + etype_size + size;
_silent = false;
return write_loc;
@ -422,6 +429,8 @@ MidiBuffer::second_simultaneous_midi_byte_is_first (uint8_t a, uint8_t b)
bool
MidiBuffer::merge_in_place (const MidiBuffer &other)
{
const size_t header_size = sizeof(TimeType) + sizeof(Evoral::EventType);
if (other.size() && size()) {
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("merge in place, sizes %1/%2\n", size(), other.size()));
}
@ -458,7 +467,7 @@ MidiBuffer::merge_in_place (const MidiBuffer &other)
if (merge_offset == -1) {
merge_offset = them.offset;
}
bytes_to_merge += sizeof (TimeType) + (*them).size();
bytes_to_merge += header_size + (*them).size();
++them;
}
@ -505,11 +514,11 @@ MidiBuffer::merge_in_place (const MidiBuffer &other)
DEBUG_TRACE (DEBUG::MidiIO,
string_compose ("simultaneous MIDI events discovered during merge, times %1/%2 status %3/%4\n",
(*us).time(), (*them).time(),
(int) *(_data + us.offset + sizeof (TimeType)),
(int) *(other._data + them.offset + sizeof (TimeType))));
(int) *(_data + us.offset + header_size),
(int) *(other._data + them.offset + header_size)));
uint8_t our_midi_status_byte = *(_data + us.offset + sizeof (TimeType));
uint8_t their_midi_status_byte = *(other._data + them.offset + sizeof (TimeType));
uint8_t our_midi_status_byte = *(_data + us.offset + header_size);
uint8_t their_midi_status_byte = *(other._data + them.offset + header_size);
bool them_first = second_simultaneous_midi_byte_is_first (our_midi_status_byte, their_midi_status_byte);
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("other message came first ? %1\n", them_first));
@ -519,7 +528,7 @@ MidiBuffer::merge_in_place (const MidiBuffer &other)
++us;
}
bytes_to_merge = sizeof (TimeType) + (*them).size();
bytes_to_merge = header_size + (*them).size();
/* move our remaining events later in the buffer by
* enough to fit the one message we're going to merge

View File

@ -48,6 +48,7 @@ MidiRingBuffer<T>::read (MidiBuffer& dst, samplepos_t start, samplepos_t end, sa
}
T ev_time;
Evoral::EventType ev_type;
uint32_t ev_size;
size_t count = 0;
const size_t prefix_size = sizeof(T) + sizeof(Evoral::EventType) + sizeof(uint32_t);
@ -62,6 +63,7 @@ MidiRingBuffer<T>::read (MidiBuffer& dst, samplepos_t start, samplepos_t end, sa
this->peek (peekbuf, prefix_size);
ev_time = *(reinterpret_cast<T*>((uintptr_t)peekbuf));
ev_type = *(reinterpret_cast<Evoral::EventType*>((uintptr_t)(peekbuf + sizeof(T))));
ev_size = *(reinterpret_cast<uint32_t*>((uintptr_t)(peekbuf + sizeof(T) + sizeof (Evoral::EventType))));
if (this->read_space() < ev_size) {
@ -92,7 +94,7 @@ MidiRingBuffer<T>::read (MidiBuffer& dst, samplepos_t start, samplepos_t end, sa
/* lets see if we are going to be able to write this event into dst.
*/
uint8_t* write_loc = dst.reserve (ev_time, ev_size);
uint8_t* write_loc = dst.reserve (ev_time, ev_type, ev_size);
if (write_loc == 0) {
if (stop_on_overflow_in_dst) {
DEBUG_TRACE (DEBUG::MidiRingBuffer, string_compose ("MidiRingBuffer: overflow in destination MIDI buffer, stopped after %1 events\n", count));