13
0

Prepare scaleable analysis (variable width, bins)

This commit is contained in:
Robin Gareus 2021-12-24 19:48:35 +01:00
parent ea9512ff1a
commit 122d219354
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
3 changed files with 80 additions and 57 deletions

View File

@ -21,7 +21,9 @@
#include <map>
#include <set>
#include <vector>
#include <cstring>
#include <boost/shared_ptr.hpp>
#include "ardour/types.h"
@ -29,8 +31,9 @@
namespace ARDOUR {
struct ExportAnalysis {
public:
ExportAnalysis ()
: peak (0)
ExportAnalysis (size_t w = 800, size_t b = 200)
: width (w)
, peak (0)
, truepeak (0)
, loudness_range (0)
, integrated_loudness (0)
@ -45,14 +48,23 @@ namespace ARDOUR {
, 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));
memset (limiter_pk, 0, sizeof(limiter_pk));
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) {
b = std::max<size_t> (100, b);
width = std::max<size_t> (800, width);
peaks[0].resize (w);
peaks[1].resize (width);
spectrum.resize (width);
for (size_t i = 0; i < width; ++i) {
spectrum[i].resize (b);
}
lgraph_i = new float [width]();
lgraph_s = new float [width]();
lgraph_m = new float [width]();
limiter_pk = new float [width]();
for (size_t i = 0; i < width; ++i) {
/* d compare to ebu_r128_proc.cc */
lgraph_i [i] = -200;
lgraph_s [i] = -200;
@ -61,7 +73,8 @@ namespace ARDOUR {
}
ExportAnalysis (const ExportAnalysis& other)
: peak (other.peak)
: width (other.width)
, peak (other.peak)
, truepeak (other.truepeak)
, loudness_range (other.loudness_range)
, integrated_loudness (other.integrated_loudness)
@ -75,43 +88,60 @@ namespace ARDOUR {
, normalized (other.normalized)
, n_channels (other.n_channels)
, n_samples (other.n_samples)
, peaks (other.peaks)
, spectrum (other.spectrum)
{
lgraph_i = new float [width];
lgraph_s = new float [width];
lgraph_m = new float [width];
limiter_pk = new float [width]();
truepeakpos[0] = other.truepeakpos[0];
truepeakpos[1] = other.truepeakpos[1];
memcpy (peaks, other.peaks, sizeof(peaks));
memcpy (spectrum, other.spectrum, sizeof(spectrum));
memcpy (loudness_hist, other.loudness_hist, sizeof(loudness_hist));
memcpy (loudness_hist, other.loudness_hist, sizeof(float) * width);
memcpy (lgraph_i, other.lgraph_i, sizeof(float) * width);
memcpy (lgraph_s, other.lgraph_s, sizeof(float) * width);
memcpy (lgraph_m, other.lgraph_m, sizeof(float) * width);
memcpy (limiter_pk, other.limiter_pk, sizeof(float) * width);
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));
memcpy (limiter_pk, other.limiter_pk, sizeof(limiter_pk));
}
float peak;
float truepeak;
float loudness_range;
float integrated_loudness;
float max_loudness_short;
float max_loudness_momentary;
int loudness_hist[540];
int loudness_hist_max;
bool have_loudness;
bool have_lufs_graph;
bool have_dbtp;
float norm_gain_factor;
bool normalized;
~ExportAnalysis ()
{
delete [] lgraph_i;
delete [] lgraph_s;
delete [] lgraph_m;
delete [] limiter_pk;
}
size_t width;
float peak;
float truepeak;
float loudness_range;
float integrated_loudness;
float max_loudness_short;
float max_loudness_momentary;
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];
float limiter_pk[800];
std::vector<PeakData> peaks[2];
std::vector<std::vector<float> > spectrum;
float* lgraph_i; //[800];
float* lgraph_s; //[800];
float* lgraph_m; //[800];
float* limiter_pk; //[800];
std::set<samplecnt_t> truepeakpos[2]; // bins with >= -1dBTB
};

View File

