From 8d05f6d4b788d2f100eb309965d398adc4198045 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 5 Dec 2019 15:01:41 -0700 Subject: initial conversion to double buffering inside DiskReader Second buffer is not used (or allocated) yet. --- libs/ardour/ardour/disk_io.h | 15 ++++++++--- libs/ardour/disk_io.cc | 17 ++++++++++--- libs/ardour/disk_reader.cc | 60 ++++++++++++++++++++++++-------------------- libs/pbd/pbd/debug.h | 1 + 4 files changed, 60 insertions(+), 33 deletions(-) (limited to 'libs') diff --git a/libs/ardour/ardour/disk_io.h b/libs/ardour/ardour/disk_io.h index 1c60a19fc2..43898551a8 100644 --- a/libs/ardour/ardour/disk_io.h +++ b/libs/ardour/ardour/disk_io.h @@ -151,10 +151,19 @@ protected: ChannelInfo (samplecnt_t buffer_size); virtual ~ChannelInfo (); - /** A random-access ringbuffer for data to be played back. - * written to in the butler thread, read from in the process thread. + /** A pair of random-access ringbuffers for data to be played back. + * written to in the butler thread, read from in the process + * thread. + * + * */ - PBD::PlaybackBuffer* rbuf; + PBD::PlaybackBuffer* _rbuf[2]; + /* This returns a pointer to the correct PlaybackBuffer to use + for reading from within process context. + */ + PBD::PlaybackBuffer* rbuf(); + gint current_rbuf; + gint read_switch_rbuf; /** A ringbuffer for data to be recorded back, written to in the * process thread, read from in the butler thread. diff --git a/libs/ardour/disk_io.cc b/libs/ardour/disk_io.cc index a55e2c559b..cd41f78505 100644 --- a/libs/ardour/disk_io.cc +++ b/libs/ardour/disk_io.cc @@ -324,23 +324,34 @@ DiskIOProcessor::use_playlist (DataType dt, boost::shared_ptr playlist } DiskIOProcessor::ChannelInfo::ChannelInfo (samplecnt_t bufsize) - : rbuf (0) + : current_rbuf (0) + , read_switch_rbuf (0) , wbuf (0) , capture_transition_buf (0) , curr_capture_cnt (0) { + _rbuf[0] = 0; + _rbuf[1] = 0; } DiskIOProcessor::ChannelInfo::~ChannelInfo () { - delete rbuf; + delete _rbuf[0]; + delete _rbuf[1]; delete wbuf; delete capture_transition_buf; - rbuf = 0; + _rbuf[0] = 0; + _rbuf[1] = 0; wbuf = 0; capture_transition_buf = 0; } +PlaybackBuffer* +DiskIOProcessor::ChannelInfo::rbuf() +{ + return _rbuf[0]; +} + void DiskIOProcessor::drop_track () { diff --git a/libs/ardour/disk_reader.cc b/libs/ardour/disk_reader.cc index f97f9f3fc3..3e1db0e94f 100644 --- a/libs/ardour/disk_reader.cc +++ b/libs/ardour/disk_reader.cc @@ -79,10 +79,16 @@ DiskReader::~DiskReader () void DiskReader::ReaderChannelInfo::resize (samplecnt_t bufsize) { - delete rbuf; - rbuf = new PlaybackBuffer (bufsize); + delete _rbuf[0]; _rbuf[0] = 0; + delete _rbuf[1]; _rbuf[1] = 0; + + _rbuf[0] = new PlaybackBuffer (bufsize); /* touch memory to lock it */ - memset (rbuf->buffer(), 0, sizeof (Sample) * rbuf->bufsize()); + memset (_rbuf[0]->buffer(), 0, sizeof (Sample) * _rbuf[0]->bufsize()); + g_atomic_int_set (¤t_rbuf, 0); + g_atomic_int_set (&read_switch_rbuf, 0); + + /* the alternate rbuf is lazily allocated in ::overwrite_existing_buffers() */ } void @@ -106,8 +112,8 @@ DiskReader::add_channel_to (boost::shared_ptr c, uint32_t how_many) c->push_back (new ReaderChannelInfo (_session.butler()->audio_diskstream_playback_buffer_size(), loop_fade_length)); DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1: new reader channel, write space = %2 read = %3\n", name(), - c->back()->rbuf->write_space(), - c->back()->rbuf->read_space())); + c->back()->rbuf()->write_space(), + c->back()->rbuf()->read_space())); } return 0; @@ -216,7 +222,7 @@ DiskReader::buffer_load () const return 1.0; } - PBD::PlaybackBuffer* b = c->front()->rbuf; + PBD::PlaybackBuffer* b = c->front()->rbuf(); return (float) ((double) b->read_space() / (double) b->bufsize()); } @@ -337,7 +343,7 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp if (!still_locating || _no_disk_output) { for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - (*chan)->rbuf->increment_read_ptr (disk_samples_to_consume); + (*chan)->rbuf()->increment_read_ptr (disk_samples_to_consume); } } @@ -386,7 +392,7 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp if (!declick_out) { - const samplecnt_t total = chaninfo->rbuf->read (disk_buf.data(), disk_samples_to_consume); + const samplecnt_t total = chaninfo->rbuf()->read (disk_buf.data(), disk_samples_to_consume); if (disk_samples_to_consume > total) { cerr << _name << " Need " << total << " have only " << disk_samples_to_consume << endl; @@ -410,7 +416,7 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp to ::run() */ - const samplecnt_t total = chaninfo->rbuf->read (disk_buf.data(), nframes, false, declick_offs); + const samplecnt_t total = chaninfo->rbuf()->read (disk_buf.data(), nframes, false, declick_offs); if (n == 0) { _declick_offs += total; @@ -470,13 +476,13 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp if (_playlists[DataType::AUDIO]) { if (!c->empty()) { if (_slaved) { - if (c->front()->rbuf->write_space() >= c->front()->rbuf->bufsize() / 2) { - DEBUG_TRACE (DEBUG::Butler, string_compose ("%1: slaved, write space = %2 of %3\n", name(), c->front()->rbuf->write_space(), c->front()->rbuf->bufsize())); + if (c->front()->rbuf()->write_space() >= c->front()->rbuf()->bufsize() / 2) { + DEBUG_TRACE (DEBUG::Butler, string_compose ("%1: slaved, write space = %2 of %3\n", name(), c->front()->rbuf()->write_space(), c->front()->rbuf()->bufsize())); butler_required = true; } } else { - if ((samplecnt_t) c->front()->rbuf->write_space() >= _chunk_samples) { - DEBUG_TRACE (DEBUG::Butler, string_compose ("%1: write space = %2 of %3\n", name(), c->front()->rbuf->write_space(), + if ((samplecnt_t) c->front()->rbuf()->write_space() >= _chunk_samples) { + DEBUG_TRACE (DEBUG::Butler, string_compose ("%1: write space = %2 of %3\n", name(), c->front()->rbuf()->write_space(), _chunk_samples)); butler_required = true; } @@ -515,7 +521,7 @@ DiskReader::set_pending_overwrite () boost::shared_ptr c = channels.reader (); for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - (*chan)->rbuf->read_flush (); + (*chan)->rbuf()->read_flush (); } g_atomic_int_set (&_pending_overwrite, 1); @@ -538,7 +544,7 @@ DiskReader::overwrite_existing_buffers () const bool reversed = _session.transport_speed() < 0.0f; /* assume all are the same size */ - samplecnt_t size = c->front()->rbuf->write_space (); + samplecnt_t size = c->front()->rbuf()->write_space (); assert (size > 0); boost::scoped_array sum_buffer (new Sample[size]); @@ -559,7 +565,7 @@ DiskReader::overwrite_existing_buffers () ReaderChannelInfo* rci = dynamic_cast (*chan); - if (audio_read ((*chan)->rbuf, sum_buffer.get(), mixdown_buffer.get(), gain_buffer.get(), start, to_read, rci, n, reversed)) { + if (audio_read ((*chan)->rbuf(), sum_buffer.get(), mixdown_buffer.get(), gain_buffer.get(), start, to_read, rci, n, reversed)) { error << string_compose(_("DiskReader %1: when refilling, cannot read %2 from playlist at sample %3"), id(), size, overwrite_sample) << endmsg; goto midi; } @@ -614,7 +620,7 @@ DiskReader::seek (samplepos_t sample, bool complete_refill) } for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) { - (*chan)->rbuf->reset (); + (*chan)->rbuf()->reset (); } playback_sample = sample; @@ -645,7 +651,7 @@ DiskReader::can_internal_playback_seek (sampleoffset_t distance) boost::shared_ptr c = channels.reader(); for (chan = c->begin(); chan != c->end(); ++chan) { - if (!(*chan)->rbuf->can_seek (distance)) { + if (!(*chan)->rbuf()->can_seek (distance)) { return false; } } @@ -668,9 +674,9 @@ DiskReader::internal_playback_seek (sampleoffset_t distance) boost::shared_ptr c = channels.reader(); for (chan = c->begin(); chan != c->end(); ++chan) { if (distance < 0) { - off = 0 - (sampleoffset_t) (*chan)->rbuf->decrement_read_ptr (::llabs (distance)); + off = 0 - (sampleoffset_t) (*chan)->rbuf()->decrement_read_ptr (::llabs (distance)); } else { - off = (*chan)->rbuf->increment_read_ptr (distance); + off = (*chan)->rbuf()->increment_read_ptr (distance); } } @@ -890,7 +896,7 @@ DiskReader::refill_audio (Sample* sum_buffer, Sample* mixdown_buffer, float* gai assert(mixdown_buffer); assert(gain_buffer); - samplecnt_t total_space = c->front()->rbuf->write_space(); + samplecnt_t total_space = c->front()->rbuf()->write_space(); if (total_space == 0) { DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1: no space to refill\n", name())); @@ -928,7 +934,7 @@ DiskReader::refill_audio (Sample* sum_buffer, Sample* mixdown_buffer, float* gai work with. */ - if (_slaved && total_space < (samplecnt_t) (c->front()->rbuf->bufsize() / 2)) { + if (_slaved && total_space < (samplecnt_t) (c->front()->rbuf()->bufsize() / 2)) { DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1: not enough to refill while slaved\n", this)); return 0; } @@ -941,7 +947,7 @@ DiskReader::refill_audio (Sample* sum_buffer, Sample* mixdown_buffer, float* gai /* at start: nothing to do but fill with silence */ for (chan_n = 0, i = c->begin(); i != c->end(); ++i, ++chan_n) { ChannelInfo* chan (*i); - chan->rbuf->write_zero (chan->rbuf->write_space ()); + chan->rbuf()->write_zero (chan->rbuf()->write_space ()); } return 0; } @@ -960,7 +966,7 @@ DiskReader::refill_audio (Sample* sum_buffer, Sample* mixdown_buffer, float* gai /* at end: nothing to do but fill with silence */ for (chan_n = 0, i = c->begin(); i != c->end(); ++i, ++chan_n) { ChannelInfo* chan (*i); - chan->rbuf->write_zero (chan->rbuf->write_space ()); + chan->rbuf()->write_zero (chan->rbuf()->write_space ()); } return 0; } @@ -998,7 +1004,7 @@ DiskReader::refill_audio (Sample* sum_buffer, Sample* mixdown_buffer, float* gai file_sample_tmp = ffa; samplecnt_t ts = total_space; - samplecnt_t to_read = min (ts, (samplecnt_t) chan->rbuf->write_space ()); + samplecnt_t to_read = min (ts, (samplecnt_t) chan->rbuf()->write_space ()); to_read = min (to_read, samples_to_read); assert (to_read >= 0); @@ -1006,7 +1012,7 @@ DiskReader::refill_audio (Sample* sum_buffer, Sample* mixdown_buffer, float* gai if (to_read) { ReaderChannelInfo* rci = dynamic_cast (chan); - if (audio_read (chan->rbuf, sum_buffer, mixdown_buffer, gain_buffer, file_sample_tmp, to_read, rci, chan_n, reversed)) { + if (audio_read (chan->rbuf(), sum_buffer, mixdown_buffer, gain_buffer, file_sample_tmp, to_read, rci, chan_n, reversed)) { error << string_compose(_("DiskReader %1: when refilling, cannot read %2 from playlist at sample %3"), id(), to_read, ffa) << endmsg; ret = -1; goto out; @@ -1017,7 +1023,7 @@ DiskReader::refill_audio (Sample* sum_buffer, Sample* mixdown_buffer, float* gai /* not sure if action is needed, * we'll later hit the "to close to the end" case */ - //chan->rbuf->write_zero (zero_fill); + //chan->rbuf()->write_zero (zero_fill); } } diff --git a/libs/pbd/pbd/debug.h b/libs/pbd/pbd/debug.h index 7d3a901a11..d82e646582 100644 --- a/libs/pbd/pbd/debug.h +++ b/libs/pbd/pbd/debug.h @@ -72,6 +72,7 @@ namespace PBD { } #ifndef NDEBUG + #define DEBUG_TRACE(bits,str) if (((bits) & PBD::debug_bits).any()) { PBD::debug_print (# bits, str); } #define DEBUG_STR_DECL(id) std::stringstream __debug_str ## id; #define DEBUG_STR(id) __debug_str ## id -- cgit v1.2.3