[SCM] calf/master: + Knob: proper keyboard handling + Flanger: delay length ramping for click removal + Filter: inertia for resonance knob

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


The following commit has been merged in the master branch:
commit 826c5e59aa145acb7a87e5ed09c7cf908187b666
Author: kfoltman <kfoltman at 78b06b96-2940-0410-b7fc-879d825d01d8>
Date:   Fri Jan 25 21:23:27 2008 +0000

    + Knob: proper keyboard handling
    + Flanger: delay length ramping for click removal
    + Filter: inertia for resonance knob
    
    
    
    git-svn-id: https://calf.svn.sourceforge.net/svnroot/calf/trunk@115 78b06b96-2940-0410-b7fc-879d825d01d8

diff --git a/src/calf/audio_fx.h b/src/calf/audio_fx.h
index c5c4e76..a11e987 100644
--- a/src/calf/audio_fx.h
+++ b/src/calf/audio_fx.h
@@ -85,7 +85,7 @@ public:
     void set_mod_depth(float mod_depth) {
         this->mod_depth = mod_depth;
         // 128 because it's then multiplied by (hopefully) a value of 32768..-32767
-        this->mod_depth_samples = (int)(mod_depth * 128.0 * sample_rate);
+        this->mod_depth_samples = (int)(mod_depth * 32.0 * sample_rate);
     }
 };
 
