X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Faudio_ring_buffers.cc;h=d21f20968d5d087d5e668d95b6cbff6cd1ad1cbf;hb=HEAD;hp=f51ff8a38860e03b7d3e867b9fea9e861d46ead4;hpb=54e6f206305d4275808cfce36987edcc61a6a779;p=dcpomatic.git diff --git a/src/lib/audio_ring_buffers.cc b/src/lib/audio_ring_buffers.cc index f51ff8a38..d21f20968 100644 --- a/src/lib/audio_ring_buffers.cc +++ b/src/lib/audio_ring_buffers.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2016-2018 Carl Hetherington + Copyright (C) 2016-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,39 +18,48 @@ */ + #include "audio_ring_buffers.h" #include "dcpomatic_assert.h" #include "exceptions.h" -#include #include + using std::min; using std::cout; using std::make_pair; using std::pair; using std::list; -using boost::shared_ptr; +using std::shared_ptr; using boost::optional; +using namespace dcpomatic; + AudioRingBuffers::AudioRingBuffers () - : _used_in_head (0) { } + +/** @param frame_rate Frame rate in use; this is only used to check timing consistency of the incoming data */ void -AudioRingBuffers::put (shared_ptr data, DCPTime time) +AudioRingBuffers::put (shared_ptr data, DCPTime time, int frame_rate) { boost::mutex::scoped_lock lm (_mutex); if (!_buffers.empty()) { DCPOMATIC_ASSERT (_buffers.front().first->channels() == data->channels()); - DCPOMATIC_ASSERT ((_buffers.back().second + DCPTime::from_frames(_buffers.back().first->frames(), 48000)) == time); + DCPTime const end = (_buffers.back().second + DCPTime::from_frames(_buffers.back().first->frames(), frame_rate)); + if (labs(end.get() - time.get()) > 1) { + cout << "bad put " << to_string(_buffers.back().second) << " " << _buffers.back().first->frames() << " " << to_string(time) << "\n"; + } + DCPOMATIC_ASSERT (labs(end.get() - time.get()) < 2); } _buffers.push_back(make_pair(data, time)); } + /** @return time of the returned data; if it's not set this indicates an underrun */ optional AudioRingBuffers::get (float* out, int channels, int frames) @@ -66,17 +75,16 @@ AudioRingBuffers::get (float* out, int channels, int frames) *out++ = 0; } } - cout << "audio underrun; missing " << frames << "!\n"; return time; } - pair, DCPTime> front = _buffers.front (); + auto front = _buffers.front (); if (!time) { time = front.second + DCPTime::from_frames(_used_in_head, 48000); } int const to_do = min (frames, front.first->frames() - _used_in_head); - float** p = front.first->data(); + float* const* p = front.first->data(); int const c = min (front.first->channels(), channels); for (int i = 0; i < to_do; ++i) { for (int j = 0; j < c; ++j) { @@ -98,6 +106,18 @@ AudioRingBuffers::get (float* out, int channels, int frames) return time; } + +optional +AudioRingBuffers::peek () const +{ + boost::mutex::scoped_lock lm (_mutex); + if (_buffers.empty()) { + return {}; + } + return _buffers.front().second; +} + + void AudioRingBuffers::clear () { @@ -106,13 +126,14 @@ AudioRingBuffers::clear () _used_in_head = 0; } + Frame AudioRingBuffers::size () const { boost::mutex::scoped_lock lm (_mutex); Frame s = 0; - for (list, DCPTime> >::const_iterator i = _buffers.begin(); i != _buffers.end(); ++i) { - s += i->first->frames(); + for (auto const& i: _buffers) { + s += i.first->frames(); } return s - _used_in_head; }