Merge branch 'master' of ssh://git.carlh.net/home/carl/git/dcpomatic
[dcpomatic.git] / src / lib / audio_decoder.cc
index 16a03a8e93593cdc5879f1e33f72c93742660ffb..b4aa2bacda401b35d7ca3c5420b210545a9f5450 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2017 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2018 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -37,9 +37,10 @@ using std::pair;
 using boost::shared_ptr;
 using boost::optional;
 
-AudioDecoder::AudioDecoder (Decoder* parent, shared_ptr<const AudioContent> content, shared_ptr<Log> log)
+AudioDecoder::AudioDecoder (Decoder* parent, shared_ptr<const AudioContent> content, shared_ptr<Log> log, bool fast)
        : DecoderPart (parent, log)
        , _content (content)
+       , _fast (fast)
 {
        /* Set up _positions so that we have one for each stream */
        BOOST_FOREACH (AudioStreamPtr i, content->streams ()) {
@@ -65,11 +66,11 @@ AudioDecoder::emit (AudioStreamPtr stream, shared_ptr<const AudioBuffers> data,
                        silence (_content->delay ());
                }
                time += ContentTime::from_seconds (_content->delay() / 1000.0);
-               _positions[stream] = time.frames_round (stream->frame_rate ());
+               _positions[stream] = time.frames_round (_content->resampled_frame_rate ());
        }
 
        shared_ptr<Resampler> resampler;
-       map<AudioStreamPtr, shared_ptr<Resampler> >::iterator i = _resamplers.find(stream);
+       ResamplerMap::iterator i = _resamplers.find(stream);
        if (i != _resamplers.end ()) {
                resampler = i->second;
        } else {
@@ -82,6 +83,9 @@ AudioDecoder::emit (AudioStreamPtr stream, shared_ptr<const AudioBuffers> data,
                                );
 
                        resampler.reset (new Resampler (stream->frame_rate(), _content->resampled_frame_rate(), stream->channels()));
+                       if (_fast) {
+                               resampler->set_fast ();
+                       }
                        _resamplers[stream] = resampler;
                }
        }
@@ -94,14 +98,15 @@ AudioDecoder::emit (AudioStreamPtr stream, shared_ptr<const AudioBuffers> data,
                data = ro;
        }
 
-       _positions[stream] += Data(stream, ContentAudio (data, _positions[stream])).get_value_or(0);
+       Data(stream, ContentAudio (data, _positions[stream]));
+       _positions[stream] += data->frames();
 }
 
 /** @return Time just after the last thing that was emitted from a given stream */
 ContentTime
 AudioDecoder::stream_position (AudioStreamPtr stream) const
 {
-       map<AudioStreamPtr, Frame>::const_iterator i = _positions.find (stream);
+       PositionMap::const_iterator i = _positions.find (stream);
        DCPOMATIC_ASSERT (i != _positions.end ());
        return ContentTime::from_frames (i->second, _content->resampled_frame_rate());
 }
@@ -110,7 +115,7 @@ ContentTime
 AudioDecoder::position () const
 {
        optional<ContentTime> p;
-       for (map<AudioStreamPtr, Frame>::const_iterator i = _positions.begin(); i != _positions.end(); ++i) {
+       for (PositionMap::const_iterator i = _positions.begin(); i != _positions.end(); ++i) {
                ContentTime const ct = stream_position (i->first);
                if (!p || ct < *p) {
                        p = ct;
@@ -123,12 +128,12 @@ AudioDecoder::position () const
 void
 AudioDecoder::seek ()
 {
-       for (map<AudioStreamPtr, shared_ptr<Resampler> >::iterator i = _resamplers.begin(); i != _resamplers.end(); ++i) {
+       for (ResamplerMap::iterator i = _resamplers.begin(); i != _resamplers.end(); ++i) {
                i->second->flush ();
                i->second->reset ();
        }
 
-       for (map<AudioStreamPtr, Frame>::iterator i = _positions.begin(); i != _positions.end(); ++i) {
+       for (PositionMap::iterator i = _positions.begin(); i != _positions.end(); ++i) {
                i->second = 0;
        }
 }
@@ -136,7 +141,7 @@ AudioDecoder::seek ()
 void
 AudioDecoder::flush ()
 {
-       for (map<AudioStreamPtr, shared_ptr<Resampler> >::iterator i = _resamplers.begin(); i != _resamplers.end(); ++i) {
+       for (ResamplerMap::iterator i = _resamplers.begin(); i != _resamplers.end(); ++i) {
                shared_ptr<const AudioBuffers> ro = i->second->flush ();
                if (ro->frames() > 0) {
                        Data (i->first, ContentAudio (ro, _positions[i->first]));