update export analyser for dBTP
authorRobin Gareus <robin@gareus.org>
Thu, 11 Feb 2016 13:07:27 +0000 (14:07 +0100)
committerRobin Gareus <robin@gareus.org>
Thu, 11 Feb 2016 13:14:01 +0000 (14:14 +0100)
libs/ardour/ardour/export_analysis.h
libs/audiographer/audiographer/general/analyser.h
libs/audiographer/src/general/analyser.cc

index 0b40a4194788d8ef0c92fe541ed9dd4cbf491719..9da0a4f7876d02f844198e00335669b69152d0af 100644 (file)
@@ -29,10 +29,13 @@ namespace ARDOUR {
        struct ExportAnalysis {
        public:
                ExportAnalysis ()
-                       : loudness (0)
+                       : peak (0)
+                       , truepeak (0)
+                       , loudness (0)
                        , loudness_range (0)
                        , loudness_hist_max (0)
                        , have_loudness (false)
+                       , have_dbtp (false)
                        , n_channels (1)
                {
                        memset (peaks, 0, sizeof(peaks));
@@ -42,10 +45,13 @@ namespace ARDOUR {
                }
 
                ExportAnalysis (const ExportAnalysis& other)
-                       : loudness (other.loudness)
+                       : peak (other.peak)
+                       , truepeak (other.truepeak)
+                       , loudness (other.loudness)
                        , loudness_range (other.loudness_range)
                        , loudness_hist_max (other.loudness_hist_max)
                        , have_loudness (other.have_loudness)
+                       , have_dbtp (other.have_dbtp)
                        , n_channels (other.n_channels)
                {
                        memcpy (peaks, other.peaks, sizeof(peaks));
@@ -54,11 +60,14 @@ namespace ARDOUR {
                        memcpy (freq, other.freq, sizeof(freq));
                }
 
+               float peak;
+               float truepeak;
                float loudness;
                float loudness_range;
                int loudness_hist[540];
                int loudness_hist_max;
                bool have_loudness;
+               bool have_dbtp;
 
                uint32_t n_channels;
                uint32_t freq[6]; // y-pos, 50, 100, 500, 1k, 5k, 10k [Hz]
index 0869ad7550e512eed4c8848c416456c8b578c079..a6029006a3ba6ed76e7d46246617f3db1b52367f 100644 (file)
@@ -47,7 +47,8 @@ class /*LIBAUDIOGRAPHER_API*/ Analyser : public ListedSource<float>, public Sink
        float fft_power_at_bin (const uint32_t b, const float norm) const;
 
        ARDOUR::ExportAnalysis _result;
-       Vamp::Plugin* _ebur128_plugin;
+       Vamp::Plugin*  _ebur128_plugin;
+       Vamp::Plugin** _dbtp_plugin;
 
        float        _sample_rate;
        unsigned int _channels;
index 2764971a7dae106445b3dd79327ea94dd28a19d0..726fb1bc2d7828a62b5ae5d8b76419d2c18f6c7b 100644 (file)
@@ -23,6 +23,7 @@ using namespace AudioGrapher;
 
 Analyser::Analyser (float sample_rate, unsigned int channels, framecnt_t bufsize, framecnt_t n_samples)
        : _ebur128_plugin (0)
+       , _dbtp_plugin (0)
        , _sample_rate (sample_rate)
        , _channels (channels)
        , _bufsize (bufsize / channels)
@@ -37,8 +38,27 @@ Analyser::Analyser (float sample_rate, unsigned int channels, framecnt_t bufsize
                _ebur128_plugin = loader->loadPlugin ("libardourvampplugins:ebur128", sample_rate, PluginLoader::ADAPT_ALL_SAFE);
                assert (_ebur128_plugin);
                _ebur128_plugin->reset ();
-               _ebur128_plugin->initialise (channels, _bufsize, _bufsize);
+               if (!_ebur128_plugin->initialise (channels, _bufsize, _bufsize)) {
+                       printf ("FAILED TO INITIALIZE EBUR128\n");
+                       delete _ebur128_plugin;
+                       _ebur128_plugin = 0;
+               }
+       }
+
+       _dbtp_plugin = (Vamp::Plugin**) malloc (sizeof(Vamp::Plugin*) * channels);
+       for (unsigned int c = 0; c < _channels; ++c) {
+               using namespace Vamp::HostExt;
+               PluginLoader* loader (PluginLoader::getInstance ());
+               _dbtp_plugin[c] = loader->loadPlugin ("libardourvampplugins:dBTP", sample_rate, PluginLoader::ADAPT_ALL_SAFE);
+               assert (_dbtp_plugin[c]);
+               _dbtp_plugin[c]->reset ();
+               if (!_dbtp_plugin[c]->initialise (1, _bufsize, _bufsize)) {
+                       printf ("FAILED TO INITIALIZE DBTP %d\n", c);
+                       delete _dbtp_plugin[c];
+                       _dbtp_plugin[c] = 0;
+               }
        }
+
        _bufs[0] = (float*) malloc (sizeof (float) * _bufsize);
        _bufs[1] = (float*) malloc (sizeof (float) * _bufsize);
 
@@ -102,6 +122,10 @@ Analyser::Analyser (float sample_rate, unsigned int channels, framecnt_t bufsize
 Analyser::~Analyser ()
 {
        delete _ebur128_plugin;
+       for (unsigned int c = 0; c < _channels; ++c) {
+               delete _dbtp_plugin[c];
+       }
+       free (_dbtp_plugin);
        free (_bufs[0]);
        free (_bufs[1]);
        fftwf_destroy_plan (_fft_plan);
@@ -120,13 +144,15 @@ Analyser::process (ProcessContext<float> const & c)
        //printf ("PROC %p @%ld F: %ld, S: %ld C:%d\n", this, _pos, c.frames (), n_samples, c.channels ());
        float const * d = c.data ();
        framecnt_t s;
+       const unsigned cmask = _result.n_channels - 1; // [0, 1]
        for (s = 0; s < n_samples; ++s) {
                _fft_data_in[s] = 0;
                const framecnt_t pk = (_pos + s) / _spp;
                for (unsigned int c = 0; c < _channels; ++c) {
                        const float v = *d;
+                       if (fabsf(v) > _result.peak) { _result.peak = fabsf(v); }
                        _bufs[c][s] = v;
-                       const unsigned int cc = c % _result.n_channels; // TODO optimize
+                       const unsigned int cc = c & cmask;
                        if (_result.peaks[cc][pk].min > v) { _result.peaks[cc][pk].min = *d; }
                        if (_result.peaks[cc][pk].max < v) { _result.peaks[cc][pk].max = *d; }
                        _fft_data_in[s] += v * _hann_window[s] / (float) _channels;
@@ -145,6 +171,15 @@ Analyser::process (ProcessContext<float> const & c)
                _ebur128_plugin->process (_bufs, Vamp::RealTime::fromSeconds ((double) _pos / _sample_rate));
        }
 
+       float const * const data = c.data ();
+       for (unsigned int c = 0; c < _channels; ++c) {
+               if (!_dbtp_plugin[c]) { continue; }
+               for (s = 0; s < n_samples; ++s) {
+                       _bufs[0][s] = data[s * _channels + c];
+               }
+               _dbtp_plugin[c]->process (_bufs, Vamp::RealTime::fromSeconds ((double) _pos / _sample_rate));
+       }
+
        fftwf_execute (_fft_plan);
 
        _fft_power[0] = _fft_data_out[0] * _fft_data_out[0];
@@ -208,6 +243,17 @@ Analyser::result ()
                        _result.have_loudness = true;
                }
        }
+
+       for (unsigned int c = 0; c < _channels; ++c) {
+               if (!_dbtp_plugin[c]) { continue; }
+               Vamp::Plugin::FeatureSet features = _dbtp_plugin[c]->getRemainingFeatures ();
+               if (!features.empty () && features.size () == 1) {
+                       _result.have_dbtp = true;
+                       float p = features[0][0].values[0];
+                       if (p > _result.truepeak) { _result.truepeak = p; }
+               }
+       }
+
        return ARDOUR::ExportAnalysisPtr (new ARDOUR::ExportAnalysis (_result));
 }