summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2015-09-08 01:10:38 +0100
committerCarl Hetherington <cth@carlh.net>2015-09-14 10:21:14 +0100
commitd22e839b94af048bdeaba61e427bcd2f07b4a3ee (patch)
tree18f37e00d1a5a64c0426588fa530bcffb14e66a3
parent4704d088ae03ab2b5f73ceed577fd84935ad0640 (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.cc9
-rw-r--r--src/lib/audio_buffers.cc27
-rw-r--r--src/lib/audio_buffers.h24
-rw-r--r--src/lib/film.cc1
-rw-r--r--src/lib/playlist.cc17
-rw-r--r--src/lib/playlist.h1
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;