13
0

move ownership of an RT MIDI buffer from DiskIO to MidiPlaylist

This commit is contained in:
Paul Davis 2019-10-17 23:15:53 -06:00
parent 5c0fd05c52
commit addebc3240
8 changed files with 63 additions and 34 deletions

View File

@ -191,8 +191,6 @@ protected:
gint _samples_written_to_ringbuffer;
gint _samples_read_from_ringbuffer;
RTMidiBuffer _mbuf;
static void get_location_times (const Location* location, samplepos_t* start, samplepos_t* end, samplepos_t* length);
};

View File

@ -189,6 +189,8 @@ private:
sampleoffset_t calculate_playback_distance (pframes_t);
RTMidiBuffer* rt_midibuffer();
void get_midi_playback (MidiBuffer& dst, samplepos_t start_sample, samplepos_t end_sample, MonitorState, BufferSet&, double speed, samplecnt_t distance);
};

View File

@ -36,6 +36,7 @@
#include "ardour/playlist.h"
#include "evoral/Note.hpp"
#include "evoral/Parameter.hpp"
#include "ardour/rt_midibuffer.h"
namespace Evoral {
template<typename Time> class EventSink;
@ -48,7 +49,6 @@ namespace ARDOUR
class BeatsSamplesConverter;
class MidiChannelFilter;
class MidiRegion;
class RTMidiBuffer;
class Session;
class Source;
@ -89,7 +89,8 @@ public:
uint32_t chan_n = 0,
MidiChannelFilter* filter = NULL);
void render (RTMidiBuffer&, MidiChannelFilter*);
void render (MidiChannelFilter*);
RTMidiBuffer* rendered();
int set_state (const XMLNode&, int version);
@ -131,6 +132,8 @@ private:
NoteTrackers _note_trackers;
NoteMode _note_mode;
samplepos_t _read_end;
RTMidiBuffer _rendered;
};
} /* namespace ARDOUR */

View File

@ -42,7 +42,7 @@ class LIBARDOUR_API RTMidiBuffer : public Evoral::EventSink<samplepos_t>
public:
typedef samplepos_t TimeType;
RTMidiBuffer (size_t capacity);
RTMidiBuffer ();
~RTMidiBuffer();
void clear();

View File

@ -59,7 +59,6 @@ DiskIOProcessor::DiskIOProcessor (Session& s, string const & str, Flag f)
, _midi_buf (0)
, _samples_written_to_ringbuffer (0)
, _samples_read_from_ringbuffer (0)
, _mbuf (0)
{
set_display_to_user (false);
}
@ -190,7 +189,6 @@ DiskIOProcessor::configure_io (ChanCount in, ChanCount out)
if (in.n_midi() > 0 && !_midi_buf) {
const size_t size = _session.butler()->midi_diskstream_buffer_size();
_midi_buf = new MidiRingBuffer<samplepos_t>(size);
_mbuf.resize (1048576);
changed = true;
}

View File

