[SCM] calf/master: + organ: removed rotary speaker emulation altogether, might get back some day as B3-style vibrato/chorus, decreased default master volume, increased foldover point (sounded bad previously!), set 1' stop to 0.3 + rotaryspeaker: new effect, unoptimized so far, I want to make it good-sounding first (pretty close!)

js at users.alioth.debian.org js at users.alioth.debian.org
Tue May 7 15:36:50 UTC 2013


The following commit has been merged in the master branch:
commit 6f9bac53330482e3bef2d7934335a4e246819853
Author: kfoltman <kfoltman at 78b06b96-2940-0410-b7fc-879d825d01d8>
Date:   Fri Dec 28 00:11:41 2007 +0000

    + organ: removed rotary speaker emulation altogether, might get back some day as B3-style vibrato/chorus, decreased default master volume, increased foldover point (sounded bad previously!), set 1' stop to 0.3
    + rotaryspeaker: new effect, unoptimized so far, I want to make it good-sounding first (pretty close!)
    
    
    
    git-svn-id: https://calf.svn.sourceforge.net/svnroot/calf/trunk@51 78b06b96-2940-0410-b7fc-879d825d01d8

diff --git a/src/calf/delay.h b/src/calf/delay.h
index f3a4b0c..e33ff05 100644
--- a/src/calf/delay.h
+++ b/src/calf/delay.h
@@ -98,6 +98,22 @@ struct simple_delay {
         odata = lerp(data[ppos], data[pppos], udelay);
     }
     
