Export analysis: log loudness / time

This commit is contained in:
Robin Gareus 2021-04-04 01:11:55 +02:00
parent e3a6fab05e
commit c1d98ca3c8
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
3 changed files with 65 additions and 3 deletions

View File

@ -38,15 +38,25 @@ namespace ARDOUR {
, max_loudness_momentary (0)
, loudness_hist_max (0)
, have_loudness (false)
, have_lufs_graph (false)
, have_dbtp (false)
, norm_gain_factor (1.0)
, normalized (false)
, n_channels (1)
, n_samples (0)
{
memset (peaks, 0, sizeof(peaks));
memset (spectrum, 0, sizeof(spectrum));
memset (loudness_hist, 0, sizeof(loudness_hist));
memset (freq, 0, sizeof(freq));
assert (sizeof(lgraph_i) == sizeof(lgraph_s));
assert (sizeof(lgraph_i) == sizeof(lgraph_m));
for (size_t i = 0; i < sizeof(lgraph_i) / sizeof (float); ++i) {
/* d compare to ebu_r128_proc.cc */
lgraph_i [i] = -200;
lgraph_s [i] = -200;
lgraph_m [i] = -200;
}
}
ExportAnalysis (const ExportAnalysis& other)
@ -58,10 +68,12 @@ namespace ARDOUR {
, max_loudness_momentary (other.max_loudness_momentary)
, loudness_hist_max (other.loudness_hist_max)
, have_loudness (other.have_loudness)
, have_lufs_graph (other.have_lufs_graph)
, have_dbtp (other.have_dbtp)
, norm_gain_factor (other.norm_gain_factor)
, normalized (other.normalized)
, n_channels (other.n_channels)
, n_samples (other.n_samples)
{
truepeakpos[0] = other.truepeakpos[0];
truepeakpos[1] = other.truepeakpos[1];
@ -69,6 +81,9 @@ namespace ARDOUR {
memcpy (spectrum, other.spectrum, sizeof(spectrum));
memcpy (loudness_hist, other.loudness_hist, sizeof(loudness_hist));
memcpy (freq, other.freq, sizeof(freq));
memcpy (lgraph_i, other.lgraph_i, sizeof(lgraph_i));
memcpy (lgraph_s, other.lgraph_s, sizeof(lgraph_s));
memcpy (lgraph_m, other.lgraph_m, sizeof(lgraph_m));
}
float peak;
@ -80,15 +95,20 @@ namespace ARDOUR {
int loudness_hist[540];
int loudness_hist_max;
bool have_loudness;
bool have_lufs_graph;
bool have_dbtp;
float norm_gain_factor;
bool normalized;
uint32_t n_channels;
uint32_t n_samples;
uint32_t freq[6]; // y-pos, 50, 100, 500, 1k, 5k, 10k [Hz]
PeakData peaks[2][800];
float spectrum[800][200];
float lgraph_i[800];
float lgraph_s[800];
float lgraph_m[800];
std::set<samplecnt_t> truepeakpos[2]; // bins with >= -1dBTB
};

View File

@ -123,6 +123,7 @@ Analyser::process (ProcessContext<float> const & ctx)
for (s = 0; s < n_samples; ++s) {
_fft_data_in[s] = 0;
const samplecnt_t pbin = (_pos + s) / _spp;
assert (pbin >= 0 && pbin < (sizeof (_result.peaks) / sizeof (ARDOUR::PeakData::PeakDatum) / 4));
for (unsigned int c = 0; c < _channels; ++c) {
const float v = *d;
if (fabsf(v) > _result.peak) { _result.peak = fabsf(v); }
@ -145,7 +146,18 @@ Analyser::process (ProcessContext<float> const & ctx)
}
if (_ebur_plugin) {
_ebur_plugin->process (_bufs, Vamp::RealTime::fromSeconds ((double) _pos / _sample_rate));
Vamp::Plugin::FeatureSet features = _ebur_plugin->process (_bufs, Vamp::RealTime::fromSeconds ((double) _pos / _sample_rate));
if (!features.empty ()) {
const samplecnt_t p0 = _pos / _spp;
const samplecnt_t p1 = (_pos + n_samples -1) / _spp;
for (samplecnt_t p = p0; p <= p1; ++p) {
assert (p >= 0 && p < (sizeof (_result.lgraph_i) / sizeof(float)));
_result.lgraph_i[p] = features[0][0].values[0];
_result.lgraph_s[p] = features[0][1].values[0];
_result.lgraph_m[p] = features[0][2].values[0];
}
_result.have_lufs_graph = true;
}
}
float const * const data = ctx.data ();
@ -208,6 +220,8 @@ Analyser::result ()
return ARDOUR::ExportAnalysisPtr ();
}
_result.n_samples = _pos;
if (_pos + 1 < _n_samples) {
// crude re-bin (silence stripped version)
const size_t peaks = sizeof (_result.peaks) / sizeof (ARDOUR::PeakData::PeakDatum) / 4;
@ -229,6 +243,15 @@ Analyser::result ()
_result.spectrum[b][y] = _result.spectrum[sb][y];
}
}
/* re-scale loudnes graphs */
const size_t lw = sizeof (_result.lgraph_i) / sizeof (float);
for (samplecnt_t b = lw - 1; b > 0; --b) {
const samplecnt_t sb = b * _pos / _n_samples;
_result.lgraph_i[b] = _result.lgraph_i[sb];
_result.lgraph_s[b] = _result.lgraph_s[sb];
_result.lgraph_m[b] = _result.lgraph_m[sb];
}
}
if (_ebur_plugin) {

View File

@ -107,8 +107,9 @@ VampEBUr128::getOutputDescriptors () const
OutputList list;
OutputDescriptor zc;
zc.identifier = "loundless";
zc.name = "Integrated loudness";
zc.name = "Loudness";
zc.description = "Loudness (integrated, short, momentary)";
zc.unit = "LUFS";
zc.hasFixedBinCount = true;
@ -157,7 +158,25 @@ VampEBUr128::process (const float* const* inputBuffers,
ebu.integr_start (); // noop if already started
ebu.process (m_stepSize, inputBuffers);
return FeatureSet ();
FeatureSet returnFeatures;
Feature loudness_integrated;
loudness_integrated.hasTimestamp = false;
loudness_integrated.values.push_back (ebu.integrated ());
Feature loudness_short;
loudness_short.hasTimestamp = false;
loudness_short.values.push_back (ebu.loudness_S ());
Feature loudness_momentary;
loudness_momentary.hasTimestamp = false;
loudness_momentary.values.push_back (ebu.loudness_M ());
returnFeatures[0].push_back (loudness_integrated);
returnFeatures[0].push_back (loudness_short);
returnFeatures[0].push_back (loudness_momentary);
return returnFeatures;
}
VampEBUr128::FeatureSet