From 44ac5f5097af43ec6bf60489d73a532f43702bf3 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 1 Feb 2009 21:04:12 +0000 Subject: Removed fixed/maximum event size assumption/limitation from MIDI buffer. git-svn-id: svn://localhost/ardour2/branches/3.0@4471 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/midi_buffer.cc | 169 ++++++++++++--------------------------------- 1 file changed, 43 insertions(+), 126 deletions(-) (limited to 'libs/ardour/midi_buffer.cc') diff --git a/libs/ardour/midi_buffer.cc b/libs/ardour/midi_buffer.cc index 51f7dd43e6..df4ee13558 100644 --- a/libs/ardour/midi_buffer.cc +++ b/libs/ardour/midi_buffer.cc @@ -33,7 +33,7 @@ using namespace ARDOUR; // FIXME: mirroring for MIDI buffers? MidiBuffer::MidiBuffer(size_t capacity) : Buffer(DataType::MIDI, capacity) - , _events(0) + , _size(0) , _data(0) { if (capacity) { @@ -44,12 +44,7 @@ MidiBuffer::MidiBuffer(size_t capacity) MidiBuffer::~MidiBuffer() { - if (_events) { - free(_events); - } - if (_data) { - free(_data); - } + free(_data); } void @@ -62,30 +57,24 @@ MidiBuffer::resize(size_t size) } free(_data); - free(_events); _size = 0; _capacity = size; #ifdef NO_POSIX_MEMALIGN - _events = (Evoral::MIDIEvent *) malloc(sizeof(Evoral::MIDIEvent) * _capacity); - _data = (uint8_t *) malloc(sizeof(uint8_t) * _capacity * MAX_EVENT_SIZE); + _data = (uint8_t*)malloc(_capacity); #else - 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); + posix_memalign((void**)&_data, CPU_CACHE_ALIGN, _capacity); #endif assert(_data); - assert(_events); } void MidiBuffer::copy(const MidiBuffer& copy) { - assert(_capacity >= copy._capacity); - _size = 0; - - for (size_t i = 0; i < copy.size(); ++i) - push_back(copy[i]); + assert(_capacity >= copy._size); + _size = copy._size; + memcpy(_data, copy._data, copy._size); } @@ -109,11 +98,11 @@ MidiBuffer::read_from(const Buffer& src, nframes_t nframes, nframes_t offset) assert(_size == 0); } - // FIXME: slow - for (size_t i = 0; i < msrc.size(); ++i) { - const Evoral::MIDIEvent& ev = msrc[i]; - //cout << "MidiBuffer::read_from event type: " << int(ev.type()) - // << " time: " << ev.time() << " buffer size: " << _size << endl; + for (MidiBuffer::const_iterator i = msrc.begin(); i != msrc.end(); ++i) { + const Evoral::MIDIEvent ev(*i, false); + /*cout << this << " MidiBuffer::read_from event type: " << int(ev.type()) + << " time: " << ev.time() << " size: " << ev.size() + << " status: " << (int)*ev.buffer() << " buffer size: " << _size << endl;*/ if (ev.time() < offset) { //cout << "MidiBuffer::read_from skipped event before " << offset << endl; } else if (ev.time() < (nframes + offset)) { @@ -139,27 +128,19 @@ MidiBuffer::read_from(const Buffer& src, nframes_t nframes, nframes_t offset) bool MidiBuffer::push_back(const Evoral::MIDIEvent& ev) { - if (_size == _capacity) { + const size_t stamp_size = sizeof(Evoral::EventTime); + if (_size + stamp_size + ev.size() >= _capacity) { cerr << "MidiBuffer::push_back failed (buffer is full)" << endl; return false; } - uint8_t* const write_loc = _data + (_size * MAX_EVENT_SIZE); + uint8_t* const write_loc = _data + _size; + *((Evoral::EventTime*)write_loc) = ev.time(); + memcpy(write_loc + stamp_size, ev.buffer(), ev.size()); - memcpy(write_loc, ev.buffer(), ev.size()); - _events[_size] = ev; - _events[_size].set_buffer(ev.size(), write_loc, false); - - /*cerr << "MidiBuffer: pushed @ " << _events[_size].time() - << " size = " << _size << endl; - for (size_t i = 0; i < _events[_size].size(); ++i) { - printf("%X ", _events[_size].buffer()[i]); - } - printf("\n");*/ - - ++_size; + _size += stamp_size + ev.size(); _silent = false; - + return true; } @@ -174,27 +155,19 @@ MidiBuffer::push_back(const Evoral::MIDIEvent& ev) bool MidiBuffer::push_back(const jack_midi_event_t& ev) { - if (_size == _capacity) { + const size_t stamp_size = sizeof(Evoral::EventTime); + if (_size + stamp_size + ev.size >= _capacity) { cerr << "MidiBuffer::push_back failed (buffer is full)" << endl; return false; } - uint8_t* const write_loc = _data + (_size * MAX_EVENT_SIZE); + uint8_t* const write_loc = _data + _size; + *((Evoral::EventTime*)write_loc) = ev.time; + memcpy(write_loc + stamp_size, ev.buffer, ev.size); - memcpy(write_loc, ev.buffer, ev.size); - _events[_size].time() = (double)ev.time; - _events[_size].set_buffer(ev.size, write_loc, false); - - /*cerr << "MidiBuffer: pushed @ " << _events[_size].time() - << " size = " << _size << endl; - for (size_t i = 0; i < _events[_size].size(); ++i) { - printf("%X ", _events[_size].buffer()[i]); - } - printf("\n");*/ - - ++_size; + _size += stamp_size + ev.size; _silent = false; - + return true; } @@ -207,27 +180,19 @@ MidiBuffer::push_back(const jack_midi_event_t& ev) * location, or the buffer will be corrupted and very nasty things will happen. */ uint8_t* -MidiBuffer::reserve(double time, size_t size) +MidiBuffer::reserve(Evoral::EventTime time, size_t size) { - if (size > MAX_EVENT_SIZE) { - cerr << "WARNING: Failed to reserve " << size << " bytes for event"; + const size_t stamp_size = sizeof(Evoral::EventTime); + if (_size + stamp_size + size >= _capacity) { return 0; } - if (_size == _capacity) { - return 0; - } - - uint8_t* const write_loc = _data + (_size * MAX_EVENT_SIZE); - - _events[_size].time() = time; - _events[_size].set_buffer(size, write_loc, false); - ++_size; - - //cerr << "MidiBuffer: reserved, size = " << _size << endl; + uint8_t* const write_loc = _data + _size; + *((Evoral::EventTime*)write_loc) = time; + _size += stamp_size + size; _silent = false; - + return write_loc; } @@ -239,12 +204,11 @@ MidiBuffer::silence(nframes_t dur, nframes_t offset) if (offset != 0) cerr << "WARNING: MidiBuffer::silence w/ offset != 0 (not implemented)" << endl; - memset(_events, 0, sizeof(Evoral::Event) * _capacity); - memset(_data, 0, sizeof(uint8_t) * _capacity * MAX_EVENT_SIZE); _size = 0; _silent = true; } +/** Merge \a other into this buffer. Realtime safe. */ bool MidiBuffer::merge_in_place(const MidiBuffer &other) { @@ -252,36 +216,21 @@ MidiBuffer::merge_in_place(const MidiBuffer &other) return true; } - if (this->size() == 0) { + if (_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; + if (_size + other.size() > _capacity) { + cerr << "MidiBuffer::merge failed (no space)" << endl; + return false; } + + cerr << "FIXME: MIDI BUFFER IN-PLACE MERGE" << endl; + return true; } /** Clear, and merge \a a and \a b into this buffer. - * - * FIXME: This is slow. * * \return true if complete merge was successful */ @@ -297,40 +246,8 @@ MidiBuffer::merge(const MidiBuffer& a, const MidiBuffer& 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) { - - if (size() == capacity()) { - cerr << "WARNING: MIDI buffer overrun, events lost!" << endl; - return false; - } - - if (a_index == a.size()) { - push_back(b[b_index]); - ++b_index; - } else if (b_index == b.size()) { - push_back(a[a_index]); - ++a_index; - } else { - 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); - ++a_index; - } else { - push_back(b_ev); - ++b_index; - } - } - - --count; - } - + + cerr << "FIXME: MIDI BUFFER MERGE" << endl; return true; } -- cgit v1.2.3