aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Kelly <edkelly@users.sourceforge.net>2012-03-29 11:38:21 +0000
committerEd Kelly <edkelly@users.sourceforge.net>2012-03-29 11:38:21 +0000
commit71e00a32a3b7cb8462d2ff8e92d92ac6343593d8 (patch)
tree8e27a74f38b5dd7d76880a4b0ed7846008e0389c
parent35905a3692b10d90122303692d706f106b047419 (diff)
A new filter external has been added
svn path=/trunk/externals/ekext/; revision=16099
-rw-r--r--Makefile2
-rw-r--r--ekext-meta.pd4
-rw-r--r--mvcf~-help.pd33
-rw-r--r--mvcf~.c172
4 files changed, 208 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index d87c32c..c44e5e5 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ LIBRARY_NAME = ekext
# add your .c source files, one object per file, to the SOURCES
# variable, help files will be included automatically
-SOURCES = bmt~.c cup.c cupd.c doubledelta.c framescore~.c framespect~.c hasc~.c hssc~.c ihisto.c listmoses.c list_sum.c lpc~.c lpreson~.c maskxor.c peakit~.c polymap.c polystat.c sieve.c simile~.c simile.c steady.c valve.c voicing_detector~.c weightonset.c zeroxpos~.c
+SOURCES = bmt~.c cup.c cupd.c doubledelta.c framescore~.c framespect~.c hasc~.c hssc~.c ihisto.c listmoses.c list_sum.c lpc~.c lpreson~.c maskxor.c mvcf~.c peakit~.c polymap.c polystat.c sieve.c simile~.c simile.c steady.c valve.c voicing_detector~.c weightonset.c zeroxpos~.c
# list all pd objects (i.e. myobject.pd) files here, and their helpfiles will
# be included automatically
diff --git a/ekext-meta.pd b/ekext-meta.pd
index f49bc89..3d50706 100644
--- a/ekext-meta.pd
+++ b/ekext-meta.pd
@@ -1,6 +1,6 @@
#N canvas 15 49 200 200 10;
-#N canvas 25 49 420 300 META 1;
+#N canvas 25 49 420 300 META 0;
#X text 13 41 NAME ekext;
#X text 10 25 AUTHOR Ed Kelly;
-#X text 10 10 VERSION 0.1.1;
+#X text 10 10 VERSION 0.1.3;
#X restore 10 10 pd META;
diff --git a/mvcf~-help.pd b/mvcf~-help.pd
new file mode 100644
index 0000000..09e5119
--- /dev/null
+++ b/mvcf~-help.pd
@@ -0,0 +1,33 @@
+#N canvas 0 0 450 300 10;
+#X obj 123 196 mvcf~;
+#X obj 84 51 noise~;
+#X floatatom 135 13 5 0 100 0 - - -;
+#X floatatom 135 48 5 0 0 0 - - -;
+#X obj 135 67 sig~;
+#X floatatom 182 11 5 0 100 0 - - -;
+#X floatatom 182 46 5 0 0 0 - - -;
+#X obj 182 65 sig~;
+#X obj 182 27 * 0.01;
+#X obj 121 270 dac~;
+#X obj 119 224 *~ 0.1;
+#X obj 135 29 * 0.01;
+#X msg 231 83 clear;
+#X msg 280 83 debug \$1;
+#X obj 280 61 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
+1;
+#X obj 245 153 adsr 1 40 380 50 700;
+#X connect 0 0 10 0;
+#X connect 1 0 0 0;
+#X connect 2 0 11 0;
+#X connect 3 0 4 0;
+#X connect 4 0 0 1;
+#X connect 5 0 8 0;
+#X connect 6 0 7 0;
+#X connect 7 0 0 2;
+#X connect 8 0 6 0;
+#X connect 10 0 9 0;
+#X connect 10 0 9 1;
+#X connect 11 0 3 0;
+#X connect 12 0 0 0;
+#X connect 13 0 0 0;
+#X connect 14 0 13 0;
diff --git a/mvcf~.c b/mvcf~.c
new file mode 100644
index 0000000..b745b63
--- /dev/null
+++ b/mvcf~.c
@@ -0,0 +1,172 @@
+/*
+ * moog vcf, 4-pole lowpass resonant filter
+ *
+ * (c) Edward Kelly 2012
+ * BSD License
+ */
+#include "m_pd.h"
+#include <math.h>
+#define _limit 0.95
+
+static t_class *mvcf_tilde_class;
+
+typedef struct _mvcf_tilde {
+ t_object x_obj;
+ t_float b0, b1, b2, b3, b4; //filter buffers to keep (beware denormals!)
+ t_float token, debug, safety;
+ t_outlet *lp;
+} t_mvcf_tilde;
+
+/* We could have a mode where the fc and res are only registered at the start of the block (quick) or are registered in signal mode (slow) - i.e. a flag */
+
+
+static inline float saturate( float input ) { //clamp without branching
+ float x1 = fabsf( input + _limit );
+ float x2 = fabsf( input - _limit );
+ return 0.5 * (x1 - x2);
+}
+
+
+t_int *mvcf_tilde_perform(t_int *w) {
+ t_mvcf_tilde *x = (t_mvcf_tilde *)(w[1]);
+ t_sample *in = (t_sample *)(w[2]);
+ t_sample *fc = (t_sample *)(w[3]);
+ t_sample *res = (t_sample *)(w[4]);
+ t_sample *out = (t_sample *)(w[5]);
+ int n = (int)(w[6]);
+
+ //x *b0 =
+
+ /*
+ q = 1.0f - frequency;
+ p = frequency + 0.8f * frequency * q;
+ f = p + p - 1.0f;
+ q = resonance * (1.0f + 0.5f * q * (1.0f - q + 5.6f * q * q));
+ */
+
+ // while (n--) {
+ // float f = *(in++);
+ // setup_svf(obj, *(freq++), *(res++));
+ // *(out++) = run_svf(obj, f + ((obj->b) * (*(res++))));
+ // }
+
+ float t1 = 0;
+ float t2 = 0;
+ float xb0 = x->b0;
+ float xb1 = x->b1;
+ float xb2 = x->b2;
+ float xb3 = x->b3;
+ float xb4 = x->b4;
+ float i1 = 0;
+ float fc1 = 0;
+ float res1 = 0;
+ float q = 0;
+ float p = 0;
+ float fcoeff = 0;
+
+ // while (n-=4) {
+ while (n--) {
+ i1=(*in++);
+ fc1 = (*fc++);
+ /* This failsafe line stops the filter bursting
+ * ...but it is expensive! */
+ if(x->safety) {
+ fc1 = fc1 <= 1 ? fc1 >= 0 ? fc1 : 0 : 1;
+ }
+ res1 = (*res++);
+ q = 1.0f - fc1;
+ p = fc1 + 0.8f * fc1 * q;
+ fcoeff = p + p - 1.0f;
+ q = res1 * (1.0f + 0.5f * q * (1.0f - q + 5.6f * q * q));
+ i1 -= q * xb4; //feedback
+ t1 = xb1;
+ xb1 = (i1 + xb0) * p - xb1 * fcoeff;
+ t2 = xb2;
+ xb2 = (xb1 + t1) * p - xb2 * fcoeff;
+ t1 = xb3;
+ xb3 = (xb2 + t2) * p - xb3 * fcoeff;
+ xb4 = (xb3 + t1) * p - xb4 * fcoeff;
+ xb4 = saturate(xb4);
+ xb4 = xb4 - xb4 * xb4 * xb4 * 0.01f;
+ xb0 = i1;
+ *out++ = xb4; // lowpass mode
+ // *out++ = i1 - x->b4; // highpass mode
+// Lowpass output: xb4
+// Highpass output: in - xb4;
+// Bandpass output: 3.0f * (b3 - xb4);
+
+ }
+ x->b0 = xb0;
+ x->b1 = xb1;
+ x->b2 = xb2;
+ x->b3 = xb3;
+ x->b4 = xb4;
+ if(x->debug != 0) {
+ x->token +=1;
+ if(x->token == 15) {
+ post("q = %f, p=%f, fcoeff=%f, b0=%f, b1=%f, b2=%f, b3=%f, b4=%f",q,p,fcoeff,xb0,xb1,xb2,xb3,xb4);
+ x->token = 0;
+ }
+ }
+ return (w+7);
+}
+
+void mvcf_tilde_dsp(t_mvcf_tilde *x, t_signal **sp) {
+ dsp_add(mvcf_tilde_perform, 6, x, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[0]->s_n);
+}
+
+void mvcf_tilde_safety(t_mvcf_tilde *x, t_floatarg f) {
+ x->safety = f != 0 ? 1 : 0;
+}
+
+/*void mvcf_tilde_mode(t_mvcf_tilde *x, t_floatarg f) {
+x->mode = f < 1 ? 0 : f > 1 ? 2 : 1;
+}
+ */
+
+void mvcf_tilde_clear(t_mvcf_tilde *x) {
+ x->b0 = 0;
+ x->b1 = 0;
+ x->b2 = 0;
+ x->b3 = 0;
+ x->b4 = 0;
+}
+
+void mvcf_tilde_debug(t_mvcf_tilde *x, t_floatarg f) {
+ x->debug = f != 0 ? 1 : 0;
+}
+
+void *mvcf_tilde_new(t_floatarg f) {
+ t_mvcf_tilde *x = (t_mvcf_tilde *)pd_new(mvcf_tilde_class);
+
+ x->b0 = 0;
+ x->b1 = 0;
+ x->b2 = 0;
+ x->b3 = 0;
+ x->b4 = 0;
+ x->token = 0;
+ x->safety = 1;
+
+ inlet_new (&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ inlet_new (&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ return (void *)x;
+}
+
+void mvcf_tilde_setup(void) {
+ mvcf_tilde_class = class_new(gensym("mvcf~"),
+ (t_newmethod)mvcf_tilde_new,
+ 0, sizeof(t_mvcf_tilde),
+ CLASS_DEFAULT, A_DEFFLOAT, 0);
+
+ post("~~~~~~~~~~~~~~~>mvcf~");
+ post("~~~>by Ed Kelly, 2012");
+
+ class_addmethod(mvcf_tilde_class,
+ (t_method)mvcf_tilde_dsp, gensym("dsp"), 0);
+ CLASS_MAINSIGNALIN(mvcf_tilde_class, t_mvcf_tilde, token);
+ class_addmethod(mvcf_tilde_class, (t_method)mvcf_tilde_clear, gensym("clear"), 0);
+ class_addmethod(mvcf_tilde_class, (t_method)mvcf_tilde_debug, gensym("debug"), 0);
+ class_addmethod(mvcf_tilde_class, (t_method)mvcf_tilde_safety, gensym("safe"), 0);
+ // class_addmethod(mvcf_tilde_class, (t_method)mvcf_tilde_mode, gensym("mode"), A_DEFFLOAT, 0);
+}