[SCM] calf/master: + Organ: added LFO mode parameter (off, direct/filter1/filter2, voice, global)

js at users.alioth.debian.org js at users.alioth.debian.org
Tue May 7 15:37:10 UTC 2013


The following commit has been merged in the master branch:
commit e803124b37ebaa8be1b602ddf7394fe6699ba7a6
Author: kfoltman <kfoltman at 78b06b96-2940-0410-b7fc-879d825d01d8>
Date:   Wed Apr 30 20:33:41 2008 +0000

    + Organ: added LFO mode parameter (off, direct/filter1/filter2, voice, global)
    
    
    
    git-svn-id: https://calf.svn.sourceforge.net/svnroot/calf/trunk@165 78b06b96-2940-0410-b7fc-879d825d01d8

diff --git a/src/calf/modules_synths.h b/src/calf/modules_synths.h
index 75afe40..c2a8b87 100644
--- a/src/calf/modules_synths.h
+++ b/src/calf/modules_synths.h
@@ -196,23 +196,6 @@ public:
     using drawbar_organ::note_on;
     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_frequency1, par_frequency2, par_frequency3, par_frequency4, par_frequency5, par_frequency6, par_frequency7, par_frequency8, par_frequency9, 
-        par_waveform1, par_waveform2, par_waveform3, par_waveform4, par_waveform5, par_waveform6, par_waveform7, par_waveform8, par_waveform9, 
-        par_detune1, par_detune2, par_detune3, par_detune4, par_detune5, par_detune6, par_detune7, par_detune8, par_detune9, 
-        par_phase1, par_phase2, par_phase3, par_phase4, par_phase5, par_phase6, par_phase7, par_phase8, par_phase9, 
-        par_pan1, par_pan2, par_pan3, par_pan4, par_pan5, par_pan6, par_pan7, par_pan8, par_pan9, 
-        par_routing1, par_routing2, par_routing3, par_routing4, par_routing5, par_routing6, par_routing7, par_routing8, par_routing9, 
-        par_foldover,
-        par_percdecay, par_perclevel, par_percharm, par_master, 
-        par_f1cutoff, par_f1res, par_f1env1, par_f1env2, par_f1env3, par_f1keyf,
-        par_f2cutoff, par_f2res, par_f2env1, par_f2env2, par_f2env3, par_f2keyf,
-        par_eg1attack, par_eg1decay, par_eg1sustain, par_eg1release, par_eg1velscl, par_eg1ampctl, 
-        par_eg2attack, par_eg2decay, par_eg2sustain, par_eg2release, par_eg2velscl, par_eg2ampctl, 
-        par_eg3attack, par_eg3decay, par_eg3sustain, par_eg3release, par_eg3velscl, par_eg3ampctl, 
-        par_lforate, par_lfoamt, par_lfowet, par_lfophase,
-        param_count };
     enum { in_count = 0, out_count = 2, support_midi = true, rt_capable = true };
     static const char *port_names[];
     float *ins[in_count]; 
@@ -243,7 +226,7 @@ public:
     }
     uint32_t process(uint32_t offset, uint32_t nsamples, uint32_t inputs_mask, uint32_t outputs_mask) {
         float *o[2] = { outs[0] + offset, outs[1] + offset };
-        render_to(o, nsamples);
+        render_separate(o, nsamples);
         return 3;
     }
     static const char *get_name() { return "organ"; }    
diff --git a/src/calf/organ.h b/src/calf/organ.h
index e4857c1..16a09fc 100644
--- a/src/calf/organ.h
+++ b/src/calf/organ.h
@@ -61,6 +61,7 @@ struct organ_parameters {
     float lfo_amt;
     float lfo_wet;
     float lfo_phase;
+    float lfo_mode;
     
     double perc_decay_const;
     float multiplier[9];
@@ -92,6 +93,15 @@ public:
         ampctl_all,
         ampctl_count
     };
+    enum { 
+        lfomode_off = 0,
+        lfomode_direct,
+        lfomode_filter1,
+        lfomode_filter2,
+        lfomode_voice,
+        lfomode_global,
+        lfomode_count
+    };
 protected:
     static waveform_family<ORGAN_WAVE_BITS> waves[wave_count];
     // dsp::sine_table<float, ORGAN_WAVE_SIZE, 1> sine_wave;
@@ -107,9 +117,21 @@ public:
     organ_parameters *parameters;
 };
 
