[SCM] calf/master: Multiband limiter: ASC fixes.

js at users.alioth.debian.org js at users.alioth.debian.org
Tue May 7 15:40:52 UTC 2013


The following commit has been merged in the master branch:
commit a6ff6573bdb24b42eb8301b8340980d2b2c56f37
Author: Markus Schmidt <schmidt at boomshop.net>
Date:   Fri Feb 10 00:29:00 2012 +0000

    Multiband limiter: ASC fixes.

diff --git a/src/audio_fx.cpp b/src/audio_fx.cpp
index a5695be..139c090 100644
--- a/src/audio_fx.cpp
+++ b/src/audio_fx.cpp
@@ -633,6 +633,26 @@ void lookahead_limiter::reset_asc() {
     asc_changed = true;
 }
 
+float lookahead_limiter::get_rdelta(float peak, float _limit, float _att, bool _asc) {
+    
+    // calc the att for average input to walk to if we use asc (att of average signal)
+    float _a_att = (limit * weight) / (asc_coeff * asc) * (float)asc_c;
+
+    // calc a release delta from this attenuation
+    float _rdelta = (1.0 - _att) / (srate * release);
+    if(_asc and auto_release and asc_c > 0 and _a_att > _att) {
+        // check if releasing to average level of peaks is steeper than
+        // releasing to 1.f
+        float _delta = std::max((_a_att - _att) / (srate * release), _rdelta / 10);
+        if(_delta < _rdelta) {
+            asc_active = true;
+            _asc_used = true;
+            _rdelta = _delta;
+        }
+    }
+    return _rdelta;
+}
+
 void lookahead_limiter::process(float &left, float &right, float * multi_buffer)
 {
     // PROTIP: harming paying customers enough to make them develop a competing
@@ -648,15 +668,15 @@ void lookahead_limiter::process(float &left, float &right, float * multi_buffer)
         buffer[pos] = left;
         buffer[pos + 1] = right;
     }
-
+    
     // are we using multiband? get the multiband coefficient or use 1.f
     float multi_coeff = (use_multi) ? multi_buffer[pos] : 1.f;
-
-    // input peak - impact higher in left or right channel?
-    peak = fabs(left) > fabs(right) ? fabs(left) : fabs(right);
-
+    
     // calc the real limit including weight and multi coeff
     float _limit = limit * multi_coeff * weight;
