Take a JPEG2000 header marked as SRGB to mean that no XYZ -> RGB conversion should...
[dcpomatic.git] / src / lib / analyse_audio_job.cc
index ab985bdf75468ee557a81f0307d09a919df390e0..31b9dccae953e4ced010feeab571e5a12fadd3a6 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -18,6 +18,7 @@
 */
 
 #include "audio_analysis.h"
+#include "audio_buffers.h"
 #include "analyse_audio_job.h"
 #include "compose.hpp"
 #include "film.h"
@@ -33,11 +34,13 @@ using boost::shared_ptr;
 
 int const AnalyseAudioJob::_num_points = 1024;
 
-AnalyseAudioJob::AnalyseAudioJob (shared_ptr<const Film> f, shared_ptr<AudioContent> c)
+AnalyseAudioJob::AnalyseAudioJob (shared_ptr<const Film> f, shared_ptr<const Playlist> p)
        : Job (f)
-       , _content (c)
+       , _playlist (p)
        , _done (0)
        , _samples_per_point (1)
+       , _overall_peak (0)
+       , _overall_peak_frame (0)
 {
 
 }
@@ -48,40 +51,40 @@ AnalyseAudioJob::name () const
        return _("Analyse audio");
 }
 
+string
+AnalyseAudioJob::json_name () const
+{
+       return N_("analyse_audio");
+}
+
 void
 AnalyseAudioJob::run ()
 {
-       shared_ptr<AudioContent> content = _content.lock ();
-       if (!content) {
-               return;
-       }
-
-       shared_ptr<Playlist> playlist (new Playlist);
-       playlist->add (content);
-       shared_ptr<Player> player (new Player (_film, playlist));
-       player->disable_video ();
+       shared_ptr<Player> player (new Player (_film, _playlist));
+       player->set_ignore_video ();
        
-       player->Audio.connect (bind (&AnalyseAudioJob::audio, this, _1, _2));
-
-       _samples_per_point = max (int64_t (1), _film->time_to_audio_frames (_film->length()) / _num_points);
+       int64_t const len = _film->length().frames (_film->audio_frame_rate());
+       _samples_per_point = max (int64_t (1), len / _num_points);
 
        _current.resize (_film->audio_channels ());
        _analysis.reset (new AudioAnalysis (_film->audio_channels ()));
 
        _done = 0;
-       OutputAudioFrame const len = _film->time_to_audio_frames (_film->length ());
-       while (!player->pass ()) {
-               set_progress (double (_done) / len);
+       DCPTime const block = DCPTime::from_seconds (1.0 / 8);
+       for (DCPTime t; t < _film->length(); t += block) {
+               analyse (player->get_audio (t, block, false));
+               set_progress (t.seconds() / _film->length().seconds());
        }
 
-       _analysis->write (content->audio_analysis_path ());
+       _analysis->set_peak (_overall_peak, DCPTime::from_frames (_overall_peak_frame, _film->audio_frame_rate ()));
+       _analysis->write (_film->audio_analysis_path (_playlist));
        
        set_progress (1);
        set_state (FINISHED_OK);
 }
 
 void
-AnalyseAudioJob::audio (shared_ptr<const AudioBuffers> b, Time)
+AnalyseAudioJob::analyse (shared_ptr<const AudioBuffers> b)
 {
        for (int i = 0; i < b->frames(); ++i) {
                for (int j = 0; j < b->channels(); ++j) {
@@ -94,6 +97,15 @@ AnalyseAudioJob::audio (shared_ptr<const AudioBuffers> b, Time)
                        _current[j][AudioPoint::RMS] += pow (s, 2);
                        _current[j][AudioPoint::PEAK] = max (_current[j][AudioPoint::PEAK], fabsf (s));
 
+                       float const as = fabs (s);
+
+                       _current[j][AudioPoint::PEAK] = max (_current[j][AudioPoint::PEAK], as);
+
+                       if (as > _overall_peak) {
+                               _overall_peak = as;
+                               _overall_peak_frame = _done + i;
+                       }
+
                        if ((_done % _samples_per_point) == 0) {
                                _current[j][AudioPoint::RMS] = sqrt (_current[j][AudioPoint::RMS] / _samples_per_point);
                                _analysis->add_point (j, _current[j]);