+class organ_vibrato
+{
+protected:
+    enum { VibratoSize = 6 };
+    float vibrato_x1[VibratoSize][2], vibrato_y1[VibratoSize][2];
+    float lfo_phase;
+    onepole<float> vibrato[2];
+public:
+    void reset();
+    void process(organ_parameters *parameters, float (*data)[2], unsigned int len, float sample_rate);
+};
+
 class organ_voice: public synth::voice, public organ_voice_base {
 protected:    
-    enum { Channels = 2, BlockSize = 64, EnvCount = organ_parameters::EnvCount, FilterCount = organ_parameters::FilterCount, VibratoSize = 6 };
+    enum { Channels = 2, BlockSize = 64, EnvCount = organ_parameters::EnvCount, FilterCount = organ_parameters::FilterCount };
     union {
         float output_buffer[BlockSize][Channels];
         float aux_buffers[3][BlockSize][Channels];
@@ -117,11 +139,10 @@ protected:
     bool released;
     dsp::fixed_point<int64_t, 52> phase, dphase;
     biquad<float> filterL[2], filterR[2];
-    onepole<float> vibrato[2];
-    float vibrato_x1[VibratoSize][2], vibrato_y1[VibratoSize][2];
     adsr envs[EnvCount];
     inertia<linear_ramp> expression;
-    float velocity, lfo_phase;
+    organ_vibrato vibrato;
+    float velocity;
 
 public:
     organ_voice()
@@ -130,19 +151,17 @@ public:
     }
 
     void reset() {
+        vibrato.reset();
         phase = 0;
         for (int i = 0; i < FilterCount; i++)
         {
             filterL[i].reset();
             filterR[i].reset();
         }
-        for (int i = 0; i < VibratoSize; i++)
-            vibrato_x1[i][0] = vibrato_y1[i][0] = vibrato_x1[i][1] = vibrato_y1[i][1] = 0.f;
     }
 
     void note_on(int note, int vel) {
         reset();
-        this->lfo_phase = 0.f;
         this->note = note;
         const float sf = 0.001f;
         for (int i = 0; i < EnvCount; i++)
@@ -196,7 +215,7 @@ public:
     }
 
     // this doesn't really have a voice interface
-    void render_to(float *buf[2], int nsamples) {
+    void render_to(float (*buf)[2], int nsamples) {
         if (note == -1)
             return;
 
@@ -212,8 +231,8 @@ public:
         for (int i = 0; i < nsamples; i++) {
             float osc = level * wave(data, percussion_harmonic * phase);
             osc *= level * amp.get();
-            buf[0][i] += osc;
-            buf[1][i] += osc;
+            buf[i][0] += osc;
+            buf[i][1] += osc;
             amp.age_exp(age_const, 1.0 / 32768.0);
             phase += dphase;
         }
@@ -229,23 +248,44 @@ public:
 struct drawbar_organ: public synth::basic_synth {
     organ_parameters *parameters;
     percussion_voice percussion;
+    organ_vibrato global_vibrato;
     
-    drawbar_organ(organ_parameters *_parameters)
+    enum { 
+        par_drawbar1, par_drawbar2, par_drawbar3, par_drawbar4, par_drawbar5, par_drawbar6, par_drawbar7, par_drawbar8, par_drawbar9, 
+        par_frequency1, par_frequency2, par_frequency3, par_frequency4, par_frequency5, par_frequency6, par_frequency7, par_frequency8, par_frequency9, 
+        par_waveform1, par_waveform2, par_waveform3, par_waveform4, par_waveform5, par_waveform6, par_waveform7, par_waveform8, par_waveform9, 
+        par_detune1, par_detune2, par_detune3, par_detune4, par_detune5, par_detune6, par_detune7, par_detune8, par_detune9, 
+        par_phase1, par_phase2, par_phase3, par_phase4, par_phase5, par_phase6, par_phase7, par_phase8, par_phase9, 
+        par_pan1, par_pan2, par_pan3, par_pan4, par_pan5, par_pan6, par_pan7, par_pan8, par_pan9, 
+        par_routing1, par_routing2, par_routing3, par_routing4, par_routing5, par_routing6, par_routing7, par_routing8, par_routing9, 
+        par_foldover,
+        par_percdecay, par_perclevel, par_percharm, par_master, 
+        par_f1cutoff, par_f1res, par_f1env1, par_f1env2, par_f1env3, par_f1keyf,
+        par_f2cutoff, par_f2res, par_f2env1, par_f2env2, par_f2env3, par_f2keyf,
+        par_eg1attack, par_eg1decay, par_eg1sustain, par_eg1release, par_eg1velscl, par_eg1ampctl, 
+        par_eg2attack, par_eg2decay, par_eg2sustain, par_eg2release, par_eg2velscl, par_eg2ampctl, 
+        par_eg3attack, par_eg3decay, par_eg3sustain, par_eg3release, par_eg3velscl, par_eg3ampctl, 
+        par_lforate, par_lfoamt, par_lfowet, par_lfophase, par_lfomode,
+        param_count
+    };
+
+     drawbar_organ(organ_parameters *_parameters)
     : parameters(_parameters)
     , percussion(_parameters) {
     }
-    void render_to(float *output[], int nsamples)
+    void render_separate(float *output[], int nsamples)
     {
-        float buf[2][4096], *bufptr[] = { buf[0], buf[1] };
-        dsp::zero(buf[0], nsamples);
-        dsp::zero(buf[1], nsamples);
-        basic_synth::render_to(bufptr, nsamples);
+        float buf[4096][2];
+        dsp::zero(&buf[0][0], 2 * nsamples);
+        basic_synth::render_to(buf, nsamples);
+        if (fastf2i_drm(parameters->lfo_mode) == organ_voice_base::lfomode_global)
+            global_vibrato.process(parameters, buf, nsamples, sample_rate);
         if (percussion.get_active())
-            percussion.render_to(bufptr, nsamples);
+            percussion.render_to(buf, nsamples);
         float gain = parameters->master * (1.0 / (9 * 8));
         for (int i=0; i<nsamples; i++) {
-            output[0][i] = gain*buf[0][i];
-            output[1][i] = gain*buf[1][i];
+            output[0][i] = gain*buf[i][0];
+            output[1][i] = gain*buf[i][1];
         }
     }
     synth::voice *alloc_voice() {
diff --git a/src/calf/synth.h b/src/calf/synth.h
index 797fc05..4d74eab 100644
--- a/src/calf/synth.h
+++ b/src/calf/synth.h
@@ -118,7 +118,7 @@ public:
     /// check if voice can be removed from active voice list
     virtual bool get_active()=0;
     /// render voice data to buffer
-    virtual void render_to(float *buf[], int nsamples)=0;
+    virtual void render_to(float (*buf)[2], int nsamples)=0;
     /// return the note used by this voice
     virtual int get_current_note()=0;
     /// empty virtual destructor
@@ -153,7 +153,7 @@ public:
         Base::reset();
         read_ptr = BlockSize;
     }
-    virtual void render_to(float *buf[], int nsamples)
+    virtual void render_to(float (*buf)[2], int nsamples)
     {
         int p = 0;
         while(p < nsamples)
@@ -166,7 +166,7 @@ public:
             int ncopy = std::min<int>(BlockSize - read_ptr, nsamples - p);
             for (int i = 0; i < ncopy; i++)
                 for (int c = 0; c < Channels; c++)
-                    buf[c][p + i] += output_buffer[read_ptr + i][c];
+                    buf[p + i][c] += output_buffer[read_ptr + i][c];
             p += ncopy;
             read_ptr += ncopy;
         }
@@ -197,7 +197,7 @@ public:
     }
     virtual synth::voice *give_voice();
     virtual synth::voice *alloc_voice()=0;
-    virtual void render_to(float *output[], int nsamples);
+    virtual void render_to(float (*output)[2], int nsamples);
     virtual void note_on(int note, int vel);
     virtual void first_note_on(int note, int vel) {}
     virtual void control_change(int ctl, int val);
diff --git a/src/organ.cpp b/src/organ.cpp
index 2a415e3..0276bc3 100644
--- a/src/organ.cpp
+++ b/src/organ.cpp
@@ -256,22 +256,26 @@ const char *organ_audio_module::get_gui_xml()
                 "</vbox>"
                 "<frame label=\"LFO\">"
                     "<vbox>"
-                        "<vbox>"
+                        "<vbox expand=\"0\" fill=\"0\">"
                             "<label param=\"vib_rate\" />"
                             "<align><knob param=\"vib_rate\" expand=\"0\" fill=\"0\"/></align><value param=\"vib_rate\"/>"
                         "</vbox>"
-                        "<vbox>"
+                        "<vbox expand=\"0\" fill=\"0\">"
                             "<label param=\"vib_amt\" />"
                             "<align><knob param=\"vib_amt\" expand=\"0\" fill=\"0\"/></align><value param=\"vib_amt\"/>"
                         "</vbox>"
-                        "<vbox>"
+                        "<vbox expand=\"0\" fill=\"0\">"
                             "<label param=\"vib_wet\" />"
                             "<align><knob param=\"vib_wet\" expand=\"0\" fill=\"0\"/></align><value param=\"vib_wet\"/>"
                         "</vbox>"
-                        "<vbox>"
+                        "<vbox expand=\"0\" fill=\"0\">"
                             "<label param=\"vib_phase\" />"
                             "<align><knob param=\"vib_phase\" expand=\"0\" fill=\"0\"/></align><value param=\"vib_phase\"/>"
                         "</vbox>"
+                        "<vbox expand=\"0\" fill=\"0\">"
+                            "<label param=\"vib_mode\" />"
+                            "<combo param=\"vib_mode\" expand=\"0\" fill=\"0\"/>"
+                        "</vbox>"
                     "</vbox>"
                 "</frame>"
             "</hbox>"
@@ -299,6 +303,8 @@ const char *organ_routing_names[] = { "Out", "Flt 1", "Flt 2"  };
 
 const char *organ_ampctl_names[] = { "None", "Direct", "Flt 1", "Flt 2", "All"  };
 
+const char *organ_vibrato_mode_names[] = { "None", "Direct", "Flt 1", "Flt 2", "Voice", "Global"  };
+
 parameter_properties organ_audio_module::param_props[] = {
     { 8,       0,  8, 80, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "l1", "16'" },
     { 8,       0,  8, 80, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "l2", "5 1/3'" },
@@ -419,6 +425,7 @@ parameter_properties organ_audio_module::param_props[] = {
     { 0.5,        0,    1,    0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB , NULL, "vib_amt", "Vib Mod Amt" },
     { 0.5,        0,    1,    0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB , NULL, "vib_wet", "Vib Wet" },
     { 180,        0,  360,    0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG, NULL, "vib_phase", "Vib Stereo" },
+    { organ_voice_base::lfomode_global,        0,  organ_voice_base::lfomode_count - 1,    0, PF_ENUM | PF_CTL_COMBO, organ_vibrato_mode_names, "vib_mode", "Vib Mode" },
 //    { 0,  0, organ_voice_base::ampctl_count - 1,
 //                              0, PF_INT | PF_CTL_COMBO, organ_ampctl_names, "vel_amp_ctl", "Vel To Amp"},
 };
@@ -443,7 +450,8 @@ static void phaseshift(bandlimiter<ORGAN_WAVE_BITS> &bl, float tmp[ORGAN_WAVE_SI
 {
     bl.compute_spectrum(tmp);
     for (int i = 1; i <= ORGAN_WAVE_SIZE / 2; i++) {
-        float phase = sin(i*i);
+        float frac = i * 2.0 / ORGAN_WAVE_SIZE;
+        float phase = 2 * M_PI * frac * frac;
         complex<float> shift = complex<float>(cos(phase), sin(phase));
         bl.spectrum[i] *= shift;
         bl.spectrum[ORGAN_WAVE_SIZE - i] *= conj(shift);
@@ -615,6 +623,46 @@ organ_voice_base::organ_voice_base(organ_parameters *_parameters)
     }
 }
 
+void organ_vibrato::reset()
+{
+    for (int i = 0; i < VibratoSize; i++)
+        vibrato_x1[i][0] = vibrato_y1[i][0] = vibrato_x1[i][1] = vibrato_y1[i][1] = 0.f;
+    lfo_phase = 0.f;
+}
+
+void organ_vibrato::process(organ_parameters *parameters, float (*data)[2], unsigned int len, float sample_rate)
+{
+    float lfo1 = lfo_phase < 0.5 ? 2 * lfo_phase : 2 - 2 * lfo_phase;
+    float lfo_phase2 = lfo_phase + parameters->lfo_phase * (1.0 / 360.0);
+    if (lfo_phase2 >= 1.0)
+        lfo_phase2 -= 1.0;
+    float lfo2 = lfo_phase2 < 0.5 ? 2 * lfo_phase2 : 2 - 2 * lfo_phase2;
+    lfo_phase += parameters->lfo_rate * len / sample_rate;
+    if (lfo_phase >= 1.0)
+        lfo_phase -= 1.0;
+    vibrato[0].set_ap(3000 + 7000 * parameters->lfo_amt * lfo1 * lfo1, sample_rate);
+    vibrato[1].set_ap(3000 + 7000 * parameters->lfo_amt * lfo2 * lfo2, sample_rate);
+    
+    float vib_wet = parameters->lfo_wet;
+    for (int c = 0; c < 2; c++)
+    {
+        for (unsigned int i = 0; i < len; i++)
+        {
+            float v = data[i][c];
+            float v0 = v;
+            for (int t = 0; t < VibratoSize; t++)
+                v = vibrato[c].process_ap(v, vibrato_x1[t][c], vibrato_y1[t][c]);
+            
+            data[i][c] += (v - v0) * vib_wet;
+        }
+        for (int t = 0; t < VibratoSize; t++)
+        {
+            sanitize(vibrato_x1[t][c]);
+            sanitize(vibrato_y1[t][c]);
+        }
+    }
+}
+
 void organ_voice::render_block() {
     if (note == -1)
         return;
@@ -626,6 +674,7 @@ void organ_voice::render_block() {
     
     dsp::fixed_point<int, 20> tphase, tdphase;
     unsigned int foldvalue = parameters->foldvalue;
+    int vibrato_mode = fastf2i_drm(parameters->lfo_mode);
     int muln = 0;
     for (int h = 0; h < 9; h++)
     {
@@ -704,6 +753,8 @@ void organ_voice::render_block() {
         amp_pre[mode - 1] *= pre;
         amp_post[mode - 1] *= post;
     }
+    if (vibrato_mode >= lfomode_direct && vibrato_mode <= lfomode_filter2)
+        vibrato.process(parameters, aux_buffers[vibrato_mode - lfomode_direct], BlockSize, sample_rate);
     if (!any_running)
         released = true;
     // calculate delta from pre and post
@@ -716,36 +767,9 @@ void organ_voice::render_block() {
         output_buffer[i][1] = a3 * (a0 * output_buffer[i][1] + a1 * filterR[0].process_d1(aux_buffers[1][i][1]) + a2 * filterR[1].process_d1(aux_buffers[2][i][1]));
         a0 += d0, a1 += d1, a2 += d2, a3 += d3;
     }
+    if (vibrato_mode == lfomode_voice)
+        vibrato.process(parameters, output_buffer, BlockSize, sample_rate);
 
-    float lfo1 = lfo_phase < 0.5 ? 2 * lfo_phase : 2 - 2 * lfo_phase;
-    float lfo_phase2 = lfo_phase + parameters->lfo_phase * (1.0 / 360.0);
-    if (lfo_phase2 >= 1.0)
-        lfo_phase2 -= 1.0;
-    float lfo2 = lfo_phase2 < 0.5 ? 2 * lfo_phase2 : 2 - 2 * lfo_phase2;
-    lfo_phase += parameters->lfo_rate * BlockSize / sample_rate;
-    if (lfo_phase >= 1.0)
-        lfo_phase -= 1.0;
-    vibrato[0].set_ap(3000 + 7000 * parameters->lfo_amt * lfo1 * lfo1, sample_rate);
-    vibrato[1].set_ap(3000 + 7000 * parameters->lfo_amt * lfo2 * lfo2, sample_rate);
-    
-    float vib_wet = parameters->lfo_wet;
-    for (int c = 0; c < 2; c++)
-    {
-        for (int i = 0; i < (int) BlockSize; i++)
-        {
-            float v = output_buffer[i][c];
-            float v0 = v;
-            for (int t = 0; t < VibratoSize; t++)
-                v = vibrato[c].process_ap(v, vibrato_x1[t][c], vibrato_y1[t][c]);
-            
-            output_buffer[i][c] += (v - v0) * vib_wet;
-        }
-        for (int t = 0; t < VibratoSize; t++)
-        {
-            sanitize(vibrato_x1[t][c]);
-            sanitize(vibrato_y1[t][c]);
-        }
-    }
     if (released)
     {
         for (int i = 0; i < (int) BlockSize; i++) {
diff --git a/src/synth.cpp b/src/synth.cpp
index eb137a1..682be9b 100644
--- a/src/synth.cpp
+++ b/src/synth.cpp
@@ -154,7 +154,7 @@ void basic_synth::control_change(int ctl, int val)
     }
 }
 
-void basic_synth::render_to(float *output[], int nsamples)
+void basic_synth::render_to(float (*output)[2], int nsamples)
 {
     // render voices, eliminate ones that aren't sounding anymore
     for (list<synth::voice *>::iterator i = active_voices.begin(); i != active_voices.end();) {

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list