diff options
author | Hans-Christoph Steiner <eighthave@users.sourceforge.net> | 2012-10-08 01:02:21 +0000 |
---|---|---|
committer | Hans-Christoph Steiner <eighthave@users.sourceforge.net> | 2012-10-08 01:02:21 +0000 |
commit | 5aeafcb5b77b06ef6e14d140db81bd79b2f173c4 (patch) | |
tree | 3b343d232f84196c4b17d662313ffab90a079919 /externals/extra/0.43.3/loop~/loop~.c | |
parent | 3391e44d8d82a3e221888d0b8a19b0e4953cb104 (diff) |
tagging extra 0.43.3
svn path=/trunk/; revision=16355
Diffstat (limited to 'externals/extra/0.43.3/loop~/loop~.c')
-rw-r--r-- | externals/extra/0.43.3/loop~/loop~.c | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/externals/extra/0.43.3/loop~/loop~.c b/externals/extra/0.43.3/loop~/loop~.c new file mode 100644 index 00000000..ebe3d9d5 --- /dev/null +++ b/externals/extra/0.43.3/loop~/loop~.c @@ -0,0 +1,169 @@ +/* loop~ -- loop generator for sampling */ + +/* Copyright 1997-1999 Miller Puckette. +Permission is granted to use this software for any purpose provided you +keep this copyright notice intact. + +THE AUTHOR AND HIS EMPLOYERS MAKE NO WARRANTY, EXPRESS OR IMPLIED, +IN CONNECTION WITH THIS SOFTWARE. + +This file is downloadable from http://www.crca.ucsd.edu/~msp . + +*/ + +#ifdef PD +#include "m_pd.h" +#else +#define t_sample float +#define t_float float +#endif + + + +typedef struct _loopctl +{ + double l_phase; + t_sample l_invwindow; + t_sample l_window; + int l_resync; +} t_loopctl; + +static void loopctl_run(t_loopctl *x, t_sample *transposein, + t_sample *windowin, t_sample *rawout, t_sample *windowout, int n) +{ + t_sample window, invwindow; + double phase = x->l_phase; + if (x->l_resync) + { + window = *windowin; + if (window < 0) + { + if (window > -1) + window = -1; + invwindow = -1/window; + } + else + { + if (window < 1) + window = 1; + invwindow = 1/window; + } + x->l_resync = 0; + } + else + { + window = x->l_window; + phase = x->l_phase; + invwindow = x->l_invwindow; + } + while (n--) + { + double phaseinc = invwindow * *transposein++; + double newphase; + t_sample nwind = *windowin++; + if (phaseinc >= 1 || phaseinc < 0) + phaseinc = 0; + newphase = phase + phaseinc; + if (newphase >= 1) + { + window = nwind; + if (window < 0) + { + if (window > -1) + window = -1; + invwindow = -1/window; + } + else + { + if (window < 1) + window = 1; + invwindow = 1/window; + } + newphase -= 1.; + } + phase = newphase; + *rawout++ = (t_sample)phase; + *windowout++ = window; + } + x->l_invwindow = invwindow; + x->l_window = window; + x->l_phase = phase; +} + +static void loopctl_init(t_loopctl *x) +{ + x->l_window = 1; + x->l_invwindow = 1; + x->l_phase = 0; +} + +static void loopctl_set(t_loopctl *x, t_float val) +{ + if (val < 0 || val > 1) + val = 0; + x->l_phase = val; + x->l_resync = 1; +} + +#ifdef PD + +typedef struct _loop +{ + t_object x_obj; + t_float x_f; + t_loopctl x_loopctl; +} t_loop; + +static t_class *loop_class; + +static void *loop_new(void) +{ + t_loop *x = (t_loop *)pd_new(loop_class); + loopctl_init(&x->x_loopctl); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + outlet_new(&x->x_obj, gensym("signal")); + outlet_new(&x->x_obj, gensym("signal")); + return (x); +} + +static t_int *loop_perform(t_int *w) +{ + t_loopctl *ctl = (t_loopctl *)(w[1]); + t_sample *in1 = (t_sample *)(w[2]); + t_sample *in2 = (t_sample *)(w[3]); + t_sample *out1 = (t_sample *)(w[4]); + t_sample *out2 = (t_sample *)(w[5]); + int n = (int)(w[6]); + loopctl_run(ctl, in1, in2, out1, out2, n); + return (w+7); +} + +static void loop_dsp(t_loop *x, t_signal **sp) +{ + dsp_add(loop_perform, 6, + &x->x_loopctl, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, + sp[0]->s_n); +} + +static void loop_set(t_loop *x, t_floatarg val) +{ + loopctl_set(&x->x_loopctl, val); +} + +static void loop_bang(t_loop *x) +{ + loopctl_set(&x->x_loopctl, 0); +} + +void loop_tilde_setup(void) +{ + loop_class = class_new(gensym("loop~"), (t_newmethod)loop_new, 0, + sizeof(t_loop), 0, 0); + class_addmethod(loop_class, (t_method)loop_dsp, gensym("dsp"), A_CANT, 0); + CLASS_MAINSIGNALIN(loop_class, t_loop, x_f); + class_addmethod(loop_class, (t_method)loop_set, gensym("set"), + A_DEFFLOAT, 0); + class_addbang(loop_class, loop_bang); +} + +#endif /* PD */ |