[SCM] calf/master: New Deesser, some minor bugs in sc-comp

js at users.alioth.debian.org js at users.alioth.debian.org
Tue May 7 15:39:41 UTC 2013


The following commit has been merged in the master branch:
commit 8bdf238d3e4d5a31df6784f74cbbd62c6fbbb94d
Author: Markus Schmidt <schmidt at boomshop.net>
Date:   Wed Oct 28 03:23:21 2009 +0100

    New Deesser, some minor bugs in sc-comp

diff --git a/gui/gui-deesser.xml b/gui/gui-deesser.xml
new file mode 100644
index 0000000..7519c73
--- /dev/null
+++ b/gui/gui-deesser.xml
@@ -0,0 +1,92 @@
+<hbox spacing="8">
+    <vbox spacing="8">
+        <table cols="4" rows="4" fill="0" expand="0">
+            <label param="bypass" attach-x="0" attach-y="0" expand-x="0" fill-x="0" />
+            <toggle param="bypass" attach-x="0" attach-y="1" attach-h="2" expand-x="0" fill-x="0" />
+            
+            <label param="detected" attach-x="1" attach-y="0" />
+            <vumeter param="detected" hold="1.5" falloff="2.5" attach-x="1" attach-y="1" />
+            <vumeter param="compression" mode="2" hold="1.5" falloff="2.5" attach-x="1" attach-y="2" />
+            <label param="compression" attach-x="1" attach-y="3" />
+            
+            <label param="detected_led" attach-x="2" attach-y="0" expand-x="0" fill-x="0" />
+            <led param="detected_led" attach-x="2" attach-y="1" expand-x="0" fill-x="0" />
+            <led param="clip_out" mode="6" attach-x="2" attach-y="2" expand-x="0" fill-x="0" />
+            <label param="clip_out" attach-x="2" attach-y="3" expand-x="0" fill-x="0" />
+            
+            <label param="sc_listen" attach-x="3" attach-y="0" expand-x="0" fill-x="0" />
+            <toggle param="sc_listen" attach-x="3" attach-y="1" attach-h="2" expand-x="0" fill-x="0" />
+        </table>
+        <frame label="Deesser">
+            <vbox spacing="10">
+                <hbox spacing="15">
+                    <align><vbox fill="0">
+                        <label param="laxity" fill="0" expand="0" />
+                        <knob param="laxity" fill="0" expand="0" />
+                        <value param="laxity" fill="0" expand="0" />
+                    </vbox></align>
+                    <vbox>
+                        <label param="threshold" />
+                        <knob param="threshold" size="5" />
+                        <value param="threshold" />
+                    </vbox>
+                    <vbox>
+                        <label param="ratio" />
+                        <knob param="ratio" size="5" />
+                        <value param="ratio" />
+                    </vbox>
+                    <align><vbox fill="0">
+                        <label param="makeup" fill="0" expand="0" />
+                        <knob param="makeup" fill="0" expand="0" />
+                        <value param="makeup" fill="0" expand="0" />
+                    </vbox></align>
+                </hbox>
+                <hbox spacing="20">
+                    <vbox>
+                        <label param="detection" />
+                        <combo param="detection" />
+                    </vbox>
+                    <vbox>
+                        <label param="mode" />
+                        <combo param="mode" />
+                    </vbox>
+                </hbox>
+            </vbox>
+        </frame>
+    </vbox>
+    <frame label="Sidechain">
+        <vbox spacing="5">
+            <if cond="directlink">
+                <line-graph refresh="1" param="f1_freq" expand="1" fill="1" width="400" height="200" />
+            </if>
+            <hbox homogeneous="1" fill="0" expand="0">
+                <vbox fill="0" expand="0">
+                    <label param="f1_freq" />
+                    <knob param="f1_freq" />
+                    <value param="f1_freq" />
+                </vbox>
+                <vbox fill="0" expand="0">
+                    <label param="f1_level" />
+                    <knob param="f1_level" />
+                    <value param="f1_level" />
+                </vbox>
+                <vbox fill="0" expand="0">
+                    <label param="f2_freq" />
+                    <knob param="f2_freq" />
+                    <value param="f2_freq" />
+                </vbox>
+                <vbox fill="0" expand="0">
+                    <label param="f2_level" />
+                    <knob param="f2_level" />
+                    <value param="f2_level" />
+                </vbox>
+                <vbox fill="0" expand="0">
+                    <label param="f2_q" />
+                    <knob param="f2_q" />
+                    <value param="f2_q" />
+                </vbox>
+            </hbox>
+        </vbox>
+    </frame>
+</hbox>
+                
diff --git a/src/calf/metadata.h b/src/calf/metadata.h
index 6ba14fb..c959e19 100644
--- a/src/calf/metadata.h
+++ b/src/calf/metadata.h
@@ -168,6 +168,18 @@ struct multibandcompressor_metadata: public plugin_metadata<multibandcompressor_
     PLUGIN_NAME_ID_LABEL("multiband_compressor", "multibandcompressor", "Multiband Compressor")
 };
 
