[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