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;
}
/* 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;
}
/* 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;
}
}
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);
}
}
}
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; }
Glib::Threads::Mutex _reset_lock;
};
-
template<class T> /*LIBPBD_API*/ guint
PlaybackBuffer<T>::write (T const *src, guint cnt)
{
return to_write;
}
+template<class T> /*LIBPBD_API*/ guint
+PlaybackBuffer<T>::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<class T> /*LIBPBD_API*/ guint
PlaybackBuffer<T>::read (T *dest, guint cnt, bool commit)
{