From 968e313857743435e662c831a8b29f50b20e0d41 Mon Sep 17 00:00:00 2001 From: Tom Schouten Date: Mon, 27 Jan 2003 17:06:07 +0000 Subject: creb 0.7 svn path=/trunk/externals/creb/; revision=364 --- Makefile.config | 5 +- doc/fdn~.pd | 61 +++++++ doc/junction~.pd | 56 ++++++ doc/reference.txt | 2 + include/extlib_util.h | 3 + modules/Makefile | 3 +- modules/abs.c | 23 +-- modules/bdiag.c | 7 +- modules/diag.c | 14 +- modules/dist.c | 14 +- modules/ead.c | 2 +- modules/eadsr.c | 2 +- modules/ear.c | 2 +- modules/fdn.c | 497 ++++++++++++++++++++++++++++++++++++++++++++++++++ modules/junction.c | 207 +++++++++++++++++++++ system/setup.c | 10 +- 16 files changed, 871 insertions(+), 37 deletions(-) create mode 100644 doc/fdn~.pd create mode 100644 doc/junction~.pd create mode 100644 modules/fdn.c create mode 100644 modules/junction.c diff --git a/Makefile.config b/Makefile.config index 5dee604..a57eeb5 100644 --- a/Makefile.config +++ b/Makefile.config @@ -1,8 +1,9 @@ PD_DIR = /home/tom/pd/distro/pd/src CREB_DIR = /home/tom/pd/extlib -CREB_VERSION = 0.6 +CREB_VERSION = 0.7 -DEFS = -DPD -DCREB_VERSION=\"$(CREB_VERSION)\" +DEFS = -DPD -DCREB_VERSION=\"$(CREB_VERSION)\" +#-DHAVE_ABS_TILDE LINUXCFLAGS = $(DEFS) -O2 -funroll-loops -fomit-frame-pointer \ -Wall -W -Wstrict-prototypes -Werror \ diff --git a/doc/fdn~.pd b/doc/fdn~.pd new file mode 100644 index 0000000..32bee94 --- /dev/null +++ b/doc/fdn~.pd @@ -0,0 +1,61 @@ +#N canvas 310 312 826 610 10; +#X obj 146 529 vols~; +#X floatatom 203 509 5 0 0; +#X obj 143 562 dac~; +#X obj 128 131 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X msg 10 415 print; +#X floatatom 216 431 5 0 0; +#X floatatom 267 432 5 0 0; +#X obj 54 144 noise~; +#X obj 94 190 *~; +#X floatatom 203 111 5 0 0; +#X obj 146 157 ead~; +#X msg 360 119 lines 501 752 5003 7504 105 206 307 408; +#X floatatom 152 110 5 0 0; +#X msg 361 248 linear 32 100 105; +#X msg 360 271 linear 32 1000 1005; +#X msg 12 465 reset; +#X obj 142 463 fdn~ 64 40000; +#X msg 358 351 exponential 64 10 1000; +#X msg 358 327 exponential 32 10 5000; +#X msg 360 292 linear 32 100 2015; +#X msg 361 224 linear 8 75 100; +#X msg 361 201 linear 32 50 2175; +#X msg 360 374 exponential 8 50 175; +#X text 186 20 fdn~ a feedback delay network; +#X text 316 468 creation arguments: ; +#X text 3 396 print delay lengths; +#X text 2 448 reset state; +#X text 316 512 nb delay lines is always a multiple of 4; +#X text 358 96 specify delay line lengths manually; +#X text 359 152 specify a linear/exponential delay length range; +#X text 361 170 ; +#X text 359 430 inlets: low/high frequency reverb time (60dB time) +; +#X connect 0 0 2 0; +#X connect 0 1 2 1; +#X connect 1 0 0 2; +#X connect 3 0 10 0; +#X connect 4 0 16 0; +#X connect 5 0 16 1; +#X connect 6 0 16 2; +#X connect 7 0 8 0; +#X connect 8 0 16 0; +#X connect 9 0 10 2; +#X connect 10 0 8 1; +#X connect 10 0 16 0; +#X connect 11 0 16 0; +#X connect 12 0 10 1; +#X connect 13 0 16 0; +#X connect 14 0 16 0; +#X connect 15 0 16 0; +#X connect 16 0 0 0; +#X connect 16 1 0 1; +#X connect 17 0 16 0; +#X connect 18 0 16 0; +#X connect 19 0 16 0; +#X connect 20 0 16 0; +#X connect 21 0 16 0; +#X connect 22 0 16 0; diff --git a/doc/junction~.pd b/doc/junction~.pd new file mode 100644 index 0000000..591e4bc --- /dev/null +++ b/doc/junction~.pd @@ -0,0 +1,56 @@ +#N canvas 420 323 450 300 10; +#X obj 181 138 junction~ 4; +#X obj 253 167 delwrite~ del1 1000; +#X obj 123 51 vd~ del1; +#X obj 183 51 vd~ del2; +#X obj 244 51 vd~ del3; +#X obj 304 51 vd~ del4; +#X obj 123 30 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 32 10 +-262144 -1 -1 115 256; +#X obj 183 30 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 32 10 +-262144 -1 -1 87 256; +#X obj 245 31 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 32 10 +-262144 -1 -1 270 256; +#X obj 305 31 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 32 10 +-262144 -1 -1 144 256; +#X obj 63 262 dac~; +#X obj 13 121 ead~; +#X obj 30 97 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 32 10 +-262144 -1 -1 37 256; +#X obj 90 97 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 32 10 +-262144 -1 -1 77 256; +#X obj 4 97 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144 -1 +-1; +#X obj 229 189 delwrite~ del2 1000; +#X obj 205 210 delwrite~ del3 1000; +#X obj 181 232 delwrite~ del4 1000; +#X msg 313 111 random \$1; +#X obj 314 85 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 32 10 +-262144 -1 -1 74 256; +#X text 61 5 junction~: a circular lossless signal junction; +#X obj 58 238 vols~; +#X obj 105 221 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 32 +10 -262144 -1 -1 77 256; +#X connect 0 0 17 0; +#X connect 0 0 21 0; +#X connect 0 1 16 0; +#X connect 0 1 21 1; +#X connect 0 2 15 0; +#X connect 0 3 1 0; +#X connect 2 0 0 0; +#X connect 3 0 0 1; +#X connect 4 0 0 2; +#X connect 5 0 0 3; +#X connect 6 0 2 0; +#X connect 7 0 3 0; +#X connect 8 0 4 0; +#X connect 9 0 5 0; +#X connect 11 0 0 0; +#X connect 12 0 11 1; +#X connect 13 0 11 2; +#X connect 14 0 11 0; +#X connect 18 0 0 0; +#X connect 19 0 18 0; +#X connect 21 0 10 0; +#X connect 21 1 10 1; +#X connect 22 0 21 2; diff --git a/doc/reference.txt b/doc/reference.txt index 6485266..b167b72 100644 --- a/doc/reference.txt +++ b/doc/reference.txt @@ -36,6 +36,8 @@ dynwav~ dynamic wavetable: use a signal block as wavetable ead~ exp. attack decay eadsr~ exp. attack decay sustain release ear~ exp. attack release +fdn~ a feedback delay network +junction~ a circulant lossless signal junction lattice~ lattice filter matrix~ multiply a signal block with an arbitrary matrix permut~ random permute a signal block diff --git a/include/extlib_util.h b/include/extlib_util.h index 259d944..6e4d94b 100644 --- a/include/extlib_util.h +++ b/include/extlib_util.h @@ -29,3 +29,6 @@ /* convert milliseconds to 1-p, with p a real pole */ float milliseconds_2_one_minus_realpole(float time); + +/* check if floating point number is denormal */ +#define IS_DENORMAL(f) (((*(unsigned int *)&(f))&0x7f800000) == 0) diff --git a/modules/Makefile b/modules/Makefile index 4e1cabd..17a4893 100644 --- a/modules/Makefile +++ b/modules/Makefile @@ -2,7 +2,8 @@ include ../Makefile.config current: ead.o ear.o eadsr.o dist.o tabreadmix.o xfm.o qmult.o qnorm.o \ cheby.o abs.o ramp.o dwt.o bfft.o dynwav.o statwav.o bdiag.o \ - diag.o matrix.o permut.o lattice.o ratio.o ffpoly.o fwarp.o + diag.o matrix.o permut.o lattice.o ratio.o ffpoly.o fwarp.o \ + junction.o fdn.o clean: diff --git a/modules/abs.c b/modules/abs.c index 4d8b8eb..0cb3d4d 100644 --- a/modules/abs.c +++ b/modules/abs.c @@ -1,21 +1,6 @@ -/* - * abs.c - computes absolute value of a signal - * Copyright (c) 2000-2003 by Tom Schouten - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ + +// since this is present in a lot of libs, it is conditionally compiled +#ifdef HAVE_ABS_TILDE #include "m_pd.h" #include @@ -62,3 +47,5 @@ void abs_tilde_setup(void) class_addmethod(abs_class, (t_method)nullfn, &s_signal, A_NULL); class_addmethod(abs_class, (t_method)abs_dsp, gensym("dsp"), A_NULL); } + +#endif diff --git a/modules/bdiag.c b/modules/bdiag.c index 37a0349..be2b8c4 100644 --- a/modules/bdiag.c +++ b/modules/bdiag.c @@ -22,9 +22,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "m_pd.h" -#include +#include "extlib_util.h" #include #include @@ -170,6 +168,9 @@ static t_int *bdiag_perform(t_int *w) s1new = (a * s1) - (b * s2) + u1; /* update state */ s2new = (a * s2) + (b * s1) + u2; + s1new = IS_DENORMAL(s1new) ? 0 : s1new; /* clear denormals */ + s2new = IS_DENORMAL(s2new) ? 0 : s2new; + *state++ = s1new; /* store state */ *state++ = s2new; diff --git a/modules/diag.c b/modules/diag.c index 5f7fe36..1e6bd96 100644 --- a/modules/diag.c +++ b/modules/diag.c @@ -22,8 +22,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "m_pd.h" -#include +#include "extlib_util.h" #include #include @@ -113,17 +112,16 @@ static t_int *diag_perform(t_int *w) t_float *eigen = ctl->c_eigen; t_float *state = ctl->c_state; t_int n = (t_int)(w[2]); - - t_float x; + t_float newstate; int i; for (i=0; i 0.0f) ? 1.0f : -1.0f; + + *out++ = x; + + } + break; + default: for (i = 0; i < n; i++) *out++ = *in++; diff --git a/modules/ead.c b/modules/ead.c index 8b93faa..4d301b8 100644 --- a/modules/ead.c +++ b/modules/ead.c @@ -96,7 +96,7 @@ static t_int *ead_perform(t_int *w) state -= decay*state; } - ctl->c_state = state; + ctl->c_state = IS_DENORMAL(state) ? 0 : state; return (w+4); /* pd quirk: pointer for sequencer */ } diff --git a/modules/eadsr.c b/modules/eadsr.c index 0e0b9db..bba96cd 100644 --- a/modules/eadsr.c +++ b/modules/eadsr.c @@ -115,7 +115,7 @@ static t_int *eadsr_perform(t_int *w) state -= decay*(state-sustain); } - ctl->c_state = state; + ctl->c_state = IS_DENORMAL(state) ? 0 : state; return (w+4); } diff --git a/modules/ear.c b/modules/ear.c index efe9b3f..d842065 100644 --- a/modules/ear.c +++ b/modules/ear.c @@ -81,7 +81,7 @@ static t_int *ear_perform(t_int *w) state -= release*state; } - ctl->c_state = state; + ctl->c_state = IS_DENORMAL(state) ? 0 : state; return (w+4); } diff --git a/modules/fdn.c b/modules/fdn.c new file mode 100644 index 0000000..7842508 --- /dev/null +++ b/modules/fdn.c @@ -0,0 +1,497 @@ +/* + * fdn.c - a feedback delay network (reverb tail) + * using a housholder reflection feedback matrix (In - 2/n 11T) + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* TODO: CLEAN UP THIS MESS + +add delay time generation code +add prime calculation routine (for prime delay line lengths) +add more diffuse feedback matrix (hadamard) +check filtering code + +*/ + +#include "extlib_util.h" +#include +#include + +#define FDN_MIN_DECAY_TIME .01f + +/* + +#define NBPRIMES +int prime[NBPRIMES]; + +static int isprime(int n) +{ + int i=1; + int d,m,p; + while(1){ + p = prime[i++]; + m = n % p; + if (m == 0) return 0; // it is a prime + d = n / p; + if (d < p) return 1; // it is not a prime + } +} + +static int initprimes(void) +{ + int i, curprime; + prime[0] = 1; + prime[1] = 2; + curprime = 3; + + for(i=2; i x->x_ctl.c_maxorder) { + post("fdn: this should not happen (panic!) order %d is larger than maxorder %d:", + order, x->x_ctl.c_maxorder ); + exit(1); + } + x->x_ctl.c_order = order; + x->x_ctl.c_leak = -2./ order; + x->x_ctl.c_input = 1./ sqrt(order); //???????????????? + +} + +static void fdn_print(t_fdn *x) +{ + int i; + fprintf(stderr, "fdn: delay coefficients (ms)\n"); + for (i=0;ix_ctl.c_order;i++) { + fprintf(stderr, "%f ", x->x_ctl.c_length[i]); + } + fprintf(stderr, "\n"); + +} + + +static void fdn_reset(t_fdn *x) +{ + int i; + if (x->x_ctl.c_buf) memset(x->x_ctl.c_buf, 0, x->x_ctl.c_bufsize * sizeof(float)); + if (x->x_ctl.c_vectorbuffer) memset(x->x_ctl.c_vectorbuffer, 0, x->x_ctl.c_maxorder * 2 * sizeof(float)); +} + + + + +static t_int *fdn_perform(t_int *w) +{ + + + t_float *in = (float *)(w[3]); + t_float *outr = (float *)(w[4]); + t_float *outl = (float *)(w[5]); + t_fdnctl *ctl = (t_fdnctl *)(w[1]); + t_int n = (t_int)(w[2]); + t_float input = ctl->c_input; + t_float output = ctl->c_output; + t_float *gain_in = ctl->c_gain_in; + t_float *gain_state = ctl->c_gain_state; + t_int order = ctl->c_order; + t_int *tap = ctl->c_tap; + t_float *buf = ctl->c_buf; + t_int mask = ctl->c_bufsize - 1; + + t_int i,j; + t_float x,y,v,left,right,z; + t_float filt_in, filt_last; + + t_float *cvec, *lvec; + + t_float save; + + + for(i=0;ic_vector[ctl->c_curvector]; + lvec = ctl->c_vector[ctl->c_curvector ^ 1]; + ctl->c_curvector ^= 1; + + + /* read input vector + get sum and left/right output*/ + for(j=0;jc_leak; + + + + /* perform feedback */ + /* todo: decouple feedback & permutation */ + save = cvec[0]; + for (j=0; jx_ctl.c_fsample = sp[0]->s_sr; + dsp_add(fdn_perform, + 5, + &x->x_ctl, + sp[0]->s_n, + sp[0]->s_vec, + sp[1]->s_vec, + sp[2]->s_vec); + + +} +static void fdn_free(t_fdn *x) +{ + if ( x->x_ctl.c_tap) free( x->x_ctl.c_tap); + if ( x->x_ctl.c_length) free( x->x_ctl.c_length); + if ( x->x_ctl.c_gain_in) free( x->x_ctl.c_gain_in); + if ( x->x_ctl.c_gain_state) free( x->x_ctl.c_gain_state); + if ( x->x_ctl.c_buf) free ( x->x_ctl.c_buf); + if ( x->x_ctl.c_vectorbuffer) free ( x->x_ctl.c_vectorbuffer ); +} + + +/* + +each delay line is filtered with a first order iir filter: +(gl: dc gain, gh: ny gain) + +H(z) = 2 gl gh / (gl + gh - z^-1 (gl - gh)) + +this results in the difference equation + +yk = (2 gl gh ) / (gl + gh) x + (gl - gh) / (gl + gh) yk-1 + +*/ + + +static void fdn_time(t_fdn *x, t_float timelow, t_float timehigh){ + t_float elow, ehigh; + t_int i; + t_float gainlow, gainhigh, gainscale; + + if (timelow < FDN_MIN_DECAY_TIME) timelow = FDN_MIN_DECAY_TIME; + if (timehigh < FDN_MIN_DECAY_TIME) timehigh = FDN_MIN_DECAY_TIME; + + elow = -.003 / (timelow); + ehigh = -.003 / (timehigh); + + /* setup gains */ + for(i=0;ix_ctl.c_order;i++){ + gainlow = pow(10, elow * (x->x_ctl.c_length[i])); + gainhigh = pow(10, ehigh * (x->x_ctl.c_length[i])); + gainscale = 1.0f / (gainlow + gainhigh); + x->x_ctl.c_gain_in[i] = 2.0f * gainlow * gainhigh * gainscale; + x->x_ctl.c_gain_state[i] = (gainlow - gainhigh) * gainscale; + } + x->x_ctl.c_timehigh = timehigh; + x->x_ctl.c_timelow = timelow; +} + +static void fdn_updatedamping(t_fdn *x) +{ + fdn_time(x, x->x_ctl.c_timelow, x->x_ctl.c_timehigh); +} + +static void fdn_timelow(t_fdn *x, t_float f){ + x->x_ctl.c_timelow = f; + fdn_updatedamping(x); +} +static void fdn_timehigh(t_fdn *x, t_float f){ + x->x_ctl.c_timehigh = f; + fdn_updatedamping(x); +} + + +static void fdn_setupdelayline(t_fdn *x){ + int sum, t, n; + int mask = x->x_ctl.c_bufsize - 1; + int start = x->x_ctl.c_tap[0]; + int *tap = x->x_ctl.c_tap; + float *length = x->x_ctl.c_length; + float scale = sys_getsr() * .001f; + + sum = 0; + tap[0] = (start & mask); + for (t=1; t<= x->x_ctl.c_order; t++){ + sum += (int)(length[t-1] * scale); + tap[t]=(start+sum)&mask; + } + + if (sum > mask){ + post("fdn: warning: not enough delay memory, behaviour is undefined (this could lead to instability...)"); + } + + +} + +static void fdn_list (t_fdn *x, t_symbol *s, int argc, t_atom *argv){ + int i; + float l; + int sum=0; + + int order = argc & 0xfffffffc; + + if (order < 4) return; + if (order > x->x_ctl.c_maxorder) return; + + + fdn_order(x, order); + for(i=0; ix_ctl.c_length[i] = argv[i].a_w.w_float; + + fdn_setupdelayline(x); + fdn_updatedamping(x); +} + +static void fdn_linear(t_fdn *x, t_float forder, t_float min, t_float max) +{ + t_int order = ((int)forder) & 0xfffffffc; + t_float length, inc; + t_int i; + + if (order < 4) return; + if (order > x->x_ctl.c_maxorder) return; + if (min <= 0) return; + if (max <= 0) return; + + inc = (max - min) / (float)(order - 1); + length = min; + + for (i=0; ix_ctl.c_length[i] = length; + length += inc; + } + + fdn_order(x, order); + fdn_setupdelayline(x); + fdn_updatedamping(x); +} + + + +static void fdn_exponential(t_fdn *x, t_float forder, t_float min, t_float max) +{ + t_int order = ((int)forder) & 0xfffffffc; + t_float length, inc; + t_int i; + + if (order < 4) return; + if (order > x->x_ctl.c_maxorder) return; + if (min <= 0) return; + if (max <= 0) return; + + inc = pow (max / min, 1.0f / ((float)(order - 1))); + length = min; + + for (i=0; ix_ctl.c_length[i] = length; + length *= inc; + } + + fdn_order(x, order); + fdn_setupdelayline(x); + fdn_updatedamping(x); +} + + + + + +t_class *fdn_class; + +static void *fdn_new(t_floatarg maxiorder, t_floatarg maxibufsize) +{ + t_int order = maxiorder; + t_int bufround; + t_fdn *x = (t_fdn *)pd_new(fdn_class); + t_float scale = sys_getsr() * .001f; + t_int bufsize = (t_int)(scale * maxibufsize); + + + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("timelow")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("timehigh")); + outlet_new(&x->x_obj, gensym("signal")); + outlet_new(&x->x_obj, gensym("signal")); + + /* init data */ + if (order < 4) order = 8; + if (bufsize < 64) bufsize = 65536; + + bufround = 1; + while (bufround < bufsize) bufround *= 2; + bufsize = bufround; + + + post("fdn: maximum nb of delay lines %d, total buffer size %d samples (%f seconds)", + order, bufsize, ((float)bufsize) / sys_getsr()); + + + x->x_ctl.c_maxorder = order; + x->x_ctl.c_buf = (float *)malloc(sizeof(float) * bufsize); + x->x_ctl.c_bufsize = bufsize; + x->x_ctl.c_fsample = sys_getsr(); + x->x_ctl.c_tap = (t_int *)malloc((order + 1) * sizeof(t_int)); + x->x_ctl.c_length = (t_float *)malloc(order * sizeof(t_int)); + x->x_ctl.c_gain_in = (t_float *)malloc(order * sizeof(t_float)); + x->x_ctl.c_gain_state = (t_float *)malloc(order * sizeof(t_float)); + x->x_ctl.c_vectorbuffer = (t_float *)malloc(order * 2 * sizeof(float)); + memset(x->x_ctl.c_vectorbuffer, 0, order * 2 * sizeof(float)); + x->x_ctl.c_curvector = 0; + x->x_ctl.c_vector[0] = &x->x_ctl.c_vectorbuffer[0]; + x->x_ctl.c_vector[1] = &x->x_ctl.c_vectorbuffer[order]; + + /* preset */ + fdn_order(x,8); + x->x_ctl.c_length[0]= 29.0f; + x->x_ctl.c_length[1]= 31.0f; + x->x_ctl.c_length[2]= 37.0f; + x->x_ctl.c_length[3]= 67.0f; + x->x_ctl.c_length[4]= 82.0f; + x->x_ctl.c_length[5]= 110.0f; + x->x_ctl.c_length[6]= 172.0f; + x->x_ctl.c_length[7]= 211.0f; + fdn_setupdelayline(x); + fdn_time(x, 4, 1); + + /* reset delay memory to zero */ + fdn_reset(x); + + + return (void *)x; +} + + +void fdn_tilde_setup(void) +{ + //post("fdn~ v0.1"); + fdn_class = class_new(gensym("fdn~"), (t_newmethod)fdn_new, + (t_method)fdn_free, sizeof(t_fdn), 0, A_DEFFLOAT, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(fdn_class, t_fdn, x_f); + class_addmethod(fdn_class, (t_method)fdn_print, gensym("print"), 0); + class_addmethod(fdn_class, (t_method)fdn_reset, gensym("reset"), 0); + class_addmethod(fdn_class, (t_method)fdn_timehigh, gensym("timehigh"), A_DEFFLOAT, 0); + class_addmethod(fdn_class, (t_method)fdn_timelow, gensym("timelow"), A_DEFFLOAT, 0); + class_addmethod(fdn_class, (t_method)fdn_list, gensym("lines"), A_GIMME, 0); + class_addmethod(fdn_class, (t_method)fdn_dsp, gensym("dsp"), 0); + class_addmethod(fdn_class, (t_method)fdn_linear, gensym("linear"), A_FLOAT, A_FLOAT, A_FLOAT, 0); + class_addmethod(fdn_class, (t_method)fdn_exponential, gensym("exponential"), A_FLOAT, A_FLOAT, A_FLOAT, 0); + +} + diff --git a/modules/junction.c b/modules/junction.c new file mode 100644 index 0000000..71476da --- /dev/null +++ b/modules/junction.c @@ -0,0 +1,207 @@ +/* + * junction.c - computes a lossless circulant junction + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "m_pd.h" +#include +#include +#include +#include + + +typedef struct junctionctl +{ + t_int c_channels; + t_float **c_in; + t_float **c_out; + t_float *c_buffer; + t_float *c_coef; + t_float c_norm; +} t_junctionctl; + +typedef struct junction +{ + t_object x_obj; + t_float x_f; + t_junctionctl x_ctl; +} t_junction; + +void junction_bang(t_junction *x) +{ + int i, n = x->x_ctl.c_channels; + t_float *coef = x->x_ctl.c_coef; + t_float r; + + for (i=1; ic_channels; + t_float **in = ctl->c_in; + t_float **out = ctl->c_out; + t_float *buf = ctl->c_buffer; + t_float *coef = ctl->c_coef; + + t_float norm = ctl->c_norm; + + + for (i=0;ix_ctl.c_channels; + float norm; + + for (i=0;ix_ctl.c_in[i] = sp[i]->s_vec; + x->x_ctl.c_out[i] = sp[i+c]->s_vec; + } + + norm = c; + norm = 1. / (norm); + x->x_ctl.c_norm = norm; + + + dsp_add(junction_perform, 2, &x->x_ctl, sp[0]->s_n); + + /* dsp_add(junction_perform, 4, &x->x_ctl, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec);*/ + +} + + +void junction_free(t_junction *x) +{ + + if (x->x_ctl.c_in) free (x->x_ctl.c_in); + if (x->x_ctl.c_out) free (x->x_ctl.c_out); + if (x->x_ctl.c_buffer) free (x->x_ctl.c_buffer); + if (x->x_ctl.c_coef) free (x->x_ctl.c_coef); + +} + +t_class *junction_class; + +void *junction_new(t_floatarg channels) +{ + + int l = ilog2(channels); + int i,n; + + t_junction *x = (t_junction *)pd_new(junction_class); + + + if (l<2) l = 2; + if (l>4) l = 4; + + n=1; + while (l--) n *= 2; + + for (i=1;ix_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal")); + for (i=0;ix_obj, gensym("signal")); + + x->x_ctl.c_in = (float **)malloc(n*sizeof(float *)); + x->x_ctl.c_out = (float **)malloc(n*sizeof(float *)); + x->x_ctl.c_buffer = (float *)malloc(n*sizeof(float)); + x->x_ctl.c_coef = (float *)malloc(n*sizeof(float)); + x->x_ctl.c_channels = n; + + junction_bang(x); + + return (void *)x; +} + +void junction_tilde_setup(void) +{ + //post("junction~ v0.1"); + junction_class = class_new(gensym("junction~"), (t_newmethod)junction_new, + (t_method)junction_free, sizeof(t_junction), 0, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(junction_class, t_junction, x_f); + class_addmethod(junction_class, (t_method)junction_bang, gensym("bang"), 0); + class_addmethod(junction_class, (t_method)junction_random, gensym("random"), A_FLOAT, 0); + class_addmethod(junction_class, (t_method)junction_dsp, gensym("dsp"), 0); + +} + diff --git a/system/setup.c b/system/setup.c index b425f84..7274349 100644 --- a/system/setup.c +++ b/system/setup.c @@ -25,6 +25,8 @@ void lattice_tilde_setup(void); void ratio_setup(void); void ffpoly_setup(void); void fwarp_setup(void); +void junction_tilde_setup(void); +void fdn_tilde_setup(void); void creb_setup(void) { @@ -40,7 +42,6 @@ void creb_setup(void) qmult_tilde_setup(); qnorm_tilde_setup(); cheby_tilde_setup(); - abs_tilde_setup(); ramp_tilde_setup(); dwt_tilde_setup(); bfft_tilde_setup(); @@ -51,6 +52,8 @@ void creb_setup(void) matrix_tilde_setup(); permut_tilde_setup(); lattice_tilde_setup(); + junction_tilde_setup(); + fdn_tilde_setup(); /* setup other objects */ ratio_setup(); @@ -61,4 +64,9 @@ void creb_setup(void) biquadseries_tilde_setup(); filterortho_tilde_setup(); + /* optional modules */ +#ifdef HAVE_ABS_TILDE + abs_tilde_setup(); +#endif + } -- cgit v1.2.1