+/// Markus's deesser - metadata
+struct deesser_metadata: public plugin_metadata<deesser_metadata>
+{
+    enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true };
+    enum { param_bypass, param_detected, param_compression, param_detected_led, param_clip_out,
+           param_detection, param_mode,
+           param_threshold, param_ratio, param_laxity, param_makeup,
+           param_f1_freq, param_f2_freq, param_f1_level, param_f2_level, param_f2_q,
+           param_sc_listen, param_count };
+    PLUGIN_NAME_ID_LABEL("deesser", "deesser", "Deesser")
+};
+
 /// Markus's 5-band EQ - metadata
 struct equalizer5band_metadata: public plugin_metadata<equalizer5band_metadata>
 {
diff --git a/src/calf/modulelist.h b/src/calf/modulelist.h
index 2fba14b..83c123c 100644
--- a/src/calf/modulelist.h
+++ b/src/calf/modulelist.h
@@ -12,6 +12,7 @@
     PER_MODULE_ITEM(compressor, false, "compressor")
     PER_MODULE_ITEM(sidechaincompressor, false, "sidechaincompressor")
     PER_MODULE_ITEM(multibandcompressor, false, "multibandcompressor")
+    PER_MODULE_ITEM(deesser, false, "deesser")
     PER_MODULE_ITEM(equalizer5band, false, "equalizer5band")
     PER_MODULE_ITEM(equalizer8band, false, "equalizer8band")
     PER_MODULE_ITEM(equalizer12band, false, "equalizer12band")
diff --git a/src/calf/modules.h b/src/calf/modules.h
index 5ba9fff..8612106 100644
--- a/src/calf/modules.h
+++ b/src/calf/modules.h
@@ -1052,6 +1052,41 @@ public:
     virtual int  get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline);
 };
 