@ -523,13 +523,16 @@ DiskReader::overwrite_existing_buffers ()
midi:
if (_playlists[DataType::MIDI]) {
RTMidiBuffer* mbuf = rt_midibuffer ();
if (mbuf) {
PBD::Timing minsert;
minsert.start();
midi_playlist()->render (_mbuf, 0);
midi_playlist()->render (0);
minsert.update();
//cerr << "Reading " << name() << " took " << minsert.elapsed() << " microseconds, final size = " << _mbuf.size() << endl;
assert (midi_playlist()->rendered());
//cerr << "Reading " << name() << " took " << minsert.elapsed() << " microseconds, final size = " << midi_playlist()->rendered()->size() << endl;
//midi_playlist()->rendered()->dump (100);
}
g_atomic_int_set (&_pending_overwrite, 0);
@ -1074,7 +1077,9 @@ DiskReader::get_midi_playback (MidiBuffer& dst, samplepos_t start_sample, sample
MidiBuffer* target;
samplepos_t nframes = ::llabs (end_sample - start_sample);
if (_mbuf.size() == 0) {
RTMidiBuffer* mbuf = rt_midibuffer();
if (!mbuf || (mbuf->size() == 0)) {
/* no data to read, so do nothing */
return;
}
@ -1086,14 +1091,14 @@ DiskReader::get_midi_playback (MidiBuffer& dst, samplepos_t start_sample, sample
target = &scratch_bufs.get_midi (0);
}
size_t events_read = 0;
if (!pending_overwrite() && (ms & MonitoringDisk)) {
/* disk data needed */
Location* loc = _loop_location;
size_t events_read = 0;
if (loc) {
samplepos_t effective_start;
@ -1130,23 +1135,23 @@ DiskReader::get_midi_playback (MidiBuffer& dst, samplepos_t start_sample, sample
if (first) {
DEBUG_TRACE (DEBUG::MidiDiskIO, string_compose ("loop read #1, from %1 for %2\n",
effective_start, first));
events_read = _mbuf.read (*target, effective_start, effective_start + first, _tracker);
events_read = mbuf->read (*target, effective_start, effective_start + first, _tracker);
}
if (second) {
DEBUG_TRACE (DEBUG::MidiDiskIO, string_compose ("loop read #2, from %1 for %2\n",
loc->start(), second));
events_read += _mbuf.read (*target, loc->start(), loc->start() + second, _tracker);
events_read += mbuf->read (*target, loc->start(), loc->start() + second, _tracker);
}
} else {
DEBUG_TRACE (DEBUG::MidiDiskIO, string_compose ("loop read #3, adjusted start as %1 for %2\n",
effective_start, nframes));
events_read = _mbuf.read (*target, effective_start, effective_start + nframes, _tracker);
events_read = mbuf->read (*target, effective_start, effective_start + nframes, _tracker);
}
} else {
DEBUG_TRACE (DEBUG::MidiDiskIO, string_compose ("playback buffer read, from %1 to %2 (%3)", start_sample, end_sample, nframes));
events_read = _mbuf.read (*target, start_sample, end_sample, _tracker, Port::port_offset ());
events_read = mbuf->read (*target, start_sample, end_sample, _tracker, Port::port_offset ());
}
DEBUG_TRACE (DEBUG::MidiDiskIO, string_compose ("%1 MDS events read %2 range %3 .. %4\n", _name, events_read, playback_sample, playback_sample + nframes));
@ -1258,3 +1263,22 @@ DiskReader::DeclickAmp::apply_gain (AudioBuffer& buf, samplecnt_t n_samples, con
_g = g;
}
}
RTMidiBuffer*
DiskReader::rt_midibuffer ()
{
boost::shared_ptr<Playlist> pl = _playlists[DataType::MIDI];
if (!pl) {
return 0;
}
boost::shared_ptr<MidiPlaylist> mpl = boost::dynamic_pointer_cast<MidiPlaylist> (pl);
if (!mpl) {
/* error, but whatever ... */
return 0;
}
return mpl->rendered();
}

View File

@ -467,7 +467,7 @@ MidiPlaylist::contained_automation()
}
void
MidiPlaylist::render (RTMidiBuffer& dst, MidiChannelFilter* filter)
MidiPlaylist::render (MidiChannelFilter* filter)
{
typedef pair<MidiStateTracker*,samplepos_t> TrackerInfo;
@ -488,19 +488,19 @@ MidiPlaylist::render (RTMidiBuffer& dst, MidiChannelFilter* filter)
regs.push_back (*i);
}
/* If we are reading from a single region, we can read directly into dst. Otherwise,
we read into a temporarily list, sort it, then write that to dst.
/* If we are reading from a single region, we can read directly into _rendered. Otherwise,
we read into a temporarily list, sort it, then write that to _rendered.
*/
Evoral::EventList<samplepos_t> evlist;
Evoral::EventSink<samplepos_t>* tgt;
/* RAII */
RTMidiBuffer::WriteProtectRender wpr (dst);
RTMidiBuffer::WriteProtectRender wpr (_rendered);
if (regs.size() == 1) {
tgt = &dst;
tgt = &_rendered;
wpr.acquire ();
dst.clear ();
_rendered.clear ();
} else {
tgt = &evlist;
}
@ -524,14 +524,14 @@ MidiPlaylist::render (RTMidiBuffer& dst, MidiChannelFilter* filter)
EventsSortByTimeAndType<samplepos_t> cmp;
evlist.sort (cmp);
/* Copy ordered events from event list to dst. */
/* Copy ordered events from event list to _rendered. */
wpr.acquire ();
dst.clear ();
_rendered.clear ();
for (Evoral::EventList<samplepos_t>::iterator e = evlist.begin(); e != evlist.end(); ++e) {
Evoral::Event<samplepos_t>* ev (*e);
dst.write (ev->time(), ev->event_type(), ev->size(), ev->buffer());
_rendered.write (ev->time(), ev->event_type(), ev->size(), ev->buffer());
delete ev;
}
}
@ -539,5 +539,11 @@ MidiPlaylist::render (RTMidiBuffer& dst, MidiChannelFilter* filter)
/* no need to release - RAII with WriteProtectRender takes care of it */
DEBUG_TRACE (DEBUG::MidiPlaylistIO, "---- End MidiPlaylist::dump ----\n");
DEBUG_TRACE (DEBUG::MidiPlaylistIO, string_compose ("---- End MidiPlaylist::render, events: %1\n", _rendered.size()));
}
RTMidiBuffer*
MidiPlaylist::rendered ()
{
return &_rendered;
}

View File

@ -35,7 +35,7 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
RTMidiBuffer::RTMidiBuffer (size_t capacity)
RTMidiBuffer::RTMidiBuffer ()
: _size (0)
, _capacity (0)
, _data (0)
@ -43,9 +43,6 @@ RTMidiBuffer::RTMidiBuffer (size_t capacity)
, _pool_capacity (0)
, _pool (0)
{
if (capacity) {
resize (capacity);
}
}
RTMidiBuffer::~RTMidiBuffer()
@ -102,16 +99,17 @@ RTMidiBuffer::dump (uint32_t cnt)
} else {
/* MIDI data is in bytes[1..3] (variable depending on message type */
size = Evoral::midi_event_size (item->bytes[1]);
addr = &item->bytes[1];
}
cerr << "@ " << item->timestamp << " sz=" << size << '\t';
cerr << i << " @ " << item->timestamp << " sz=" << size << '\t';
cerr << hex;
for (size_t j =0 ; j < size; ++j) {
cerr << "0x" << hex << (int)addr[j] << dec << '/' << (int)addr[i] << ' ';
cerr << "0x" << hex << (int)addr[j] << dec << '/' << (int)addr[j] << ' ';
}
cerr << dec << endl;
}
@ -184,7 +182,7 @@ RTMidiBuffer::read (MidiBuffer& dst, samplepos_t start, samplepos_t end, MidiSta
TimeType unadjusted_time;
#endif
DEBUG_TRACE (DEBUG::MidiRingBuffer, string_compose ("read from %1 .. %2 .. initial index = %3 (time = %4)\n", start, end, item, item->timestamp));
DEBUG_TRACE (DEBUG::MidiRingBuffer, string_compose ("read from %1 .. %2 .. initial index = %3 (time = %4) (range in list of %7 %5..%6)\n", start, end, item - _data, item->timestamp, _data->timestamp, iend->timestamp, _size));
while ((item < iend) && (item->timestamp < end)) {