changes/extensions to RTMidiBuffer API to make it more suitable for slots/triggers
This commit is contained in:
parent
65f85dfdfe
commit
2b754568a0
@ -29,6 +29,8 @@
|
||||
|
||||
#include "evoral/Event.h"
|
||||
#include "evoral/EventSink.h"
|
||||
#include "evoral/midi_util.h"
|
||||
|
||||
#include "ardour/types.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
@ -39,6 +41,12 @@ class MidiStateTracker;
|
||||
/** */
|
||||
class LIBARDOUR_API RTMidiBuffer : public Evoral::EventSink<samplepos_t>
|
||||
{
|
||||
private:
|
||||
struct Blob {
|
||||
uint32_t size;
|
||||
uint8_t data[0];
|
||||
};
|
||||
|
||||
public:
|
||||
typedef samplepos_t TimeType;
|
||||
|
||||
@ -48,6 +56,9 @@ class LIBARDOUR_API RTMidiBuffer : public Evoral::EventSink<samplepos_t>
|
||||
void clear();
|
||||
void resize(size_t);
|
||||
size_t size() const { return _size; }
|
||||
bool empty() const { return _size == 0; }
|
||||
|
||||
samplecnt_t span() const;
|
||||
|
||||
uint32_t write (TimeType time, Evoral::EventType type, uint32_t size, const uint8_t* buf);
|
||||
uint32_t read (MidiBuffer& dst, samplepos_t start, samplepos_t end, MidiStateTracker& tracker, samplecnt_t offset = 0);
|
||||
@ -64,14 +75,29 @@ class LIBARDOUR_API RTMidiBuffer : public Evoral::EventSink<samplepos_t>
|
||||
};
|
||||
};
|
||||
|
||||
Item const & operator[](size_t n) const {
|
||||
if (n >= _size) {
|
||||
throw std::exception ();
|
||||
}
|
||||
return _data[n];
|
||||
}
|
||||
|
||||
uint8_t const * bytes (Item const & item, uint32_t& size) {
|
||||
if (item.bytes[0]) {
|
||||
size = Evoral::midi_event_size (item.bytes[1]);
|
||||
return item.bytes;
|
||||
} else {
|
||||
uint32_t offset = item.offset & ~(1<<(CHAR_BIT-1));
|
||||
Blob* blob = reinterpret_cast<Blob*> (&_pool[offset]);
|
||||
|
||||
size = blob->size;
|
||||
return blob->data;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
friend struct WriteProtectRender;
|
||||
|
||||
struct Blob {
|
||||
uint32_t size;
|
||||
uint8_t data[0];
|
||||
};
|
||||
|
||||
/* The main store. Holds Items (timestamp+up to 3 bytes of data OR
|
||||
* offset into secondary storage below)
|
||||
*/
|
||||
|
@ -24,8 +24,6 @@
|
||||
#include "pbd/error.h"
|
||||
#include "pbd/debug.h"
|
||||
|
||||
#include "evoral/midi_util.h"
|
||||
|
||||
#include "ardour/debug.h"
|
||||
#include "ardour/midi_buffer.h"
|
||||
#include "ardour/midi_state_tracker.h"
|
||||
@ -194,8 +192,12 @@ RTMidiBuffer::write (TimeType time, Evoral::EventType /*type*/, uint32_t size, c
|
||||
{
|
||||
/* This buffer stores only MIDI, we don't care about the value of "type" */
|
||||
|
||||
if (_size == _capacity) {
|
||||
resize (_capacity + 1024); // XXX 1024 is completely arbitrary
|
||||
if (_size + size >= _capacity) {
|
||||
if (size > 1024) {
|
||||
resize (_capacity + size + 1024); // XXX 1024 is completely arbitrary
|
||||
} else {
|
||||
resize (_capacity + 1024); // XXX 1024 is completely arbitrary
|
||||
}
|
||||
}
|
||||
|
||||
_data[_size].timestamp = time;
|
||||
@ -232,13 +234,15 @@ RTMidiBuffer::write (TimeType time, Evoral::EventType /*type*/, uint32_t size, c
|
||||
return size;
|
||||
}
|
||||
|
||||
/* These (non-matching) comparison arguments weren't supported prior to C99 !!!
|
||||
/* requires C++20 to be usable */
|
||||
/*
|
||||
static
|
||||
bool
|
||||
item_timestamp_earlier (ARDOUR::RTMidiBuffer::Item const & item, samplepos_t time)
|
||||
item_timestamp_earlier (ARDOUR::RTMidiBuffer::Item const & item, samplepos_t const & time)
|
||||
{
|
||||
return item.timestamp < time;
|
||||
}*/
|
||||
}
|
||||
*/
|
||||
|
||||
static
|
||||
bool
|
||||
@ -260,9 +264,8 @@ RTMidiBuffer::read (MidiBuffer& dst, samplepos_t start, samplepos_t end, MidiSta
|
||||
Item foo;
|
||||
Item* iend;
|
||||
Item* item;
|
||||
|
||||
uint32_t count = 0;
|
||||
foo.timestamp = start;
|
||||
uint32_t count = 0;
|
||||
|
||||
if (start < end) {
|
||||
iend = _data+_size;
|
||||
@ -271,7 +274,7 @@ RTMidiBuffer::read (MidiBuffer& dst, samplepos_t start, samplepos_t end, MidiSta
|
||||
} else {
|
||||
iend = _data;
|
||||
--iend; /* yes, this is technically "illegal" but we will never indirect */
|
||||
Item* uend = _data+_size;
|
||||
Item* uend = _data + _size;
|
||||
item = upper_bound (_data, uend, foo, item_item_earlier);
|
||||
|
||||
if (item == uend) {
|
||||
@ -412,3 +415,17 @@ RTMidiBuffer::clear ()
|
||||
/* rendering new data .. it will not be reversed */
|
||||
_reversed = false;
|
||||
}
|
||||
|
||||
samplecnt_t
|
||||
RTMidiBuffer::span() const
|
||||
{
|
||||
if (_size == 0 || _size == 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Item* last = &_data[_size-1];
|
||||
const Item* first = &_data[0];
|
||||
|
||||
return last->timestamp - first->timestamp;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user