+/// Deesser by Markus Schmidt (based on Thor's compressor and Krzysztof's filters)
+class deesser_audio_module: public audio_module<deesser_metadata>, public frequency_response_line_graph  {
+private:
+    enum CalfDeessModes {
+        WIDE,
+        SPLIT
+    };
+    float f1_freq_old, f2_freq_old, f1_level_old, f2_level_old, f2_q_old;
+    float f1_freq_old1, f2_freq_old1, f1_level_old1, f2_level_old1, f2_q_old1;
+    uint32_t detected_led;
+    float detected, clip_out;
+    gain_reduction_audio_module compressor;
+    biquad_d2<float> hpL, hpR, lpL, lpR, pL, pR;
+public:
+    float *ins[in_count];
+    float *outs[out_count];
+    float *params[param_count];
+    uint32_t srate;
+    bool is_active;
+    volatile int last_generation, last_calculated_generation;
+    deesser_audio_module();
+    void activate();
+    void deactivate();
+    void params_changed();
+    float freq_gain(int index, double freq, uint32_t sr)
+    {
+        return hpL.freq_gain(freq, sr) * pL.freq_gain(freq, sr);
+    }
+    void set_sample_rate(uint32_t sr);
+    uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask);
+    bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context);
+    bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context);
+    int  get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline);
+};
+
 /// Equalizer 12 Band by Markus Schmidt (based on Krzysztof's filters)
 class equalizer12band_audio_module: public audio_module<equalizer12band_metadata>, public frequency_response_line_graph  {
 private:
diff --git a/src/modules.cpp b/src/modules.cpp
index 7dff743..5f90f8f 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -284,7 +284,7 @@ CALF_PORT_PROPS(sidechaincompressor) = {
     { 0,      0,  1,    0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "f2_active", "active" },
 };
 
-CALF_PLUGIN_INFO(sidechaincompressor) = { 0x8502, "Sidechaincompressor", "Calf Sidechain Compressor", "Thor Harald Johansen / Markus Schmidt", calf_plugins::calf_copyright_info, "CompressorPlugin" };
+CALF_PLUGIN_INFO(sidechaincompressor) = { 0x8502, "Sidechaincompressor", "Calf Sidechain Compressor", "Markus Schmidt / Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" };
 
 ////////////////////////////////////////////////////////////////////////////
 
@@ -374,6 +374,37 @@ CALF_PLUGIN_INFO(multibandcompressor) = { 0x8502, "Multibandcompressor", "Calf M
 
 ////////////////////////////////////////////////////////////////////////////
 
+CALF_PORT_NAMES(deesser) = {"In L", "In R", "Out L", "Out R"};
+
+const char *deesser_detection_names[] = { "RMS", "Peak" };
+const char *deesser_mode_names[] = { "Wide", "Split" };
+
+
+CALF_PORT_PROPS(deesser) = {
+    { 0,      0,  1,    0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" },
+    { 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, "detected", "Detected" },
+    { 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| PF_PROP_GRAPH, NULL, "compression", "Gain Reduction" },
+    { 0,      0,  1,    0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "detected_led", "Active" },
+    { 0,      0,  1,    0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_out", "Out" },
+    { 0,      0,  1,    0, PF_ENUM | PF_CTL_COMBO, deesser_detection_names, "detection", "Detection" },
+    { 0,      0,  1,    0, PF_ENUM | PF_CTL_COMBO, deesser_mode_names, "mode", "Mode" },
+    { 0.0625, 0.000976563, 1,    0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold", "Threshold" },
+    { 5,      1, 20,  21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio", "Ratio" },
+    { 15,     1, 100,   1, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "laxity", "Laxity" },
+    { 1,      1, 64,    0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup", "Makeup" },
+
+    { 5000,   10,   18000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "f1_freq", "Split" },
+    { 6000,   10,   18000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "f2_freq", "Peak" },
+    { 1,      0.0625,  16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "f1_level", "Gain" },
+    { 4,      0.0625,  16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "f2_level", "Level" },
+    { 1,      0.1,     100,1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "f2_q", "Peak Q" },
+    { 0,      0,  1,    0, PF_BOOL | PF_CTL_TOGGLE, NULL, "sc_listen", "S/C-Listen" },
+};
+
+CALF_PLUGIN_INFO(deesser) = { 0x8502, "Deesser", "Calf Deesser", "Markus Schmidt / Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" };
+
+////////////////////////////////////////////////////////////////////////////
+
 CALF_PORT_NAMES(equalizer5band) = {"In L", "In R", "Out L", "Out R"};
 
 CALF_PORT_PROPS(equalizer5band) = {
diff --git a/src/modules_dsp.cpp b/src/modules_dsp.cpp
index 131d036..22bbc57 100644
--- a/src/modules_dsp.cpp
+++ b/src/modules_dsp.cpp
@@ -1108,7 +1108,7 @@ void sidechaincompressor_audio_module::params_changed()
                 f2_active = 1.f;
                 break;
             case DEESSER_SPLIT:
-                f1L.set_lp_rbj((float)*params[param_f1_freq] * (1 + 0.17), q, (float)srate);
+                f1L.set_lp_rbj((float)*params[param_f2_freq] * (1 + 0.17), q, (float)srate);
                 f1R.copy_coeffs(f1L);
                 f2L.set_hp_rbj((float)*params[param_f2_freq] * (1 - 0.17), q, (float)srate, *params[param_f2_level]);
                 f2R.copy_coeffs(f2L);
@@ -1126,7 +1126,7 @@ void sidechaincompressor_audio_module::params_changed()
             case DERUMBLER_SPLIT:
                 f1L.set_lp_rbj((float)*params[param_f1_freq] * (1 + 0.17), q, (float)srate, *params[param_f1_level]);
                 f1R.copy_coeffs(f1L);
-                f2L.set_hp_rbj((float)*params[param_f2_freq] * (1 - 0.17), q, (float)srate);
+                f2L.set_hp_rbj((float)*params[param_f1_freq] * (1 - 0.17), q, (float)srate);
                 f2R.copy_coeffs(f2L);
                 f1_active = 1.f;
                 f2_active = 0.f;
@@ -1158,7 +1158,7 @@ void sidechaincompressor_audio_module::params_changed()
             case BANDPASS_1:
                 f1L.set_bp_rbj((float)*params[param_f1_freq], q, (float)srate, *params[param_f1_level]);
                 f1R.copy_coeffs(f1L);
-                f2L.set_highshelf_rbj((float)*params[param_f2_freq], q, *params[param_f2_level], (float)srate);
+                f2L.set_hp_rbj((float)*params[param_f2_freq], q, *params[param_f2_level], (float)srate);
                 f2R.copy_coeffs(f2L);
                 f1_active = 1.f;
                 f2_active = 0.f;
@@ -1411,6 +1411,222 @@ int sidechaincompressor_audio_module::get_changed_offsets(int index, int generat
     return false;
 }
 
+/// Deesser by Markus Schmidt
+///
+/// This module splits the signal in a sidechain- and a process signal.
+/// The sidechain is processed through Krzystofs filters and compresses
+/// the process signal via Thor's compression routine afterwards.
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+deesser_audio_module::deesser_audio_module()
+{
+    is_active = false;
+    srate = 0;
+    last_generation = 0;
+}
+
+void deesser_audio_module::activate()
+{
+    is_active = true;
+    // set all filters and strips
+    compressor.activate();
+    params_changed();
+    detected = 0.f;
+    detected_led = 0.f;
+    clip_out = 0.f;
+}
+void deesser_audio_module::deactivate()
+{
+    is_active = false;
+    compressor.deactivate();
+}
+
+void deesser_audio_module::params_changed()
+{
+    // set the params of all filters
+    if(*params[param_f1_freq] != f1_freq_old or *params[param_f1_level] != f1_level_old
+        or *params[param_f2_freq] != f2_freq_old or *params[param_f2_level] != f2_level_old
+        or *params[param_f2_q] != f2_q_old) {
+        float q = 0.707;
+        
+        hpL.set_hp_rbj((float)*params[param_f1_freq] * (1 - 0.17), q, (float)srate, *params[param_f1_level]);
+        hpR.copy_coeffs(hpL);
+        lpL.set_lp_rbj((float)*params[param_f1_freq] * (1 + 0.17), q, (float)srate);
+        lpR.copy_coeffs(lpL);
+        pL.set_peakeq_rbj((float)*params[param_f2_freq], *params[param_f2_q], *params[param_f2_level], (float)srate);
+        pR.copy_coeffs(pL);
+        f1_freq_old = *params[param_f1_freq];
+        f1_level_old = *params[param_f1_level];
+        f2_freq_old = *params[param_f2_freq];
+        f2_level_old = *params[param_f2_level];
+        f2_q_old = *params[param_f2_q];
+    }
+    // and set the compressor module
+    compressor.set_params((float)*params[param_laxity], (float)*params[param_laxity] * 1.33, *params[param_threshold], *params[param_ratio], 2.8, *params[param_makeup], *params[param_detection], 0.f, *params[param_bypass], 0.f);
+}
+
+void deesser_audio_module::set_sample_rate(uint32_t sr)
+{
+    srate = sr;
+    compressor.set_sample_rate(srate);
+}
+
+uint32_t deesser_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask)
+{
+    bool bypass = *params[param_bypass] > 0.5f;
+    numsamples += offset;
+    if(bypass) {
+        // everything bypassed
+        while(offset < numsamples) {
+            outs[0][offset] = ins[0][offset];
+            outs[1][offset] = ins[1][offset];
+            ++offset;
+        }
+        // displays, too
+        clip_out   = 0.f;
+        detected = 0.f;
+        detected_led = 0.f;
+    } else {
+        // process
+        
+        detected_led -= std::min(detected_led,  numsamples);
+        
+        while(offset < numsamples) {
+            // cycle through samples
+            float outL = 0.f;
+            float outR = 0.f;
+            float inL = ins[0][offset];
+            float inR = ins[1][offset];
+            
+            
+            float leftAC = inL;
+            float rightAC = inR;
+            float leftSC = inL;
+            float rightSC = inR;
+            float leftMC = inL;
+            float rightMC = inR;
+            
+            leftSC = pL.process(hpL.process(leftSC));
+            rightSC = pR.process(hpR.process(rightSC));
+            leftMC = leftSC;
+            rightMC = rightSC;
+                    
+            switch ((int)*params[param_mode]) {
+                default:
+                case WIDE:
+                    compressor.process(leftAC, rightAC, leftSC, rightSC);
+                    break;
+                case SPLIT:
+                    compressor.process(leftSC, rightSC, leftSC, rightSC);
+                    leftAC = lpL.process(leftAC);
+                    rightAC = lpR.process(rightAC);
+                    leftAC += leftSC;
+                    rightAC += rightSC;
+                    break;
+            }
+            
+            if(*params[param_sc_listen] > 0.f) {
+                outL = leftMC;
+                outR = rightMC;
+            } else {
+                outL = leftAC;
+                outR = rightAC;
+            }
+            
+            // send to output
+            outs[0][offset] = outL;
+            outs[1][offset] = outR;
+            
+            if(std::max(fabs(leftSC), fabs(rightSC)) > 0.1) {
+                detected_led   = srate >> 3;
+            }
+            clip_out = std::max(fabs(outL), fabs(outR));
+            detected = std::max(fabs(leftMC), fabs(rightMC));
+            
+            // next sample
+            ++offset;
+        } // cycle trough samples
+        hpL.sanitize();
+        hpR.sanitize();
+        lpL.sanitize();
+        lpR.sanitize();
+        pL.sanitize();
+        pR.sanitize();
+    }
+    // draw meters
+    if(params[param_detected_led] != NULL) {
+        *params[param_detected_led] = detected_led;
+    }
+    if(params[param_clip_out] != NULL) {
+        *params[param_clip_out] = clip_out;
+    }
+    if(params[param_detected] != NULL) {
+        *params[param_detected] = detected;
+    }
+    // draw strip meter
+    if(bypass > 0.5f) {
+        if(params[param_compression] != NULL) {
+            *params[param_compression] = 1.0f;
+        }
+    } else {
+        if(params[param_compression] != NULL) {
+            *params[param_compression] = compressor.get_comp_level();
+        }
+    }
+    // whatever has to be returned x)
+    return outputs_mask;
+}
+bool deesser_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context)
+{
+    if (!is_active)
+        return false;
+    if (index == param_f1_freq && !subindex) {
+        context->set_line_width(1.5);
+        return ::get_graph(*this, subindex, data, points);
+    }
+    return false;
+}
+
+bool deesser_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context)
+{
+    return get_freq_gridline(subindex, pos, vertical, legend, context);
+    
+//    return false;
+}
+
+int deesser_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline)
+{
+    if (!is_active) {
+        return false;
+    } else {
+        //  (fabs(inertia_cutoff.get_last() - old_cutoff) + 100 * fabs(inertia_resonance.get_last() - old_resonance) + fabs(*params[par_mode] - old_mode) > 0.1f)
+        if (*params[param_f1_freq] != f1_freq_old1
+            or *params[param_f2_freq] != f2_freq_old1
+            or *params[param_f1_level] != f1_level_old1
+            or *params[param_f2_level] != f2_level_old1
+            or *params[param_f2_q] !=f2_q_old1)
+        {
+            f1_freq_old1 = *params[param_f1_freq];
+            f2_freq_old1 = *params[param_f2_freq];
+            f1_level_old1 = *params[param_f1_level];
+            f2_level_old1 = *params[param_f2_level];
+            f2_q_old1 = *params[param_f2_q];
+            last_generation++;
+            subindex_graph = 0;
+            subindex_dot = INT_MAX;
+            subindex_gridline = INT_MAX;
+        }
+        else {
+            subindex_graph = 0;
+            subindex_dot = subindex_gridline = generation ? INT_MAX : 0;
+        }
+        if (generation == last_calculated_generation)
+            subindex_graph = INT_MAX;
+        return last_generation;
+    }
+    return false;
+}
+
 /// Gain reduction module implemented by Markus Schmidt
 /// Nearly all functions of this module are originally written
 /// by Thor, while some features have been stripped (mainly stereo linking

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list