+    
+    // input peak - impact higher in left or right channel?
+    peak = fabs(left) > fabs(right) ? fabs(left) : fabs(right);
 
     // add an eventually appearing peak to the asc fake buffer if asc active
     if(auto_release and peak > _limit) {
@@ -667,22 +687,11 @@ void lookahead_limiter::process(float &left, float &right, float * multi_buffer)
     if(peak > _limit or multi_coeff < 1.0) {
         float _multi_coeff = 1.f;
         float _peak;
-
+        
         // calc the attenuation needed to reduce incoming peak
         float _att = std::min(_limit / peak, 1.f);
-
-
-        // calc a release delta from this attenuation
-        float _rdelta = (1.0 - _att) / (srate * release);
-        if(auto_release and asc_c > 0) {
-            // check if releasing to average level of peaks is steeper than
-            // releasing to 1.f
-            float _delta = std::max((limit * weight) / (asc_coeff * asc) * (float)asc_c - _att, 0.000001f) / (srate * release);
-            if(_delta < _rdelta) {
-                asc_active = true;
-                _rdelta = _delta;
-            }
-        }
+        // calc release without any asc to keep all relevant peaks
+        float _rdelta = get_rdelta(peak, _limit, _att, false);
 
         // calc the delta for walking to incoming peak attenuation
         float _delta = (_limit / peak - att) / buffer_size * channels;
@@ -764,12 +773,32 @@ void lookahead_limiter::process(float &left, float &right, float * multi_buffer)
     // ...and calculate outpout from it
     left *= att;
     right *= att;
-
+    
     if((pos + channels) % buffer_size == nextpos[nextiter]) {
         // if we reach a buffered position, change the actual delta and erase
         // this (the first) element from nextpos and nextdelta buffer
-        delta = nextdelta[nextiter];
-        nextlen = (nextlen - 1) % buffer_size;
+        if(auto_release) {
+            // set delta to asc influenced release delta
+            delta = get_rdelta(_peak, (limit * weight * _multi_coeff), att);
+            if(nextlen > 1) {
+                // if there are more positions to walk to, calc delta to next
+                // position in buffer and compare it to release delta (keep
+                // changes between peaks below asc steepness)
+                int _nextpos = nextpos[(nextiter + 1) % buffer_size];
+                float __peak = fabs(buffer[_nextpos]) > fabs(buffer[_nextpos + 1]) ? fabs(buffer[_nextpos]) : fabs(buffer[_nextpos + 1]);
+                float __multi_coeff = (use_multi) ? multi_buffer[_nextpos] : 1.f;
+                float __delta = ((limit * __multi_coeff * weight) / __peak - att) / (((buffer_size + _nextpos - ((pos + channels) % buffer_size)) % buffer_size) / channels);
+                if(__delta < delta) {
+                    delta = __delta;
+                }
+            }
+        } else {
+            // if no asc set delta from nextdelta buffer and fix the attenuation
+            delta = nextdelta[nextiter];
+            att = (limit * weight * _multi_coeff) / _peak;
+        }
+        // remove first element from circular nextpos buffer
+        nextlen -= 1;
         nextpos[nextiter] = -1;
         nextiter = (nextiter + 1) % buffer_size;
     }
@@ -778,6 +807,9 @@ void lookahead_limiter::process(float &left, float &right, float * multi_buffer)
         // release time seems over, reset attenuation and delta
         att = 1.0f;
         delta = 0.0f;
+        nextiter = 0;
+        nextlen = 0;
+        nextpos[0] = -1;
     }
 
     // main limiting party is over, let's cleanup the puke
diff --git a/src/calf/audio_fx.h b/src/calf/audio_fx.h
index b4db50f..e2032e2 100644
--- a/src/calf/audio_fx.h
+++ b/src/calf/audio_fx.h
@@ -574,9 +574,9 @@ public:
     uint32_t srate;
     float att; // a coefficient the output is multiplied with
     float att_max; // a memory for the highest attenuation - used for display
-    unsigned int pos; // where we are actually in our sample buffer
-    unsigned int buffer_size;
-    unsigned int overall_buffer_size;
+    int pos; // where we are actually in our sample buffer
+    int buffer_size;
+    int overall_buffer_size;
     bool is_active;
     bool debug;
     bool auto_release;
@@ -600,10 +600,12 @@ public:
     int asc_pos;
     bool asc_changed;
     float asc_coeff;
+    bool _asc_used;
     static inline void denormal(volatile float *f) {
 	    *f += 1e-18;
 	    *f -= 1e-18;
     }
+    inline float get_rdelta(float peak, float _limit, float _att, bool _asc = true);
     void reset();
     void reset_asc();
     bool get_asc();
diff --git a/src/calf/modules_limit.h b/src/calf/modules_limit.h
index d5d4b9a..29a61ba 100644
--- a/src/calf/modules_limit.h
+++ b/src/calf/modules_limit.h
@@ -66,7 +66,7 @@ private:
     float meter_inL, meter_inR, meter_outL, meter_outR;
     dsp::lookahead_limiter strip[strips];
     dsp::lookahead_limiter broadband;
-    dsp::biquad_d2<float> lpL[strips - 1][3], lpR[strips - 1][3], hpL[strips - 1][3], hpR[strips - 1][3];
+    dsp::biquad_d2<float> lpL[strips - 1][strips - 1], lpR[strips - 1][strips - 1], hpL[strips - 1][strips - 1], hpR[strips - 1][strips - 1];
     float freq_old[strips - 1], sep_old[strips - 1], q_old[strips - 1];
     unsigned int pos;
     unsigned int buffer_size;
diff --git a/src/modules_limit.cpp b/src/modules_limit.cpp
index f7fb6fc..e8a4666 100644
--- a/src/modules_limit.cpp
+++ b/src/modules_limit.cpp
@@ -354,12 +354,12 @@ void multibandlimiter_audio_module::params_changed()
     rel = *params[param_release] *  pow(0.25, *params[param_release0] * -1);
     rel = (*params[param_minrel] > 0.5) ? std::max(2500 * (1.f / 30), rel) : rel;
     weight[0] = pow(0.25, *params[param_weight0] * -1);
-    strip[0].set_params(*params[param_limit], *params[param_attack], rel, weight[0], *params[param_asc], pow(0.5, (*params[param_asc_coeff] - 0.5) * 2 * -1), true);
+    strip[0].set_params(*params[param_limit], *params[param_attack], rel, weight[0], *params[param_asc], pow(0.5, (*params[param_asc_coeff] - 0.5) * 2 * -1));
     *params[param_effrelease0] = rel;
     rel = *params[param_release] *  pow(0.25, *params[param_release1] * -1);
     rel = (*params[param_minrel] > 0.5) ? std::max(2500 * (1.f / *params[param_freq0]), rel) : rel;
     weight[1] = pow(0.25, *params[param_weight1] * -1);
-    strip[1].set_params(*params[param_limit], *params[param_attack], rel, weight[1], *params[param_asc], pow(0.5, (*params[param_asc_coeff] - 0.5) * 2 * -1));
+    strip[1].set_params(*params[param_limit], *params[param_attack], rel, weight[1], *params[param_asc], pow(0.5, (*params[param_asc_coeff] - 0.5) * 2 * -1), true);
     *params[param_effrelease1] = rel;
     rel = *params[param_release] *  pow(0.25, *params[param_release2] * -1);
     rel = (*params[param_minrel] > 0.5) ? std::max(2500 * (1.f / *params[param_freq1]), rel) : rel;
@@ -421,6 +421,7 @@ void multibandlimiter_audio_module::set_sample_rate(uint32_t sr)
     if(params[param_att##index] != NULL) \
         *params[param_att##index] = strip[index].get_attenuation(); \
 
+
 uint32_t multibandlimiter_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
 {
     bool bypass = *params[param_bypass] > 0.5f;
@@ -656,22 +657,14 @@ bool multibandlimiter_audio_module::get_graph(int index, int subindex, float *da
                 break;
         }
         for(int j = 0; j <= j1; j ++) {
-            switch(subindex) {
-                case 0:
-                    ret *= lpL[0][j].freq_gain(freq, (float)srate);
-                    break;
-                case 1:
-                    ret *= hpL[0][j].freq_gain(freq, (float)srate);
-                    ret *= lpL[1][j].freq_gain(freq, (float)srate);
-                    break;
-                case 2:
-                    ret *= hpL[1][j].freq_gain(freq, (float)srate);
-                    ret *= lpL[2][j].freq_gain(freq, (float)srate);
-                    break;
-                case 3:
-                    ret *= hpL[2][j].freq_gain(freq, (float)srate);
-                    break;
+            if(subindex == 0)
+                ret *= lpL[0][j].freq_gain(freq, (float)srate);
+            if(subindex > 0 and subindex < strips - 1) {
+                ret *= hpL[subindex - 1][j].freq_gain(freq, (float)srate);
+                ret *= lpL[subindex][j].freq_gain(freq, (float)srate);
             }
+            if(subindex == strips - 1)
+                ret *= hpL[2][j].freq_gain(freq, (float)srate);
         }
         data[i] = dB_grid(ret);
     }

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list