X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fanalyse_audio_job.cc;h=acd730a68bc1e4588546a64cdabed407ba5aac80;hb=f20ec58b5fa6b5ffd49f0af6865290a775077e73;hp=fe56b3b6c9265005f8ba9c6e9dd427a6250246e1;hpb=366910025ce80231f1192662efe79f76d78ff572;p=dcpomatic.git diff --git a/src/lib/analyse_audio_job.cc b/src/lib/analyse_audio_job.cc index fe56b3b6c..acd730a68 100644 --- a/src/lib/analyse_audio_job.cc +++ b/src/lib/analyse_audio_job.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2015 Carl Hetherington + Copyright (C) 2012-2018 Carl Hetherington This file is part of DCP-o-matic. @@ -23,6 +23,7 @@ #include "analyse_audio_job.h" #include "audio_content.h" #include "compose.hpp" +#include "dcpomatic_log.h" #include "film.h" #include "player.h" #include "playlist.h" @@ -30,6 +31,7 @@ #include "audio_filter_graph.h" #include "config.h" extern "C" { +#include #include #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG #include @@ -47,12 +49,23 @@ using std::min; using std::cout; using boost::shared_ptr; using boost::dynamic_pointer_cast; +using namespace dcpomatic; int const AnalyseAudioJob::_num_points = 1024; -AnalyseAudioJob::AnalyseAudioJob (shared_ptr film, shared_ptr playlist) +static void add_if_required(vector& v, size_t i, double db) +{ + if (v.size() > i) { + v[i] = pow(10, db / 20); + } +} + +/** @param from_zero true to analyse audio from time 0 in the playlist, otherwise begin at Playlist::start */ +AnalyseAudioJob::AnalyseAudioJob (shared_ptr film, shared_ptr playlist, bool from_zero) : Job (film) , _playlist (playlist) + , _path (film->audio_analysis_path(playlist)) + , _from_zero (from_zero) , _done (0) , _samples_per_point (1) , _current (0) @@ -62,6 +75,8 @@ AnalyseAudioJob::AnalyseAudioJob (shared_ptr film, shared_ptraudio_frame_rate(), film->audio_channels())) #endif { + LOG_DEBUG_AUDIO_ANALYSIS_NC("AnalyseAudioJob::AnalyseAudioJob"); + #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG _filters.push_back (new Filter ("ebur128", "ebur128", "audio", "ebur128=peak=true")); _ebur128->setup (_filters); @@ -71,10 +86,40 @@ AnalyseAudioJob::AnalyseAudioJob (shared_ptr film, shared_ptrstart().get_value_or(DCPTime()); + } + + /* XXX: is this right? Especially for more than 5.1? */ + vector channel_corrections(film->audio_channels(), 1); + add_if_required (channel_corrections, 4, -3); // Ls + add_if_required (channel_corrections, 5, -3); // Rs + add_if_required (channel_corrections, 6, -144); // HI + add_if_required (channel_corrections, 7, -144); // VI + add_if_required (channel_corrections, 8, -3); // Lc + add_if_required (channel_corrections, 9, -3); // Rc + add_if_required (channel_corrections, 10, -3); // Lc + add_if_required (channel_corrections, 11, -3); // Rc + add_if_required (channel_corrections, 12, -144); // DBox + add_if_required (channel_corrections, 13, -144); // Sync + add_if_required (channel_corrections, 14, -144); // Sign Language + add_if_required (channel_corrections, 15, -144); // Unused + + _leqm.reset(new leqm_nrt::Calculator( + film->audio_channels(), + film->audio_frame_rate(), + 24, + channel_corrections, + 850, // suggested by leqm_nrt CLI source + 64, // suggested by leqm_nrt CLI source + boost::thread::hardware_concurrency() + )); } AnalyseAudioJob::~AnalyseAudioJob () { + stop_thread (); BOOST_FOREACH (Filter const * i, _filters) { delete const_cast (i); } @@ -86,7 +131,7 @@ AnalyseAudioJob::~AnalyseAudioJob () string AnalyseAudioJob::name () const { - return _("Analyse audio"); + return _("Analysing audio"); } string @@ -98,17 +143,18 @@ AnalyseAudioJob::json_name () const void AnalyseAudioJob::run () { - shared_ptr player (new Player (_film, _playlist)); + LOG_DEBUG_AUDIO_ANALYSIS_NC("AnalyseAudioJob::run"); + + shared_ptr player (new Player(_film, _playlist)); player->set_ignore_video (); - player->set_ignore_subtitle (); + player->set_ignore_text (); player->set_fast (); player->set_play_referenced (); player->Audio.connect (bind (&AnalyseAudioJob::analyse, this, _1, _2)); - DCPTime const start = _playlist->start().get_value_or (DCPTime ()); - DCPTime const length = _playlist->length (); + DCPTime const length = _playlist->length (_film); - Frame const len = DCPTime (length - start).frames_round (_film->audio_frame_rate()); + Frame const len = DCPTime (length - _start).frames_round (_film->audio_frame_rate()); _samples_per_point = max (int64_t (1), len / _num_points); delete[] _current; @@ -123,10 +169,15 @@ AnalyseAudioJob::run () } if (has_any_audio) { + LOG_DEBUG_AUDIO_ANALYSIS("Seeking to %1", to_string(_start)); + player->seek (_start, true); _done = 0; + LOG_DEBUG_AUDIO_ANALYSIS("Starting loop for playlist of length %1", to_string(length)); while (!player->pass ()) {} } + LOG_DEBUG_AUDIO_ANALYSIS_NC("Loop complete"); + vector sample_peak; for (int i = 0; i < _film->audio_channels(); ++i) { sample_peak.push_back ( @@ -153,12 +204,17 @@ AnalyseAudioJob::run () gain was when we analysed it. */ shared_ptr ac = _playlist->content().front()->audio; - DCPOMATIC_ASSERT (ac); - _analysis->set_analysis_gain (ac->gain ()); + if (ac) { + _analysis->set_analysis_gain (ac->gain()); + } } - _analysis->write (_film->audio_analysis_path (_playlist)); + _analysis->set_samples_per_point (_samples_per_point); + _analysis->set_sample_rate (_film->audio_frame_rate ()); + _analysis->set_leqm (_leqm->leq_m()); + _analysis->write (_path); + LOG_DEBUG_AUDIO_ANALYSIS_NC("Job finished"); set_progress (1); set_state (FINISHED_OK); } @@ -166,6 +222,9 @@ AnalyseAudioJob::run () void AnalyseAudioJob::analyse (shared_ptr b, DCPTime time) { + LOG_DEBUG_AUDIO_ANALYSIS("Received %1 frames at %2", b->frames(), to_string(time)); + DCPOMATIC_ASSERT (time >= _start); + #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG if (Config::instance()->analyse_ebur128 ()) { _ebur128->process (b); @@ -174,11 +233,15 @@ AnalyseAudioJob::analyse (shared_ptr b, DCPTime time) int const frames = b->frames (); int const channels = b->channels (); + vector interleaved(frames * channels); for (int j = 0; j < channels; ++j) { float* data = b->data(j); for (int i = 0; i < frames; ++i) { float s = data[i]; + + interleaved[i * channels + j] = s; + float as = fabsf (s); if (as < 10e-7) { /* We may struggle to serialise and recover inf or -inf, so prevent such @@ -201,9 +264,11 @@ AnalyseAudioJob::analyse (shared_ptr b, DCPTime time) } } + _leqm->add(interleaved); + _done += frames; - DCPTime const start = _playlist->start().get_value_or (DCPTime ()); - DCPTime const length = _playlist->length (); - set_progress ((time.seconds() - start.seconds()) / (length.seconds() - start.seconds())); + DCPTime const length = _playlist->length (_film); + set_progress ((time.seconds() - _start.seconds()) / (length.seconds() - _start.seconds())); + LOG_DEBUG_AUDIO_ANALYSIS_NC("Frames processed"); }