Some comments and a few small cleanups.
authorCarl Hetherington <cth@carlh.net>
Tue, 28 Feb 2017 11:09:38 +0000 (11:09 +0000)
committerCarl Hetherington <cth@carlh.net>
Wed, 19 Apr 2017 22:04:32 +0000 (23:04 +0100)
src/lib/audio_buffers.cc
src/lib/audio_decoder.cc
src/lib/audio_decoder.h
src/lib/audio_merger.cc
src/lib/audio_merger.h

index f01f8baaff3c9b1ac834805875015763957a38b8..aea581a07311ea151d1508cd1a26b60dcd448009 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2017 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -134,7 +134,7 @@ AudioBuffers::set_frames (int32_t f)
        _frames = f;
 }
 
-/** Make all samples on all channels silent */
+/** Make all frames silent */
 void
 AudioBuffers::make_silent ()
 {
@@ -156,6 +156,10 @@ AudioBuffers::make_silent (int c)
        }
 }
 
+/** Make some frames.
+ *  @param from Start frame.
+ *  @param frames Number of frames to silence.
+ */
 void
 AudioBuffers::make_silent (int32_t from, int32_t frames)
 {
@@ -198,7 +202,6 @@ AudioBuffers::copy_from (AudioBuffers const * from, int32_t frames_to_copy, int3
  *  @param to Offset to move to.
  *  @param frames Number of frames to move.
  */
-
 void
 AudioBuffers::move (int32_t frames, int32_t from, int32_t to)
 {
@@ -272,6 +275,12 @@ AudioBuffers::ensure_size (int32_t frames)
        _allocated_frames = frames;
 }
 
+/** Mix some other buffers with these ones.  The AudioBuffers must have the same number of channels.
+ *  @param from Audio buffers to get data from.
+ *  @param frames Number of frames to mix.
+ *  @param read_offset Offset within `from' to read from.
+ *  @param write_offset Offset within this to mix into.
+ */
 void
 AudioBuffers::accumulate_frames (AudioBuffers const * from, int32_t frames, int32_t read_offset, int32_t write_offset)
 {
@@ -311,6 +320,11 @@ AudioBuffers::channel (int c) const
        return o;
 }
 
+/** Copy all the samples from a channel on another AudioBuffers to a channel on this one.
+ *  @param from AudioBuffers to copy from.
+ *  @param from_channel Channel index in `from' to copy from.
+ *  @param to_channel Channel index in this to copy into, overwriting what's already there.
+ */
 void
 AudioBuffers::copy_channel_from (AudioBuffers const * from, int from_channel, int to_channel)
 {
@@ -318,6 +332,7 @@ AudioBuffers::copy_channel_from (AudioBuffers const * from, int from_channel, in
        memcpy (data(to_channel), from->data(from_channel), frames() * sizeof (float));
 }
 
+/** Make a copy of these AudioBuffers */
 shared_ptr<AudioBuffers>
 AudioBuffers::clone () const
 {
@@ -326,14 +341,17 @@ AudioBuffers::clone () const
        return b;
 }
 
+/** Extend these buffers with the data from another.  The AudioBuffers must have the same number of channels. */
 void
 AudioBuffers::append (shared_ptr<const AudioBuffers> other)
 {
+       DCPOMATIC_ASSERT (channels() == other->channels());
        ensure_size (_frames + other->frames());
        copy_from (other.get(), other->frames(), 0, _frames);
        _frames += other->frames();
 }
 
+/** Remove some frames from the start of these AudioBuffers */
 void
 AudioBuffers::trim_start (int32_t frames)
 {
index 31f713fda3a3b743ec42b90133563af4d1192b38..3e4584a3f5a04552523344fa54ba8f1c3b0593cc 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2017 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -36,6 +36,7 @@ using boost::optional;
 AudioDecoder::AudioDecoder (Decoder* parent, shared_ptr<const AudioContent> content, shared_ptr<Log> log)
        : DecoderPart (parent, log)
 {
+       /* Set up _positions so that we have one for each stream */
        BOOST_FOREACH (AudioStreamPtr i, content->streams ()) {
                _positions[i] = 0;
        }
@@ -49,6 +50,11 @@ AudioDecoder::emit (AudioStreamPtr stream, shared_ptr<const AudioBuffers> data,
        }
 
        if (_positions[stream] == 0) {
+               /* This is the first data we have received since initialisation or seek.  Set
+                  the position based on the ContentTime that was given.  After this first time
+                  we just count samples, as it seems that ContentTimes are unreliable from
+                  FFmpegDecoder (not quite continuous; perhaps due to some rounding error).
+               */
                _positions[stream] = time.frames_round (stream->frame_rate ());
        }
 
index 25d858681eea36e6e4ed0f6605526f88a37c49d2..c104d8201971a3b1ee98bf72dfed3f58f619945c 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2017 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -52,6 +52,7 @@ public:
        boost::signals2::signal<void (AudioStreamPtr, ContentAudio)> Data;
 
 private:
+       /** Frame after the last one that was emitted from Data for each AudioStream */
        std::map<AudioStreamPtr, Frame> _positions;
 };
 
index 10a71535b4794e7e80cebe792898d5deab03ed17..4bed4b3a5850539f8617f3ecb4a348889eacb2a8 100644 (file)
 
 */
 
+/** @file  src/audio_merger.cc
+ *  @brief AudioMerger class.
+ */
+
 #include "audio_merger.h"
 #include "dcpomatic_time.h"
 #include <iostream>
@@ -31,14 +35,21 @@ using boost::shared_ptr;
 using boost::optional;
 
 AudioMerger::AudioMerger (int frame_rate)
-       : _last_pull (0)
-       , _frame_rate (frame_rate)
+       : _frame_rate (frame_rate)
 {
 
 }
 
+Frame
+AudioMerger::frames (DCPTime t) const
+{
+       return t.frames_floor (_frame_rate);
+}
+
 /** Pull audio up to a given time; after this call, no more data can be pushed
  *  before the specified time.
+ *  @param time Time to pull up to.
+ *  @return Blocks of merged audio up to `time'.
  */
 list<pair<shared_ptr<AudioBuffers>, DCPTime> >
 AudioMerger::pull (DCPTime time)
@@ -56,7 +67,7 @@ AudioMerger::pull (DCPTime time)
                        out.push_back (make_pair (i.audio, i.time));
                } else if (i.time < time) {
                        /* Overlaps the end of the pull period */
-                       shared_ptr<AudioBuffers> audio (new AudioBuffers (i.audio->channels(), DCPTime(time - i.time).frames_floor(_frame_rate)));
+                       shared_ptr<AudioBuffers> audio (new AudioBuffers (i.audio->channels(), frames(DCPTime(time - i.time))));
                        audio->copy_from (i.audio.get(), audio->frames(), 0, 0);
                        out.push_back (make_pair (audio, i.time));
                        i.audio->trim_start (audio->frames ());
@@ -72,6 +83,7 @@ AudioMerger::pull (DCPTime time)
        return out;
 }
 
+/** Push some data into the merger at a given time */
 void
 AudioMerger::push (boost::shared_ptr<const AudioBuffers> audio, DCPTime time)
 {
@@ -79,16 +91,16 @@ AudioMerger::push (boost::shared_ptr<const AudioBuffers> audio, DCPTime time)
 
        DCPTimePeriod period (time, time + DCPTime::from_frames (audio->frames(), _frame_rate));
 
-       /* Mix any parts of this new block with existing ones */
+       /* Mix any overlapping parts of this new block with existing ones */
        BOOST_FOREACH (Buffer i, _buffers) {
                optional<DCPTimePeriod> overlap = i.period().overlap (period);
                if (overlap) {
-                       int32_t const offset = DCPTime(overlap->from - i.time).frames_floor(_frame_rate);
-                       int32_t const frames = overlap->duration().frames_floor(_frame_rate);
+                       int32_t const offset = frames(DCPTime(overlap->from - i.time));
+                       int32_t const frames_to_mix = frames(overlap->duration());
                        if (i.time < time) {
-                               i.audio->accumulate_frames(audio.get(), frames, 0, offset);
+                               i.audio->accumulate_frames(audio.get(), frames_to_mix, 0, offset);
                        } else {
-                               i.audio->accumulate_frames(audio.get(), frames, offset, 0);
+                               i.audio->accumulate_frames(audio.get(), frames_to_mix, offset, 0);
                        }
                }
        }
@@ -112,8 +124,8 @@ AudioMerger::push (boost::shared_ptr<const AudioBuffers> audio, DCPTime time)
                }
 
                /* Get the part of audio that we want to use */
-               shared_ptr<AudioBuffers> part (new AudioBuffers (audio->channels(), i.to.frames_floor(_frame_rate) - i.from.frames_floor(_frame_rate)));
-               part->copy_from (audio.get(), part->frames(), DCPTime(i.from - time).frames_floor(_frame_rate), 0);
+               shared_ptr<AudioBuffers> part (new AudioBuffers (audio->channels(), frames(i.to) - frames(i.from)));
+               part->copy_from (audio.get(), part->frames(), frames(DCPTime(i.from - time)), 0);
 
                if (before == _buffers.end() && after == _buffers.end()) {
                        /* New buffer */
index 87bda7f8b2f58fa190379d85ac21cd2e1e16e0a1..ffca29c57cdf471908115a42b6fc01fee3c8ffe8 100644 (file)
 
 */
 
+/** @file  src/audio_merger.h
+ *  @brief AudioMerger class.
+ */
+
 #include "audio_buffers.h"
 #include "dcpomatic_time.h"
 #include "util.h"
 
+/** @class AudioMerger.
+ *  @brief A class that can merge audio data from many sources.
+ */
 class AudioMerger
 {
 public:
        AudioMerger (int frame_rate);
 
-       /** Pull audio up to a given time; after this call, no more data can be pushed
-        *  before the specified time.
-        */
        std::list<std::pair<boost::shared_ptr<AudioBuffers>, DCPTime> > pull (DCPTime time);
        void push (boost::shared_ptr<const AudioBuffers> audio, DCPTime time);
 
 private:
+       Frame frames (DCPTime t) const;
+
        class Buffer
        {
        public: