[SCM] calf/master: Implement a naive simulation of osc sync in Monosynth (Osc1 Stretch).

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


The following commit has been merged in the master branch:
commit 89aa6c9134331623fbb4eb6aead7c8a08c99cc6f
Author: Krzysztof Foltman <wdev at foltman.com>
Date:   Sat May 8 18:42:12 2010 +0100

    Implement a naive simulation of osc sync in Monosynth (Osc1 Stretch).

diff --git a/gui/gui-monosynth.xml b/gui/gui-monosynth.xml
index b0a547a..af0313a 100644
--- a/gui/gui-monosynth.xml
+++ b/gui/gui-monosynth.xml
@@ -45,6 +45,11 @@
             <if cond="directlink">
               <line-graph param="o1_wave" refresh="1" width="80" height="80" expand="0" fill="0"/>
             </if>
+            <vbox>
+              <label param="o1_stretch" text="Stretch"/>
+              <knob param="o1_stretch"/>
+              <value param="o1_stretch"/>
+            </vbox>
           </hbox>
         </frame>
         <frame label="Oscillator 2">
diff --git a/src/calf/metadata.h b/src/calf/metadata.h
index 4637afa..4254b45 100644
--- a/src/calf/metadata.h
+++ b/src/calf/metadata.h
@@ -109,6 +109,7 @@ struct monosynth_metadata: public plugin_metadata<monosynth_metadata>
         par_lforate, par_lfodelay, par_lfofilter, par_lfopitch, par_lfopw, par_mwhl_lfo, par_scaledetune,
         par_env2tocutoff, par_env2tores, par_env2toamp, 
         par_env2attack, par_env2decay, par_env2sustain, par_env2fade, par_env2release, 
+        par_stretch1,
         param_count };
     enum { in_count = 0, out_count = 2, ins_optional = 0, outs_optional = 0, support_midi = true, require_midi = true, rt_capable = true };
     enum { step_size = 64, step_shift = 6 };
@@ -133,6 +134,7 @@ struct monosynth_metadata: public plugin_metadata<monosynth_metadata>
         moddest_o2detune,
         moddest_o1pw,
         moddest_o2pw,
+        moddest_o1stretch,
         moddest_count,
     };
     PLUGIN_NAME_ID_LABEL("monosynth", "monosynth", "Monosynth")
diff --git a/src/calf/modules_synths.h b/src/calf/modules_synths.h
index 63e72ed..6f11e7f 100644
--- a/src/calf/modules_synths.h
+++ b/src/calf/modules_synths.h
@@ -69,6 +69,8 @@ public:
     int32_t last_pwshift1;
     /// Last value of phase shift for pulse width emulation for OSC2
     int32_t last_pwshift2;
+    /// Last value of stretch for osc sync emulation for OSC1
+    int32_t last_stretch1;
     int queue_note_on, stop_count, modwheel_value_int;
     int legato;
     dsp::adsr envelope1, envelope2;
diff --git a/src/calf/osc.h b/src/calf/osc.h
index ba01a2f..85af5e6 100644
--- a/src/calf/osc.h
+++ b/src/calf/osc.h
@@ -245,12 +245,12 @@ struct waveform_oscillator: public simple_oscillator
     {
         waveform = NULL;
     }
+    
+    /// Get the value from single oscillator at current position
     inline float get()
     {
         uint32_t wpos = phase >> (32 - SIZE_BITS);
-        float value = dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], (phase & (SCALE - 1)) * (1.0f / SCALE));
-        phase += phasedelta;
-        return value;
+        return dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], (phase & (SCALE - 1)) * (1.0f / SCALE));
     }
     /// Add/substract two phase-shifted values
     inline float get_phaseshifted(uint32_t shift, float mix)
@@ -259,9 +259,23 @@ struct waveform_oscillator: public simple_oscillator
         float value1 = dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], (phase & (SCALE - 1)) * (1.0f / SCALE));
         wpos = (phase + shift) >> (32 - SIZE_BITS);
         float value2 = dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], ((phase + shift) & (SCALE - 1)) * (1.0f / SCALE));
-        float value = value1 + mix * value2;
+        return value1 + mix * value2;
+    }
+    /// Get the value of a hard synced osc (65536 = 1:1 ratio)
+    inline float get_phasedist(uint32_t sync, uint32_t shift, float mix)
+    {
+        uint32_t phase_mod = (uint64_t(phase) * sync >> 16);
+        
+        uint32_t wpos = phase_mod >> (32 - SIZE_BITS);
+        float value1 = dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], (phase & (SCALE - 1)) * (1.0f / SCALE));
+        wpos = (phase_mod + shift) >> (32 - SIZE_BITS);
+        float value2 = dsp::lerp(waveform[wpos], waveform[(wpos + 1) & MASK], ((phase + shift) & (SCALE - 1)) * (1.0f / SCALE));
+        return value1 + mix * value2;
+    }
+    /// One step
+    inline void advance()
+    {
         phase += phasedelta;
-        return value;
     }
 };
 