+    /** Read one C-channel sample at fractional position.
+     * This version can be used for modulated delays, because
+     * it uses linear interpolation.
+     * @param odata value to write into
+     * @param delay delay relative to current writing pos
+     * @param udelay fractional delay (0..1)
+     */
+    inline T get_interp_1616(unsigned int delay) {
+        float udelay = (float)((delay & 0xFFFF) * (1.0 / 65536.0));
+        delay = delay >> 16;
+//        assert(delay >= 0 && delay < N-1);
+        int ppos = wrap_around<N>(pos + N - delay);
+        int pppos = wrap_around<N>(ppos + N - 1);
+        return lerp(data[ppos], data[pppos], udelay);
+    }
+    
     /**
      * Comb filter. Feedback delay line with given delay and feedback values
      * @param in input signal
diff --git a/src/calf/modules_dev.h b/src/calf/modules_dev.h
index 0724d97..2345504 100644
--- a/src/calf/modules_dev.h
+++ b/src/calf/modules_dev.h
@@ -40,7 +40,7 @@ public:
     using drawbar_organ::note_off;
     using drawbar_organ::control_change;
     enum { par_drawbar1, par_drawbar2, par_drawbar3, par_drawbar4, par_drawbar5, par_drawbar6, par_drawbar7, par_drawbar8, par_drawbar9, par_foldover,
-        par_percmode, par_percharm, par_vibrato, par_master, param_count };
+        par_percmode, par_percharm, par_master, param_count };
     enum { in_count = 0, out_count = 2, support_midi = true, rt_capable = true };
     static const char *port_names[];
     float *ins[in_count]; 
@@ -60,7 +60,6 @@ public:
     void params_changed() {
         for (int i = 0; i < param_count; i++)
             ((float *)&par_values)[i] = *params[i];
-        set_vibrato();
     }
     void activate() {
         setup(srate);
@@ -75,6 +74,127 @@ public:
     
 };
 
+class rotary_speaker_audio_module: public null_audio_module
+{
+public:
+    enum { par_speed, param_count };
+    enum { in_count = 2, out_count = 2, support_midi = true, rt_capable = true };
+    static const char *port_names[];
+    float *ins[in_count]; 
+    float *outs[out_count];
+    float *params[param_count];
+    float phase_h, dphase_h;
+    float phase_l, dphase_l;
+    dsp::simple_delay<4096, float> delay;
+    dsp::biquad<float> crossover1l, crossover1r, crossover2l, crossover2r;
+    dsp::simple_delay<8, float> phaseshift;
+    uint32_t srate;
+    int vibrato_mode;
+    static parameter_properties param_props[];
+    float mwhl_value, hold_value;
+
+    rotary_speaker_audio_module()
+    {
+        mwhl_value = hold_value = 0.f;
+        phase_h = phase_l = 0.f;
+    }    
+    void set_sample_rate(uint32_t sr) {
+        srate = sr;
+        setup();
+    }
+    void setup()
+    {
+        crossover1l.set_lp_rbj(800.f, 0.7, (float)srate);
+        crossover1r.set_lp_rbj(800.f, 0.7, (float)srate);
+        crossover2l.set_hp_rbj(800.f, 0.7, (float)srate);
+        crossover2r.set_hp_rbj(800.f, 0.7, (float)srate);
+        set_vibrato();
+    }
+    void params_changed() {
+        set_vibrato();
+    }
+    void activate() {
+        phase_h = phase_l = 0.f;
+        setup();
+    }
+    void deactivate() {
+    }
+    void set_vibrato()
+    {
+        vibrato_mode = fastf2i_drm(*params[par_speed]);
+        if (!vibrato_mode)
+            return;
+        float speed = vibrato_mode - 1;
+        if (vibrato_mode == 3)
+            speed = hold_value;
+        if (vibrato_mode == 4)
+            speed = mwhl_value;
+        speed = (speed < 0.5f) ? 0 : 1;
+        float speed_h = 48 + (400-48) * speed;
+        float speed_l = 40 + (342-40) * speed;
+        dphase_h = 2 * PI * speed_h / (60 * srate);
+        dphase_l = 2 * PI * speed_l / (60 * srate);
+    }
+    uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask)
+    {
+        if (vibrato_mode)
+        {
+            for (unsigned int i = 0; i < nsamples; i++) {
+                float in_l = ins[0][i + offset], in_r = ins[1][i + offset];
+                float in_mono = 0.5f * (in_l + in_r);
+                
+                // XXXKF this is of course criminal, but I'm working on sound, not performance at this stage
+                int xl = (int)(10000 * cos(phase_l)), yl = (int)(10000 * sin(phase_l));
+                int xh = (int)(10000 * cos(phase_h)), yh = (int)(10000 * sin(phase_h));
+                phase_l += dphase_l;
+                phase_h += dphase_h;
+                
+                float out_hi_l = delay.get_interp_1616(500000 + 40 * xh) + 0.0001 * xh * delay.get_interp_1616(500000 - 40 * yh) - delay.get_interp_1616(800000 - 60 * xh);
+                float out_hi_r = delay.get_interp_1616(550000 - 48 * yh) - 0.0001 * yh * delay.get_interp_1616(700000 + 46 * xh) - delay.get_interp_1616(1000000 + 76 * yh);
+
+                float out_lo_l = 0.5f * in_mono + delay.get_interp_1616(400000 + 34 * xl) + delay.get_interp_1616(600000 - 18 * yl);
+                float out_lo_r = 0.5f * in_mono + delay.get_interp_1616(600000 - 50 * xl) - delay.get_interp_1616(900000 + 15 * yl);
+                
+                out_hi_l = crossover2l.process_d2(out_hi_l);
+                out_hi_r = crossover2r.process_d2(out_hi_r);
+                out_lo_l = crossover1l.process_d2(out_lo_l);
+                out_lo_r = crossover1r.process_d2(out_lo_r);
+                
+                float out_l = out_hi_l + out_lo_l;
+                float out_r = out_hi_r + out_lo_r;
+                
+                in_mono += 0.06f * (out_l + out_r);
+                
+                outs[0][i + offset] = out_l;
+                outs[1][i + offset] = out_r;
+                delay.put(in_mono);
+            }
+            phase_l = fmod(phase_l, (float)(2 * PI));
+            phase_h = fmod(phase_h, (float)(2 * PI));
+        } else
+        {
+            memcpy(outs[0] + offset, ins[0] + offset, sizeof(float) * nsamples);
+            memcpy(outs[1] + offset, ins[1] + offset, sizeof(float) * nsamples);
+        }
+        return outputs_mask;
+    }
+    virtual void control_change(int ctl, int val)
+    {
+        if (vibrato_mode == 3 && ctl == 64)
+        {
+            hold_value = val / 127.f;
+            set_vibrato();
+            return;
+        }
+        if (vibrato_mode == 4 && ctl == 1)
+        {
+            mwhl_value = val / 127.f;
+            set_vibrato();
+            return;
+        }
+    }
+};
+
 };
 
 #endif
diff --git a/src/calf/organ.h b/src/calf/organ.h
index 5fb65ff..04cca28 100644
--- a/src/calf/organ.h
+++ b/src/calf/organ.h
@@ -32,13 +32,11 @@ struct organ_parameters {
     float foldover;
     float percussion_mode;
     float harmonic;
-    float vibrato_mode;
     float master;
 
     inline bool get_foldover() { return foldover >= 0.5f; }
     inline int get_percussion_mode() { return dsp::fastf2i_drm(percussion_mode); }
     inline int get_harmonic() { return dsp::fastf2i_drm(harmonic); }
-    inline int get_vibrato_mode() { return dsp::fastf2i_drm(vibrato_mode); }
 };
 
 class organ_voice_base
@@ -86,7 +84,7 @@ public:
     void calc_foldover() {
         h4 = 4, h6 = 6, h8 = 8, h10 = 10, h12 = 12, h16 = 16;
         if (!parameters->get_foldover()) return;
-        const int foc = 108, foc2 = 108 + 12, foc3 = 108 + 24;
+        const int foc = 120, foc2 = 120 + 12, foc3 = 120 + 24;
         if (note + 24 >= foc) h4 = 2;
         if (note + 24 >= foc2) h4 = 1;
         if (note + 36 >= foc) h8 = 4;
@@ -189,17 +187,10 @@ public:
 struct drawbar_organ: public synth::basic_synth {
     organ_parameters *parameters;
     percussion_voice percussion;
-    // chorus instead of rotary speaker is, well, cheesy
-    // let me think of something better some day
-    dsp::simple_flanger<float, 4096> chorus, chorus2;
-    dsp::biquad<float> crossover1, crossover2;
-    dsp::simple_delay<8, float> phaseshift;
-    float mwhl_value, hold_value;
     
     drawbar_organ(organ_parameters *_parameters)
     : parameters(_parameters)
     , percussion(_parameters) {
-        mwhl_value = hold_value = 0.f;
     }
     void render_to(float *output[], int nsamples)
     {
@@ -209,20 +200,6 @@ struct drawbar_organ: public synth::basic_synth {
         if (percussion.get_active())
             percussion.render_to(buf, nsamples);
         float gain = parameters->master;
-        if (parameters->get_vibrato_mode())
-        {
-            float chorus_buffer[4096];
-            float chorus_buffer2[4096];
-            chorus.process(chorus_buffer, buf, nsamples);
-            chorus2.process(chorus_buffer2, buf, nsamples);
-            for (int i=0; i<nsamples; i++) {
-                float lower_drum = crossover1.process_d2(chorus_buffer[i]);
-                float upper_drum = crossover2.process_d2(chorus_buffer2[i]);
-                output[0][i] = gain*(buf[i] + lower_drum - upper_drum);
-                output[1][i] = gain*(buf[i] - phaseshift.process(lower_drum - upper_drum, 7));
-            }
-        }
-        else
         for (int i=0; i<nsamples; i++) {
             output[0][i] = gain*buf[i];
             output[1][i] = gain*buf[i];
@@ -236,54 +213,7 @@ struct drawbar_organ: public synth::basic_synth {
     }
     virtual void setup(int sr) {
         basic_synth::setup(sr);
-        crossover1.set_lp_rbj(800.f, 0.7, (float)sr);
-        crossover2.set_hp_rbj(800.f, 0.7, (float)sr);
-        set_vibrato();
-        chorus.setup(sr);chorus2.setup(sr);
-        chorus.set_min_delay(0.0041f);chorus2.set_min_delay(0.0025f);
-        chorus.set_mod_depth(0.0024f);chorus2.set_mod_depth(0.0034f);
-
-        chorus.set_rate(0.63f);chorus2.set_rate(0.63f);
-        chorus.set_wet(0.5f);chorus2.set_wet(0.5f);
-        chorus.set_dry(0.0f);chorus2.set_dry(0.0f);
         percussion.setup(sr);
-        mwhl_value = hold_value = 0.f;
-    }
-    virtual void control_change(int ctl, int val)
-    {
-        int mode = parameters->get_vibrato_mode();
-        if (mode == 3 && ctl == 64)
-        {
-            hold_value = val / 127.f;
-            set_vibrato();
-            return;
-        }
-        if (mode == 4 && ctl == 1)
-        {
-            mwhl_value = val / 127.f;
-            set_vibrato();
-            return;
-        }
-        synth::basic_synth::control_change(ctl, val);
-    }
-    void set_vibrato()
-    {
-        int mode = parameters->get_vibrato_mode();
-        if (!mode)
-            return;
-        float speed = mode - 1;
-        if (mode == 3)
-            speed = hold_value;
-        if (mode == 4)
-            speed = mwhl_value;
-        chorus.set_mod_depth(0.002f - 0.0015f*speed);
-        chorus2.set_mod_depth(0.0025f - 0.002f*speed);
-        chorus.set_min_delay(0.0061f);
-        chorus2.set_min_delay(0.0085f);
-        chorus.set_rate((40.0 + (342 - 40)*speed) / 60.0);
-        chorus2.set_rate((48.0 + (400 - 48)*speed) / 60.0);
-        chorus.set_fb(0.3f);
-        chorus2.set_fb(-0.3f);
     }
 };
 
diff --git a/src/jackhost.cpp b/src/jackhost.cpp
index a35e690..a7304ae 100644
--- a/src/jackhost.cpp
+++ b/src/jackhost.cpp
@@ -59,6 +59,8 @@ jack_host_base *synth::create_jack_host(const char *effect_name)
 #ifdef ENABLE_EXPERIMENTAL
     else if (!strcmp(effect_name, "organ"))
         return new jack_host<organ_audio_module>();
+    else if (!strcmp(effect_name, "rotaryspeaker"))
+        return new jack_host<rotary_speaker_audio_module>();
 #endif
     else
         return NULL;
@@ -174,7 +176,7 @@ int main(int argc, char *argv[])
             jack_host_base *jh = create_jack_host(names[i].c_str());
             if (!jh) {
 #ifdef ENABLE_EXPERIMENTAL
-                fprintf(stderr, "Unknown plugin name; allowed are: reverb, flanger, filter, vintagedelay, monosynth, organ\n");
+                fprintf(stderr, "Unknown plugin name; allowed are: reverb, flanger, filter, vintagedelay, monosynth, organ, rotaryspeaker\n");
 #else
                 fprintf(stderr, "Unknown plugin name; allowed are: reverb, flanger, filter, vintagedelay, monosynth\n");
 #endif
diff --git a/src/modules.cpp b/src/modules.cpp
index 80756fa..300d3be 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -141,7 +141,6 @@ const char *organ_audio_module::port_names[] = {"Out L", "Out R"};
 
 const char *organ_percussion_mode_names[] = { "Off", "Short", "Long" };
 const char *organ_percussion_harmonic_names[] = { "2nd", "3rd" };
-const char *organ_vibrato_speed_names[] = { "Off", "Swell", "Tremolo", "HoldPedal", "ModWheel" };
 
 parameter_properties organ_audio_module::param_props[] = {
     { 0.3,       0,  1, 1.01, PF_FLOAT | PF_SCALE_QUAD | PF_CTL_FADER, NULL, "h1", "16'" },
@@ -152,14 +151,13 @@ parameter_properties organ_audio_module::param_props[] = {
     { 0,         0,  1, 1.01, PF_FLOAT | PF_SCALE_QUAD | PF_CTL_FADER, NULL, "h8", "2'" },
     { 0,         0,  1, 1.01, PF_FLOAT | PF_SCALE_QUAD | PF_CTL_FADER, NULL, "h10", "1 3/5'" },
     { 0,         0,  1, 1.01, PF_FLOAT | PF_SCALE_QUAD | PF_CTL_FADER, NULL, "h12", "1 1/3'" },
-    { 0,         0,  1, 1.01, PF_FLOAT | PF_SCALE_QUAD | PF_CTL_FADER, NULL, "h16", "1'" },
+    { 0.3,       0,  1, 1.01, PF_FLOAT | PF_SCALE_QUAD | PF_CTL_FADER, NULL, "h16", "1'" },
 
     { 1,         0,  1, 1.01, PF_BOOL | PF_CTL_TOGGLE, NULL, "foldover", "Foldover" },
     { 1,         0,  2, 1.01, PF_ENUM | PF_CTL_COMBO, organ_percussion_mode_names, "perc_mode", "Perc. mode" },
     { 3,         2,  3, 1.01, PF_ENUM | PF_CTL_COMBO, organ_percussion_harmonic_names, "perc_hrm", "Perc. harmonic" },
-    { 1,         0,  4, 1.01, PF_ENUM | PF_CTL_COMBO, organ_vibrato_speed_names, "vib_speed", "Vibrato mode" },
 
-    { 0.2,         0,  1, 1.01, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB, NULL, "amount", "Amount" },
+    { 0.1,         0,  1, 1.01, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB, NULL, "amount", "Amount" },
 };
 
 static synth::ladspa_info organ_info = { 0x8481, "Organ", "Calf Organ", "Krzysztof Foltman", copyright, "SynthesizerPlugin" };
@@ -168,6 +166,22 @@ static synth::ladspa_info organ_info = { 0x8481, "Organ", "Calf Organ", "Krzyszt
 static synth::ladspa_wrapper<organ_audio_module> organ(organ_info);
 #endif
 
+////////////////////////////////////////////////////////////////////////////
+
+const char *rotary_speaker_audio_module::port_names[] = {"In L", "In R", "Out L", "Out R"};
+
+const char *rotary_speaker_speed_names[] = { "Off", "Swell", "Tremolo", "HoldPedal", "ModWheel" };
+
+parameter_properties rotary_speaker_audio_module::param_props[] = {
+    { 2,         0,  4, 1.01, PF_ENUM | PF_CTL_COMBO, rotary_speaker_speed_names, "vib_speed", "Speed Mode" },
+};
+
+static synth::ladspa_info rotary_speaker_info = { 0x8483, "RotarySpeaker", "Calf Rotary Speaker", "Krzysztof Foltman", copyright, "SimulationPlugin" };
+
+#if USE_LADSPA
+static synth::ladspa_wrapper<rotary_speaker_audio_module> rotary_speaker(rotary_speaker_info);
+#endif
+
 #endif
 ////////////////////////////////////////////////////////////////////////////
 
@@ -189,6 +203,9 @@ const LADSPA_Descriptor *ladspa_descriptor(unsigned long Index)
         case 1: return &::flanger.descriptor;
         case 2: return &::reverb.descriptor;
         case 3: return &::vintage_delay.descriptor;
+#ifdef ENABLE_EXPERIMENTAL
+        case 4: return &::rotary_speaker.descriptor;
+#endif
         default: return NULL;
     }
 }
@@ -208,6 +225,7 @@ const DSSI_Descriptor *dssi_descriptor(unsigned long Index)
         case 4: return &::vintage_delay.dssi_descriptor;
 #ifdef ENABLE_EXPERIMENTAL
         case 5: return &::organ.dssi_descriptor;
+        case 6: return &::rotary_speaker.dssi_descriptor;
 #endif
         default: return NULL;
     }

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list