[SCM] calf/master: + Wavetable: initial work at adding mod matrix to wavetable, very incomplete/broken

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


The following commit has been merged in the master branch:
commit 759ef0e2cf444cd7ba72481ac544f34c27dccc46
Author: Krzysztof Foltman <wdev at foltman.com>
Date:   Wed May 20 00:13:55 2009 +0100

    + Wavetable: initial work at adding mod matrix to wavetable, very incomplete/broken

diff --git a/gui/gui-wavetable.xml b/gui/gui-wavetable.xml
index 2591e15..c79ea7b 100644
--- a/gui/gui-wavetable.xml
+++ b/gui/gui-wavetable.xml
@@ -90,6 +90,7 @@
         <value attach-x="5" attach-y="6" param="adsr3_r"/>
         <value attach-x="6" attach-y="6" param="adsr3_v"/>
       </table>
+      <listview param="adsr_s" />
     </vbox>
   </frame>
 </vbox>
diff --git a/src/calf/metadata.h b/src/calf/metadata.h
index 8f4a60a..4d2bd0c 100644
--- a/src/calf/metadata.h
+++ b/src/calf/metadata.h
@@ -274,22 +274,24 @@ struct wavetable_metadata: public plugin_metadata<wavetable_metadata>
     };
     enum {
         modsrc_none,
+        modsrc_velocity,
+        modsrc_pressure,
+        modsrc_modwheel,
         modsrc_env1,
         modsrc_env2,
         modsrc_env3,
-        modsrc_velocity,
-        modsrc_modwheel,
         modsrc_count,
     };
     enum {
         moddest_none,
+        moddest_attenuation,
+        moddest_oscmix,
+        moddest_cutoff,
+        moddest_resonance,
         moddest_o1shift,
         moddest_o2shift,
         moddest_o1detune,
         moddest_o2detune,
-        moddest_o1pitch,
-        moddest_o2pitch,
-        moddest_dca,
         moddest_count,
     };
     enum { 
@@ -298,6 +300,7 @@ struct wavetable_metadata: public plugin_metadata<wavetable_metadata>
         par_eg1attack, par_eg1decay, par_eg1sustain, par_eg1fade, par_eg1release, par_eg1velscl,
         par_eg2attack, par_eg2decay, par_eg2sustain, par_eg2fade, par_eg2release, par_eg2velscl,
         par_eg3attack, par_eg3decay, par_eg3sustain, par_eg3fade, par_eg3release, par_eg3velscl,
+        par_pwhlrange, 
         param_count };
     enum { in_count = 0, out_count = 2, support_midi = true, require_midi = true, rt_capable = true };
     enum { step_size = 64 };
diff --git a/src/calf/modmatrix.h b/src/calf/modmatrix.h
index 580e443..88cbba2 100644
--- a/src/calf/modmatrix.h
+++ b/src/calf/modmatrix.h
@@ -18,6 +18,9 @@
  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
  * Boston, MA 02111-1307, USA.
  */
+#ifndef __CALF_MODMATRIX_H
+#define __CALF_MODMATRIX_H
+ 
 #include "giface.h"
 
 namespace dsp {
@@ -63,3 +66,5 @@ public:
 };
     
 };
+
+#endif
diff --git a/src/calf/wavetable.h b/src/calf/wavetable.h
index a7c6a9e..a553538 100644
--- a/src/calf/wavetable.h
+++ b/src/calf/wavetable.h
@@ -9,6 +9,7 @@
 #include "osc.h"
 #include "synth.h"
 #include "envelope.h"
+#include "modmatrix.h"
 
 namespace calf_plugins {
 
@@ -54,13 +55,23 @@ protected:
     dsp::decay amp;
     wavetable_oscillator oscs[OscCount];
     dsp::adsr envs[EnvCount];
+    /// Current MIDI velocity
     float velocity;
+    /// Current calculated mod matrix outputs
+    float moddest[wavetable_metadata::moddest_count];
+    /// Last oscillator shift (wavetable index) of each oscillator
+    float last_oscshift[OscCount];
+    /// Last oscillator amplitude of each oscillator
+    float last_oscamp[OscCount];
+    /// Current osc amplitude
+    float cur_oscamp[OscCount];
 public:
     wavetable_voice();
     void set_params_ptr(wavetable_audio_module *_parent, int _srate);
     void reset();
     void note_on(int note, int vel);
     void note_off(int /* vel */);
+    void channel_pressure(int value);
     void steal();
     void render_block();
     virtual int get_current_note() {
@@ -70,9 +81,14 @@ public:
         // printf("note %d getactive %d use_percussion %d pamp active %d\n", note, amp.get_active(), use_percussion(), pamp.get_active());
         return (note != -1) && (amp.get_active()) && !envs[0].stopped();
     }
+    inline void calc_derived_dests() {
+        float cv = dsp::clip<float>(0.5f + moddest[wavetable_metadata::moddest_oscmix], 0.f, 1.f);
+        cur_oscamp[0] = (cv) * *params[wavetable_metadata::par_o1level];
+        cur_oscamp[1] = (1 - cv) * *params[wavetable_metadata::par_o2level];
+    }
 };    
 
