13
0

Keep track of export-limiter redux

This commit is contained in:
Robin Gareus 2021-04-09 05:52:51 +02:00
parent 89a65f76b0
commit c4f0393cf9
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
6 changed files with 69 additions and 5 deletions

View File

@ -49,6 +49,7 @@ namespace ARDOUR {
memset (spectrum, 0, sizeof(spectrum)); memset (spectrum, 0, sizeof(spectrum));
memset (loudness_hist, 0, sizeof(loudness_hist)); memset (loudness_hist, 0, sizeof(loudness_hist));
memset (freq, 0, sizeof(freq)); 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_s));
assert (sizeof(lgraph_i) == sizeof(lgraph_m)); assert (sizeof(lgraph_i) == sizeof(lgraph_m));
for (size_t i = 0; i < sizeof(lgraph_i) / sizeof (float); ++i) { for (size_t i = 0; i < sizeof(lgraph_i) / sizeof (float); ++i) {
@ -84,6 +85,7 @@ namespace ARDOUR {
memcpy (lgraph_i, other.lgraph_i, sizeof(lgraph_i)); memcpy (lgraph_i, other.lgraph_i, sizeof(lgraph_i));
memcpy (lgraph_s, other.lgraph_s, sizeof(lgraph_s)); memcpy (lgraph_s, other.lgraph_s, sizeof(lgraph_s));
memcpy (lgraph_m, other.lgraph_m, sizeof(lgraph_m)); memcpy (lgraph_m, other.lgraph_m, sizeof(lgraph_m));
memcpy (limiter_pk, other.limiter_pk, sizeof(limiter_pk));
} }
float peak; float peak;
@ -109,6 +111,7 @@ namespace ARDOUR {
float lgraph_i[800]; float lgraph_i[800];
float lgraph_s[800]; float lgraph_s[800];
float lgraph_m[800]; float lgraph_m[800];
float limiter_pk[800];
std::set<samplecnt_t> truepeakpos[2]; // bins with >= -1dBTB std::set<samplecnt_t> truepeakpos[2]; // bins with >= -1dBTB
}; };

View File

@ -460,6 +460,7 @@ ExportGraphBuilder::SFC::SFC (ExportGraphBuilder &parent, FileSpec const & new_c
config.filename->set_channel_config (config.channel_config); config.filename->set_channel_config (config.channel_config);
parent.add_analyser (config.filename->get_path (config.format), analyser); parent.add_analyser (config.filename->get_path (config.format), analyser);
limiter->set_result (analyser->result (true));
chunker->add_output (analyser); chunker->add_output (analyser);
intermediate->add_output (chunker); intermediate->add_output (chunker);
@ -510,6 +511,9 @@ ExportGraphBuilder::SFC::set_duration (samplecnt_t n_samples)
if (analyser) { if (analyser) {
analyser->set_duration (n_samples); analyser->set_duration (n_samples);
} }
if (limiter) {
limiter->set_duration (n_samples);
}
} }
void void

View File

@ -32,7 +32,7 @@ class LIBAUDIOGRAPHER_API Analyser : public LoudnessReader
Analyser (float sample_rate, unsigned int channels, samplecnt_t bufsize, samplecnt_t n_samples); Analyser (float sample_rate, unsigned int channels, samplecnt_t bufsize, samplecnt_t n_samples);
~Analyser (); ~Analyser ();
void process (ProcessContext<float> const & c); void process (ProcessContext<float> const & c);
ARDOUR::ExportAnalysisPtr result (); ARDOUR::ExportAnalysisPtr result (bool ptr = false);
void set_duration (samplecnt_t n_samples); void set_duration (samplecnt_t n_samples);
@ -48,7 +48,8 @@ class LIBAUDIOGRAPHER_API Analyser : public LoudnessReader
private: private:
float fft_power_at_bin (const uint32_t b, const float norm) const; float fft_power_at_bin (const uint32_t b, const float norm) const;
ARDOUR::ExportAnalysis _result; ARDOUR::ExportAnalysisPtr _rp;
ARDOUR::ExportAnalysis& _result;
samplecnt_t _n_samples; samplecnt_t _n_samples;
samplecnt_t _pos; samplecnt_t _pos;

View File

@ -1,6 +1,8 @@
#ifndef AUDIOGRAPHER_LIMITER_H #ifndef AUDIOGRAPHER_LIMITER_H
#define AUDIOGRAPHER_LIMITER_H #define AUDIOGRAPHER_LIMITER_H
#include "ardour/export_analysis.h"
#include "audiographer/visibility.h" #include "audiographer/visibility.h"
#include "audiographer/sink.h" #include "audiographer/sink.h"
#include "audiographer/utils/listed_source.h" #include "audiographer/utils/listed_source.h"
@ -23,16 +25,26 @@ public:
void set_threshold (float dB); void set_threshold (float dB);
void set_release (float s); void set_release (float s);
void set_duration (samplecnt_t);
void set_result (ARDOUR::ExportAnalysisPtr);
void process (ProcessContext<float> const& ctx); void process (ProcessContext<float> const& ctx);
using Sink<float>::process; using Sink<float>::process;
private: private:
void stats (samplecnt_t);
bool _enabled; bool _enabled;
float* _buf; float* _buf;
samplecnt_t _size; samplecnt_t _size;
samplecnt_t _latency; samplecnt_t _latency;
AudioGrapherDSP::Limiter _limiter; samplecnt_t _cnt;
samplecnt_t _spp;
size_t _pos;
ARDOUR::ExportAnalysisPtr _result;
AudioGrapherDSP::Limiter _limiter;
}; };
} // namespace } // namespace

