diff options
| author | Carl Hetherington <cth@carlh.net> | 2015-09-08 01:10:38 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2015-09-14 10:21:14 +0100 |
| commit | d22e839b94af048bdeaba61e427bcd2f07b4a3ee (patch) | |
| tree | 18f37e00d1a5a64c0426588fa530bcffb14e66a3 | |
| parent | 4704d088ae03ab2b5f73ceed577fd84935ad0640 (diff) | |
Fix analysis of audio when the subject is later in the playlist than
some other long piece of content. Small optimisation to AudioBuffers
to extend size logarithmically.
| -rw-r--r-- | src/lib/analyse_audio_job.cc | 9 | ||||
| -rw-r--r-- | src/lib/audio_buffers.cc | 27 | ||||
| -rw-r--r-- | src/lib/audio_buffers.h | 24 | ||||
| -rw-r--r-- | src/lib/film.cc | 1 | ||||
| -rw-r--r-- | src/lib/playlist.cc | 17 | ||||
| -rw-r--r-- | src/lib/playlist.h | 1 |
6 files changed, 58 insertions, 21 deletions
diff --git a/src/lib/analyse_audio_job.cc b/src/lib/analyse_audio_job.cc index c863c6c68..6c142f5cf 100644 --- a/src/lib/analyse_audio_job.cc +++ b/src/lib/analyse_audio_job.cc @@ -74,7 +74,10 @@ AnalyseAudioJob::run () player->set_ignore_video (); player->set_fast (); - int64_t const len = _playlist->length().frames_round (_film->audio_frame_rate()); + DCPTime const start = _playlist->start().get_value_or (DCPTime ()); + DCPTime const length = _playlist->length (); + + Frame const len = DCPTime (length - start).frames_round (_film->audio_frame_rate()); _samples_per_point = max (int64_t (1), len / _num_points); delete[] _current; @@ -91,9 +94,9 @@ AnalyseAudioJob::run () if (has_any_audio) { _done = 0; DCPTime const block = DCPTime::from_seconds (1.0 / 8); - for (DCPTime t; t < _film->length(); t += block) { + for (DCPTime t = start; t < length; t += block) { analyse (player->get_audio (t, block, false)); - set_progress (t.seconds() / _film->length().seconds()); + set_progress ((t.seconds() - start.seconds()) / (length.seconds() - start.seconds())); } } diff --git a/src/lib/audio_buffers.cc b/src/lib/audio_buffers.cc index 0130f17b4..05b3d4a44 100644 --- a/src/lib/audio_buffers.cc +++ b/src/lib/audio_buffers.cc @@ -31,7 +31,7 @@ using boost::shared_ptr; * @param channels Number of channels. * @param frames Number of frames to reserve space for. */ -AudioBuffers::AudioBuffers (int channels, int frames) +AudioBuffers::AudioBuffers (int channels, int32_t frames) { allocate (channels, frames); } @@ -72,7 +72,7 @@ AudioBuffers::~AudioBuffers () } void -AudioBuffers::allocate (int channels, int frames) +AudioBuffers::allocate (int channels, int32_t frames) { DCPOMATIC_ASSERT (frames >= 0); DCPOMATIC_ASSERT (channels >= 0); @@ -120,7 +120,7 @@ AudioBuffers::data (int c) const * @param f Frames; must be less than or equal to the number of allocated frames. */ void -AudioBuffers::set_frames (int f) +AudioBuffers::set_frames (int32_t f) { DCPOMATIC_ASSERT (f <= _allocated_frames); @@ -156,7 +156,7 @@ AudioBuffers::make_silent (int c) } void -AudioBuffers::make_silent (int from, int frames) +AudioBuffers::make_silent (int32_t from, int32_t frames) { DCPOMATIC_ASSERT ((from + frames) <= _allocated_frames); @@ -174,7 +174,7 @@ AudioBuffers::make_silent (int from, int frames) * @param write_offset Offset to write to in `to'. */ void -AudioBuffers::copy_from (AudioBuffers const * from, int frames_to_copy, int read_offset, int write_offset) +AudioBuffers::copy_from (AudioBuffers const * from, int32_t frames_to_copy, int32_t read_offset, int32_t write_offset) { if (frames_to_copy == 0) { /* Prevent the asserts from firing if there is nothing to do */ @@ -199,7 +199,7 @@ AudioBuffers::copy_from (AudioBuffers const * from, int frames_to_copy, int read */ void -AudioBuffers::move (int from, int to, int frames) +AudioBuffers::move (int32_t from, int32_t to, int32_t frames) { if (frames == 0) { return; @@ -241,12 +241,23 @@ AudioBuffers::accumulate_channel (AudioBuffers const * from, int from_channel, i * the buffers, fill the new space with silence. */ void -AudioBuffers::ensure_size (int frames) +AudioBuffers::ensure_size (int32_t frames) { if (_allocated_frames >= frames) { return; } + /* Round up frames to the next power of 2 to reduce the number + of realloc()s that are necessary. + */ + frames--; + frames |= frames >> 1; + frames |= frames >> 2; + frames |= frames >> 4; + frames |= frames >> 8; + frames |= frames >> 16; + frames++; + for (int i = 0; i < _channels; ++i) { _data[i] = static_cast<float*> (realloc (_data[i], frames * sizeof (float))); if (!_data[i]) { @@ -261,7 +272,7 @@ AudioBuffers::ensure_size (int frames) } void -AudioBuffers::accumulate_frames (AudioBuffers const * from, int read_offset, int write_offset, int frames) +AudioBuffers::accumulate_frames (AudioBuffers const * from, int32_t read_offset, int32_t write_offset, int32_t frames) { DCPOMATIC_ASSERT (_channels == from->channels ()); DCPOMATIC_ASSERT (read_offset >= 0); diff --git a/src/lib/audio_buffers.h b/src/lib/audio_buffers.h index bcf5d5928..122716d77 100644 --- a/src/lib/audio_buffers.h +++ b/src/lib/audio_buffers.h @@ -28,11 +28,15 @@ /** @class AudioBuffers * @brief A class to hold multi-channel audio data in float format. + * + * The use of int32_t for frame counts in this class is due to the + * round-up to the next power-of-2 code in ::ensure_size; if that + * were changed the frame count could use any integer type. */ class AudioBuffers { public: - AudioBuffers (int channels, int frames); + AudioBuffers (int channels, int32_t frames); AudioBuffers (AudioBuffers const &); AudioBuffers (boost::shared_ptr<const AudioBuffers>); ~AudioBuffers (); @@ -42,7 +46,7 @@ public: boost::shared_ptr<AudioBuffers> clone () const; boost::shared_ptr<AudioBuffers> channel (int) const; - void ensure_size (int); + void ensure_size (int32_t); float** data () const { return _data; @@ -58,30 +62,30 @@ public: return _frames; } - void set_frames (int f); + void set_frames (int32_t f); void make_silent (); void make_silent (int c); - void make_silent (int from, int frames); + void make_silent (int32_t from, int32_t frames); void apply_gain (float); - void copy_from (AudioBuffers const * from, int frames_to_copy, int read_offset, int write_offset); + void copy_from (AudioBuffers const * from, int32_t frames_to_copy, int32_t read_offset, int32_t write_offset); void copy_channel_from (AudioBuffers const * from, int from_channel, int to_channel); - void move (int from, int to, int frames); + void move (int32_t from, int32_t to, int32_t frames); void accumulate_channel (AudioBuffers const * from, int from_channel, int to_channel, float gain = 1); - void accumulate_frames (AudioBuffers const *, int read_offset, int write_offset, int frames); + void accumulate_frames (AudioBuffers const *, int32_t read_offset, int32_t write_offset, int32_t frames); private: - void allocate (int, int); + void allocate (int channels, int32_t frames); void deallocate (); /** Number of channels */ int _channels; /** Number of frames (where a frame is one sample across all channels) */ - int _frames; + int32_t _frames; /** Number of frames that _data can hold */ - int _allocated_frames; + int32_t _allocated_frames; /** Audio data (so that, e.g. _data[2][6] is channel 2, sample 6) */ float** _data; }; diff --git a/src/lib/film.cc b/src/lib/film.cc index e48b08f3b..c89d96584 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -994,6 +994,7 @@ Film::move_content_later (shared_ptr<Content> c) _playlist->move_later (c); } +/** @return length of the film from time 0 to the last thing on the playlist */ DCPTime Film::length () const { diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index a1b209a11..4aff1015d 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -263,6 +263,7 @@ Playlist::best_dcp_frame_rate () const return best->dcp; } +/** @return length of the playlist from time 0 to the last thing on the playlist */ DCPTime Playlist::length () const { @@ -274,6 +275,22 @@ Playlist::length () const return len; } +/** @return position of the first thing on the playlist, if it's not empty */ +optional<DCPTime> +Playlist::start () const +{ + if (_content.empty ()) { + return optional<DCPTime> (); + } + + DCPTime start = DCPTime::max (); + BOOST_FOREACH (shared_ptr<Content> i, _content) { + start = min (start, i->position ()); + } + + return start; +} + void Playlist::reconnect () { diff --git a/src/lib/playlist.h b/src/lib/playlist.h index d9c035ac7..76055bea0 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -58,6 +58,7 @@ public: std::string video_identifier () const; DCPTime length () const; + boost::optional<DCPTime> start () const; int best_dcp_frame_rate () const; DCPTime video_end () const; |
