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
This commit is contained in:
Paul Davis 2009-09-25 05:08:23 +00:00
parent ddf532a655
commit 756fc18394
3 changed files with 57 additions and 6 deletions

View File

@ -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;
}

View File

@ -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 {

View File

@ -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;