Add normalization gain factor to Export Analysis
authorRobin Gareus <robin@gareus.org>
Mon, 15 Feb 2016 14:46:49 +0000 (15:46 +0100)
committerRobin Gareus <robin@gareus.org>
Mon, 15 Feb 2016 14:46:49 +0000 (15:46 +0100)
libs/ardour/ardour/export_analysis.h
libs/ardour/ardour/export_graph_builder.h
libs/ardour/export_graph_builder.cc
libs/audiographer/audiographer/general/analyser.h
libs/audiographer/audiographer/general/normalizer.h
libs/audiographer/src/general/analyser.cc
libs/audiographer/src/general/normalizer.cc

index 8c55edd6ab3a29db0e30dd07cb37035effc75b07..c911acf9f095356e7e01a9641cb6a2b6d224f44f 100644 (file)
@@ -37,6 +37,8 @@ namespace ARDOUR {
                        , loudness_hist_max (0)
                        , have_loudness (false)
                        , have_dbtp (false)
+                       , norm_gain_factor (1.0)
+                       , normalized (false)
                        , n_channels (1)
                {
                        memset (peaks, 0, sizeof(peaks));
@@ -53,6 +55,8 @@ namespace ARDOUR {
                        , loudness_hist_max (other.loudness_hist_max)
                        , have_loudness (other.have_loudness)
                        , have_dbtp (other.have_dbtp)
+                       , norm_gain_factor (other.norm_gain_factor)
+                       , normalized (other.normalized)
                        , n_channels (other.n_channels)
                {
                        truepeakpos[0] = other.truepeakpos[0];
@@ -71,6 +75,8 @@ namespace ARDOUR {
                int loudness_hist_max;
                bool have_loudness;
                bool have_dbtp;
+               float norm_gain_factor;
+               bool normalized;
 
                uint32_t n_channels;
                uint32_t freq[6]; // y-pos, 50, 100, 500, 1k, 5k, 10k [Hz]
index 979e3632b97fb4f636d9924e007e5199184d0432..f2fbbb63fa548b361ed46be7bb86512fa731de5c 100644 (file)
@@ -124,6 +124,7 @@ class LIBARDOUR_API ExportGraphBuilder
                void add_child (FileSpec const & new_config);
                void remove_children (bool remove_out_files);
                bool operator== (FileSpec const & other_config) const;
+               void set_peak (float);
 
                                                private:
                typedef boost::shared_ptr<AudioGrapher::SampleFormatConverter<Sample> > FloatConverterPtr;
index bdcdf2620e21f924ddb087895ea5edf28ef3122a..75587dedae4e7933fa88d669538f428ed0e55580 100644 (file)
@@ -332,6 +332,14 @@ ExportGraphBuilder::SFC::SFC (ExportGraphBuilder &parent, FileSpec const & new_c
        }
 }
 
+void
+ExportGraphBuilder::SFC::set_peak (float gain)
+{
+       if (_analyse) {
+               analyser->set_normalization_gain (gain);
+       }
+}
+
 ExportGraphBuilder::FloatSinkPtr
 ExportGraphBuilder::SFC::sink ()
 {
@@ -476,7 +484,10 @@ ExportGraphBuilder::Normalizer::process()
 void
 ExportGraphBuilder::Normalizer::start_post_processing()
 {
-       normalizer->set_peak (peak_reader->get_peak());
+       const float gain = normalizer->set_peak (peak_reader->get_peak());
+       for (boost::ptr_list<SFC>::iterator i = children.begin(); i != children.end(); ++i) {
+               (*i).set_peak (gain);
+       }
        tmp_file->seek (0, SEEK_SET);
        tmp_file->add_output (normalizer);
        parent.normalizers.push_back (this);
index e79e4107dc77c02211b07eccbf2cce81b6f3b012..e8ca534954245df7835773ce3075242194ff9ce3 100644 (file)
@@ -41,8 +41,15 @@ class LIBAUDIOGRAPHER_API Analyser : public ListedSource<float>, public Sink<flo
        void process (ProcessContext<float> const & c);
        ARDOUR::ExportAnalysisPtr result ();
 
+       void set_normalization_gain (float gain) {
+               _result.normalized = true;
+               _result.norm_gain_factor = gain;
+       }
+
        using Sink<float>::process;
 
+       static const float fft_range_db;
+
        private:
        float fft_power_at_bin (const uint32_t b, const float norm) const;
 
index 025131022e207ef8363c558d3699d70c56ef4a1a..e5f73a0f0833cc19714ffbfc12948c5dbdf5958f 100644 (file)
@@ -21,7 +21,7 @@ public:
        ~Normalizer();
 
        /// Sets the peak found in the material to be normalized \see PeakReader \n RT safe
-       void set_peak (float peak);
+       float set_peak (float peak);
 
        /** Allocates a buffer for using with const ProcessContexts
          * This function does not need to be called if
index d969095b0847c0c1281115a665ab128902033e06..c27d7dae085c7980486b614c35951768e23426bd 100644 (file)
@@ -21,6 +21,8 @@
 
 using namespace AudioGrapher;
 
+const float Analyser::fft_range_db (80); // dB
+
 Analyser::Analyser (float sample_rate, unsigned int channels, framecnt_t bufsize, framecnt_t n_samples)
        : _ebur128_plugin (0)
        , _dbtp_plugin (0)
@@ -196,12 +198,11 @@ Analyser::process (ProcessContext<float> const & c)
        const framecnt_t x0 = _pos / _fpp;
        framecnt_t x1 = (_pos + n_samples) / _fpp;
        if (x0 == x1) x1 = x0 + 1;
-       const float range = 80; // dB
 
        for (uint32_t i = 0; i < _fft_data_size - 1; ++i) {
                const float level = fft_power_at_bin (i, i);
-               if (level < -range) continue;
-               const float pk = level > 0.0 ? 1.0 : (range + level) / range;
+               if (level < -fft_range_db) continue;
+               const float pk = level > 0.0 ? 1.0 : (fft_range_db + level) / fft_range_db;
 #if 0 // linear
                const uint32_t y0 = floor (i * (float) height / _fft_data_size);
                uint32_t y1 = ceil ((i + 1.0) * (float) height / _fft_data_size);
index d241d71892db5cf95e06b12c051e96021e1962c8..a10382031a520de6ec8cbb5065f2bf708c11856c 100644 (file)
@@ -37,7 +37,7 @@ Normalizer::~Normalizer()
 }
 
 /// Sets the peak found in the material to be normalized \see PeakReader \n RT safe
-void Normalizer::set_peak (float peak)
+float Normalizer::set_peak (float peak)
 {
        if (peak == 0.0f || peak == target) {
                /* don't even try */
@@ -46,6 +46,7 @@ void Normalizer::set_peak (float peak)
                enabled = true;
                gain = target / peak;
        }
+       return enabled ? gain : 1.0;
 }
 
 /** Allocates a buffer for using with const ProcessContexts