_capacity = size;
#ifdef NO_POSIX_MEMALIGN
- _events = (MIDI::Event *) malloc(sizeof(MIDI::Event) * _capacity);
- _data = (Byte *) malloc(sizeof(Byte) * _capacity * MAX_EVENT_SIZE);
+ _events = (Evoral::Event *) malloc(sizeof(Evoral::Event) * _capacity);
+ _data = (uint8_t *) malloc(sizeof(uint8_t) * _capacity * MAX_EVENT_SIZE);
#else
- posix_memalign((void**)&_events, CPU_CACHE_ALIGN, sizeof(MIDI::Event) * _capacity);
- posix_memalign((void**)&_data, CPU_CACHE_ALIGN, sizeof(Byte) * _capacity * MAX_EVENT_SIZE);
+ posix_memalign((void**)&_events, CPU_CACHE_ALIGN, sizeof(Evoral::Event) * _capacity);
+ posix_memalign((void**)&_data, CPU_CACHE_ALIGN, sizeof(uint8_t) * _capacity * MAX_EVENT_SIZE);
#endif
assert(_data);
assert(_events);
assert(_capacity >= msrc.size());
- clear();
- assert(_size == 0);
+ if (offset == 0) {
+ clear();
+ assert(_size == 0);
+ }
// FIXME: slow
for (size_t i=0; i < msrc.size(); ++i) {
- const MIDI::Event& ev = msrc[i];
- if (ev.time() >= offset && ev.time() < offset+nframes) {
- //cout << "MidiBuffer::read_from got event, " << ev.time() << endl;
+ const Evoral::MIDIEvent& ev = msrc[i];
+ if (ev.time() < offset)
+ continue;
+ if (ev.time() < (nframes + offset)) {
+ //cout << "MidiBuffer::read_from got event, " << int(ev.type()) << " time: " << ev.time() << " buffer size: " << _size << endl;
push_back(ev);
} else {
cerr << "MidiBuffer event out of range, " << ev.time() << endl;
* @return false if operation failed (not enough room)
*/
bool
-MidiBuffer::push_back(const MIDI::Event& ev)
+MidiBuffer::push_back(const Evoral::MIDIEvent& ev)
{
if (_size == _capacity)
return false;
- Byte* const write_loc = _data + (_size * MAX_EVENT_SIZE);
+ uint8_t* const write_loc = _data + (_size * MAX_EVENT_SIZE);
memcpy(write_loc, ev.buffer(), ev.size());
_events[_size] = ev;
- _events[_size].set_buffer(write_loc, false);
+ _events[_size].set_buffer(ev.size(), write_loc, false);
++_size;
//cerr << "MidiBuffer: pushed, size = " << _size << endl;
if (_size == _capacity)
return false;
- Byte* const write_loc = _data + (_size * MAX_EVENT_SIZE);
+ uint8_t* const write_loc = _data + (_size * MAX_EVENT_SIZE);
memcpy(write_loc, ev.buffer, ev.size);
_events[_size].time() = (double)ev.time;
- _events[_size].size() = ev.size;
- _events[_size].set_buffer(write_loc, false);
+ _events[_size].set_buffer(ev.size, write_loc, false);
++_size;
//cerr << "MidiBuffer: pushed, size = " << _size << endl;
* This call MUST be immediately followed by a write to the returned data
* location, or the buffer will be corrupted and very nasty things will happen.
*/
-Byte*
+uint8_t*
MidiBuffer::reserve(double time, size_t size)
{
- assert(size <= MAX_EVENT_SIZE);
+ if (size > MAX_EVENT_SIZE) {
+ cerr << "WARNING: Failed to reserve " << size << " bytes for event";
+ return 0;
+ }
if (_size == _capacity)
return 0;
- Byte* const write_loc = _data + (_size * MAX_EVENT_SIZE);
+ uint8_t* const write_loc = _data + (_size * MAX_EVENT_SIZE);
_events[_size].time() = time;
- _events[_size].size() = size;
- _events[_size].set_buffer(write_loc, false);
+ _events[_size].set_buffer(size, write_loc, false);
++_size;
//cerr << "MidiBuffer: reserved, size = " << _size << endl;
if (offset != 0)
cerr << "WARNING: MidiBuffer::silence w/ offset != 0 (not implemented)" << endl;
- memset(_events, 0, sizeof(MIDI::Event) * _capacity);
- memset(_data, 0, sizeof(Byte) * _capacity * MAX_EVENT_SIZE);
+ memset(_events, 0, sizeof(Evoral::Event) * _capacity);
+ memset(_data, 0, sizeof(uint8_t) * _capacity * MAX_EVENT_SIZE);
_size = 0;
_silent = true;
}
+bool
+MidiBuffer::merge_in_place( const MidiBuffer &other )
+{
+ if( other.size() == 0 )
+ return true;
+
+ if( this->size() == 0 ) {
+ copy( other );
+ return true;
+ }
+
+ {
+ MidiBuffer merge_buffer( 0 );
+ Evoral::MIDIEvent onstack_events[_capacity];
+ uint8_t onstack_data[_capacity * MAX_EVENT_SIZE];
+ merge_buffer._events = onstack_events;
+ merge_buffer._data = onstack_data;
+ merge_buffer._size = 0;
+
+ bool retval = merge_buffer.merge( *this, other );
+
+ copy( merge_buffer );
+
+ // set pointers to zero again, so destructor
+ // does not end in calling free() for memory
+ // on the stack;
+ merge_buffer._events = 0;
+ merge_buffer._data = 0;
+
+ return retval;
+ }
+}
/** Clear, and merge \a a and \a b into this buffer.
*
{
_size = 0;
- // Die if a merge isn't necessary as it's expensive
- assert(a.size() > 0 && b.size() > 0);
+ // This is mostly the case :(
+ if( this == &a )
+ merge_in_place( b );
+
+ if( this == &b )
+ merge_in_place( a );
size_t a_index = 0;
size_t b_index = 0;
size_t count = a.size() + b.size();
- while (count > 0 && a_index < a.size() && b_index < b.size()) {
+ while (count > 0) {
if (size() == capacity()) {
cerr << "WARNING: MIDI buffer overrun, events lost!" << endl;
}
if (a_index == a.size()) {
- push_back(a[a_index]);
- ++a_index;
- } else if (b_index == b.size()) {
push_back(b[b_index]);
++b_index;
+ } else if (b_index == b.size()) {
+ push_back(a[a_index]);
+ ++a_index;
} else {
- const MIDI::Event& a_ev = a[a_index];
- const MIDI::Event& b_ev = b[b_index];
+ const Evoral::MIDIEvent& a_ev = a[a_index];
+ const Evoral::MIDIEvent& b_ev = b[b_index];
if (a_ev.time() <= b_ev.time()) {
push_back(a_ev);