#include "pbd/malign.h"
#include "pbd/compose.h"
#include "pbd/debug.h"
+#include "pbd/stacktrace.h"
#include "ardour/debug.h"
#include "ardour/midi_buffer.h"
// FIXME: mirroring for MIDI buffers?
MidiBuffer::MidiBuffer(size_t capacity)
- : Buffer(DataType::MIDI, capacity)
- , _data(0)
+ : Buffer (DataType::MIDI)
+ , _data (0)
{
if (capacity) {
- resize(_capacity);
- silence(_capacity);
+ resize (capacity);
+ silence (capacity);
}
}
void
MidiBuffer::resize(size_t size)
{
- assert(size > 0);
+ if (_data && size < _capacity) {
+
+ if (_size < size) {
+ /* truncate */
+ _size = size;
+ }
- if (size < _capacity) {
return;
}
- free(_data);
+ free (_data);
+
+ cache_aligned_malloc ((void**) &_data, size);
_size = 0;
_capacity = size;
- cache_aligned_malloc ((void**) &_data, _capacity);
assert(_data);
}
if (_size + stamp_size + ev.size() >= _capacity) {
cerr << "MidiBuffer::push_back failed (buffer is full)" << endl;
+ PBD::stacktrace (cerr, 20);
return false;
}
#endif
if (_size + stamp_size + size >= _capacity) {
- cerr << "MidiBuffer::push_back failed (buffer is full)" << endl;
+ cerr << "MidiBuffer::push_back2 failed (buffer is full; _size = " << _size << " capacity "
+ << _capacity << " stamp " << stamp_size << " size = " << size << ")" << endl;
+ PBD::stacktrace (cerr, 20);
return false;
}
}
uint8_t* const write_loc = _data + _size;
- *((TimeType*)write_loc) = time;
+ *(reinterpret_cast<TimeType*>((uintptr_t)write_loc)) = time;
memcpy(write_loc + stamp_size, data, size);
_size += stamp_size + size;
return true;
}
+bool
+MidiBuffer::insert_event(const Evoral::MIDIEvent<TimeType>& ev)
+{
+ if (size() == 0) {
+ return push_back(ev);
+ }
+
+ const size_t stamp_size = sizeof(TimeType);
+ const size_t bytes_to_merge = stamp_size + ev.size();
+
+ if (_size + bytes_to_merge >= _capacity) {
+ cerr << "MidiBuffer::push_back failed (buffer is full)" << endl;
+ PBD::stacktrace (cerr, 20);
+ return false;
+ }
+
+ TimeType t = ev.time();
+
+ ssize_t insert_offset = -1;
+ for (MidiBuffer::iterator m = begin(); m != end(); ++m) {
+ if ((*m).time() < t) {
+ continue;
+ }
+ if ((*m).time() == t) {
+ const uint8_t our_midi_status_byte = *(_data + m.offset + sizeof (TimeType));
+ if (second_simultaneous_midi_byte_is_first (ev.type(), our_midi_status_byte)) {
+ continue;
+ }
+ }
+ insert_offset = m.offset;
+ break;
+ }
+ if (insert_offset == -1) {
+ return push_back(ev);
+ }
+
+ // don't use memmove - it may use malloc(!)
+ // memmove (_data + insert_offset + bytes_to_merge, _data + insert_offset, _size - insert_offset);
+ for (ssize_t a = _size + bytes_to_merge - 1, b = _size - 1; b >= insert_offset; --b, --a) {
+ _data[a] = _data[b];
+ }
+
+ 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());
+
+ _size += bytes_to_merge;
+
+ return true;
+}
+
/** Reserve space for a new event in the buffer.
*
* This call is for copying MIDI directly into the buffer, the data location
// write timestamp
uint8_t* write_loc = _data + _size;
- *((TimeType*)write_loc) = time;
+ *(reinterpret_cast<TimeType*>((uintptr_t)write_loc)) = time;
// move write_loc to begin of MIDI buffer data to write to
write_loc += stamp_size;