View File

@ -25,9 +25,12 @@ const float Analyser::fft_range_db (120); // dB
Analyser::Analyser (float sample_rate, unsigned int channels, samplecnt_t bufsize, samplecnt_t n_samples) Analyser::Analyser (float sample_rate, unsigned int channels, samplecnt_t bufsize, samplecnt_t n_samples)
: LoudnessReader (sample_rate, channels, bufsize) : LoudnessReader (sample_rate, channels, bufsize)
, _rp (ARDOUR::ExportAnalysisPtr (new ARDOUR::ExportAnalysis))
, _result (*_rp)
, _n_samples (n_samples) , _n_samples (n_samples)
, _pos (0) , _pos (0)
{ {
//printf ("NEW ANALYSER %p r:%.1f c:%d f:%ld l%ld\n", this, sample_rate, channels, bufsize, n_samples); //printf ("NEW ANALYSER %p r:%.1f c:%d f:%ld l%ld\n", this, sample_rate, channels, bufsize, n_samples);
assert (bufsize % channels == 0); assert (bufsize % channels == 0);
assert (bufsize > 1); assert (bufsize > 1);
@ -223,8 +226,12 @@ Analyser::process (ProcessContext<float> const & ctx)
} }
ARDOUR::ExportAnalysisPtr ARDOUR::ExportAnalysisPtr
Analyser::result () Analyser::result (bool ptr_only)
{ {
if (ptr_only) {
return _rp;
}
//printf ("PROCESSED %ld / %ld samples\n", _pos, _n_samples); //printf ("PROCESSED %ld / %ld samples\n", _pos, _n_samples);
if (_pos == 0 || _pos > _n_samples + 1) { if (_pos == 0 || _pos > _n_samples + 1) {
return ARDOUR::ExportAnalysisPtr (); return ARDOUR::ExportAnalysisPtr ();
@ -300,7 +307,7 @@ Analyser::result ()
} }
} }
return ARDOUR::ExportAnalysisPtr (new ARDOUR::ExportAnalysis (_result)); return _rp;
} }
float float

View File

@ -25,6 +25,9 @@ Limiter::Limiter (float sample_rate, unsigned int channels, samplecnt_t size)
: _enabled (false) : _enabled (false)
, _buf (0) , _buf (0)
, _size (0) , _size (0)
, _cnt (0)
, _spp (0)
, _pos (0)
{ {
_limiter.init (sample_rate, channels); _limiter.init (sample_rate, channels);
@ -63,6 +66,38 @@ Limiter::set_release (float s)
_limiter.set_release (s); _limiter.set_release (s);
} }
void
Limiter::set_duration (samplecnt_t s)
{
if (_pos != 0 || !_result) {
return;
}
const size_t n_data = sizeof (ARDOUR::ExportAnalysis::limiter_pk) / sizeof (float);
_spp = ceilf (s / (float) n_data);
}
void
Limiter::set_result (ARDOUR::ExportAnalysisPtr r)
{
_result = r;
}
void
Limiter::stats (samplecnt_t n_samples)
{
if (!_result || _spp == 0) {
return;
}
_cnt += n_samples;
while (_cnt >= _spp) {
float peak, gmax, gmin;
_limiter.get_stats (&peak, &gmax, &gmin);
_cnt -= _spp;
assert (_pos < sizeof (ARDOUR::ExportAnalysis::limiter_pk) / sizeof (float));
_result->limiter_pk[_pos++] = peak;
}
}
void Limiter::process (ProcessContext<float> const& ctx) void Limiter::process (ProcessContext<float> const& ctx)
{ {
const samplecnt_t n_samples = ctx.samples_per_channel (); const samplecnt_t n_samples = ctx.samples_per_channel ();
@ -75,6 +110,7 @@ void Limiter::process (ProcessContext<float> const& ctx)
} }
_limiter.process (n_samples, ctx.data (), _buf); _limiter.process (n_samples, ctx.data (), _buf);
stats (n_samples);
if (_latency > 0) { if (_latency > 0) {
samplecnt_t ns = n_samples > _latency ? n_samples - _latency : 0; samplecnt_t ns = n_samples > _latency ? n_samples - _latency : 0;
@ -101,6 +137,7 @@ void Limiter::process (ProcessContext<float> const& ctx)
memset (_buf, 0, _size * sizeof (float)); memset (_buf, 0, _size * sizeof (float));
samplecnt_t ns = _latency > bs ? bs : _latency; samplecnt_t ns = _latency > bs ? bs : _latency;
_limiter.process (ns, _buf, _buf); _limiter.process (ns, _buf, _buf);
//stats (ns);
ProcessContext<float> ctx_out (ctx, _buf, ns * n_channels); ProcessContext<float> ctx_out (ctx, _buf, ns * n_channels);
if (_latency == ns) { if (_latency == ns) {
ctx_out.set_flag (ProcessContext<float>::EndOfInput); ctx_out.set_flag (ProcessContext<float>::EndOfInput);