-class wavetable_audio_module: public audio_module<wavetable_metadata>, public dsp::basic_synth
+class wavetable_audio_module: public audio_module<wavetable_metadata>, public dsp::basic_synth, public mod_matrix
 {
 public:
     using dsp::basic_synth::note_on;
@@ -85,10 +101,21 @@ protected:
     bool panic_flag;
 
 public:
+    enum { mod_matrix_slots = 10 };
     float *ins[in_count]; 
     float *outs[out_count];
     float *params[param_count];
     int16_t tables[wt_count][129][256]; // one dummy level for interpolation
+    /// Rows of the modulation matrix
+    dsp::modulation_entry mod_matrix_data[mod_matrix_slots];
+    /// Smoothed cutoff value
+    dsp::inertia<dsp::exponential_ramp> inertia_cutoff;
+    /// Smoothed pitch bend value
+    dsp::inertia<dsp::exponential_ramp> inertia_pitchbend;
+    /// Smoothed channel pressure value
+    dsp::inertia<dsp::linear_ramp> inertia_pressure;
+    /// Unsmoothed mod wheel value
+    float modwheel_value;
 
 public:
     wavetable_audio_module();
@@ -122,6 +149,16 @@ public:
     void set_sample_rate(uint32_t sr) {
         setup(sr);
         crate = sample_rate / wavetable_voice::BlockSize;
+        inertia_cutoff.ramp.set_length(crate / 30); // 1/30s    
+        inertia_pitchbend.ramp.set_length(crate / 30); // 1/30s    
+        inertia_pressure.ramp.set_length(crate / 30); // 1/30s - XXXKF monosynth needs that too
+    }
+    /// Handle MIDI Channel Pressure
+    void channel_pressure(int value);
+    /// Handle pitch bend message.
+    inline void pitch_bend(int value)
+    {
+        inertia_pitchbend.set_inertia(pow(2.0, (value * *params[par_pwhlrange]) / (1200.0 * 8192.0)));
     }
 };
 