diff --git a/src/metadata.cpp b/src/metadata.cpp
index f7d5a41..bd3cca3 100644
--- a/src/metadata.cpp
+++ b/src/metadata.cpp
@@ -633,7 +633,7 @@ CALF_PORT_PROPS(monosynth) = {
     { 0,      -2400, 2400,    0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "filter_sep", "Separation" },
     { 8000,  -10800,10800,    0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "env2cutoff", "Env->Cutoff" },
     { 1,          0,    1,    0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "env2res", "Env->Res" },
-    { 0,          0,    1,    0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "env2amp", "Env->Amp" },
+    { 0,          0,    1,    0, PF_BOOL | PF_CTL_TOGGLE, NULL, "env2amp", "Env->Amp" },
     
     { 1,          1,20000,    0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr_a", "EG1 Attack" },
     { 350,       10,20000,    0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr_d", "EG1 Decay" },
@@ -663,13 +663,15 @@ CALF_PORT_PROPS(monosynth) = {
 
     { 0,  -10800,10800,    0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "adsr2_cutoff", "EG2->Cutoff" },
     { 0.3,        0,    1,    0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "adsr2_res", "EG2->Res" },
-    { 1,          0,    1,    0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "adsr2_amp", "EG2->Amp" },
+    { 1,          0,    1,    0, PF_BOOL | PF_CTL_TOGGLE, NULL, "adsr2_amp", "EG2->Amp" },
     
     { 1,          1,20000,    0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr2_a", "EG2 Attack" },
     { 100,       10,20000,    0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr2_d", "EG2 Decay" },
     { 0.5,        0,    1,    0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr2_s", "EG2 Sustain" },
     { 0,     -10000,10000,   21, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr2_f", "EG2 Fade" },
     { 50,       10,20000,     0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr2_r", "Release" },
+
+    { 1,          1,   16,    0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "o1_stretch", "Osc1 Stretch" },
 };
 
 ////////////////////////////////////////////////////////////////////////////
diff --git a/src/monosynth.cpp b/src/monosynth.cpp
index 682fbb9..41011c5 100644
--- a/src/monosynth.cpp
+++ b/src/monosynth.cpp
@@ -32,8 +32,10 @@ static const char *monosynth_mod_src_names[] = {
     "Velocity",
     "Pressure",
     "ModWheel",
-    "Envelope",
-    "LFO",
+    "Envelope 1",
+    "Envelope 2",
+    "LFO 1",
+    "LFO 2",
     NULL
 };
 
@@ -47,6 +49,7 @@ static const char *monosynth_mod_dest_names[] = {
     "O2: Detune [ct]",
     "O1: PW (%)",
     "O2: PW (%)",
+    "O1: Stretch",
     NULL
 };
 
@@ -73,6 +76,7 @@ void monosynth_audio_module::activate() {
     filter2.reset();
     stack.clear();
     last_pwshift1 = last_pwshift2 = 0;
+    last_stretch1 = 65536;
 }
 
 waveform_family<MONOSYNTH_WAVE_BITS> *monosynth_audio_module::waves;
@@ -220,7 +224,12 @@ bool monosynth_audio_module::get_graph(int index, int subindex, float *data, int
             wave = wave_saw;
         float *waveform = waves[wave].original;
         for (int i = 0; i < points; i++)
-            data[i] = (sign * waveform[i * S / points] + waveform[(i * S / points + shift) & (S - 1)]) / (sign == -1 ? 1 : 2);
+        {
+            int pos = i * S / points;
+            if (index == par_wave1)
+                pos = int(pos * 1.0 * last_stretch1 / 65536.0 ) % S;
+            data[i] = (sign * waveform[pos] + waveform[(pos + shift) & (S - 1)]) / (sign == -1 ? 1 : 2);
+        }
         return true;
     }
     if (index == par_filtertype) {
@@ -250,15 +259,20 @@ void monosynth_audio_module::calculate_buffer_oscs(float lfo)
 {
     int flag1 = (wave1 == wave_sqr);
     int flag2 = (wave2 == wave_sqr);
+    
     int32_t shift1 = last_pwshift1;
     int32_t shift2 = last_pwshift2;
+    int32_t stretch1 = last_stretch1;
     int32_t shift_target1 = (int32_t)(0x78000000 * dsp::clip11(*params[par_pw1] + lfo * *params[par_lfopw] + 0.01f * moddest[moddest_o1pw]));
     int32_t shift_target2 = (int32_t)(0x78000000 * dsp::clip11(*params[par_pw2] + lfo * *params[par_lfopw] + 0.01f * moddest[moddest_o2pw]));
+    int32_t stretch_target1 = (int32_t)(65536 * dsp::clip(*params[par_stretch1] + 0.01f * moddest[moddest_o1stretch], 1.f, 16.f));
     int32_t shift_delta1 = ((shift_target1 >> 1) - (last_pwshift1 >> 1)) >> (step_shift - 1);
     int32_t shift_delta2 = ((shift_target2 >> 1) - (last_pwshift2 >> 1)) >> (step_shift - 1);
+    int32_t stretch_delta1 = ((stretch_target1 >> 1) - (last_stretch1 >> 1)) >> (step_shift - 1);
     last_lfov = lfo;
     last_pwshift1 = shift_target1;
     last_pwshift2 = shift_target2;
+    last_stretch1 = stretch_target1;
     
     shift1 += (flag1 << 31);
     shift2 += (flag2 << 31);
@@ -270,12 +284,13 @@ void monosynth_audio_module::calculate_buffer_oscs(float lfo)
     
     for (uint32_t i = 0; i < step_size; i++) 
     {
-        float osc1val = osc1.get_phaseshifted(shift1, mix1);
-        float osc2val = osc2.get_phaseshifted(shift2, mix2);
-        float wave = osc1val + (osc2val - osc1val) * cur_xfade;
-        buffer[i] = wave;
+        //buffer[i] = lerp(osc1.get_phaseshifted(shift1, mix1), osc2.get_phaseshifted(shift2, mix2), cur_xfade);
+        buffer[i] = lerp(osc1.get_phasedist(stretch1, shift1, mix1), osc2.get_phaseshifted(shift2, mix2), cur_xfade);
+        osc1.advance();
+        osc2.advance();
         shift1 += shift_delta1;
         shift2 += shift_delta2;
+        stretch1 += stretch_delta1;
         cur_xfade += xfade_step;
     }
     last_xfade = new_xfade;

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list