summaryrefslogtreecommitdiff
path: root/src/lib/audio_ring_buffers.cc
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2017-03-07 19:27:33 +0000
committerCarl Hetherington <cth@carlh.net>2017-04-19 23:04:32 +0100
commit4f9cb03792e85cbb5b4d554ab8ec0a3275fa7524 (patch)
tree2821608ecf5f7cc50649333903caff07d78fdbba /src/lib/audio_ring_buffers.cc
parent67a68bd971ebe1b35daa3f75873b4ccb53c00ba0 (diff)
Initial butler work.
Diffstat (limited to 'src/lib/audio_ring_buffers.cc')
-rw-r--r--src/lib/audio_ring_buffers.cc104
1 files changed, 104 insertions, 0 deletions
diff --git a/src/lib/audio_ring_buffers.cc b/src/lib/audio_ring_buffers.cc
new file mode 100644
index 000000000..81072474e
--- /dev/null
+++ b/src/lib/audio_ring_buffers.cc
@@ -0,0 +1,104 @@
+/*
+ Copyright (C) 2016-2017 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "audio_ring_buffers.h"
+#include "dcpomatic_assert.h"
+#include "exceptions.h"
+#include <boost/foreach.hpp>
+
+using std::min;
+using std::cout;
+using boost::shared_ptr;
+
+AudioRingBuffers::AudioRingBuffers ()
+ : _used_in_head (0)
+{
+
+}
+
+void
+AudioRingBuffers::put (shared_ptr<const AudioBuffers> data, DCPTime time)
+{
+ boost::mutex::scoped_lock lm (_mutex);
+
+ if (!_buffers.empty ()) {
+ DCPOMATIC_ASSERT (_buffers.front()->channels() == data->channels());
+ }
+
+ _buffers.push_back (data);
+ _latest = time;
+}
+
+void
+AudioRingBuffers::get (float* out, int channels, int frames)
+{
+ boost::mutex::scoped_lock lm (_mutex);
+
+ while (frames > 0) {
+ if (_buffers.empty ()) {
+ for (int i = 0; i < frames; ++i) {
+ for (int j = 0; j < channels; ++j) {
+ *out++ = 0;
+ }
+ }
+ cout << "audio underrun; missing " << frames << "!\n";
+ return;
+ }
+
+ int const to_do = min (frames, _buffers.front()->frames() - _used_in_head);
+ float** p = _buffers.front()->data();
+ int const c = min (_buffers.front()->channels(), channels);
+ for (int i = 0; i < to_do; ++i) {
+ for (int j = 0; j < c; ++j) {
+ *out++ = p[j][i + _used_in_head];
+ }
+ for (int j = c; j < channels; ++j) {
+ *out++ = 0;
+ }
+ }
+ _used_in_head += to_do;
+ frames -= to_do;
+
+ if (_used_in_head == _buffers.front()->frames()) {
+ _buffers.pop_front ();
+ _used_in_head = 0;
+ }
+ }
+}
+
+void
+AudioRingBuffers::clear ()
+{
+ boost::mutex::scoped_lock lm (_mutex);
+ _buffers.clear ();
+ _used_in_head = 0;
+ _latest = DCPTime ();
+}
+
+Frame
+AudioRingBuffers::size ()
+{
+ boost::mutex::scoped_lock lm (_mutex);
+ Frame s = 0;
+ BOOST_FOREACH (shared_ptr<const AudioBuffers> i, _buffers) {
+ s += i->frames ();
+ }
+ return s - _used_in_head;
+}