Update MIDI buffer implementation to retain EventType
This commit is contained in:
parent
472fe2b556
commit
7c37a18b75
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user