@@ -121,7 +121,7 @@ public:
     }
     template<class OutIter, class InIter>
     void process(OutIter buf_out, InIter buf_in, int nsamples) {
-        int mds = min_delay_samples + mod_depth_samples * 256 + 2*65536;
+        int mds = min_delay_samples + mod_depth_samples * 1024 + 2*65536;
         int mdepth = mod_depth_samples;
         for (int i=0; i<nsamples; i++) {
             phase += dphase;
@@ -129,7 +129,7 @@ public:
             
             float in = *buf_in++;
             int lfo = phase.lerp_by_fract_int<int, 14, int>(sine.data[ipart], sine.data[ipart+1]);
-            int v = mds + (mdepth * lfo >> 8);
+            int v = mds + (mdepth * lfo >> 6);
             // if (!(i & 7)) printf("%d\n", v);
             int ifv = v >> 16;
             delay.put(in);
@@ -145,17 +145,21 @@ public:
 /**
  * Single-tap flanger (chorus plus feedback).
  */
-template<class T, int MaxDelay=256>
+template<class T, int MaxDelay=1024>
 class simple_flanger: public chorus_base
 {
 protected:
     simple_delay<MaxDelay,T> delay;
     float fb;
+    int last_delay_pos, last_actual_delay_pos;
+    int ramp_pos, ramp_delay_pos;
 public:
     simple_flanger()
     : fb(0) {}
     void reset() {
         delay.reset();
+        last_delay_pos = 0;
+        ramp_pos = 1024;
     }
     virtual void setup(int sample_rate) {
         this->sample_rate = sample_rate;
@@ -173,25 +177,64 @@ public:
     }
     template<class OutIter, class InIter>
     void process(OutIter buf_out, InIter buf_in, int nsamples) {
-        int mds = this->min_delay_samples + this->mod_depth_samples * 256 + 2 * 65536;
+        if (!nsamples)
+            return;
+        int mds = this->min_delay_samples + this->mod_depth_samples * 1024 + 2 * 65536;
         int mdepth = this->mod_depth_samples;
-        for (int i=0; i<nsamples; i++) {
-            this->phase += this->dphase;
-            unsigned int ipart = this->phase.ipart();
+        int delay_pos;
+        unsigned int ipart = this->phase.ipart();
+        int lfo = phase.lerp_by_fract_int<int, 14, int>(this->sine.data[ipart], this->sine.data[ipart+1]);
+        delay_pos = mds + (mdepth * lfo >> 6);
+        
+        if (delay_pos != last_delay_pos || ramp_pos < 1024)
+        {
+            if (delay_pos != last_delay_pos) {
+                // we need to ramp from what the delay tap length actually was, 
+                // not from old (ramp_delay_pos) or desired (delay_pos) tap length
+                ramp_delay_pos = last_actual_delay_pos;
+                ramp_pos = 0;
+            }
             
-            float in = *buf_in++;
-            int lfo = phase.lerp_by_fract_int<int, 14, int>(this->sine.data[ipart], this->sine.data[ipart+1]);
-            int v = mds + (mdepth * lfo >> 8);
-            // if (!(i & 7)) printf("%d\n", v);
-            int ifv = v >> 16;
-            T fd; // signal from delay's output
-            this->delay.get_interp(fd, ifv, (v & 0xFFFF)*(1.0/65536.0));
-            sanitize(fd);
-            T sdry = in * this->dry;
-            T swet = fd * this->wet;
-            *buf_out++ = sdry + swet;
-            this->delay.put(in+fb*fd);
+            int64_t dp;
+            for (int i=0; i<nsamples; i++) {
+                float in = *buf_in++;
+                T fd; // signal from delay's output
+                dp = (((int64_t)ramp_delay_pos) * (1024 - ramp_pos) + ((int64_t)delay_pos) * ramp_pos) >> 10;
+                ramp_pos++;
+                if (ramp_pos > 1024) ramp_pos = 1024;
+                this->delay.get_interp(fd, dp >> 16, (dp & 0xFFFF)*(1.0/65536.0));
+                sanitize(fd);
+                T sdry = in * this->dry;
+                T swet = fd * this->wet;
+                *buf_out++ = sdry + swet;
+                this->delay.put(in+fb*fd);
+
+                this->phase += this->dphase;
+                ipart = this->phase.ipart();
+                lfo = phase.lerp_by_fract_int<int, 14, int>(this->sine.data[ipart], this->sine.data[ipart+1]);
+                delay_pos = mds + (mdepth * lfo >> 6);
+            }
+            last_actual_delay_pos = dp;
+        }
+        else {
+            for (int i=0; i<nsamples; i++) {
+                float in = *buf_in++;
+                T fd; // signal from delay's output
+                this->delay.get_interp(fd, delay_pos >> 16, (delay_pos & 0xFFFF)*(1.0/65536.0));
+                sanitize(fd);
+                T sdry = in * this->dry;
+                T swet = fd * this->wet;
+                *buf_out++ = sdry + swet;
+                this->delay.put(in+fb*fd);
+
+                this->phase += this->dphase;
+                ipart = this->phase.ipart();
+                lfo = phase.lerp_by_fract_int<int, 14, int>(this->sine.data[ipart], this->sine.data[ipart+1]);
+                delay_pos = mds + (mdepth * lfo >> 6);
+            }
+            last_actual_delay_pos = delay_pos;
         }
+        last_delay_pos = delay_pos;
     }
 };
 
diff --git a/src/calf/modules.h b/src/calf/modules.h
index 9474a14..4b3b7fb 100644
--- a/src/calf/modules.h
+++ b/src/calf/modules.h
@@ -174,11 +174,12 @@ public:
     uint32_t srate;
     static parameter_properties param_props[];
     int order;
-    inertia<exponential_ramp> inertia_cutoff;
+    inertia<exponential_ramp> inertia_cutoff, inertia_resonance;
     once_per_n timer;
     
     filter_audio_module()
     : inertia_cutoff(exponential_ramp(128), 20)
+    , inertia_resonance(exponential_ramp(128), 20)
     , timer(128)
     {
         order = 0;
@@ -189,7 +190,7 @@ public:
         float freq = inertia_cutoff.get_last();
         // printf("freq=%g inr.cnt=%d timer.left=%d\n", freq, inertia_cutoff.count, timer.left);
         // XXXKF this is resonance of a single stage, obviously for three stages, resonant gain will be different
-        float q = *params[par_resonance];
+        float q = inertia_resonance.get_last();
         // XXXKF this is highly inefficient and should be replaced as soon as I have fast f2i in primitives.h
         int mode = (int)*params[par_mode];
         // printf("freq = %f q = %f mode = %d\n", freq, q, mode);
@@ -201,9 +202,11 @@ public:
             order = mode - 2;
         }
         // XXXKF this is highly inefficient and should be replaced as soon as I have fast f2i in primitives.h
-        int inertia = (int)*params[par_inertia];
-        if (inertia != inertia_cutoff.ramp.length())
+        int inertia = dsp::fastf2i_drm(*params[par_inertia]);
+        if (inertia != inertia_cutoff.ramp.length()) {
             inertia_cutoff.ramp.set_length(inertia);
+            inertia_resonance.ramp.set_length(inertia);
+        }
         
         right[0].copy_coeffs(left[0]);
         for (int i = 1; i < order; i++) {
@@ -214,11 +217,13 @@ public:
     void params_changed()
     {
         inertia_cutoff.set_inertia(*params[par_cutoff]);
+        inertia_resonance.set_inertia(*params[par_resonance]);
         calculate_filter();
     }
     void on_timer()
     {
         inertia_cutoff.step();
+        inertia_resonance.step();
         calculate_filter();
     }
     void activate() {
@@ -288,7 +293,7 @@ public:
         while(offset < numsamples) {
             uint32_t numnow = numsamples - offset;
             // if inertia's inactive, we can calculate the whole buffer at once
-            if (inertia_cutoff.active())
+            if (inertia_cutoff.active() || inertia_resonance.active())
                 numnow = timer.get(numnow);
             if (outputs_mask & 1) {
                 ostate |= process_channel(left, ins[0] + offset, outs[0] + offset, numnow, inputs_mask & 1);
diff --git a/src/custom_ctl.cpp b/src/custom_ctl.cpp
index b9afe9c..d5afd1b 100644
--- a/src/custom_ctl.cpp
+++ b/src/custom_ctl.cpp
@@ -18,6 +18,7 @@
  * Boston, MA 02111-1307, USA.
  */
 #include <calf/custom_ctl.h>
+#include <gdk/gdkkeysyms.h>
 #include <cairo/cairo.h>
 #include <math.h>
 
@@ -197,6 +198,10 @@ calf_knob_expose (GtkWidget *widget, GdkEventExpose *event)
     }
     gdk_draw_pixbuf(GDK_DRAWABLE(widget->window), widget->style->fg_gc[0], CALF_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget))->knob_image, phase * 40, self->knob_type * 40, ox, oy, 40, 40, GDK_RGB_DITHER_NORMAL, 0, 0);
     // printf("exposed %p %d+%d\n", widget->window, widget->allocation.x, widget->allocation.y);
+    if (gtk_widget_is_focus(widget))
+    {
+        gtk_paint_focus(widget->style, window, GTK_STATE_NORMAL, NULL, widget, NULL, ox, oy, widget->allocation.width, widget->allocation.height);
+    }
     
     return TRUE;
 }
@@ -210,6 +215,62 @@ calf_knob_size_request (GtkWidget *widget,
     CalfKnob *self = CALF_KNOB(widget);
 }
 
+static void
+calf_knob_incr (GtkWidget *widget, int dir_down)
+{
+    g_assert(CALF_IS_KNOB(widget));
+    CalfKnob *self = CALF_KNOB(widget);
+    GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget));
+    
+    float oldvalue = adj->value;
+
+    float halfrange = (adj->upper + adj->lower) / 2;
+    int oldstep = (int)(0.5f + (adj->value - adj->lower) / adj->step_increment);
+    int step;
+    int nsteps = (int)(0.5f + (adj->upper - adj->lower) / adj->step_increment); // less 1 actually
+    if (dir_down)
+        step = oldstep - 1;
+    else
+        step = oldstep + 1;
+    
+    // trying to reduce error cumulation here, by counting from lowest or from highest
+    float value = adj->lower + step * adj->step_increment;
+    if (step >= nsteps / 2)
+        value = adj->upper - (nsteps - step) * adj->step_increment;
+    gtk_range_set_value(GTK_RANGE(widget), value);
+    // printf("step %d:%d nsteps %d value %f:%f\n", oldstep, step, nsteps, oldvalue, value);
+}
+
+static gboolean
+calf_knob_key_press (GtkWidget *widget, GdkEventKey *event)
+{
+    g_assert(CALF_IS_KNOB(widget));
+    CalfKnob *self = CALF_KNOB(widget);
+    GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget));
+
+    switch(event->keyval)
+    {
+        case GDK_Home:
+            gtk_range_set_value(GTK_RANGE(widget), adj->lower);
+            return TRUE;
+
+        case GDK_End:
+            gtk_range_set_value(GTK_RANGE(widget), adj->upper);
+            return TRUE;
+
+        case GDK_Up:
+            calf_knob_incr(widget, 0);
+            return TRUE;
+
+        case GDK_Down:
+            calf_knob_incr(widget, 1);
+            return TRUE;
+            
+    }
+    
+    return FALSE;
+}
+
 static gboolean
 calf_knob_button_press (GtkWidget *widget, GdkEventButton *event)
 {
@@ -250,28 +311,7 @@ calf_knob_pointer_motion (GtkWidget *widget, GdkEventMotion *event)
 static gboolean
 calf_knob_scroll (GtkWidget *widget, GdkEventScroll *event)
 {
-    g_assert(CALF_IS_KNOB(widget));
-    CalfKnob *self = CALF_KNOB(widget);
-    GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget));
-    
-    float oldvalue = adj->value;
-
-    float halfrange = (adj->upper + adj->lower) / 2;
-    int oldstep = (int)(0.5f + (adj->value - adj->lower) / adj->step_increment);
-    int step;
-    int nsteps = (int)(0.5f + (adj->upper - adj->lower) / adj->step_increment); // less 1 actually
-    if (event->direction)
-        step = oldstep - 1;
-    else
-        step = oldstep + 1;
-    
-    // trying to reduce error cumulation here, by counting from lowest or from highest
-    float value = adj->lower + step * adj->step_increment;
-    if (step >= nsteps / 2)
-        value = adj->upper - (nsteps - step) * adj->step_increment;
-    gtk_range_set_value(GTK_RANGE(widget), value);
-    // printf("step %d:%d nsteps %d value %f:%f\n", oldstep, step, nsteps, oldvalue, value);
-        
+    calf_knob_incr(widget, event->direction);
     return FALSE;
 }
 
@@ -285,6 +325,7 @@ calf_knob_class_init (CalfKnobClass *klass)
     widget_class->button_press_event = calf_knob_button_press;
     widget_class->button_release_event = calf_knob_button_release;
     widget_class->motion_notify_event = calf_knob_pointer_motion;
+    widget_class->key_press_event = calf_knob_key_press;
     widget_class->scroll_event = calf_knob_scroll;
     GError *error = NULL;
     klass->knob_image = gdk_pixbuf_new_from_file(PKGLIBDIR "/knob.png", &error);

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list