7fd73c0cf1f723896826c77fec3720c5c404d4e8 from master; tidy audio analysis dialogue...
[dcpomatic.git] / src / lib / analyse_audio_job.cc
index a6926bc14a02a4a465cd01b37496eb5e97bdd6ea..cdf6238767e21bc7ba0931a04edaf52d75de1277 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"
@@ -38,6 +39,8 @@ AnalyseAudioJob::AnalyseAudioJob (shared_ptr<const Film> f, shared_ptr<AudioCont
        , _content (c)
        , _done (0)
        , _samples_per_point (1)
+       , _overall_peak (0)
+       , _overall_peak_frame (0)
 {
 
 }
@@ -65,21 +68,22 @@ AnalyseAudioJob::run ()
        shared_ptr<Playlist> playlist (new Playlist);
        playlist->add (content);
        shared_ptr<Player> player (new Player (_film, playlist));
-       player->disable_video ();
+       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;
-       AudioFrame 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->set_peak (_overall_peak, DCPTime::from_frames (_overall_peak_frame, _film->audio_frame_rate ()));
        _analysis->write (content->audio_analysis_path ());
        
        set_progress (1);
@@ -87,19 +91,28 @@ AnalyseAudioJob::run ()
 }
 
 void
-AnalyseAudioJob::audio (shared_ptr<const AudioBuffers> b, DCPTime)
+AnalyseAudioJob::analyse (shared_ptr<const AudioBuffers> b)
 {
        for (int i = 0; i < b->frames(); ++i) {
                for (int j = 0; j < b->channels(); ++j) {
                        float s = b->data(j)[i];
                        if (fabsf (s) < 10e-7) {
-                               /* stringstream can't serialise and recover inf or -inf, so prevent such
+                               /* SafeStringStream can't serialise and recover inf or -inf, so prevent such
                                   values by replacing with this (140dB down) */
                                s = 10e-7;
                        }
                        _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]);