[SCM] calf/master: + Compressor: Proper RMS, Stereo Average and Bypass.

js at users.alioth.debian.org js at users.alioth.debian.org
Tue May 7 15:38:13 UTC 2013


The following commit has been merged in the master branch:
commit 599ca7c1db79988705356e800c33e050c4d7a63d
Author: Thor Harald Johansen <thj at thj.no>
Date:   Sat Nov 1 17:23:36 2008 +0100

    + Compressor: Proper RMS, Stereo Average and Bypass.

diff --git a/src/calf/modules_dev.h b/src/calf/modules_dev.h
index 81598c0..a9b18e4 100644
--- a/src/calf/modules_dev.h
+++ b/src/calf/modules_dev.h
@@ -26,9 +26,11 @@ namespace synth {
 #if ENABLE_EXPERIMENTAL
 
 class compressor_audio_module: public null_audio_module {
+private:
+    float linslope, clip, peak;
 public:
-    enum { in_count = 2, out_count = 2, support_midi = false, rt_capable = true };
-    enum { param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_rms, param_compression, param_peak, param_clip, param_count };
+    enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true };
+    enum { param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_rms, param_average, param_compression, param_peak, param_clip, param_bypass, param_count };
 
     static const char *port_names[in_count + out_count];
     static synth::ladspa_plugin_info plugin_info;
@@ -37,15 +39,15 @@ public:
     float *params[param_count];
     uint32_t srate;
     static parameter_properties param_props[];
-    float clip, peak, asample2;
     void activate() {
-        target = 1.f;
-        aim = 1.f;
+        linslope = 0.f;
         peak = 0.f;
+        clip = 0.f;
     }
     uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
-        numsamples += offset;
+        bool bypass = *params[param_bypass] > 0.5f;
         bool rms = *params[param_rms] > 0.5f;
+        bool average = *params[param_average] > 0.5f;
         float threshold = *params[param_threshold];
         float ratio = *params[param_ratio];
         float attack = *params[param_attack];
@@ -55,56 +57,75 @@ public:
         float makeup = *params[param_makeup];
         float knee = *params[param_knee];
 
+        numsamples += offset;
+        
+        if(bypass) {
+            int count = numsamples * sizeof(float);
+            memcpy(outs[0], ins[0], count);
+            memcpy(outs[1], ins[1], count);
+
+            if(params[param_compression] != NULL) {
+                *params[param_compression] = 1.f;
+            }
+
+            if(params[param_clip] != NULL) {
+                *params[param_clip] = 0.f;
+            }
+
+            if(params[param_peak] != NULL) {
+                *params[param_peak] = 0.f;
+            }
+      
+            return inputs_mask;
+        }
+
+        float gain = 1.f;
+        
         while(offset < numsamples) {
-            float asample1 = std::max(fabs(ins[0][offset]), fabs(ins[1][offset]));
-            float asample;
-            if(rms) {
-                asample2 += (asample1*asample1 - asample2) * 200 / srate;
-                asample = sqrt(asample2);
-            } else asample = asample1;
-
-            if(asample > 0 && (asample > threshold || knee < 1)) {
+            float absample = average ? (fabs(ins[0][offset]) + fabs(ins[1][offset])) / 2 : std::max(fabs(ins[0][offset]), fabs(ins[1][offset]));
+            if(rms) absample *= absample;
+            linslope += (absample - linslope) * (absample > linslope ? attack_coeff : release_coeff);
+            float slope = rms ? sqrt(linslope) : linslope;
+
+            if(slope > 0 && (slope > threshold || knee < 1)) {
                 if(IS_FAKE_INFINITY(ratio)) {
-                    target = threshold;
+                    gain = threshold;
                 } else {
-                    target = (asample - threshold) / ratio + threshold;
+                    gain = (slope - threshold) / ratio + threshold;
                 }
                 
                 if(knee < 1) {
-                    float t = std::min(1.f, std::max(0.f, asample / threshold - knee) / (1.f - knee));
-                    target = (target - asample) * t + asample;
+                    float t = std::min(1.f, std::max(0.f, slope / threshold - knee) / (1.f - knee));
+                    gain = (gain - slope) * t + slope;
                 }
                 
-                target /= asample;
-            } else {
-                target = 1.f;
+                gain /= slope;
             }
         
-            aim += (target - aim) * (aim > target ? attack_coeff : release_coeff);
-            
-            peak -= peak * 0.0001;
             
-            float outL = ins[0][offset] * aim * makeup;
+            float outL = ins[0][offset] * gain * makeup;
             outs[0][offset] = outL;
 
-            float outR = ins[1][offset] * aim * makeup;
+            float outR = ins[1][offset] * gain * makeup;
             outs[1][offset] = outR;
 
             ++offset;
             
             float maxLR = std::max(fabs(outL), fabs(outR));
-           
-            if(maxLR > 1) clip = srate / 10; /* blink clip LED for 100 ms */
-            if(maxLR > peak) peak = maxLR;
             
             if(clip > 0) {
                 --clip;
             }
-
+            if(maxLR > 1.f) clip = srate / 10.f; /* blink clip LED for 100 ms */
+            
+            peak -= peak * 0.0001;
+            if(maxLR > peak) {
+                peak = maxLR;
+            }
         }
         
         if(params[param_compression] != NULL) {
-            *params[param_compression] = aim;
+            *params[param_compression] = gain;
         }
 
         if(params[param_clip] != NULL) {
@@ -125,8 +146,6 @@ public:
     void set_sample_rate(uint32_t sr) {
             srate = sr;
     }
-private:
-    float aim, target;
 };
 
 #endif
diff --git a/src/modules.cpp b/src/modules.cpp
index d1d03ec..456842c 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -183,9 +183,11 @@ parameter_properties compressor_audio_module::param_props[] = {
     { 1,      1, 12,   0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup", "Makeup Gain" },
     { 1,      0,  1,   0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee", "Knee" },
     { 0,      0,  1,   0, PF_BOOL | PF_CTL_TOGGLE, NULL, "rms", "RMS" },
+    { 0,      0,  1,   0, PF_BOOL | PF_CTL_TOGGLE, NULL, "average", "Stereo Average" },
     { 0, 0.03125, 1,    0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "compression", "Compression" },
     { 0,      0,  1,    0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "peak", "Peak" },
-    { 0,      1,  0,    0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip", "Clip" }
+    { 0,      1,  0,    0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip", "Clip" },
+    { 0,      0,  1,    0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" },
 };
 
 synth::ladspa_plugin_info compressor_audio_module::plugin_info = { 0x8502, "Compressor", "Calf Compressor", "Thor Harald Johansen", synth::calf_copyright_info, "CompressorPlugin" };

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list