Make MIDI disk-reader a bit less buggy :)
* use start/end frame * differentiate nframes and disk_samples_to_consume * add global Port::port_offset () when writing data. * add a note about b0rked vari-speed ..
This commit is contained in:
parent
eb0dded095
commit
93d11d155c
@ -149,7 +149,7 @@ class LIBARDOUR_API DiskReader : public DiskIOProcessor
|
|||||||
|
|
||||||
sampleoffset_t calculate_playback_distance (pframes_t);
|
sampleoffset_t calculate_playback_distance (pframes_t);
|
||||||
|
|
||||||
void get_midi_playback (MidiBuffer& dst, samplecnt_t nframes, MonitorState, BufferSet&, double speed, samplecnt_t distance);
|
void get_midi_playback (MidiBuffer& dst, samplepos_t start_sample, samplepos_t end_sample, MonitorState, BufferSet&, double speed, samplecnt_t distance);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -416,7 +416,7 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((ms & MonitoringDisk) && !still_locating) {
|
if ((ms & MonitoringDisk) && !still_locating) {
|
||||||
get_midi_playback (*dst, disk_samples_to_consume, ms, scratch_bufs, speed, disk_samples_to_consume);
|
get_midi_playback (*dst, start_sample, end_sample, ms, scratch_bufs, speed, disk_samples_to_consume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1243,25 +1243,26 @@ DiskReader::resolve_tracker (Evoral::EventSink<samplepos_t>& buffer, samplepos_t
|
|||||||
* so that an event at playback_sample has time = 0
|
* so that an event at playback_sample has time = 0
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
DiskReader::get_midi_playback (MidiBuffer& dst, samplecnt_t nframes, MonitorState ms, BufferSet& scratch_bufs, double speed, samplecnt_t disk_samples_to_consume)
|
DiskReader::get_midi_playback (MidiBuffer& dst, samplepos_t start_sample, samplepos_t end_sample, MonitorState ms, BufferSet& scratch_bufs, double speed, samplecnt_t disk_samples_to_consume)
|
||||||
{
|
{
|
||||||
MidiBuffer* target;
|
MidiBuffer* target;
|
||||||
|
samplepos_t nframes = end_sample - start_sample;
|
||||||
|
|
||||||
if ((ms & MonitoringInput) == 0) {
|
if ((ms & MonitoringInput) == 0) {
|
||||||
dst.clear();
|
/* Route::process_output_buffers() clears the buffer as-needed */
|
||||||
target = &dst;
|
target = &dst;
|
||||||
} else {
|
} else {
|
||||||
target = &scratch_bufs.get_midi (0);
|
target = &scratch_bufs.get_midi (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ms & MonitoringDisk) {
|
if (ms & MonitoringDisk) {
|
||||||
/* no disk data needed */
|
/* disk data needed */
|
||||||
|
|
||||||
Location* loc = loop_location;
|
Location* loc = loop_location;
|
||||||
|
|
||||||
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
|
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
|
||||||
"%1 MDS pre-read read %8 offset = %9 @ %4..%5 from %2 write to %3, LOOPED ? %6 .. %7\n", _name,
|
"%1 MDS pre-read read %8 offset = %9 @ %4..%5 from %2 write to %3, LOOPED ? %6 .. %7\n", _name,
|
||||||
_midi_buf->get_read_ptr(), _midi_buf->get_write_ptr(), playback_sample, playback_sample + nframes,
|
_midi_buf->get_read_ptr(), _midi_buf->get_write_ptr(), start_sample, end_sample,
|
||||||
(loc ? loc->start() : -1), (loc ? loc->end() : -1), nframes, Port::port_offset()));
|
(loc ? loc->start() : -1), (loc ? loc->end() : -1), nframes, Port::port_offset()));
|
||||||
|
|
||||||
//cerr << "======== PRE ========\n";
|
//cerr << "======== PRE ========\n";
|
||||||
@ -1274,7 +1275,7 @@ DiskReader::get_midi_playback (MidiBuffer& dst, samplecnt_t nframes, MonitorStat
|
|||||||
samplepos_t effective_start;
|
samplepos_t effective_start;
|
||||||
|
|
||||||
Evoral::Range<samplepos_t> loop_range (loc->start(), loc->end() - 1);
|
Evoral::Range<samplepos_t> loop_range (loc->start(), loc->end() - 1);
|
||||||
effective_start = loop_range.squish (playback_sample);
|
effective_start = loop_range.squish (start_sample);
|
||||||
|
|
||||||
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("looped, effective start adjusted to %1\n", effective_start));
|
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("looped, effective start adjusted to %1\n", effective_start));
|
||||||
|
|
||||||
@ -1321,12 +1322,12 @@ DiskReader::get_midi_playback (MidiBuffer& dst, samplecnt_t nframes, MonitorStat
|
|||||||
events_read = _midi_buf->read (*target, effective_start, effective_start + nframes);
|
events_read = _midi_buf->read (*target, effective_start, effective_start + nframes);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const size_t n_skipped = _midi_buf->skip_to (playback_sample);
|
const size_t n_skipped = _midi_buf->skip_to (start_sample);
|
||||||
if (n_skipped > 0) {
|
if (n_skipped > 0) {
|
||||||
warning << string_compose(_("MidiDiskstream %1: skipped %2 events, possible underflow"), id(), n_skipped) << endmsg;
|
warning << string_compose(_("MidiDiskstream %1: skipped %2 events, possible underflow"), id(), n_skipped) << endmsg;
|
||||||
}
|
}
|
||||||
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("playback buffer read, from %1 to %2 (%3)", playback_sample, playback_sample + nframes, nframes));
|
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("playback buffer read, from %1 to %2 (%3)", start_sample, end_sample, nframes));
|
||||||
events_read = _midi_buf->read (*target, playback_sample, playback_sample + nframes);
|
events_read = _midi_buf->read (*target, start_sample, end_sample, Port::port_offset ());
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
|
DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
|
||||||
@ -1339,10 +1340,12 @@ DiskReader::get_midi_playback (MidiBuffer& dst, samplecnt_t nframes, MonitorStat
|
|||||||
g_atomic_int_add (&_samples_read_from_ringbuffer, nframes);
|
g_atomic_int_add (&_samples_read_from_ringbuffer, nframes);
|
||||||
|
|
||||||
/* vari-speed */
|
/* vari-speed */
|
||||||
|
|
||||||
if (speed != 0.0 && fabsf (speed) != 1.0f) {
|
if (speed != 0.0 && fabsf (speed) != 1.0f) {
|
||||||
for (MidiBuffer::iterator i = target->begin(); i != target->end(); ++i) {
|
for (MidiBuffer::iterator i = target->begin(); i != target->end(); ++i) {
|
||||||
MidiBuffer::TimeType *tme = i.timeptr();
|
MidiBuffer::TimeType *tme = i.timeptr();
|
||||||
|
// XXX need to subtract port offsets before scaling
|
||||||
|
// also we must only scale events read from disk
|
||||||
|
// and not existing input data in the buffer.
|
||||||
*tme = (*tme) * nframes / disk_samples_to_consume;
|
*tme = (*tme) * nframes / disk_samples_to_consume;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user