From b3fda6236a7f62fa033d7c247a6d12d9f339061a Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Wed, 6 Feb 2019 16:59:41 +0100 Subject: [PATCH] Optimize buffer zero-filling --- libs/ardour/disk_reader.cc | 25 ++++++-------------- libs/pbd/pbd/playback_buffer.h | 42 ++++++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/libs/ardour/disk_reader.cc b/libs/ardour/disk_reader.cc index 5b7b5bde52..c87f04daf2 100644 --- a/libs/ardour/disk_reader.cc +++ b/libs/ardour/disk_reader.cc @@ -692,11 +692,7 @@ DiskReader::audio_read (PBD::PlaybackBuffer*rb, Location *loc = 0; if (!_playlists[DataType::AUDIO]) { - // TODO optimize use zero-buffer - for (uint32_t z = 0; z < cnt; ++z) { - Sample t = 0; - rb->write (&t, 1); - } + rb->write_zero (cnt); return 0; } @@ -908,12 +904,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); - // TODO optimize use zero-buffer - samplecnt_t ws = chan->rbuf->write_space (); - for (uint32_t z = 0; z < ws; ++z) { - Sample t = 0; - chan->rbuf->write (&t, 1); - } + chan->rbuf->write_zero (chan->rbuf->write_space ()); } return 0; } @@ -932,12 +923,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); - // TODO optimize use zero-buffer - samplecnt_t ws = chan->rbuf->write_space (); - for (uint32_t z = 0; z < ws; ++z) { - Sample t = 0; - chan->rbuf->write (&t, 1); - } + chan->rbuf->write_zero (chan->rbuf->write_space ()); } return 0; } @@ -990,7 +976,10 @@ DiskReader::refill_audio (Sample* sum_buffer, Sample* mixdown_buffer, float* gai } if (zero_fill) { - /* XXX: do something */ + /* not sure if action is needed, + * we'll later hit the "to close to the end" case + */ + //chan->rbuf->write_zero (zero_fill); } } diff --git a/libs/pbd/pbd/playback_buffer.h b/libs/pbd/pbd/playback_buffer.h index fc9bd4d6e0..d9f2232144 100644 --- a/libs/pbd/pbd/playback_buffer.h +++ b/libs/pbd/pbd/playback_buffer.h @@ -106,7 +106,8 @@ public: } guint read (T *dest, guint cnt, bool commit = true); - guint write (T const * src, guint cnt); + guint write (T const * src, guint cnt); + guint write_zero (guint cnt); T *buffer () { return buf; } guint bufsize () const { return size; } @@ -139,7 +140,6 @@ private: Glib::Threads::Mutex _reset_lock; }; - template /*LIBPBD_API*/ guint PlaybackBuffer::write (T const *src, guint cnt) { @@ -178,6 +178,44 @@ PlaybackBuffer::write (T const *src, guint cnt) return to_write; } +template /*LIBPBD_API*/ guint +PlaybackBuffer::write_zero (guint cnt) +{ + guint w = g_atomic_int_get (&write_idx); + const guint free_cnt = write_space (); + + if (free_cnt == 0) { + return 0; + } + + const guint to_write = cnt > free_cnt ? free_cnt : cnt; + const guint cnt2 = w + to_write; + + guint n1, n2; + if (cnt2 > size) { + n1 = size - w; + n2 = cnt2 & size_mask; + } else { + n1 = to_write; + n2 = 0; + } + + memset (&buf[w], 0, n1 * sizeof (T)); + w = (w + n1) & size_mask; + + if (n2) { + memset (buf, 0, n2 * sizeof (T)); + w = n2; + } + + { + SpinLock sl (_writepos_lock); + write_pos += to_write; + g_atomic_int_set (&write_idx, w); + } + return to_write; +} + template /*LIBPBD_API*/ guint PlaybackBuffer::read (T *dest, guint cnt, bool commit) { -- 2.30.2