X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fmidi_buffer.cc;h=adad9c35dc454f9b6128d4d7925a3d5b8688c6ea;hb=379ad3357df6cba267b7005aac572d6821487269;hp=dc8deb7727a723ffd1f91e0209a4935db1756bba;hpb=22b07e0233a29d9633ffa825a79503befaf2e16e;p=ardour.git diff --git a/libs/ardour/midi_buffer.cc b/libs/ardour/midi_buffer.cc index dc8deb7727..adad9c35dc 100644 --- a/libs/ardour/midi_buffer.cc +++ b/libs/ardour/midi_buffer.cc @@ -26,6 +26,7 @@ #include "ardour/debug.h" #include "ardour/midi_buffer.h" +#include "ardour/port.h" using namespace std; using namespace ARDOUR; @@ -35,6 +36,7 @@ using namespace PBD; MidiBuffer::MidiBuffer(size_t capacity) : Buffer (DataType::MIDI) , _data (0) + , _size (0) { if (capacity) { resize (capacity); @@ -78,6 +80,14 @@ MidiBuffer::copy(const MidiBuffer& copy) memcpy(_data, copy._data, copy._size); } +void +MidiBuffer::copy(MidiBuffer const * const copy) +{ + assert(_capacity >= copy->size ()); + _size = copy->size (); + memcpy(_data, copy->_data, _size); +} + /** Read events from @a src starting at time @a offset into the START of this buffer, for * time duration @a nframes. Relative time, where 0 = start of buffer. @@ -85,7 +95,7 @@ MidiBuffer::copy(const MidiBuffer& copy) * Note that offset and nframes refer to sample time, NOT buffer offsets or event counts. */ void -MidiBuffer::read_from (const Buffer& src, framecnt_t nframes, framecnt_t dst_offset, framecnt_t src_offset) +MidiBuffer::read_from (const Buffer& src, framecnt_t nframes, frameoffset_t dst_offset, frameoffset_t /* src_offset*/) { assert (src.type() == DataType::MIDI); assert (&src != this); @@ -99,15 +109,40 @@ MidiBuffer::read_from (const Buffer& src, framecnt_t nframes, framecnt_t dst_off assert (_size == 0); } - /* XXX use dst_offset somehow */ - for (MidiBuffer::const_iterator i = msrc.begin(); i != msrc.end(); ++i) { - const Evoral::MIDIEvent ev(*i, false); - if (ev.time() >= src_offset && ev.time() < (nframes+src_offset)) { - push_back (ev); + const Evoral::Event ev(*i, false); + + if (dst_offset >= 0) { + /* Positive offset: shifting events from internal + buffer view of time (always relative to to start of + current possibly split cycle) to from global/port + view of time (always relative to start of process + cycle). + + Check it is within range of this (split) cycle, then shift. + */ + if (ev.time() >= 0 && ev.time() < nframes) { + push_back (ev.time() + dst_offset, ev.size(), ev.buffer()); + } else { + cerr << "\t!!!! MIDI event @ " << ev.time() << " skipped, not within range 0 .. " << nframes << ": "; + } } else { - cerr << "MIDI event @ " << ev.time() << " skipped, not within range " - << src_offset << " .. " << (nframes + src_offset) << endl; + /* Negative offset: shifting events from global/port + view of time (always relative to start of process + cycle) back to internal buffer view of time (always + relative to to start of current possibly split + cycle. + + Shift first, then check it is within range of this + (split) cycle. + */ + const framepos_t evtime = ev.time() + dst_offset; + + if (evtime >= 0 && evtime < nframes) { + push_back (evtime, ev.size(), ev.buffer()); + } else { + cerr << "\t!!!! MIDI event @ " << evtime << " (based on " << ev.time() << " + " << dst_offset << ") skipped, not within range 0 .. " << nframes << ": "; + } } } @@ -115,7 +150,7 @@ MidiBuffer::read_from (const Buffer& src, framecnt_t nframes, framecnt_t dst_off } void -MidiBuffer::merge_from (const Buffer& src, framecnt_t /*nframes*/, framecnt_t /*dst_offset*/, framecnt_t /*src_offset*/) +MidiBuffer::merge_from (const Buffer& src, framecnt_t /*nframes*/, frameoffset_t /*dst_offset*/, frameoffset_t /*src_offset*/) { const MidiBuffer* mbuf = dynamic_cast(&src); assert (mbuf); @@ -133,28 +168,17 @@ MidiBuffer::merge_from (const Buffer& src, framecnt_t /*nframes*/, framecnt_t /* * @return false if operation failed (not enough room) */ bool -MidiBuffer::push_back(const Evoral::MIDIEvent& ev) +MidiBuffer::push_back(const Evoral::Event& ev) { - const size_t stamp_size = sizeof(TimeType); - - if (_size + stamp_size + ev.size() >= _capacity) { - cerr << "MidiBuffer::push_back failed (buffer is full)" << endl; - PBD::stacktrace (cerr, 20); - return false; - } - - if (!Evoral::midi_event_is_valid(ev.buffer(), ev.size())) { - cerr << "WARNING: MidiBuffer ignoring illegal MIDI event" << endl; - return false; - } - - push_back(ev.time(), ev.size(), ev.buffer()); - - return true; + return push_back (ev.time(), ev.size(), ev.buffer()); } -/** Push an event into the buffer. +/** Push MIDI data into the buffer. + * + * Note that the raw MIDI pointed to by @param data will be COPIED and unmodified. + * That is, the caller still owns it, if it needs freeing it's Not My Problem(TM). + * Realtime safe. * @return false if operation failed (not enough room) */ bool @@ -178,14 +202,10 @@ MidiBuffer::push_back(TimeType time, size_t size, const uint8_t* data) #endif if (_size + stamp_size + size >= _capacity) { - cerr << "MidiBuffer::push_back2 failed (buffer is full; _size = " << _size << " capacity " - << _capacity << " stamp " << stamp_size << " size = " << size << ")" << endl; - PBD::stacktrace (cerr, 20); return false; } if (!Evoral::midi_event_is_valid(data, size)) { - cerr << "WARNING: MidiBuffer ignoring illegal MIDI event" << endl; return false; } @@ -200,7 +220,7 @@ MidiBuffer::push_back(TimeType time, size_t size, const uint8_t* data) } bool -MidiBuffer::insert_event(const Evoral::MIDIEvent& ev) +MidiBuffer::insert_event(const Evoral::Event& ev) { if (size() == 0) { return push_back(ev); @@ -253,7 +273,7 @@ MidiBuffer::insert_event(const Evoral::MIDIEvent& ev) uint32_t MidiBuffer::write(TimeType time, Evoral::EventType type, uint32_t size, const uint8_t* buf) { - insert_event(Evoral::MIDIEvent(type, time, size, const_cast(buf))); + insert_event(Evoral::Event(type, time, size, const_cast(buf))); return size; } @@ -581,4 +601,3 @@ MidiBuffer::merge_in_place (const MidiBuffer &other) return true; } -