MidiBuffer: allow for partial processing with offset
AudioBuffer::read_from() only replaces data within the given range (offset .. n_samples + offset) leaving the rest of the buffer untouched. With in-place processing, where the same MIDI buffer is used for input and output, each sub-cycle must only clear the processed range, while leaving the rest of the buffer untouched.
This commit is contained in:
parent
64e2f16e06
commit
c5511040ec
|
@ -43,6 +43,7 @@ public:
|
||||||
MidiBuffer(size_t capacity);
|
MidiBuffer(size_t capacity);
|
||||||
~MidiBuffer();
|
~MidiBuffer();
|
||||||
|
|
||||||
|
void clear();
|
||||||
void silence (samplecnt_t nframes, samplecnt_t offset = 0);
|
void silence (samplecnt_t nframes, samplecnt_t offset = 0);
|
||||||
void read_from (const Buffer& src, samplecnt_t nframes, sampleoffset_t dst_offset = 0, sampleoffset_t src_offset = 0);
|
void read_from (const Buffer& src, samplecnt_t nframes, sampleoffset_t dst_offset = 0, sampleoffset_t src_offset = 0);
|
||||||
void merge_from (const Buffer& src, samplecnt_t nframes, sampleoffset_t dst_offset = 0, sampleoffset_t src_offset = 0);
|
void merge_from (const Buffer& src, samplecnt_t nframes, sampleoffset_t dst_offset = 0, sampleoffset_t src_offset = 0);
|
||||||
|
@ -152,8 +153,9 @@ public:
|
||||||
|
|
||||||
size_t total_data_deleted = align32 (sizeof(TimeType) + sizeof (Evoral::EventType) + event_size);
|
size_t total_data_deleted = align32 (sizeof(TimeType) + sizeof (Evoral::EventType) + event_size);
|
||||||
|
|
||||||
if (i.offset + total_data_deleted > _size) {
|
if (i.offset + total_data_deleted >= _size) {
|
||||||
_size = 0;
|
_size = 0;
|
||||||
|
_silent = true;
|
||||||
return end();
|
return end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,6 +169,8 @@ public:
|
||||||
|
|
||||||
_size -= total_data_deleted;
|
_size -= total_data_deleted;
|
||||||
|
|
||||||
|
assert (_size > 0);
|
||||||
|
|
||||||
/* all subsequent iterators are now invalid, and the one we
|
/* all subsequent iterators are now invalid, and the one we
|
||||||
* return should refer to the event we copied, which was after
|
* return should refer to the event we copied, which was after
|
||||||
* the one we just erased.
|
* the one we just erased.
|
||||||
|
|
|
@ -96,7 +96,6 @@ MidiBuffer::copy(MidiBuffer const * const copy)
|
||||||
memcpy(_data, copy->_data, _size);
|
memcpy(_data, copy->_data, _size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiBuffer::read_from (const Buffer& src, samplecnt_t nframes, sampleoffset_t dst_offset, sampleoffset_t src_offset)
|
MidiBuffer::read_from (const Buffer& src, samplecnt_t nframes, sampleoffset_t dst_offset, sampleoffset_t src_offset)
|
||||||
{
|
{
|
||||||
|
@ -107,21 +106,13 @@ MidiBuffer::read_from (const Buffer& src, samplecnt_t nframes, sampleoffset_t ds
|
||||||
|
|
||||||
assert (_capacity >= msrc.size());
|
assert (_capacity >= msrc.size());
|
||||||
|
|
||||||
clear ();
|
MidiBuffer::silence (nframes, dst_offset);
|
||||||
assert (_size == 0);
|
|
||||||
|
|
||||||
for (MidiBuffer::const_iterator i = msrc.begin(); i != msrc.end(); ++i) {
|
for (MidiBuffer::const_iterator i = msrc.begin(); i != msrc.end(); ++i) {
|
||||||
const Evoral::Event<TimeType> ev(*i, false);
|
const Evoral::Event<TimeType> ev(*i, false);
|
||||||
|
|
||||||
if (ev.time() >= src_offset && ev.time() < nframes + src_offset) {
|
if (ev.time() >= src_offset && ev.time() < nframes + src_offset) {
|
||||||
push_back (ev.time() + dst_offset - src_offset, ev.event_type (), ev.size(), ev.buffer());
|
push_back (ev.time() + dst_offset - src_offset, ev.event_type (), ev.size(), ev.buffer());
|
||||||
} else {
|
|
||||||
cerr << "\t!!!! MIDI event @ " << ev.time()
|
|
||||||
<< " skipped, not within range. nframes: " << nframes
|
|
||||||
<< " src_offset: " << src_offset
|
|
||||||
<< " dst_offset: " << dst_offset
|
|
||||||
<< "\n";
|
|
||||||
PBD::stacktrace (cerr, 30);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,18 +290,34 @@ MidiBuffer::reserve(TimeType time, Evoral::EventType event_type, size_t size)
|
||||||
return write_loc;
|
return write_loc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiBuffer::silence (samplecnt_t /*nframes*/, samplecnt_t /*offset*/)
|
MidiBuffer::clear ()
|
||||||
{
|
{
|
||||||
/* XXX iterate over existing events, find all in range given by offset & nframes,
|
|
||||||
and delete them.
|
|
||||||
*/
|
|
||||||
|
|
||||||
_size = 0;
|
_size = 0;
|
||||||
_silent = true;
|
_silent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MidiBuffer::silence (samplecnt_t nframes, samplecnt_t offset)
|
||||||
|
{
|
||||||
|
/* iterate over existing events, find all in range given by offset & nframes,
|
||||||
|
* and delete them.
|
||||||
|
*/
|
||||||
|
if (nframes == _capacity && offset == 0) {
|
||||||
|
MidiBuffer::clear ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (MidiBuffer::iterator i = begin(); i != end();) {
|
||||||
|
const Evoral::Event<TimeType> ev(*i, false);
|
||||||
|
if (ev.time() >= offset && ev.time() < nframes + offset) {
|
||||||
|
i = erase (i);
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MidiBuffer::second_simultaneous_midi_byte_is_first (uint8_t a, uint8_t b)
|
MidiBuffer::second_simultaneous_midi_byte_is_first (uint8_t a, uint8_t b)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue