X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fmidi_buffer.cc;h=7f79262b2fdd35a5bea3910fe78a767a3fb200cb;hb=8a128b33d38172ae525ac798c53bc105bc4e2c64;hp=1a6cb7fa2612d4fc461d8a3b28c88bce2b10728c;hpb=d1cc7e5a50e2144d7aea01bc5eceed6657513c1b;p=ardour.git diff --git a/libs/ardour/midi_buffer.cc b/libs/ardour/midi_buffer.cc index 1a6cb7fa26..7f79262b2f 100644 --- a/libs/ardour/midi_buffer.cc +++ b/libs/ardour/midi_buffer.cc @@ -190,7 +190,7 @@ MidiBuffer::push_back(TimeType time, size_t size, const uint8_t* data) } uint8_t* const write_loc = _data + _size; - *((TimeType*)write_loc) = time; + *(reinterpret_cast((uintptr_t)write_loc)) = time; memcpy(write_loc + stamp_size, data, size); _size += stamp_size + size; @@ -199,6 +199,57 @@ MidiBuffer::push_back(TimeType time, size_t size, const uint8_t* data) return true; } +bool +MidiBuffer::insert_event(const Evoral::MIDIEvent& 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((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 @@ -216,7 +267,7 @@ MidiBuffer::reserve(TimeType time, size_t size) // write timestamp uint8_t* write_loc = _data + _size; - *((TimeType*)write_loc) = time; + *(reinterpret_cast((uintptr_t)write_loc)) = time; // move write_loc to begin of MIDI buffer data to write to write_loc += stamp_size;