@ -52,7 +52,7 @@ Analyser::Analyser (float sample_rate, unsigned int channels, samplecnt_t bufsiz
_fft_data_out[i] = 0;
}
const size_t height = sizeof (_result.spectrum[0]) / sizeof (float);
const size_t height = _result.spectrum[0].size ();
const float nyquist = (sample_rate * .5);
#if 0 // linear
#define YPOS(FREQ) rint (height * (1.0 - FREQ / nyquist))
@ -105,13 +105,9 @@ Analyser::set_duration (samplecnt_t n_samples)
}
_n_samples = n_samples;
const size_t peaks = sizeof (_result.peaks) / sizeof (ARDOUR::PeakData::PeakDatum) / 4;
_spp = ceil ((_n_samples + 2.f) / (float) peaks);
const size_t swh = sizeof (_result.spectrum) / sizeof (float);
const size_t height = sizeof (_result.spectrum[0]) / sizeof (float);
const size_t width = swh / height;
_fpp = ceil ((_n_samples + 2.f) / (float) width);
const float width = _result.width;
_spp = ceil ((_n_samples + 2.f) / width);
_fpp = ceil ((_n_samples + 2.f) / width);
}
void
@ -136,7 +132,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));
assert (pbin >= 0 && pbin < _result.width);
for (unsigned int c = 0; c < _channels; ++c) {
const float v = *d;
if (fabsf(v) > _result.peak) { _result.peak = fabsf(v); }
@ -164,7 +160,7 @@ Analyser::process (ProcessContext<float> const & ctx)
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)));
assert (p >= 0 && p < _result.width);
_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];
@ -192,7 +188,7 @@ Analyser::process (ProcessContext<float> const & ctx)
#undef FRe
#undef FIm
const size_t height = sizeof (_result.spectrum[0]) / sizeof (float);
const size_t height = _result.spectrum[0].size ();
const samplecnt_t x0 = _pos / _fpp;
samplecnt_t x1 = (_pos + n_samples) / _fpp;
if (x0 == x1) x1 = x0 + 1;
@ -241,8 +237,8 @@ Analyser::result (bool ptr_only)
if (_pos + 1 < _n_samples) {
// crude re-bin (silence stripped version)
const size_t peaks = sizeof (_result.peaks) / sizeof (ARDOUR::PeakData::PeakDatum) / 4;
for (samplecnt_t b = peaks - 1; b > 0; --b) {
const size_t width = _result.width;
for (samplecnt_t b = width - 1; b > 0; --b) {
for (unsigned int c = 0; c < _result.n_channels; ++c) {
const samplecnt_t sb = b * _pos / _n_samples;
_result.peaks[c][b].min = _result.peaks[c][sb].min;
@ -250,9 +246,7 @@ Analyser::result (bool ptr_only)
}
}
const size_t swh = sizeof (_result.spectrum) / sizeof (float);
const size_t height = sizeof (_result.spectrum[0]) / sizeof (float);
const size_t width = swh / height;
const size_t height = _result.spectrum[0].size ();
for (samplecnt_t b = width - 1; b > 0; --b) {
// TODO round down to prev _fft_data_size bin
const samplecnt_t sb = b * _pos / _n_samples;
@ -262,7 +256,7 @@ Analyser::result (bool ptr_only)
}
/* re-scale loudnes graphs */
const size_t lw = sizeof (_result.lgraph_i) / sizeof (float);
const size_t lw = _result.width;
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];

View File

@ -72,8 +72,7 @@ Limiter::set_duration (samplecnt_t s)
if (_pos != 0 || !_result) {
return;
}
const size_t n_data = sizeof (_result->limiter_pk) / sizeof (float);
_spp = ceilf ((s + 2.f) / (float) n_data);
_spp = ceilf ((s + 2.f) / (float) _result->width);
}
void
@ -93,7 +92,7 @@ Limiter::stats (samplecnt_t n_samples)
float peak, gmax, gmin;
_limiter.get_stats (&peak, &gmax, &gmin);
_cnt -= _spp;
assert (_pos < sizeof (_result->limiter_pk) / sizeof (float));
assert (_pos < _result->width);
_result->limiter_pk[_pos++] = peak;
}
}