Fix apparently ineffective processors when analysing audio (#2671).
authorCarl Hetherington <cth@carlh.net>
Sun, 11 Feb 2024 12:10:48 +0000 (13:10 +0100)
committerCarl Hetherington <cth@carlh.net>
Sun, 11 Feb 2024 21:55:27 +0000 (22:55 +0100)
A whole film ("DCP side") analysis would behave the same as a
single piece of content analysis if the film only had one piece
of content.

Here we also clarify that audio analysis of the whole film is different
to that for a single piece of content; for the whole film we use processors,
and for single pieces of content we do not.

src/lib/analyse_audio_job.cc
src/lib/analyse_audio_job.h
src/lib/audio_analyser.cc
src/lib/audio_analyser.h
test/audio_analysis_test.cc

index ca0f49f570524499c3f85664b163fa3357bf3b30..a6ce5dcc80d8d615e3ea0b69f409899becda74dd 100644 (file)
@@ -47,12 +47,16 @@ using namespace boost::placeholders;
 #endif
 
 
-/** @param from_zero true to analyse audio from time 0 in the playlist, otherwise begin at Playlist::start */
-AnalyseAudioJob::AnalyseAudioJob (shared_ptr<const Film> film, shared_ptr<const Playlist> playlist, bool from_zero)
+/** @param whole_film true to analyse the whole film' audio (i.e. start from time 0 and use processors), false
+ *  to analyse just the single piece of content in the playlist (i.e. start from Playlist::start() and do not
+ *  use processors.
+ */
+AnalyseAudioJob::AnalyseAudioJob (shared_ptr<const Film> film, shared_ptr<const Playlist> playlist, bool whole_film)
        : Job (film)
-       , _analyser (film, playlist, from_zero, boost::bind(&Job::set_progress, this, _1, false))
+       , _analyser(film, playlist, whole_film, boost::bind(&Job::set_progress, this, _1, false))
        , _playlist (playlist)
        , _path (film->audio_analysis_path(playlist))
+       , _whole_film(whole_film)
 {
        LOG_DEBUG_AUDIO_ANALYSIS_NC("AnalyseAudioJob::AnalyseAudioJob");
 }
@@ -89,6 +93,9 @@ AnalyseAudioJob::run ()
        player->set_fast ();
        player->set_play_referenced ();
        player->Audio.connect (bind(&AudioAnalyser::analyse, &_analyser, _1, _2));
+       if (!_whole_film) {
+               player->set_disable_audio_processor();
+       }
 
        bool has_any_audio = false;
        for (auto c: _playlist->content()) {
index 2b749da6ba4b805a1ec3de988ca184e1a046d092..afd52c3040688c00f48ce215f0e2d48fe8acef35 100644 (file)
@@ -50,7 +50,7 @@ class Filter;
 class AnalyseAudioJob : public Job
 {
 public:
-       AnalyseAudioJob (std::shared_ptr<const Film>, std::shared_ptr<const Playlist>, bool from_zero);
+       AnalyseAudioJob(std::shared_ptr<const Film>, std::shared_ptr<const Playlist>, bool whole_film);
        ~AnalyseAudioJob ();
 
        std::string name () const override;
@@ -70,6 +70,7 @@ private:
        std::shared_ptr<const Playlist> _playlist;
        /** playlist's audio analysis path when the job was created */
        boost::filesystem::path _path;
+       bool _whole_film;
 
        static const int _num_points;
 };
index df76932dedb36ebad107754c6baf3f2a1fa4cd39..6e7b9fa86971152e88755fe049c9ba68c3a9f9f2 100644 (file)
@@ -52,7 +52,7 @@ using namespace dcpomatic;
 static auto constexpr num_points = 1024;
 
 
-AudioAnalyser::AudioAnalyser (shared_ptr<const Film> film, shared_ptr<const Playlist> playlist, bool from_zero, std::function<void (float)> set_progress)
+AudioAnalyser::AudioAnalyser(shared_ptr<const Film> film, shared_ptr<const Playlist> playlist, bool whole_film, std::function<void (float)> set_progress)
        : _film (film)
        , _playlist (playlist)
        , _set_progress (set_progress)
@@ -71,7 +71,7 @@ AudioAnalyser::AudioAnalyser (shared_ptr<const Film> film, shared_ptr<const Play
 
        _current = std::vector<AudioPoint>(_film->audio_channels());
 
-       if (!from_zero) {
+       if (!whole_film) {
                _start = _playlist->start().get_value_or(DCPTime());
        }
 
@@ -87,7 +87,9 @@ AudioAnalyser::AudioAnalyser (shared_ptr<const Film> film, shared_ptr<const Play
        };
 
        auto content = _playlist->content();
-       if (content.size() == 1 && content[0]->audio) {
+       if (whole_film) {
+               _leqm_channels = film->audio_channels();
+       } else {
                _leqm_channels = 0;
                for (auto channel: content[0]->audio->mapping().mapped_output_channels()) {
                        /* This means that if, for example, a file only maps C we will
@@ -96,8 +98,6 @@ AudioAnalyser::AudioAnalyser (shared_ptr<const Film> film, shared_ptr<const Play
                         */
                        _leqm_channels = std::min(film->audio_channels(), channel + 1);
                }
-       } else {
-               _leqm_channels = film->audio_channels();
        }
 
        /* XXX: is this right?  Especially for more than 5.1? */
index 4708f517a97cfd7d55d5678e6325e7cb76b0ea70..3d40f802604f07280dbcc46c120816e58f65d045 100644 (file)
@@ -39,7 +39,7 @@ class Playlist;
 class AudioAnalyser
 {
 public:
-       AudioAnalyser (std::shared_ptr<const Film> film, std::shared_ptr<const Playlist> playlist, bool from_zero, std::function<void (float)> set_progress);
+       AudioAnalyser(std::shared_ptr<const Film> film, std::shared_ptr<const Playlist> playlist, bool whole_film, std::function<void (float)> set_progress);
 
        AudioAnalyser (AudioAnalyser const&) = delete;
        AudioAnalyser& operator= (AudioAnalyser const&) = delete;
index 8bdca4c32877ccb744804f3a274608e611bc4735..8ded9eda9296d28a67f17a0fc7520e07e5a96415 100644 (file)
@@ -41,6 +41,7 @@
 #include "lib/ratio.h"
 #include "test.h"
 #include <boost/test/unit_test.hpp>
+#include <numeric>
 
 
 using std::make_shared;
@@ -283,3 +284,27 @@ BOOST_AUTO_TEST_CASE(analyse_audio_with_more_channels_than_film)
        BOOST_CHECK(!wait_for_jobs());
 }
 
+
+BOOST_AUTO_TEST_CASE(analyse_audio_uses_processor_when_analysing_whole_film)
+{
+       auto sound = content_factory(TestPaths::private_data() / "betty_stereo.wav")[0];
+       auto film = new_test_film2("analyse_audio_uses_processor_when_analysing_whole_film", { sound });
+
+       auto job = make_shared<AnalyseAudioJob>(film, film->playlist(), true);
+       JobManager::instance()->add(job);
+       BOOST_REQUIRE(!wait_for_jobs());
+
+       AudioAnalysis analysis(job->path());
+
+       BOOST_REQUIRE(analysis.channels() > 2);
+       bool centre_non_zero = false;
+       /* Make sure there's something from the mid-side decoder on the centre channel */
+       for (auto point = 0; point < analysis.points(2); ++point) {
+               if (std::abs(analysis.get_point(2, point)[AudioPoint::Type::PEAK]) > 0) {
+                       centre_non_zero = true;
+               }
+       }
+
+       BOOST_CHECK(centre_non_zero);
+}
+