diff --git a/src/modules.cpp b/src/modules.cpp
index 9e8f2a4..048eb93 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -601,6 +601,7 @@ CALF_PORT_PROPS(wavetable) = {
     { 50,       10, 20000,    0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr3_r", "EG3 Release" },
     { 0,          0,    1,    0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr3_v", "EG3 VelMod" },
 
+    { 200,        0, 2400,   25, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "pbend_range", "PBend Range" },
 };
 
 ////////////////////////////////////////////////////////////////////////////
diff --git a/src/wavetable.cpp b/src/wavetable.cpp
index 3f0ac01..2da7993 100644
--- a/src/wavetable.cpp
+++ b/src/wavetable.cpp
@@ -35,6 +35,30 @@
 using namespace dsp;
 using namespace calf_plugins;
 
+static const char *mod_src_names[] = {
+    "None", 
+    "Velocity",
+    "Pressure",
+    "ModWheel",
+    "Env 1",
+    "Env 2",
+    "Env 3",
+    NULL
+};
+
+static const char *mod_dest_names[] = {
+    "None",
+    "Attenuation",
+    "Osc Mix Ratio (%)",
+    "Cutoff [ct]",
+    "Resonance",
+    "O1: Shift (%)",
+    "O2: Shift (%)",
+    "O1: Detune [ct]",
+    "O2: Detune [ct]",
+    NULL
+};
+
 wavetable_voice::wavetable_voice()
 {
     sample_rate = -1;
@@ -54,18 +78,27 @@ void wavetable_voice::reset()
 
 void wavetable_voice::note_on(int note, int vel)
 {
+    typedef wavetable_metadata md;
     this->note = note;
     velocity = vel / 127.0;
     amp.set(1.0);
     for (int i = 0; i < OscCount; i++) {
         oscs[i].reset();
         oscs[i].set_freq(note_to_hz(note, 0), sample_rate);
+        last_oscshift[i] = 0;
     }
     int cr = sample_rate / BlockSize;
     for (int i = 0; i < EnvCount; i++) {
         envs[i].set(0.01, 0.1, 0.5, 1, cr);
         envs[i].note_on();
     }
+    float modsrc[wavetable_metadata::modsrc_count] = { 1, velocity, parent->inertia_pressure.get_last(), parent->modwheel_value, envs[0].value, envs[1].value, envs[2].value};
+    parent->calculate_modmatrix(moddest, md::moddest_count, modsrc);
+    calc_derived_dests();
+
+    float oscshift[2] = { moddest[md::moddest_o1shift], moddest[md::moddest_o2shift] };
+    memcpy(last_oscshift, oscshift, sizeof(oscshift));
+    memcpy(last_oscamp, cur_oscamp, sizeof(cur_oscamp));
 }
 
 void wavetable_voice::note_off(int vel)
@@ -84,14 +117,9 @@ void wavetable_voice::render_block()
     
     const float step = 1.f / BlockSize;
 
-    int ospc = md::par_o2level - md::par_o1level;
-    int espc = md::par_eg2attack - md::par_eg1attack;
-    for (int j = 0; j < OscCount; j++) {
-        oscs[j].tables = parent->tables[(int)*params[md::par_o1wave + j * ospc]];
-        oscs[j].set_freq(note_to_hz(note, *params[md::par_o1transpose + j * ospc] * 100+ *params[md::par_o1detune + j * ospc]), sample_rate);
-    }
     float s = 0.001;
     float scl[EnvCount];
+    int espc = md::par_eg2attack - md::par_eg1attack;
     for (int j = 0; j < EnvCount; j++) {
         int o = j*espc;
         envs[j].set(*params[md::par_eg1attack + o] * s, *params[md::par_eg1decay + o] * s, *params[md::par_eg1sustain + o], *params[md::par_eg1release + o] * s, sample_rate / BlockSize, *params[md::par_eg1fade + o] * s); 
@@ -101,20 +129,35 @@ void wavetable_voice::render_block()
     for (int i = 0; i < EnvCount; i++)
         envs[i].advance();    
     
-    float env_old = envs[0].old_value * scl[0] + 0.2 * envs[1].old_value * scl[1];
-    float env_new = envs[0].value * scl[0] + 0.2 * envs[1].value * scl[1];
+    float modsrc[wavetable_metadata::modsrc_count] = { 1, velocity, parent->inertia_pressure.get_last(), parent->modwheel_value, envs[0].value, envs[1].value, envs[2].value};
+    parent->calculate_modmatrix(moddest, md::moddest_count, modsrc);
+    calc_derived_dests();
+
+    int ospc = md::par_o2level - md::par_o1level;
+    for (int j = 0; j < OscCount; j++) {
+        oscs[j].tables = parent->tables[(int)*params[md::par_o1wave + j * ospc]];
+        oscs[j].set_freq(note_to_hz(note, *params[md::par_o1transpose + j * ospc] * 100+ *params[md::par_o1detune + j * ospc] + moddest[md::moddest_o1detune]), sample_rate);
+    }
+        
+    float oscshift[2] = { moddest[md::moddest_o1shift], moddest[md::moddest_o2shift] };
+    float osstep[2] = { (oscshift[0] - last_oscshift[0]) * step, (oscshift[1] - last_oscshift[1]) * step };
+    float oastep[2] = { (cur_oscamp[0] - last_oscamp[0]) * step, (cur_oscamp[1] - last_oscamp[1]) * step };
     for (int i = 0; i < BlockSize; i++) {        
         float value = 0.f;
 
-        float env = dsp::lerp(env_old, env_new, i * step);
         for (int j = 0; j < OscCount; j++) {
-            value += oscs[j].get(dsp::clip(fastf2i_drm((env + *params[md::par_o1offset + j * ospc]) * 127.0 * 256), 0, 127 * 256)) * *params[md::par_o1level + j * ospc];
+            float o = last_oscshift[j] * 0.01;
+            value += last_oscamp[j] * oscs[j].get(dsp::clip(fastf2i_drm((o + *params[md::par_o1offset + j * ospc]) * 127.0 * 256), 0, 127 * 256));
+            last_oscshift[j] += osstep[j];
+            last_oscamp[j] += oastep[j];
         }
         
-        output_buffer[i][0] = output_buffer[i][1] = value * env * env;
+        output_buffer[i][0] = output_buffer[i][1] = value;
     }
     if (envs[0].stopped())
         released = true;
+    memcpy(last_oscshift, oscshift, sizeof(oscshift));
+    memcpy(last_oscamp, cur_oscamp, sizeof(cur_oscamp));
 }
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -149,8 +192,13 @@ static void interpolate_wt(int16_t table[129][256], int step)
 }
 
 wavetable_audio_module::wavetable_audio_module()
+: mod_matrix(mod_matrix_data, mod_matrix_slots, ::mod_src_names, ::mod_dest_names)
+, inertia_cutoff(1)
+, inertia_pitchbend(1)
+, inertia_pressure(64)
 {
     panic_flag = false;
+    modwheel_value = 0.;
     for (int i = 0; i < 129; i += 8)
     {
         for (int j = 0; j < 256; j++)
@@ -525,4 +573,9 @@ wavetable_audio_module::wavetable_audio_module()
     }
 }
 
+void wavetable_audio_module::channel_pressure(int value)
+{
+    inertia_pressure.set_inertia(value * (1.0 / 127.0));
+}
+
 #endif

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list