[SCM] calf/master: Add Tom Szilagyi's distortion code from TAP plugins (thanks Tom!)

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


The following commit has been merged in the master branch:
commit dc9fcf7e607871cba687ead6c160b2c94ef8f25b
Author: Krzysztof Foltman <wdev at foltman.com>
Date:   Mon May 3 19:39:16 2010 +0100

    Add Tom Szilagyi's distortion code from TAP plugins (thanks Tom!)

diff --git a/src/audio_fx.cpp b/src/audio_fx.cpp
index dcba08f..389ca57 100644
--- a/src/audio_fx.cpp
+++ b/src/audio_fx.cpp
@@ -228,3 +228,80 @@ float biquad_filter_module::freq_gain(int subindex, float freq, float srate) con
         level *= left[j].freq_gain(freq, srate);
     return level;
 }
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/// Distortion Module by Tom Szilagyi
+///
+/// This module provides a blendable saturation stage
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+tap_distortion::tap_distortion()
+{
+    is_active = false;
+    srate = 0;
+    meter = 0.f;
+}
+
+void tap_distortion::activate()
+{
+    is_active = true;
+    set_params(0.f, 0.f);
+}
+void tap_distortion::deactivate()
+{
+    is_active = false;
+}
+
+void tap_distortion::set_params(float blend, float drive)
+{
+    // set distortion coeffs
+    if ((drive_old != drive) || (blend_old != blend)) {
+        rdrive = 12.0f / drive;
+        rbdr = rdrive / (10.5f - blend) * 780.0f / 33.0f;
+        kpa = D(2.0f * (rdrive*rdrive) - 1.0f) + 1.0f;
+        kpb = (2.0f - kpa) / 2.0f;
+        ap = ((rdrive*rdrive) - kpa + 1.0f) / 2.0f;
+        kc = kpa / D(2.0f * D(2.0f * (rdrive*rdrive) - 1.0f) - 2.0f * rdrive*rdrive);
+
+        srct = (0.1f * srate) / (0.1f * srate + 1.0f);
+        sq = kc*kc + 1.0f;
+        knb = -1.0f * rbdr / D(sq);
+        kna = 2.0f * kc * rbdr / D(sq);
+        an = rbdr*rbdr / sq;
+        imr = 2.0f * knb + D(2.0f * kna + 4.0f * an - 1.0f);
+        pwrq = 2.0f / (imr + 1.0f);
+        
+        drive_old = drive;
+        blend_old = blend;
+    }
+}
+
+void tap_distortion::set_sample_rate(uint32_t sr)
+{
+    srate = sr;
+}
+
+float tap_distortion::process(float in)
+{
+    meter = 0.f;
+    float out = 0.f;
+    float proc = in;
+    float med;
+    if (proc >= 0.0f) {
+        med = (D(ap + proc * (kpa - proc)) + kpb) * pwrq;
+    } else {
+        med = (D(an - proc * (kna + proc)) + knb) * pwrq * -1.0f;
+    }
+    proc = srct * (med - prev_med + prev_out);
+    prev_med = M(med);
+    prev_out = M(proc);
+    out = proc;
+    meter = proc;
+    return out;
+}
+
+float tap_distortion::get_distortion_level()
+{
+    return meter;
+}
diff --git a/src/calf/audio_fx.h b/src/calf/audio_fx.h
index 34a3b17..28215e7 100644
--- a/src/calf/audio_fx.h
+++ b/src/calf/audio_fx.h
@@ -610,6 +610,37 @@ public:
     }
 };
 
+/// Tom Szilagyi's distortion code, used with permission
+/// KF: I'm not 100% sure how this is supposed to work, but it does.
+/// I'm planning to rewrite it using more modular approach when I have more time.
+class tap_distortion {
+private:
+    float blend_old, drive_old;
+    float meter;
+    float rdrive, rbdr, kpa, kpb, kna, knb, ap, an, imr, kc, srct, sq, pwrq;
+    float prev_med, prev_out;
+public:
+    uint32_t srate;
+    bool is_active;
+    tap_distortion();
+    void activate();
+    void deactivate();
+    void set_params(float blend, float drive);
+    void set_sample_rate(uint32_t sr);
+    float process(float in);
+    float get_distortion_level();
+    static inline float M(float x)
+    {
+        return (fabs(x) > 0.000000001f) ? x : 0.0f;
+    }
+
+    static inline float D(float x)
+    {
+        x = fabs(x);
+        return (x > 0.000000001f) ? sqrtf(x) : 0.0f;
+    }
+};
+
 #if 0
 { to keep editor happy
 #endif

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list