diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2009-09-25 05:08:23 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2009-09-25 05:08:23 +0000 |
commit | 756fc1839442ae236083c918ba7c7af30e5f8100 (patch) | |
tree | d69fc81c25827fa70b905c5ca26c7c7f51ec25bb /libs/ardour | |
parent | ddf532a655ea285287d9f0f0419c97cfa2fbb827 (diff) |
implement MidiBuffer::merge_in_place() and use to support MIDI passthrough (control over this feature to be added. historical note: implemented and debugged during keith packard's excellent presentation on X at 25 during LPC2009
git-svn-id: svn://localhost/ardour2/branches/3.0@5686 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/midi_buffer.cc | 53 | ||||
-rw-r--r-- | libs/ardour/midi_diskstream.cc | 4 | ||||
-rw-r--r-- | libs/ardour/midi_track.cc | 6 |
3 files changed, 57 insertions, 6 deletions
diff --git a/libs/ardour/midi_buffer.cc b/libs/ardour/midi_buffer.cc index ae3071a53c..1e049eba72 100644 --- a/libs/ardour/midi_buffer.cc +++ b/libs/ardour/midi_buffer.cc @@ -260,8 +260,57 @@ MidiBuffer::merge_in_place(const MidiBuffer &other) cerr << "MidiBuffer::merge failed (no space)" << endl; return false; } - - cerr << "FIXME: MIDI BUFFER IN-PLACE MERGE" << endl; + + const_iterator them = other.begin(); + iterator us = begin(); + + while (them != other.end()) { + + Evoral::MIDIEvent<TimeType> ev_other (*them); + size_t sz = 0; + size_t src; + + /* gather up total size of events that are earlier than + the event referenced by "us" + */ + + src = 0; + + while (them != other.end() && ev_other.time() < (*us).time()) { + if (!src) { + src = them.offset; + } + sz += sizeof (TimeType) + ev_other.size(); + ++them; + } + + if (sz) { + /* move existing */ + memmove (_data + us.offset + sz, _data + us.offset , _size - us.offset); + /* increase _size */ + _size += sz; + /* insert new stuff */ + memcpy (_data + us.offset, other._data + src, sz); + /* update iterator to our own events. this is a miserable hack */ + us.offset += sz; + } else { + + /* advance past our own events to get to the correct insertion + point for the next event(s) from "other" + */ + + while (us != end() && (*us).time() < ev_other.time()) { + ++us; + } + } + + if (!(us != end())) { + /* just append the rest of other */ + memcpy (_data + us.offset, other._data + them.offset, other._size - them.offset); + break; + } + } + return true; } diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc index e658958b30..97a8fb3044 100644 --- a/libs/ardour/midi_diskstream.cc +++ b/libs/ardour/midi_diskstream.cc @@ -699,10 +699,6 @@ MidiDiskstream::process (nframes_t transport_frame, nframes_t nframes, bool can_ const Evoral::MIDIEvent<MidiBuffer::TimeType> ev(*i, false); assert(ev.buffer()); _capture_buf->write(ev.time() + transport_frame, ev.type(), ev.size(), ev.buffer()); - - /* put it in the playback buffer as well, so that we can monitor */ - - _playback_buf->write(ev.time() + transport_frame, ev.type(), ev.size(), ev.buffer()); } } else { diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index 000143f3d5..4f13682a89 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -32,6 +32,7 @@ #include "ardour/meter.h" #include "ardour/midi_diskstream.h" #include "ardour/midi_playlist.h" +#include "ardour/midi_port.h" #include "ardour/midi_region.h" #include "ardour/midi_source.h" #include "ardour/midi_track.h" @@ -449,6 +450,11 @@ MidiTrack::roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame, write_out_of_band_data (bufs, start_frame, end_frame, nframes); + /* send incoming data "through" output */ + if (_input->n_ports().n_midi()) { + mbuf.merge_in_place (_input->midi(0)->get_midi_buffer(nframes)); + } + // Feed the data through the MidiStateTracker bool did_loop; |