[SCM] calf/master: + Multichorus: add Overlap parameter

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


The following commit has been merged in the master branch:
commit 1d0ef3ab50304773ada44a25d80bca5128cc418d
Author: Krzysztof Foltman <wdev at foltman.com>
Date:   Wed Mar 11 23:15:31 2009 +0000

    + Multichorus: add Overlap parameter

diff --git a/gui/gui-multichorus.xml b/gui/gui-multichorus.xml
index 95e0974..a5d4641 100644
--- a/gui/gui-multichorus.xml
+++ b/gui/gui-multichorus.xml
@@ -12,6 +12,11 @@
                 <value param="mod_depth" />
             </vbox>
             <vbox border="10">
+                <label param="overlap" />
+                <knob param="overlap" />
+                <value param="overlap" />
+            </vbox>
+            <vbox border="10">
                 <label param="dry" />
                 <knob param="dry" />
                 <value param="dry" />
diff --git a/src/calf/metadata.h b/src/calf/metadata.h
index 334f3dd..733ce5e 100644
--- a/src/calf/metadata.h
+++ b/src/calf/metadata.h
@@ -87,7 +87,7 @@ public:
 struct multichorus_metadata: public plugin_metadata<multichorus_metadata>
 {
 public:    
-    enum { par_delay, par_depth, par_rate, par_stereo, par_voices, par_vphase, par_amount, par_dryamount, par_freq, par_freq2, par_q, param_count };
+    enum { par_delay, par_depth, par_rate, par_stereo, par_voices, par_vphase, par_amount, par_dryamount, par_freq, par_freq2, par_q, par_overlap, param_count };
     enum { in_count = 2, out_count = 2, rt_capable = true, support_midi = false, require_midi = false };
     PLUGIN_NAME_ID_LABEL("multichorus", "multichorus", "Multi Chorus")
 };
diff --git a/src/calf/modules.h b/src/calf/modules.h
index 7e3ea04..3a09447 100644
--- a/src/calf/modules.h
+++ b/src/calf/modules.h
@@ -752,6 +752,7 @@ public:
         float rate = *params[par_rate];
         float min_delay = *params[par_delay] / 1000.0;
         float mod_depth = *params[par_depth] / 1000.0;
+        float overlap = *params[par_overlap];
         left.set_dry(dry); right.set_dry(dry);
         left.set_wet(wet); right.set_wet(wet);
         left.set_rate(rate); right.set_rate(rate);
@@ -759,6 +760,7 @@ public:
         left.set_mod_depth(mod_depth); right.set_mod_depth(mod_depth);
         int voices = (int)*params[par_voices];
         left.lfo.set_voices(voices); right.lfo.set_voices(voices);
+        left.lfo.set_overlap(overlap);right.lfo.set_overlap(overlap);
         float vphase = *params[par_vphase] * (1.f / 360.f);
         left.lfo.vphase = right.lfo.vphase = vphase * (4096 / std::max(voices - 1, 1));
         float r_phase = *params[par_stereo] * (1.f / 360.f);
diff --git a/src/calf/multichorus.h b/src/calf/multichorus.h
index f4ab7ce..121eb98 100644
--- a/src/calf/multichorus.h
+++ b/src/calf/multichorus.h
@@ -44,10 +44,17 @@ public:
     uint32_t voices;
     /// Current scale (output multiplier)
     T scale;
+    /// Per-voice offset unit (the value that says how much the voices are offset with respect to each other in non-100% 'overlap' mode), scaled so that full range = 131072
+    int32_t voice_offset;
+    /// LFO Range scaling for non-100% overlap
+    uint32_t voice_depth;
 public:
     sine_multi_lfo()
     {
         phase = dphase = vphase = 0.0;
+        voice_offset = 0;
+        voice_depth = 1U << 31;
+        
         set_voices(Voices);
     }
     inline uint32_t get_voices() const
@@ -60,6 +67,18 @@ public:
         // use sqrt, because some phases will cancel each other - so 1 / N is usually too low
         scale = sqrt(1.0 / voices);
     }
