diff --git a/libs/ardour/analysis_graph.cc b/libs/ardour/analysis_graph.cc index df204a46e3..4e0b5f01f8 100644 --- a/libs/ardour/analysis_graph.cc +++ b/libs/ardour/analysis_graph.cc @@ -18,6 +18,7 @@ #include "ardour/analysis_graph.h" +#include "ardour/progress.h" #include "ardour/route.h" #include "ardour/session.h" @@ -54,7 +55,13 @@ AnalysisGraph::~AnalysisGraph () } void -AnalysisGraph::analyze_region (boost::shared_ptr region) +AnalysisGraph::analyze_region (boost::shared_ptr region, bool raw) +{ + analyze_region (region.get(), raw, (ARDOUR::Progress*)0); +} + +void +AnalysisGraph::analyze_region (AudioRegion const* region, bool raw, ARDOUR::Progress* p) { int n_channels = region->n_channels(); if (n_channels == 0 || n_channels > _max_chunksize) { @@ -81,7 +88,11 @@ AnalysisGraph::analyze_region (boost::shared_ptr region) samplecnt_t n = 0; for (unsigned int channel = 0; channel < region->n_channels(); ++channel) { memset (_buf, 0, chunk * sizeof (Sample)); - n = region->read_at (_buf, _mixbuf, _gainbuf, region->position() + x, chunk, channel); + if (raw) { + n = region->read_raw_internal (_buf, region->start() + x, chunk, channel); + } else { + n = region->read_at (_buf, _mixbuf, _gainbuf, region->position() + x, chunk, channel); + } ConstProcessContext context (_buf, n, 1); if (n < _max_chunksize) { context().set_flag (ProcessContext::EndOfInput); @@ -99,6 +110,12 @@ AnalysisGraph::analyze_region (boost::shared_ptr region) if (_canceled) { return; } + if (p) { + p->set_progress (_samples_read / (float) _samples_end); + if (p->cancelled ()) { + return; + } + } } _results.insert (std::make_pair (region->name(), analyser->result ())); } diff --git a/libs/ardour/ardour/analysis_graph.h b/libs/ardour/ardour/analysis_graph.h index 71fc02aed4..3651763fff 100644 --- a/libs/ardour/ardour/analysis_graph.h +++ b/libs/ardour/ardour/analysis_graph.h @@ -38,12 +38,16 @@ namespace AudioGrapher { } namespace ARDOUR { + class Progress; + class LIBARDOUR_API AnalysisGraph { public: AnalysisGraph (ARDOUR::Session*); ~AnalysisGraph (); - void analyze_region (boost::shared_ptr); + void analyze_region (ARDOUR::AudioRegion const*, bool raw = false, ARDOUR::Progress* = 0); + void analyze_region (boost::shared_ptr, bool raw = false); + void analyze_range (boost::shared_ptr, boost::shared_ptr, const std::list&); const AnalysisResults& results () const { return _results; } diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h index 6eaa37f1f4..83371abb3a 100644 --- a/libs/ardour/ardour/audioregion.h +++ b/libs/ardour/ardour/audioregion.h @@ -92,6 +92,8 @@ class LIBARDOUR_API AudioRegion : public Region */ double rms (Progress* p = 0) const; + bool loudness (float& tp, float& i, float& s, float& m, Progress* p = 0) const; + bool envelope_active () const { return _envelope_active; } bool fade_in_active () const { return _fade_in_active; } bool fade_out_active () const { return _fade_out_active; } diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index a4afb2abd2..6e663626d4 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -41,6 +41,7 @@ #include "evoral/Curve.h" +#include "ardour/analysis_graph.h" #include "ardour/audioregion.h" #include "ardour/session.h" #include "ardour/dB.h" @@ -1470,6 +1471,37 @@ AudioRegion::rms (Progress* p) const return sqrt (2. * rms / (double)(total * n_chan)); } +bool +AudioRegion::loudness (float& tp, float& i, float& s, float& m, Progress* p) const +{ + ARDOUR::AnalysisGraph ag (&_session); + tp = i = s = m = -200; + + ag.set_total_samples (_length); + ag.analyze_region (this, true, p); + + if (p && p->cancelled ()) { + return false; + } + + AnalysisResults const& ar (ag.results ()); + if (ar.size() != 1) { + return false; + } + ExportAnalysisPtr eap (ar.begin ()->second); + + if (eap->have_dbtp) { + tp = eap->truepeak; + } + if (eap->have_loudness) { + i = eap->integrated_loudness; + s = eap->max_loudness_short; + m = eap->max_loudness_momentary; + } + + return eap->have_dbtp || eap->have_loudness; +} + /** Normalize using a given maximum amplitude and target, so that region * _scale_amplitude becomes target / max_amplitude. */