(full commit): fix MIDI playback by not writing into the playback buffer from MidiDiskStream::process() unless recording. This has a negative impact on "monitoring" MIDI, but that needs a different, somewhat more expansive solution anyway

git-svn-id: svn://localhost/ardour2/branches/3.0@5685 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2009-09-21 15:43:11 +00:00
parent 378a90b345
commit ddf532a655
4 changed files with 28 additions and 33 deletions

View File

@ -599,7 +599,6 @@ MidiDiskstream::process (nframes_t transport_frame, nframes_t nframes, bool can_
nframes_t rec_nframes = 0;
bool nominally_recording;
bool re = record_enabled ();
bool collect_playback = true;
/* if we've already processed the frames corresponding to this call,
just return. this allows multiple routes that are taking input
@ -700,6 +699,10 @@ 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 {
@ -722,36 +725,14 @@ MidiDiskstream::process (nframes_t transport_frame, nframes_t nframes, bool can_
} else if (nominally_recording) {
/* can't do actual capture yet - waiting for latency effects to finish before we start*/
/* XXXX do this for MIDI !!!
can't do actual capture yet - waiting for latency effects to finish before we start
*/
playback_distance = nframes;
collect_playback = false;
}
if (collect_playback) {
/* we're doing playback */
nframes_t necessary_samples;
/* no varispeed playback if we're recording, because the output .... TBD */
if (rec_nframes == 0 && _actual_speed != 1.0f) {
necessary_samples = (nframes_t) floor ((nframes * fabs (_actual_speed))) + 1;
} else {
necessary_samples = nframes;
}
// Pump entire port buffer into playback buffer (FIXME: split cycles?)
MidiBuffer& buf = _source_port->get_midi_buffer(nframes);
for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
const Evoral::MIDIEvent<MidiBuffer::TimeType> ev(*i, false);
assert(ev.buffer());
_playback_buf->write(ev.time() + transport_frame, ev.type(), ev.size(), ev.buffer());
}
}
ret = 0;
_processed = true;
@ -1647,7 +1628,6 @@ MidiDiskstream::get_playback (MidiBuffer& dst, nframes_t start, nframes_t end)
// Translates stamps to be relative to start
_playback_buf->read(dst, start, end);
#if 0

View File

@ -80,7 +80,7 @@ MidiRingBuffer<T>::read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes
if (is_channel_event(status) && get_channel_mode() == FilterChannels) {
const uint8_t channel = status & 0x0F;
if (!(get_channel_mask() & (1L << channel))) {
//cerr << "MRB skipping event due to channel mask" << endl;
// cerr << "MRB skipping event due to channel mask" << endl;
this->skip(ev_size); // Advance read pointer to next event
continue;
}
@ -93,7 +93,7 @@ MidiRingBuffer<T>::read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes
// write the timestamp to address (write_loc - 1)
uint8_t* write_loc = dst.reserve(ev_time, ev_size);
if (write_loc == NULL) {
cerr << "MRB: Unable to reserve space in buffer, event skipped";
// cerr << "MRB: Unable to reserve space in buffer, event skipped";
continue;
}

View File

@ -138,13 +138,13 @@ MidiSource::midi_read (MidiRingBuffer<nframes_t>& dst, sframes_t source_start,
Evoral::Sequence<double>::const_iterator& i = _model_iter;
// if (_last_read_end == 0 || start != _last_read_end || !i.valid()) {
if (_last_read_end == 0 || start != _last_read_end || !i.valid()) {
for (i = _model->begin(); i != _model->end(); ++i) {
if (BEATS_TO_FRAMES(i->time()) >= start) {
break;
}
}
// }
}
_last_read_end = start + cnt;

View File

@ -118,7 +118,7 @@ SMFSource::read_unlocked (MidiRingBuffer<nframes_t>& destination, sframes_t sour
const uint64_t start_ticks = (uint64_t)(converter.from(start) * ppqn());
// if (_smf_last_read_end == 0 || start != _smf_last_read_end) {
if (_smf_last_read_end == 0 || start != _smf_last_read_end) {
//cerr << "SMFSource::read_unlocked seeking to " << start << endl;
Evoral::SMF::seek_to_start();
while (time < start_ticks) {
@ -129,7 +129,7 @@ SMFSource::read_unlocked (MidiRingBuffer<nframes_t>& destination, sframes_t sour
}
time += ev_delta_t; // accumulate delta time
}
// }
}
_smf_last_read_end = start + duration;
@ -147,15 +147,30 @@ SMFSource::read_unlocked (MidiRingBuffer<nframes_t>& destination, sframes_t sour
ev_type = EventTypeMap::instance().midi_event_type(ev_buffer[0]);
#if 0
cerr << "+++ SMF source read "
<< " delta = " << ev_delta_t
<< " time = " << time
<< " buf[0] " << hex << (int) ev_buffer[0] << dec
<< " type = " << ev_type;
#endif
assert(time >= start_ticks);
const sframes_t ev_frame_time = converter.to(time / (double)ppqn()) + stamp_offset;
#if 0
cerr << " frames = " << ev_frame_time
<< " w/offset = " << ev_frame_time - negative_stamp_offset
<< endl;
#endif
if (ev_frame_time < start + duration) {
destination.write(ev_frame_time - negative_stamp_offset, ev_type, ev_size, ev_buffer);
} else {
break;
}
_read_data_count += ev_size;
if (ev_size > scratch_size) {