+    inline void set_overlap(float overlap)
+    {
+        // If we scale the delay amount so that full range of a single LFO is 0..1, all the overlapped LFOs will cover 0..range
+        // How it's calculated:
+        // 1. First voice is assumed to always cover the range of 0..1
+        // 2. Each remaining voice contributes an interval of a width = 1 - overlap, starting from the end of the interval of the previous voice
+        // Coverage = non-overlapped part of the LFO range in the 1st voice
+        float range = 1.f + (1.f - overlap) * (voices - 1);
+        float scaling = 1.f / range;
+        voice_offset = (int)(131072 * (1 - overlap) / range);
+        voice_depth = (unsigned int)((1U << 30) * 1.0 * scaling);
+    }
     /// Get LFO value for given voice, returns a values in range of [-65536, 65535] (or close)
     inline int get_value(uint32_t voice) {
         // find this voice's phase (= phase + voice * 360 degrees / number of voices)
@@ -69,7 +88,9 @@ public:
         // interpolate (use 14 bits of precision - because the table itself uses 17 bits and the result of multiplication must fit in int32_t)
         // note, the result is still -65535 .. 65535, it's just interpolated
         // it is never reaching -65536 - but that's acceptable
-        return voice_phase.lerp_by_fract_int<int, 14, int>(sine.data[ipart], sine.data[ipart+1]);
+        int intval = voice_phase.lerp_by_fract_int<int, 14, int>(sine.data[ipart], sine.data[ipart+1]);
+        // apply the voice offset/depth (rescale from -65535..65535 to appropriate voice's "band")
+        return -65535 + voice * voice_offset + ((voice_depth >> (30-13)) * (65536 + intval) >> 13);
     }
     inline void step() {
         phase += dphase;
diff --git a/src/modules.cpp b/src/modules.cpp
index a5111e9..f297b65 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -200,6 +200,7 @@ CALF_PORT_PROPS(multichorus) = {
     { 100,       10,20000,    0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq", "Center Frq 1" },
     { 5000,      10,20000,    0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq2", "Center Frq 2" },
     { 0.125,  0.125,   8,    0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "q", "Q" },
+    { 1,          0,    1,     0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "overlap", "Overlap" },
 };
 
 CALF_PLUGIN_INFO(multichorus) = { 0x8501, "MultiChorus", "Calf MultiChorus", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "ChorusPlugin" };
diff --git a/src/modules_dsp.cpp b/src/modules_dsp.cpp
index ac94491..e01e5e7 100644
--- a/src/modules_dsp.cpp
+++ b/src/modules_dsp.cpp
@@ -355,6 +355,7 @@ bool multichorus_audio_module::get_graph(int index, int subindex, float *data, i
 {
     if (!is_active)
         return false;
+    int nvoices = (int)*params[par_voices];
     if (index == par_delay && subindex < 3) 
     {
         if (subindex < 2)
@@ -365,9 +366,15 @@ bool multichorus_audio_module::get_graph(int index, int subindex, float *data, i
         }
         return ::get_graph(*this, subindex, data, points);
     }
-    if (index == par_rate && !subindex) {
-        for (int i = 0; i < points; i++)
-            data[i] = 0.95 * sin(i * 2 * M_PI / points);
+    if (index == par_rate && subindex < nvoices) {
+        sine_multi_lfo<float, 8> &lfo = left.lfo;
+        for (int i = 0; i < points; i++) {
+            float phase = i * 2 * M_PI / points;
+            // original -65536 to 65535 value
+            float orig = subindex * lfo.voice_offset + ((lfo.voice_depth >> (30-13)) * 65536.0 * (0.95 * sin(phase) + 1)/ 8192.0) - 65536;
+            // scale to -1..1
+            data[i] = orig / 65536.0;
+        }
         return true;
     }
     return false;
@@ -375,21 +382,27 @@ bool multichorus_audio_module::get_graph(int index, int subindex, float *data, i
 
 bool multichorus_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context)
 {
-    if ((index != par_rate && index != par_depth) || subindex >= 2 * (int)*params[par_voices])
+    int voice = subindex >> 1;
+    int nvoices = (int)*params[par_voices];
+    if ((index != par_rate && index != par_depth) || voice >= nvoices)
         return false;
 
+    float unit = (1 - *params[par_overlap]);
+    float scw = 1 + unit * (nvoices - 1);
     set_channel_color(context, subindex);
     sine_multi_lfo<float, 8> &lfo = (subindex & 1 ? right : left).lfo;
     if (index == par_rate)
     {
-        x = (double)(lfo.phase + lfo.vphase * (subindex >> 1)) / 4096.0;
+        x = (double)(lfo.phase + lfo.vphase * voice) / 4096.0;
         y = 0.95 * sin(x * 2 * M_PI);
+        y = (voice * unit + (y + 1) / 2) / scw * 2 - 1;
     }
     else
     {
-        double ph = (double)(lfo.phase + lfo.vphase * (subindex >> 1)) / 4096.0;
+        double ph = (double)(lfo.phase + lfo.vphase * voice) / 4096.0;
         x = 0.5 + 0.5 * sin(ph * 2 * M_PI);
         y = subindex & 1 ? -0.75 : 0.75;
+        x = (voice * unit + x) / scw;
     }
     return true;
 }

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list