From 6b378329aa20ec2caa3f06968c2ac71d41dca7f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?IOhannes=20m=20zm=C3=B6lnig?= Date: Tue, 17 May 2005 16:50:28 +0000 Subject: renamed *_tilde.c-files to *~.c svn path=/trunk/externals/zexy/; revision=2998 --- src/avg_tilde.c | 85 ------ src/avg~.c | 85 ++++++ src/blockmirror_tilde.c | 104 ------- src/blockmirror~.c | 104 +++++++ src/blockswap_tilde.c | 99 ------- src/blockswap~.c | 99 +++++++ src/demultiplex_tilde.c | 119 -------- src/demultiplex~.c | 119 ++++++++ src/dfreq_tilde.c | 112 -------- src/dfreq~.c | 112 ++++++++ src/dirac_tilde.c | 113 -------- src/dirac~.c | 113 ++++++++ src/envrms_tilde.c | 150 ---------- src/envrms~.c | 150 ++++++++++ src/limiter_tilde.c | 719 ------------------------------------------------ src/limiter~.c | 719 ++++++++++++++++++++++++++++++++++++++++++++++++ src/multiline_tilde.c | 263 ------------------ src/multiline~.c | 263 ++++++++++++++++++ src/multiplex_tilde.c | 112 -------- src/multiplex~.c | 112 ++++++++ src/noish_tilde.c | 184 ------------- src/noish~.c | 184 +++++++++++++ src/noisi_tilde.c | 167 ----------- src/noisi~.c | 167 +++++++++++ src/pack_tilde.c | 86 ------ src/pack~.c | 86 ++++++ src/pdf_tilde.c | 140 ---------- src/pdf~.c | 140 ++++++++++ src/quantize_tilde.c | 113 -------- src/quantize~.c | 113 ++++++++ src/sigzero_tilde.c | 111 -------- src/sigzero~.c | 111 ++++++++ src/step_tilde.c | 141 ---------- src/step~.c | 141 ++++++++++ src/swap_tilde.c | 101 ------- src/swap~.c | 101 +++++++ src/tavg_tilde.c | 99 ------- src/tavg~.c | 99 +++++++ src/unpack_tilde.c | 134 --------- src/unpack~.c | 134 +++++++++ src/z_tilde.c | 132 --------- src/z~.c | 132 +++++++++ 42 files changed, 3284 insertions(+), 3284 deletions(-) delete mode 100644 src/avg_tilde.c create mode 100644 src/avg~.c delete mode 100644 src/blockmirror_tilde.c create mode 100644 src/blockmirror~.c delete mode 100644 src/blockswap_tilde.c create mode 100644 src/blockswap~.c delete mode 100644 src/demultiplex_tilde.c create mode 100644 src/demultiplex~.c delete mode 100644 src/dfreq_tilde.c create mode 100644 src/dfreq~.c delete mode 100644 src/dirac_tilde.c create mode 100644 src/dirac~.c delete mode 100644 src/envrms_tilde.c create mode 100644 src/envrms~.c delete mode 100644 src/limiter_tilde.c create mode 100644 src/limiter~.c delete mode 100644 src/multiline_tilde.c create mode 100644 src/multiline~.c delete mode 100644 src/multiplex_tilde.c create mode 100644 src/multiplex~.c delete mode 100644 src/noish_tilde.c create mode 100644 src/noish~.c delete mode 100644 src/noisi_tilde.c create mode 100644 src/noisi~.c delete mode 100644 src/pack_tilde.c create mode 100644 src/pack~.c delete mode 100644 src/pdf_tilde.c create mode 100644 src/pdf~.c delete mode 100644 src/quantize_tilde.c create mode 100644 src/quantize~.c delete mode 100644 src/sigzero_tilde.c create mode 100644 src/sigzero~.c delete mode 100644 src/step_tilde.c create mode 100644 src/step~.c delete mode 100644 src/swap_tilde.c create mode 100644 src/swap~.c delete mode 100644 src/tavg_tilde.c create mode 100644 src/tavg~.c delete mode 100644 src/unpack_tilde.c create mode 100644 src/unpack~.c delete mode 100644 src/z_tilde.c create mode 100644 src/z~.c diff --git a/src/avg_tilde.c b/src/avg_tilde.c deleted file mode 100644 index 5011cee..0000000 --- a/src/avg_tilde.c +++ /dev/null @@ -1,85 +0,0 @@ -/****************************************************** - * - * zexy - implementation file - * - * copyleft (c) IOhannes m zmölnig - * - * 1999:forum::für::umläute:2004 - * - * institute of electronic music and acoustics (iem) - * - ****************************************************** - * - * license: GNU General Public License v.2 - * - ******************************************************/ - -#include "zexy.h" -#include - -/* ------------------------ average~ ----------------------------- */ - -/* tilde object to take absolute value. */ - -static t_class *avg_class; - -typedef struct _avg -{ - t_object x_obj; - - t_float n_inv; - t_float buf; - int blocks; -} t_avg; - - -/* average :: arithmetic mean of one signal-vector */ - -static t_int *avg_perform(t_int *w) -{ - t_float *in = (t_float *)(w[1]); - - t_avg *x = (t_avg *)w[2]; - int n = (int)(w[3]); - - t_float buf = 0.; - - while (n--) - { - buf += *in++; - } - outlet_float(x->x_obj.ob_outlet, buf*x->n_inv); - - return (w+4); -} - -static void avg_dsp(t_avg *x, t_signal **sp) -{ - x->n_inv=1./sp[0]->s_n; - dsp_add(avg_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); -} - -static void *avg_new(void) -{ - t_avg *x = (t_avg *)pd_new(avg_class); - outlet_new(&x->x_obj, gensym("float")); - return (x); -} - -static void avg_help(void) -{ - post("avg~\t:: outputs the arithmetic mean of each signal-vector"); -} - - -void avg_tilde_setup(void) -{ - avg_class = class_new(gensym("avg~"), (t_newmethod)avg_new, 0, - sizeof(t_avg), 0, A_DEFFLOAT, 0); - class_addmethod(avg_class, nullfn, gensym("signal"), 0); - class_addmethod(avg_class, (t_method)avg_dsp, gensym("dsp"), 0); - - class_addmethod(avg_class, (t_method)avg_help, gensym("help"), 0); - class_sethelpsymbol(avg_class, gensym("zexy/avg~")); - zexy_register("avg~"); -} diff --git a/src/avg~.c b/src/avg~.c new file mode 100644 index 0000000..5011cee --- /dev/null +++ b/src/avg~.c @@ -0,0 +1,85 @@ +/****************************************************** + * + * zexy - implementation file + * + * copyleft (c) IOhannes m zmölnig + * + * 1999:forum::für::umläute:2004 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + * + ******************************************************/ + +#include "zexy.h" +#include + +/* ------------------------ average~ ----------------------------- */ + +/* tilde object to take absolute value. */ + +static t_class *avg_class; + +typedef struct _avg +{ + t_object x_obj; + + t_float n_inv; + t_float buf; + int blocks; +} t_avg; + + +/* average :: arithmetic mean of one signal-vector */ + +static t_int *avg_perform(t_int *w) +{ + t_float *in = (t_float *)(w[1]); + + t_avg *x = (t_avg *)w[2]; + int n = (int)(w[3]); + + t_float buf = 0.; + + while (n--) + { + buf += *in++; + } + outlet_float(x->x_obj.ob_outlet, buf*x->n_inv); + + return (w+4); +} + +static void avg_dsp(t_avg *x, t_signal **sp) +{ + x->n_inv=1./sp[0]->s_n; + dsp_add(avg_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); +} + +static void *avg_new(void) +{ + t_avg *x = (t_avg *)pd_new(avg_class); + outlet_new(&x->x_obj, gensym("float")); + return (x); +} + +static void avg_help(void) +{ + post("avg~\t:: outputs the arithmetic mean of each signal-vector"); +} + + +void avg_tilde_setup(void) +{ + avg_class = class_new(gensym("avg~"), (t_newmethod)avg_new, 0, + sizeof(t_avg), 0, A_DEFFLOAT, 0); + class_addmethod(avg_class, nullfn, gensym("signal"), 0); + class_addmethod(avg_class, (t_method)avg_dsp, gensym("dsp"), 0); + + class_addmethod(avg_class, (t_method)avg_help, gensym("help"), 0); + class_sethelpsymbol(avg_class, gensym("zexy/avg~")); + zexy_register("avg~"); +} diff --git a/src/blockmirror_tilde.c b/src/blockmirror_tilde.c deleted file mode 100644 index 1dd3659..0000000 --- a/src/blockmirror_tilde.c +++ /dev/null @@ -1,104 +0,0 @@ -/****************************************************** - * - * zexy - implementation file - * - * copyleft (c) IOhannes m zmölnig - * - * 1999:forum::für::umläute:2004 - * - * institute of electronic music and acoustics (iem) - * - ****************************************************** - * - * license: GNU General Public License v.2 - * - ******************************************************/ - -/* - 1110:forum::für::umläute:1999 -*/ - -#include "zexy.h" - -/* ------------------------ blockmirror~ ----------------------------- */ - -/* mirrors a signalblock around it's center: - {x[0], x[1], ... x[n-1]} --> {x[n-1], x[n-2], ... x[0]} -*/ - -static t_class *blockmirror_class; - -typedef struct _blockmirror -{ - t_object x_obj; - int doit; - int blocksize; - t_float *blockbuffer; -} t_blockmirror; - -static void blockmirror_float(t_blockmirror *x, t_floatarg f) -{ - x->doit = (f != 0); -} - -static t_int *blockmirror_perform(t_int *w) -{ - t_blockmirror *x = (t_blockmirror *)(w[1]); - t_float *in = (t_float *)(w[2]); - t_float *out = (t_float *)(w[3]); - int n = (int)(w[4]); - if (x->doit) { - if (in==out){ - int N=n; - t_float *dummy=x->blockbuffer; - while(n--)*dummy++=*in++; - dummy--; - while(N--)*out++=*dummy--; - } else { - in+=n-1; - while(n--)*out++=*in--; - } - } else while (n--) *out++ = *in++; - return (w+5); -} - -static void blockmirror_dsp(t_blockmirror *x, t_signal **sp) -{ - if (x->blocksizes_n){ - if(x->blockbuffer)freebytes(x->blockbuffer, sizeof(t_float)*x->blocksize); - x->blocksize = sp[0]->s_n; - x->blockbuffer = getbytes(sizeof(t_float)*x->blocksize); - } - dsp_add(blockmirror_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); -} - -static void blockmirror_helper(void) -{ - post("\n%c blockmirror~-object for reverting a signal", HEARTSYMBOL); - post("'help' : view this\n" - "signal~"); - post("outlet : signal~"); -} - -static void *blockmirror_new(void) -{ - t_blockmirror *x = (t_blockmirror *)pd_new(blockmirror_class); - outlet_new(&x->x_obj, gensym("signal")); - x->doit = 1; - x->blocksize=0; - return (x); -} - -void blockmirror_tilde_setup(void) -{ - blockmirror_class = class_new(gensym("blockmirror~"), (t_newmethod)blockmirror_new, 0, - sizeof(t_blockmirror), 0, A_NULL); - class_addmethod(blockmirror_class, nullfn, gensym("signal"), 0); - class_addmethod(blockmirror_class, (t_method)blockmirror_dsp, gensym("dsp"), 0); - - class_addfloat(blockmirror_class, blockmirror_float); - - class_addmethod(blockmirror_class, (t_method)blockmirror_helper, gensym("help"), 0); - class_sethelpsymbol(blockmirror_class, gensym("zexy/blockmirror~")); - zexy_register("blockmirror~"); -} diff --git a/src/blockmirror~.c b/src/blockmirror~.c new file mode 100644 index 0000000..1dd3659 --- /dev/null +++ b/src/blockmirror~.c @@ -0,0 +1,104 @@ +/****************************************************** + * + * zexy - implementation file + * + * copyleft (c) IOhannes m zmölnig + * + * 1999:forum::für::umläute:2004 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + * + ******************************************************/ + +/* + 1110:forum::für::umläute:1999 +*/ + +#include "zexy.h" + +/* ------------------------ blockmirror~ ----------------------------- */ + +/* mirrors a signalblock around it's center: + {x[0], x[1], ... x[n-1]} --> {x[n-1], x[n-2], ... x[0]} +*/ + +static t_class *blockmirror_class; + +typedef struct _blockmirror +{ + t_object x_obj; + int doit; + int blocksize; + t_float *blockbuffer; +} t_blockmirror; + +static void blockmirror_float(t_blockmirror *x, t_floatarg f) +{ + x->doit = (f != 0); +} + +static t_int *blockmirror_perform(t_int *w) +{ + t_blockmirror *x = (t_blockmirror *)(w[1]); + t_float *in = (t_float *)(w[2]); + t_float *out = (t_float *)(w[3]); + int n = (int)(w[4]); + if (x->doit) { + if (in==out){ + int N=n; + t_float *dummy=x->blockbuffer; + while(n--)*dummy++=*in++; + dummy--; + while(N--)*out++=*dummy--; + } else { + in+=n-1; + while(n--)*out++=*in--; + } + } else while (n--) *out++ = *in++; + return (w+5); +} + +static void blockmirror_dsp(t_blockmirror *x, t_signal **sp) +{ + if (x->blocksizes_n){ + if(x->blockbuffer)freebytes(x->blockbuffer, sizeof(t_float)*x->blocksize); + x->blocksize = sp[0]->s_n; + x->blockbuffer = getbytes(sizeof(t_float)*x->blocksize); + } + dsp_add(blockmirror_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); +} + +static void blockmirror_helper(void) +{ + post("\n%c blockmirror~-object for reverting a signal", HEARTSYMBOL); + post("'help' : view this\n" + "signal~"); + post("outlet : signal~"); +} + +static void *blockmirror_new(void) +{ + t_blockmirror *x = (t_blockmirror *)pd_new(blockmirror_class); + outlet_new(&x->x_obj, gensym("signal")); + x->doit = 1; + x->blocksize=0; + return (x); +} + +void blockmirror_tilde_setup(void) +{ + blockmirror_class = class_new(gensym("blockmirror~"), (t_newmethod)blockmirror_new, 0, + sizeof(t_blockmirror), 0, A_NULL); + class_addmethod(blockmirror_class, nullfn, gensym("signal"), 0); + class_addmethod(blockmirror_class, (t_method)blockmirror_dsp, gensym("dsp"), 0); + + class_addfloat(blockmirror_class, blockmirror_float); + + class_addmethod(blockmirror_class, (t_method)blockmirror_helper, gensym("help"), 0); + class_sethelpsymbol(blockmirror_class, gensym("zexy/blockmirror~")); + zexy_register("blockmirror~"); +} diff --git a/src/blockswap_tilde.c b/src/blockswap_tilde.c deleted file mode 100644 index 7dbe99d..0000000 --- a/src/blockswap_tilde.c +++ /dev/null @@ -1,99 +0,0 @@ -/****************************************************** - * - * zexy - implementation file - * - * copyleft (c) IOhannes m zmölnig - * - * 1999:forum::für::umläute:2004 - * - * institute of electronic music and acoustics (iem) - * - ****************************************************** - * - * license: GNU General Public License v.2 - * - ******************************************************/ - -#include "zexy.h" - -/* ------------------------ blockswap~ ----------------------------- */ - -/* swaps a signalblock around it's center: - {x[0], x[1], ... x[n-1]} --> {x[n-1], x[n-2], ... x[0]} -*/ - -static t_class *blockswap_class; - -typedef struct _blockswap -{ - t_object x_obj; - int doit; - int blocksize; - t_float *blockbuffer; -} t_blockswap; - -static void blockswap_float(t_blockswap *x, t_floatarg f) -{ - x->doit = (f != 0); -} - -static t_int *blockswap_perform(t_int *w) -{ - t_blockswap *x = (t_blockswap *)(w[1]); - t_float *in = (t_float *)(w[2]); - t_float *out = (t_float *)(w[3]); - int N = (int)(w[4]); - int N2=N/2; - if (x->doit) { - int n=N2; - t_float *dummy=x->blockbuffer; - while(n--)*dummy++=*in++; - n=N-N2; - while(n--)*out++=*in++; - dummy=x->blockbuffer; - n=N2; - while(n--)*out++=*dummy++; - } else while (N--) *out++=*in++; - return (w+5); -} - -static void blockswap_dsp(t_blockswap *x, t_signal **sp) -{ - if (x->blocksize*2s_n){ - if(x->blockbuffer)freebytes(x->blockbuffer, sizeof(t_float)*x->blocksize); - x->blocksize = sp[0]->s_n/2; - x->blockbuffer = getbytes(sizeof(t_float)*x->blocksize); - } - dsp_add(blockswap_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); -} - -static void blockswap_helper(void) -{ - post("\n%c blockswap~-object for blockwise-swapping of a signal ", HEARTSYMBOL); - post("'help' : view this\n" - "signal~"); - post("outlet : signal~"); -} - -static void *blockswap_new(void) -{ - t_blockswap *x = (t_blockswap *)pd_new(blockswap_class); - outlet_new(&x->x_obj, gensym("signal")); - x->doit = 1; - x->blocksize=0; - return (x); -} - -void blockswap_tilde_setup(void) -{ - blockswap_class = class_new(gensym("blockswap~"), (t_newmethod)blockswap_new, 0, - sizeof(t_blockswap), 0, A_NULL); - class_addmethod(blockswap_class, nullfn, gensym("signal"), 0); - class_addmethod(blockswap_class, (t_method)blockswap_dsp, gensym("dsp"), 0); - - class_addfloat(blockswap_class, blockswap_float); - - class_addmethod(blockswap_class, (t_method)blockswap_helper, gensym("help"), 0); - class_sethelpsymbol(blockswap_class, gensym("zexy/blockswap~")); - zexy_register("blockswap~"); -} diff --git a/src/blockswap~.c b/src/blockswap~.c new file mode 100644 index 0000000..7dbe99d --- /dev/null +++ b/src/blockswap~.c @@ -0,0 +1,99 @@ +/****************************************************** + * + * zexy - implementation file + * + * copyleft (c) IOhannes m zmölnig + * + * 1999:forum::für::umläute:2004 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + * + ******************************************************/ + +#include "zexy.h" + +/* ------------------------ blockswap~ ----------------------------- */ + +/* swaps a signalblock around it's center: + {x[0], x[1], ... x[n-1]} --> {x[n-1], x[n-2], ... x[0]} +*/ + +static t_class *blockswap_class; + +typedef struct _blockswap +{ + t_object x_obj; + int doit; + int blocksize; + t_float *blockbuffer; +} t_blockswap; + +static void blockswap_float(t_blockswap *x, t_floatarg f) +{ + x->doit = (f != 0); +} + +static t_int *blockswap_perform(t_int *w) +{ + t_blockswap *x = (t_blockswap *)(w[1]); + t_float *in = (t_float *)(w[2]); + t_float *out = (t_float *)(w[3]); + int N = (int)(w[4]); + int N2=N/2; + if (x->doit) { + int n=N2; + t_float *dummy=x->blockbuffer; + while(n--)*dummy++=*in++; + n=N-N2; + while(n--)*out++=*in++; + dummy=x->blockbuffer; + n=N2; + while(n--)*out++=*dummy++; + } else while (N--) *out++=*in++; + return (w+5); +} + +static void blockswap_dsp(t_blockswap *x, t_signal **sp) +{ + if (x->blocksize*2s_n){ + if(x->blockbuffer)freebytes(x->blockbuffer, sizeof(t_float)*x->blocksize); + x->blocksize = sp[0]->s_n/2; + x->blockbuffer = getbytes(sizeof(t_float)*x->blocksize); + } + dsp_add(blockswap_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); +} + +static void blockswap_helper(void) +{ + post("\n%c blockswap~-object for blockwise-swapping of a signal ", HEARTSYMBOL); + post("'help' : view this\n" + "signal~"); + post("outlet : signal~"); +} + +static void *blockswap_new(void) +{ + t_blockswap *x = (t_blockswap *)pd_new(blockswap_class); + outlet_new(&x->x_obj, gensym("signal")); + x->doit = 1; + x->blocksize=0; + return (x); +} + +void blockswap_tilde_setup(void) +{ + blockswap_class = class_new(gensym("blockswap~"), (t_newmethod)blockswap_new, 0, + sizeof(t_blockswap), 0, A_NULL); + class_addmethod(blockswap_class, nullfn, gensym("signal"), 0); + class_addmethod(blockswap_class, (t_method)blockswap_dsp, gensym("dsp"), 0); + + class_addfloat(blockswap_class, blockswap_float); + + class_addmethod(blockswap_class, (t_method)blockswap_helper, gensym("help"), 0); + class_sethelpsymbol(blockswap_class, gensym("zexy/blockswap~")); + zexy_register("blockswap~"); +} diff --git a/src/demultiplex_tilde.c b/src/demultiplex_tilde.c deleted file mode 100644 index 4d78583..0000000 --- a/src/demultiplex_tilde.c +++ /dev/null @@ -1,119 +0,0 @@ -/****************************************************** - * - * zexy - implementation file - * - * copyleft (c) IOhannes m zmölnig - * - * 1999:forum::für::umläute:2004 - * - * institute of electronic music and acoustics (iem) - * - ****************************************************** - * - * license: GNU General Public License v.2 - * - ******************************************************/ - -#include "zexy.h" - -/* ------------------------------------------------------------------------------ */ - -/* demux~ : demultiplex a signal to a specified output */ - -static t_class *demux_class; - -typedef struct _demux { - t_object x_obj; - - int output; - - int n_out; - t_float **out; - -} t_demux; - -static void demux_output(t_demux *x, t_floatarg f) -{ - if ((f>=0)&&(fn_out)){ - x->output=f; - } else - error("demultiplex: %d is channel out of range (0..%d)", (int)f, x->n_out); -} - - -static t_int *demux_perform(t_int *w) -{ - t_demux *x = (t_demux *)(w[1]); - t_float *in = (t_float *)(w[2]); - int N = (int)(w[3]); - int n = N; - - - int channel=x->n_out; - - - while(channel--){ - t_float*out=x->out[channel]; - n=N; - if(x->output==channel){ - while(n--)*out++=*in++; - } else - while(n--)*out++=0.f; - } - return (w+4); -} - -static void demux_dsp(t_demux *x, t_signal **sp) -{ - int n = x->n_out; - t_float **dummy=x->out; - while(n--)*dummy++=sp[x->n_out-n]->s_vec; - dsp_add(demux_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); -} - - -static void demux_helper(void) -{ - post("\n%c demux~\t:: demultiplex a signal to one of various outlets", HEARTSYMBOL); - post("<#out>\t : the outlet-number (counting from 0) to witch the inlet is routed" - "'help'\t : view this"); - post("creation : \"demux~ [arg1 [arg2...]]\"\t: the number of arguments equals the number of outlets\n"); -} - -static void demux_free(t_demux *x) -{ - freebytes(x->out, x->n_out * sizeof(t_float *)); -} - -static void *demux_new(t_symbol *s, int argc, t_atom *argv) -{ - t_demux *x = (t_demux *)pd_new(demux_class); - int i; - - if (!argc)argc=2; - x->n_out=argc; - x->output=0; - - while(argc--)outlet_new(&x->x_obj, gensym("signal")); - - x->out = (t_float **)getbytes(x->n_out * sizeof(t_float *)); - i=x->n_out; - while(i--)x->out[i]=0; - - return (x); -} - -void demultiplex_tilde_setup(void) -{ - demux_class = class_new(gensym("demultiplex~"), (t_newmethod)demux_new, (t_method)demux_free, sizeof(t_demux), 0, A_GIMME, 0); - class_addcreator((t_newmethod)demux_new, gensym("demux~"), A_GIMME, 0); - - class_addfloat(demux_class, demux_output); - class_addmethod(demux_class, (t_method)demux_dsp, gensym("dsp"), 0); - class_addmethod(demux_class, nullfn, gensym("signal"), 0); - - class_addmethod(demux_class, (t_method)demux_helper, gensym("help"), 0); - class_sethelpsymbol(demux_class, gensym("zexy/demultiplex~")); - - zexy_register("demultiplex~"); -} diff --git a/src/demultiplex~.c b/src/demultiplex~.c new file mode 100644 index 0000000..4d78583 --- /dev/null +++ b/src/demultiplex~.c @@ -0,0 +1,119 @@ +/****************************************************** + * + * zexy - implementation file + * + * copyleft (c) IOhannes m zmölnig + * + * 1999:forum::für::umläute:2004 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + * + ******************************************************/ + +#include "zexy.h" + +/* ------------------------------------------------------------------------------ */ + +/* demux~ : demultiplex a signal to a specified output */ + +static t_class *demux_class; + +typedef struct _demux { + t_object x_obj; + + int output; + + int n_out; + t_float **out; + +} t_demux; + +static void demux_output(t_demux *x, t_floatarg f) +{ + if ((f>=0)&&(fn_out)){ + x->output=f; + } else + error("demultiplex: %d is channel out of range (0..%d)", (int)f, x->n_out); +} + + +static t_int *demux_perform(t_int *w) +{ + t_demux *x = (t_demux *)(w[1]); + t_float *in = (t_float *)(w[2]); + int N = (int)(w[3]); + int n = N; + + + int channel=x->n_out; + + + while(channel--){ + t_float*out=x->out[channel]; + n=N; + if(x->output==channel){ + while(n--)*out++=*in++; + } else + while(n--)*out++=0.f; + } + return (w+4); +} + +static void demux_dsp(t_demux *x, t_signal **sp) +{ + int n = x->n_out; + t_float **dummy=x->out; + while(n--)*dummy++=sp[x->n_out-n]->s_vec; + dsp_add(demux_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); +} + + +static void demux_helper(void) +{ + post("\n%c demux~\t:: demultiplex a signal to one of various outlets", HEARTSYMBOL); + post("<#out>\t : the outlet-number (counting from 0) to witch the inlet is routed" + "'help'\t : view this"); + post("creation : \"demux~ [arg1 [arg2...]]\"\t: the number of arguments equals the number of outlets\n"); +} + +static void demux_free(t_demux *x) +{ + freebytes(x->out, x->n_out * sizeof(t_float *)); +} + +static void *demux_new(t_symbol *s, int argc, t_atom *argv) +{ + t_demux *x = (t_demux *)pd_new(demux_class); + int i; + + if (!argc)argc=2; + x->n_out=argc; + x->output=0; + + while(argc--)outlet_new(&x->x_obj, gensym("signal")); + + x->out = (t_float **)getbytes(x->n_out * sizeof(t_float *)); + i=x->n_out; + while(i--)x->out[i]=0; + + return (x); +} + +void demultiplex_tilde_setup(void) +{ + demux_class = class_new(gensym("demultiplex~"), (t_newmethod)demux_new, (t_method)demux_free, sizeof(t_demux), 0, A_GIMME, 0); + class_addcreator((t_newmethod)demux_new, gensym("demux~"), A_GIMME, 0); + + class_addfloat(demux_class, demux_output); + class_addmethod(demux_class, (t_method)demux_dsp, gensym("dsp"), 0); + class_addmethod(demux_class, nullfn, gensym("signal"), 0); + + class_addmethod(demux_class, (t_method)demux_helper, gensym("help"), 0); + class_sethelpsymbol(demux_class, gensym("zexy/demultiplex~")); + + zexy_register("demultiplex~"); +} diff --git a/src/dfreq_tilde.c b/src/dfreq_tilde.c deleted file mode 100644 index 7016784..0000000 --- a/src/dfreq_tilde.c +++ /dev/null @@ -1,112 +0,0 @@ -/****************************************************** - * - * zexy - implementation file - * - * copyleft (c) IOhannes m zmölnig - * - * 1999:forum::für::umläute:2004 - * - * institute of electronic music and acoustics (iem) - * - ****************************************************** - * - * license: GNU General Public License v.2 - * - ******************************************************/ - -#include - -#include "zexy.h" - -/* ------------------------ dspobj~ ----------------------------- */ - -/* datendefinition */ - -static t_class *dfreq_class; - -typedef struct _dfreq -{ - t_object x_obj; - - t_float freq; /*freqenz variable */ - t_float alt; - float sampcount; - t_float sr; -} t_dfreq; - - -static t_int *dfreq_perform(t_int *w) -{ - t_float *in = (t_float *)(w[1]); - t_float *out = (t_float *)(w[2]); - int n = (int)(w[3]); - t_dfreq *x = (t_dfreq *) w[4]; - - t_float a = x->alt, c = x->sampcount; - t_float freq = x->freq, sr=x->sr; - - t_float delta_inv; - - while (n--) { - - if( (a * *in) < 0 && (a < *in)){ - - /* interpolate for real zerocross */ - delta_inv = 1./(*in-a); - if(c > 0.0) - freq = sr / ((t_float) c + a*delta_inv); - else - freq = sr; - - c = *in*delta_inv; /*rest of time */ - }; - - a = *in; - in++; - c += 1.0; - *out++ = freq; - } - - x->alt = a; - x->sampcount = c; - x->freq=freq; - - return (w+5); -} - -static void dfreq_dsp(t_dfreq *x, t_signal **sp) -{ - dsp_add(dfreq_perform, 4, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n,x); -} - - - -static void *dfreq_new(void) -{ - t_dfreq *x = (t_dfreq *)pd_new(dfreq_class); - outlet_new(&x->x_obj, gensym("signal")); - - x->sr = sys_getsr(); - - return (x); -} - -static void helper(void) -{ - post("\n%c dfreq~\t :: pitch-detector that counts zero-crossings", HEARTSYMBOL); - post("\noutputs a frequency estimate as a stream~ that will be updated every zero-X"); - post("\ncreation::\t'dfreq~': that's all"); -} - - -void dfreq_tilde_setup(void) -{ - dfreq_class = class_new(gensym("dfreq~"), (t_newmethod)dfreq_new, 0, - sizeof(t_dfreq), 0, A_NULL); - class_addmethod(dfreq_class, nullfn, gensym("signal"), 0); - class_addmethod(dfreq_class, (t_method)dfreq_dsp, gensym("dsp"), 0); - - class_addmethod(dfreq_class, (t_method)helper, gensym("help"), 0); - class_sethelpsymbol(dfreq_class, gensym("zexy/dfreq~")); - zexy_register("dfreq~"); -} diff --git a/src/dfreq~.c b/src/dfreq~.c new file mode 100644 index 0000000..7016784 --- /dev/null +++ b/src/dfreq~.c @@ -0,0 +1,112 @@ +/****************************************************** + * + * zexy - implementation file + * + * copyleft (c) IOhannes m zmölnig + * + * 1999:forum::für::umläute:2004 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + * + ******************************************************/ + +#include + +#include "zexy.h" + +/* ------------------------ dspobj~ ----------------------------- */ + +/* datendefinition */ + +static t_class *dfreq_class; + +typedef struct _dfreq +{ + t_object x_obj; + + t_float freq; /*freqenz variable */ + t_float alt; + float sampcount; + t_float sr; +} t_dfreq; + + +static t_int *dfreq_perform(t_int *w) +{ + t_float *in = (t_float *)(w[1]); + t_float *out = (t_float *)(w[2]); + int n = (int)(w[3]); + t_dfreq *x = (t_dfreq *) w[4]; + + t_float a = x->alt, c = x->sampcount; + t_float freq = x->freq, sr=x->sr; + + t_float delta_inv; + + while (n--) { + + if( (a * *in) < 0 && (a < *in)){ + + /* interpolate for real zerocross */ + delta_inv = 1./(*in-a); + if(c > 0.0) + freq = sr / ((t_float) c + a*delta_inv); + else + freq = sr; + + c = *in*delta_inv; /*rest of time */ + }; + + a = *in; + in++; + c += 1.0; + *out++ = freq; + } + + x->alt = a; + x->sampcount = c; + x->freq=freq; + + return (w+5); +} + +static void dfreq_dsp(t_dfreq *x, t_signal **sp) +{ + dsp_add(dfreq_perform, 4, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n,x); +} + + + +static void *dfreq_new(void) +{ + t_dfreq *x = (t_dfreq *)pd_new(dfreq_class); + outlet_new(&x->x_obj, gensym("signal")); + + x->sr = sys_getsr(); + + return (x); +} + +static void helper(void) +{ + post("\n%c dfreq~\t :: pitch-detector that counts zero-crossings", HEARTSYMBOL); + post("\noutputs a frequency estimate as a stream~ that will be updated every zero-X"); + post("\ncreation::\t'dfreq~': that's all"); +} + + +void dfreq_tilde_setup(void) +{ + dfreq_class = class_new(gensym("dfreq~"), (t_newmethod)dfreq_new, 0, + sizeof(t_dfreq), 0, A_NULL); + class_addmethod(dfreq_class, nullfn, gensym("signal"), 0); + class_addmethod(dfreq_class, (t_method)dfreq_dsp, gensym("dsp"), 0); + + class_addmethod(dfreq_class, (t_method)helper, gensym("help"), 0); + class_sethelpsymbol(dfreq_class, gensym("zexy/dfreq~")); + zexy_register("dfreq~"); +} diff --git a/src/dirac_tilde.c b/src/dirac_tilde.c deleted file mode 100644 index 72cc4d3..0000000 --- a/src/dirac_tilde.c +++ /dev/null @@ -1,113 +0,0 @@ -/****************************************************** - * - * zexy - implementation file - * - * copyleft (c) IOhannes m zmölnig - * - * 1999:forum::für::umläute:2004 - * - * institute of electronic music and acoustics (iem) - * - ****************************************************** - * - * license: GNU General Public License v.2 - * - ******************************************************/ - - -/* -This external makes the two main test-functions available : -dirac~ : will make a single peak (eg: a 1 in all the 0s) at a desired position in the signal-vector - the position can be passed as an argument when creating the object -step~ : will make a unity step at a desired point in the signal-vector; the second input specifies a - length: after the so-specified time has elapsed, the step will toggle back to the previous - value; - the length can be passed as an argument when creating the object - with length==1 you might do the dirac~ thing a little bit more complicated - with length==0 the output just toggles between 0 and 1 every time you bang the object - -NOTE : the inlets do NOT specify any times but sample-NUMBERS; there are 64 samples in a signal-vector, - each "lasting" for 1/44100 secs. -*/ - -#include "zexy.h" - -/* ------------------------ dirac~ ----------------------------- */ - - -static t_class *dirac_class; - -typedef struct _dirac -{ - t_object x_obj; - t_float position; - t_float do_it; -} t_dirac; - -static void dirac_bang(t_dirac *x) -{ - x->do_it = x->position; -} - -static void dirac_float(t_dirac *x, t_float where) -{ - x->do_it = x->position = where; -} - -static t_int *dirac_perform(t_int *w) -{ - t_dirac *x = (t_dirac *)(w[1]); - t_float *out = (t_float *)(w[2]); - int n = (int)(w[3]); - - int do_it = x->do_it; - - while (n--) - { - *out++ = (!do_it--); - } - x->do_it = do_it; - - return (w+4); -} - -static void dirac_dsp(t_dirac *x, t_signal **sp) -{ - dsp_add(dirac_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); -} - -static void dirac_helper(void) -{ - post("%c dirac~-object :: generates a dirac (unity-pulse)", HEARTSYMBOL); - post("creation : \"dirac~ []\" : create a dirac at specified position (in samples)\n" - "inlet\t: \t: create a dirac at new position\n" - "\t 'bang'\t: create a dirac at specified position\n" - "\t 'help'\t: view this\n" - "outlet\t: signal~"); -} - - - -static void *dirac_new(t_floatarg where) -{ - t_dirac *x = (t_dirac *)pd_new(dirac_class); - - outlet_new(&x->x_obj, gensym("signal")); - - x->do_it = 0; - x->position = where; - return (x); -} - -void dirac_tilde_setup(void) -{ - dirac_class = class_new(gensym("dirac~"), (t_newmethod)dirac_new, 0, - sizeof(t_dirac), 0, A_DEFFLOAT, 0); - class_addfloat(dirac_class, dirac_float); - class_addbang(dirac_class, dirac_bang); - class_addmethod(dirac_class, (t_method)dirac_dsp, gensym("dsp"), 0); - - class_addmethod(dirac_class, (t_method)dirac_helper, gensym("help"), 0); - class_sethelpsymbol(dirac_class, gensym("zexy/dirac~")); - zexy_register("dirac~"); -} diff --git a/src/dirac~.c b/src/dirac~.c new file mode 100644 index 0000000..72cc4d3 --- /dev/null +++ b/src/dirac~.c @@ -0,0 +1,113 @@ +/****************************************************** + * + * zexy - implementation file + * + * copyleft (c) IOhannes m zmölnig + * + * 1999:forum::für::umläute:2004 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + * + ******************************************************/ + + +/* +This external makes the two main test-functions available : +dirac~ : will make a single peak (eg: a 1 in all the 0s) at a desired position in the signal-vector + the position can be passed as an argument when creating the object +step~ : will make a unity step at a desired point in the signal-vector; the second input specifies a + length: after the so-specified time has elapsed, the step will toggle back to the previous + value; + the length can be passed as an argument when creating the object + with length==1 you might do the dirac~ thing a little bit more complicated + with length==0 the output just toggles between 0 and 1 every time you bang the object + +NOTE : the inlets do NOT specify any times but sample-NUMBERS; there are 64 samples in a signal-vector, + each "lasting" for 1/44100 secs. +*/ + +#include "zexy.h" + +/* ------------------------ dirac~ ----------------------------- */ + + +static t_class *dirac_class; + +typedef struct _dirac +{ + t_object x_obj; + t_float position; + t_float do_it; +} t_dirac; + +static void dirac_bang(t_dirac *x) +{ + x->do_it = x->position; +} + +static void dirac_float(t_dirac *x, t_float where) +{ + x->do_it = x->position = where; +} + +static t_int *dirac_perform(t_int *w) +{ + t_dirac *x = (t_dirac *)(w[1]); + t_float *out = (t_float *)(w[2]); + int n = (int)(w[3]); + + int do_it = x->do_it; + + while (n--) + { + *out++ = (!do_it--); + } + x->do_it = do_it; + + return (w+4); +} + +static void dirac_dsp(t_dirac *x, t_signal **sp) +{ + dsp_add(dirac_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); +} + +static void dirac_helper(void) +{ + post("%c dirac~-object :: generates a dirac (unity-pulse)", HEARTSYMBOL); + post("creation : \"dirac~ []\" : create a dirac at specified position (in samples)\n" + "inlet\t: \t: create a dirac at new position\n" + "\t 'bang'\t: create a dirac at specified position\n" + "\t 'help'\t: view this\n" + "outlet\t: signal~"); +} + + + +static void *dirac_new(t_floatarg where) +{ + t_dirac *x = (t_dirac *)pd_new(dirac_class); + + outlet_new(&x->x_obj, gensym("signal")); + + x->do_it = 0; + x->position = where; + return (x); +} + +void dirac_tilde_setup(void) +{ + dirac_class = class_new(gensym("dirac~"), (t_newmethod)dirac_new, 0, + sizeof(t_dirac), 0, A_DEFFLOAT, 0); + class_addfloat(dirac_class, dirac_float); + class_addbang(dirac_class, dirac_bang); + class_addmethod(dirac_class, (t_method)dirac_dsp, gensym("dsp"), 0); + + class_addmethod(dirac_class, (t_method)dirac_helper, gensym("help"), 0); + class_sethelpsymbol(dirac_class, gensym("zexy/dirac~")); + zexy_register("dirac~"); +} diff --git a/src/envrms_tilde.c b/src/envrms_tilde.c deleted file mode 100644 index e9dc302..0000000 --- a/src/envrms_tilde.c +++ /dev/null @@ -1,150 +0,0 @@ -/****************************************************** - * - * zexy - implementation file - * - * copyleft (c) IOhannes m zmölnig - * - * 1999:forum::für::umläute:2004 - * - * institute of electronic music and acoustics (iem) - * - ****************************************************** - * - * license: GNU General Public License v.2 - * - ******************************************************/ - -/* ---------------- envrms~ - simple envelope follower. ----------------- */ -/* this is exactly the same as msp's env~-object, but does not output dB but RMS !! */ -/* i found env~+dbtorms most inconvenient (and expensive...) */ - -#include "zexy.h" -#include - -#define MAXOVERLAP 10 -#define MAXVSTAKEN 64 - -t_class *sigenvrms_class; - -typedef struct sigenvrms -{ - t_object x_obj; /* header */ - void *x_outlet; /* a "float" outlet */ - void *x_clock; /* a "clock" object */ - float *x_buf; /* a Hanning window */ - int x_phase; /* number of points since last output */ - int x_period; /* requested period of output */ - int x_realperiod; /* period rounded up to vecsize multiple */ - int x_npoints; /* analysis window size in samples */ - float x_result; /* result to output */ - float x_sumbuf[MAXOVERLAP]; /* summing buffer */ -} t_sigenvrms; - -static void sigenvrms_tick(t_sigenvrms *x); - -static void *sigenvrms_new(t_floatarg fnpoints, t_floatarg fperiod) -{ - int npoints = fnpoints; - int period = fperiod; - t_sigenvrms *x; - float *buf; - int i; - - if (npoints < 1) npoints = 1024; - if (period < 1) period = npoints/2; - if (period < npoints / MAXOVERLAP + 1) - period = npoints / MAXOVERLAP + 1; - if (!(buf = getbytes(sizeof(float) * (npoints + MAXVSTAKEN)))) - { - error("env: couldn't allocate buffer"); - return (0); - } - x = (t_sigenvrms *)pd_new(sigenvrms_class); - x->x_buf = buf; - x->x_npoints = npoints; - x->x_phase = 0; - x->x_period = period; - for (i = 0; i < MAXOVERLAP; i++) x->x_sumbuf[i] = 0; - for (i = 0; i < npoints; i++) - buf[i] = (1. - cos((2 * 3.141592654 * i) / npoints))/npoints; - for (; i < npoints+MAXVSTAKEN; i++) buf[i] = 0; - x->x_clock = clock_new(x, (t_method)sigenvrms_tick); - x->x_outlet = outlet_new(&x->x_obj, gensym("float")); - return (x); -} - -static t_int *sigenvrms_perform(t_int *w) -{ - t_sigenvrms *x = (t_sigenvrms *)(w[1]); - t_float *in = (t_float *)(w[2]); - int n = (int)(w[3]); - int count; - float *sump; - in += n; - for (count = x->x_phase, sump = x->x_sumbuf; - count < x->x_npoints; count += x->x_realperiod, sump++) - { - float *hp = x->x_buf + count; - float *fp = in; - float sum = *sump; - int i; - - for (i = 0; i < n; i++) - { - fp--; - sum += *hp++ * (*fp * *fp); - } - *sump = sum; - } - sump[0] = 0; - x->x_phase -= n; - if (x->x_phase < 0) - { - x->x_result = x->x_sumbuf[0]; - for (count = x->x_realperiod, sump = x->x_sumbuf; - count < x->x_npoints; count += x->x_realperiod, sump++) - sump[0] = sump[1]; - sump[0] = 0; - x->x_phase = x->x_realperiod - n; - clock_delay(x->x_clock, 0L); - } - return (w+4); -} - -static void sigenvrms_dsp(t_sigenvrms *x, t_signal **sp) -{ - if (x->x_period % sp[0]->s_n) x->x_realperiod = - x->x_period + sp[0]->s_n - (x->x_period % sp[0]->s_n); - else x->x_realperiod = x->x_period; - dsp_add(sigenvrms_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); - if (sp[0]->s_n > MAXVSTAKEN) bug("sigenvrms_dsp"); -} - -static void sigenvrms_tick(t_sigenvrms *x) /* callback function for the clock */ -{ - outlet_float(x->x_outlet, sqrtf(x->x_result)); -} - -static void sigenvrms_ff(t_sigenvrms *x) /* cleanup on free */ -{ - clock_free(x->x_clock); - freebytes(x->x_buf, (x->x_npoints + MAXVSTAKEN) * sizeof(float)); -} - -static void sigenvrms_help(void) -{ - post("envrms~\t:: envelope follower that does output rms instead of dB"); -} - - -void envrms_tilde_setup(void) -{ - sigenvrms_class = class_new(gensym("envrms~"), (t_newmethod)sigenvrms_new, - (t_method)sigenvrms_ff, sizeof(t_sigenvrms), 0, A_DEFFLOAT, A_DEFFLOAT, 0); - class_addmethod(sigenvrms_class, nullfn, gensym("signal"), 0); - class_addmethod(sigenvrms_class, (t_method)sigenvrms_dsp, gensym("dsp"), 0); - - class_addmethod(sigenvrms_class, (t_method)sigenvrms_help, gensym("help"), 0); - class_sethelpsymbol(sigenvrms_class, gensym("zexy/envrms~")); - zexy_register("envrms~"); -} diff --git a/src/envrms~.c b/src/envrms~.c new file mode 100644 index 0000000..e9dc302 --- /dev/null +++ b/src/envrms~.c @@ -0,0 +1,150 @@ +/****************************************************** + * + * zexy - implementation file + * + * copyleft (c) IOhannes m zmölnig + * + * 1999:forum::für::umläute:2004 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + * + ******************************************************/ + +/* ---------------- envrms~ - simple envelope follower. ----------------- */ +/* this is exactly the same as msp's env~-object, but does not output dB but RMS !! */ +/* i found env~+dbtorms most inconvenient (and expensive...) */ + +#include "zexy.h" +#include + +#define MAXOVERLAP 10 +#define MAXVSTAKEN 64 + +t_class *sigenvrms_class; + +typedef struct sigenvrms +{ + t_object x_obj; /* header */ + void *x_outlet; /* a "float" outlet */ + void *x_clock; /* a "clock" object */ + float *x_buf; /* a Hanning window */ + int x_phase; /* number of points since last output */ + int x_period; /* requested period of output */ + int x_realperiod; /* period rounded up to vecsize multiple */ + int x_npoints; /* analysis window size in samples */ + float x_result; /* result to output */ + float x_sumbuf[MAXOVERLAP]; /* summing buffer */ +} t_sigenvrms; + +static void sigenvrms_tick(t_sigenvrms *x); + +static void *sigenvrms_new(t_floatarg fnpoints, t_floatarg fperiod) +{ + int npoints = fnpoints; + int period = fperiod; + t_sigenvrms *x; + float *buf; + int i; + + if (npoints < 1) npoints = 1024; + if (period < 1) period = npoints/2; + if (period < npoints / MAXOVERLAP + 1) + period = npoints / MAXOVERLAP + 1; + if (!(buf = getbytes(sizeof(float) * (npoints + MAXVSTAKEN)))) + { + error("env: couldn't allocate buffer"); + return (0); + } + x = (t_sigenvrms *)pd_new(sigenvrms_class); + x->x_buf = buf; + x->x_npoints = npoints; + x->x_phase = 0; + x->x_period = period; + for (i = 0; i < MAXOVERLAP; i++) x->x_sumbuf[i] = 0; + for (i = 0; i < npoints; i++) + buf[i] = (1. - cos((2 * 3.141592654 * i) / npoints))/npoints; + for (; i < npoints+MAXVSTAKEN; i++) buf[i] = 0; + x->x_clock = clock_new(x, (t_method)sigenvrms_tick); + x->x_outlet = outlet_new(&x->x_obj, gensym("float")); + return (x); +} + +static t_int *sigenvrms_perform(t_int *w) +{ + t_sigenvrms *x = (t_sigenvrms *)(w[1]); + t_float *in = (t_float *)(w[2]); + int n = (int)(w[3]); + int count; + float *sump; + in += n; + for (count = x->x_phase, sump = x->x_sumbuf; + count < x->x_npoints; count += x->x_realperiod, sump++) + { + float *hp = x->x_buf + count; + float *fp = in; + float sum = *sump; + int i; + + for (i = 0; i < n; i++) + { + fp--; + sum += *hp++ * (*fp * *fp); + } + *sump = sum; + } + sump[0] = 0; + x->x_phase -= n; + if (x->x_phase < 0) + { + x->x_result = x->x_sumbuf[0]; + for (count = x->x_realperiod, sump = x->x_sumbuf; + count < x->x_npoints; count += x->x_realperiod, sump++) + sump[0] = sump[1]; + sump[0] = 0; + x->x_phase = x->x_realperiod - n; + clock_delay(x->x_clock, 0L); + } + return (w+4); +} + +static void sigenvrms_dsp(t_sigenvrms *x, t_signal **sp) +{ + if (x->x_period % sp[0]->s_n) x->x_realperiod = + x->x_period + sp[0]->s_n - (x->x_period % sp[0]->s_n); + else x->x_realperiod = x->x_period; + dsp_add(sigenvrms_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); + if (sp[0]->s_n > MAXVSTAKEN) bug("sigenvrms_dsp"); +} + +static void sigenvrms_tick(t_sigenvrms *x) /* callback function for the clock */ +{ + outlet_float(x->x_outlet, sqrtf(x->x_result)); +} + +static void sigenvrms_ff(t_sigenvrms *x) /* cleanup on free */ +{ + clock_free(x->x_clock); + freebytes(x->x_buf, (x->x_npoints + MAXVSTAKEN) * sizeof(float)); +} + +static void sigenvrms_help(void) +{ + post("envrms~\t:: envelope follower that does output rms instead of dB"); +} + + +void envrms_tilde_setup(void) +{ + sigenvrms_class = class_new(gensym("envrms~"), (t_newmethod)sigenvrms_new, + (t_method)sigenvrms_ff, sizeof(t_sigenvrms), 0, A_DEFFLOAT, A_DEFFLOAT, 0); + class_addmethod(sigenvrms_class, nullfn, gensym("signal"), 0); + class_addmethod(sigenvrms_class, (t_method)sigenvrms_dsp, gensym("dsp"), 0); + + class_addmethod(sigenvrms_class, (t_method)sigenvrms_help, gensym("help"), 0); + class_sethelpsymbol(sigenvrms_class, gensym("zexy/envrms~")); + zexy_register("envrms~"); +} diff --git a/src/limiter_tilde.c b/src/limiter_tilde.c deleted file mode 100644 index 7a53d8d..0000000 --- a/src/limiter_tilde.c +++ /dev/null @@ -1,719 +0,0 @@ -/****************************************************** - * - * zexy - implementation file - * - * copyleft (c) IOhannes m zmölnig - * - * 1999:forum::für::umläute:2004 - * - * institute of electronic music and acoustics (iem) - * - ****************************************************** - * - * license: GNU General Public License v.2 - * - ******************************************************/ - - -/* - --------------------------------- limiter/compressor --------------------------------- - - for details on how it works watch out for "http://iem.kug.ac.at/~zmoelnig/pd" - ...and search for "limiter" - - mail2me4more!n4m8ion : zmoelnig@iem.kug.ac.at -*/ - -/* - this is a limiter/compressor-object - the limiter is based on Falkner's thesis - "Entwicklung eines digitalen Stereo-limiters mit Hilfe des Signalprozessors DSP56001" pp.14 - - 2108:forum::für::umläute:1999 all rights reserved and no warranties... - - see GNU-license for details -*/ - -#define LIMIT0 0 -#define LIMIT1 1 -#define COMPRESS 2 - -#include "zexy.h" -#include - -#define LN2 .69314718056 -#define SINC1 .822462987 -#define SINC2 .404460777 -#define SINC3 -.188874003 -#define SINC4 -.143239449 -#define SINC5 .087796546 -#define SINC6 .06917082 -#define SINC7 -.041349667 -#define SINC8 -.030578954 -#define SINC9 .013226276 - -#define BUFSIZE 128 -#define XTRASAMPS 9 -#define TABLESIZE 512 /* compressor table */ - -/* ------------------------------------------------------------------------------------ */ -// first define the structs... - -static t_class *limiter_class; - -typedef struct _limctl -{ // variables changed by user - float limit, hold_samples, change_of_amplification; -} t_limctl; - -typedef struct _cmpctl -{ - float treshold, ratio; // uclimit is the very same is the limiter1-limit (decalculated relative to our treshold) - float uclimit, climit_inverse; // climit == compressed limit (uclimit == uncompressed limit) - - float limiter_limit; // start limiting (stop compressing); == tresh/limit; - - float treshdB, oneminusratio; -} t_cmpctl; - -typedef struct _inbuf -{ - float* ringbuf; - int buf_position; -} t_inbuf; - -typedef struct _limiter -{ - t_object x_obj; - - int number_of_inlets, s_n; - - // variables changed by process - - float amplification; - float samples_left, still_left; - - int mode; - - t_limctl *val1, *val2; - t_cmpctl *cmp; - - // note : limit is not the same for val1 & val2 : - // at val1 it is the limit of the INPUT_VALUE - // at val2 it is the limit for the AMPLIFICATION (in fact it is abs_limit1/abs_limit2) - - t_inbuf* in; - int buf_size; - -} t_limiter; - -/* ------------------------------------------------------------------------------------ */ -// then do the message - thing - -// do the user settings - -// calcs -static t_float calc_holdsamples(t_float htime, int buf) -{ // hold_time must be greater than buffer_time to make sure that any peak_sample is amplified with its own factor - float min_hold = buf / sys_getsr(); - return (0.001 * sys_getsr() * ((htime > min_hold)?htime:((min_hold > 50)?min_hold:50))); -} - -static t_float calc_coa(t_float hlife) -{ - return (exp(LN2 * 1000 / (((hlife > 0)?hlife:15) * sys_getsr()))); -} - -static void set_uclimit(t_limiter *x) -{ - t_cmpctl *c = x->cmp; - t_float limit = x->val1->limit, limitdB = rmstodb(limit), ratio = c->ratio, tresh = c->treshold, treshdB = rmstodb(tresh); - - c->climit_inverse = limit / tresh; - c->uclimit = tresh / dbtorms(treshdB+(limitdB - treshdB)/ratio); - - c->treshdB = treshdB; - c->oneminusratio = 1. - ratio; -} - -// settings - -static void set_treshold(t_limiter *x, float treshold) -{ - t_cmpctl *c = x->cmp; - float tresh = dbtorms (treshold); - if (tresh > x->val1->limit) tresh = x->val1->limit; - - c->treshold = tresh; - - set_uclimit(x); -} - -static void set_ratio(t_limiter *x, float ratio) -{ - if (ratio < 0) ratio = 1; - x->cmp->ratio = ratio; - - set_uclimit(x); -} - -static void set_mode(t_limiter *x, float mode) -{ - int modus = mode; - - switch (modus) { - case LIMIT0: - x->mode = LIMIT0; - break; - case LIMIT1: - x->mode = LIMIT1; - break; - case COMPRESS: - x->mode = COMPRESS; - break; - default: - x->mode = LIMIT0; - break; - } - // post("mode set to %d", x->mode); -} - -static void set_LIMIT(t_limiter *x) -{ - set_mode(x, LIMIT0); -} - -static void set_CRACK(t_limiter *x) -{ - set_mode(x, LIMIT1); -} - -static void set_COMPRESS(t_limiter *x) -{ - set_mode(x, COMPRESS); -} - -static void set_bufsize(t_limiter *x, float size) -{ // this is really unneeded...and for historical reasons only - if (size < BUFSIZE) size = BUFSIZE; - x->buf_size = size + XTRASAMPS; -} - -static void set_limit(t_limiter *x, t_floatarg limit) -{ - if (limit < 0.00001) limit = 100; - x->val1->limit = dbtorms(limit); - - if (x->val1->limit < x->cmp->treshold) x->cmp->treshold = x->val1->limit; - set_uclimit(x); -} - -static void set_limits(t_limiter *x, t_floatarg limit1, t_floatarg limit2) -{ - t_float lim1, lim2; - - if (limit1 < 0.00001) limit1 = 100; - - lim1 = dbtorms(limit1); - lim2 = dbtorms(limit2); - - if (lim2 < lim1) - { - lim2 = 2*lim1; // this is to prevent lim2 (which should trigger the FAST regulation) - x->mode = 0; // to underrun the SLOW regulation; this would cause distortion - } - - x->val1->limit = lim1; - x->val2->limit = lim1/lim2; - - if (lim1 < x->cmp->treshold) x->cmp->treshold = lim1; - set_uclimit(x); -} - -static void set1(t_limiter *x, t_floatarg limit, t_floatarg hold, t_floatarg release) -{ - t_float lim = dbtorms(limit); - - x->val1->limit = (lim > 0)?lim:1; - x->val1->hold_samples = calc_holdsamples(hold, x->buf_size); - x->val1->change_of_amplification = calc_coa(release); - - if (lim < x->cmp->treshold) x->cmp->treshold = lim; - set_uclimit(x); -} - - -static void set2(t_limiter *x, t_floatarg limit, t_floatarg hold, t_floatarg release) -{ - t_float lim = dbtorms(limit); - x->val2->limit = (lim > x->val1->limit)?(x->val1->limit/lim):.5; - x->val2->hold_samples = calc_holdsamples(hold, x->buf_size); - x->val2->change_of_amplification = calc_coa(release); -} - - - -static void set_compressor(t_limiter *x, t_floatarg limit, t_floatarg treshold, t_floatarg ratio) -{ - t_cmpctl *c = x->cmp; - t_float lim = dbtorms(limit); - t_float tresh = dbtorms(treshold); - - if ((limit == 0) && (treshold == 0) && (ratio == 0)) {set_mode(x, COMPRESS); return;} - - if (tresh > lim) tresh = lim; - if (ratio < 0.) ratio = 1.; - - c->ratio = ratio; - x->val1->limit = lim; - c->treshold = tresh; - set_uclimit(x); - - set_mode(x, COMPRESS); -} - -static void reset(t_limiter *x) -{ - x->amplification = 1.; -} - -// verbose -static void status(t_limiter *x) -{ - t_limctl *v1 = x->val1; - t_limctl *v2 = x->val2; - t_cmpctl *c = x->cmp; - - t_float sr = sys_getsr() / 1000.; - - switch (x->mode) { - case LIMIT1: - post("%d-channel crack-limiter @ %fkHz\n" - "\noutput-limit\t= %fdB\nhold1\t\t= %fms\nrelease1\t= %fms\ncrack-limit\t= %fdB\nhold2\t\t= %fms\nrelease2\t= %fms\n" - "\namplify\t\t= %fdB\n", - x->number_of_inlets, sr, - rmstodb(v1->limit), (v1->hold_samples) / sr, LN2 / (log(v1->change_of_amplification) * sr), - rmstodb(v1->limit / v2->limit), (v2->hold_samples) / sr, LN2 / (log(v2->change_of_amplification) * sr), - x->amplification); - break; - case LIMIT0: - post("%d-channel limiter @ %fkHz\n" - "\noutput-limit\t= %fdB\nhold\t\t= %fms\nrelease\t\t= %fms\n" - "\namplify\t\t= %fdB\n", - x->number_of_inlets, sr, - rmstodb(v1->limit), (v1->hold_samples) / sr, LN2 / (log(v1->change_of_amplification) * sr), - rmstodb(x->amplification)); - break; - case COMPRESS: - post("%d-channel compressor @ %fkHz\n" - "\noutput-limit\t= %fdB\ntreshold\t= %fdB\ninput-limit\t= %f\nratio\t\t= 1:%f\n" - "\nhold\t\t= %fms\nrelease\t\t= %fms\n" - "\namplify\t\t= %fdB\n", - x->number_of_inlets, sr, - rmstodb(c->treshold * c->climit_inverse), rmstodb(c->treshold), rmstodb(c->treshold / c->uclimit), 1./c->ratio, - (v1->hold_samples) / sr, LN2 / (log(v1->change_of_amplification) * sr), - rmstodb(x->amplification)); - } -} - -static void helper(t_limiter *x) -{ - post("\n\n%c %d-channel limiter-object: mode %d", HEARTSYMBOL, x->number_of_inlets, x->mode); - poststring("\n'mode '\t\t\t: (0_limiter, 1_crack-limiter, 2_compressor)"); - poststring("\n'LIMIT'\t\t\t\t: set to LIMITer"); - poststring("\n'CRACK'\t\t\t\t: set to CRACK-limiter"); - poststring("\n'COMPRESS'\t\t\t\t: set to COMPRESSor"); - - switch (x->mode) { - case LIMIT0: - poststring("\n'limit '\t\t\t: set limit (in dB)" - "\n'set '\t: set limiter"); - break; - case LIMIT1: - poststring("\n'limits '\t: set limits (in dB)" - "\n'set '\t: set limiter 1" - "\n'set2 '\t: set crack-limiter"); - break; - case COMPRESS: - poststring("\n'ratio '\t\t: set compressratio (´0.5´ instead of ´1:2´)" - "\n'treshold '\t\t: set treshold of the compressor" - "\n'compress '\t: set compressor" - "\n..........note that is the same for COMPRESSOR and LIMITER.........."); - break; - default: - break; - } - poststring("\n'print'\t\t\t\t: view actual settings" - "\n'help'\t\t\t\t: view this\n"); - poststring("\ncreating arguments are :\n" - "\"limiter~ [ [ [ [...]]]]\": may be anything\n"); - endpost(); -} - - -/* ------------------------------------------------------------------------------------ */ -// now do the dsp - thing // -/* ------------------------------------------------------------------------------------ */ - -static t_int *oversampling_maxima(t_int *w) -{ - t_limiter *x = (t_limiter *)w[1]; - t_inbuf *buf = (t_inbuf *)w[2]; - t_float *in = (t_float *)w[3]; - t_float *out = (t_float *)w[4]; - - int n = x->s_n; - int bufsize = x->buf_size; - - int i = buf->buf_position; - - t_float *vp = buf->ringbuf, *ep = vp + bufsize, *bp = vp + XTRASAMPS + i; - - i += n; - - while (n--) - { - t_float os1, os2, max; - t_float last4, last3, last2, last1, sinccurrent, current, next1, next2, next3, next4; - - if (bp == ep) - { - vp[0] = bp[-9]; - vp[1] = bp[-8]; - vp[2] = bp[-7]; - vp[3] = bp[-6]; - vp[4] = bp[-5]; - vp[5] = bp[-4]; - vp[6] = bp[-3]; - vp[7] = bp[-2]; - vp[8] = bp[-1]; - - bp = vp + XTRASAMPS; - i -= bufsize - XTRASAMPS; - } - - os1= fabsf(SINC8 * (last4 = bp[-8]) + - SINC6 * (last3 = bp[-7]) + - SINC4 * (last2 = bp[-6]) + - SINC2 * (last1 = bp[-5]) + - (sinccurrent = SINC1 * (current = bp[-4])) + - SINC3 * (next1 = bp[-3]) + - SINC5 * (next2 = bp[-2]) + - SINC7 * (next3 = bp[-1]) + - SINC9 * (next4 = bp[0])); - - os2= fabsf(SINC8 * next4 + - SINC4 * next3 + - SINC6 * next2 + - SINC2 * next1 + - sinccurrent + - SINC3 * last1 + - SINC5 * last2 + - SINC7 * last3 + - SINC9 * last4); - - max = fabsf(current); - - if (max < os1) - { - max = os1; - } - if (max < os2) - { - max = os2; - } - - *bp++ = *in++; - if (*out++ < max) *(out-1) = max; - } - buf->buf_position = i; - - return (w+5); -} - - -static t_int *limiter_perform(t_int *w) -{ - t_limiter *x=(t_limiter *)w[1]; - int n = x->s_n; - - t_float *in = (t_float *)w[2]; - t_float *out= (t_float *)w[3]; - - t_limctl *v1 = (t_limctl *)(x->val1); - t_limctl *v2 = (t_limctl *)(x->val2); - t_cmpctl *c = (t_cmpctl *)(x->cmp); - - // now let's make things a little bit faster - - // these must not be changed by process - const t_float limit = v1->limit; - const t_float holdlong = v1->hold_samples; - const t_float coa_long = v1->change_of_amplification; - - const t_float alimit = v2->limit; - const t_float holdshort = v2->hold_samples; - const t_float coa_short = v2->change_of_amplification; - - t_float tresh = c->treshold; - t_float uclimit = c->uclimit; - t_float climit_inv = c->climit_inverse; - - t_float oneminusratio = c->oneminusratio; - - // these will be changed by process - t_float amp = x->amplification; - t_float samplesleft = x->samples_left; - t_float stillleft = x->still_left; - - // an intern variable... - t_float max_val; - - switch (x->mode) { - case LIMIT0: - while (n--) - { - max_val = *in; - - // the MAIN routine for the 1-treshold-limiter - - if ((max_val * amp) > limit) - { - amp = limit / max_val; - samplesleft = holdlong; - } else - { - if (samplesleft > 0) - { - samplesleft--; - } else - { - if ((amp *= coa_long) > 1) amp = 1; - } - } - - *out++ = amp; - *in++ = 0; - } - break; - case LIMIT1: - while (n--) - { - max_val = *in; - // the main routine 2 - - if ((max_val * amp) > limit) - { - samplesleft = ((amp = (limit / max_val)) < alimit)?holdshort:holdlong; - stillleft = holdlong; - } else - { - if (samplesleft > 0) - { - samplesleft--; - stillleft--; - } else - { - if (amp < alimit) - { - if ((amp *= coa_short) > 1) amp = 1; - } else - { - if (stillleft > 0) - { - samplesleft = stillleft; - } else - { - if ((amp *= coa_long) > 1) amp = 1; - } - } - } - } - *out++ = amp; - *in++ = 0; - } - x->still_left = stillleft; - break; - case COMPRESS: - while (n--) - { - max_val = *in; - - // the MAIN routine for the compressor (very similar to the 1-treshold-limiter) - - if (max_val * amp > tresh) { - amp = tresh / max_val; - samplesleft = holdlong; - } else - if (samplesleft > 0) samplesleft--; - else if ((amp *= coa_long) > 1) amp = 1; - - if (amp < 1.) - if (amp > uclimit) // amp is still UnCompressed uclimit==limitIN/tresh; - *out++ = pow(amp, oneminusratio); - else *out++ = amp * climit_inv; // amp must fit for limiting : amp(new) = limit/maxval; = amp(old)*limitOUT/tresh; - else *out++ = 1.; - - *in++ = 0.; - } - break; - default: - while (n--) *out++ = *in++ = 0.; - break; - } - - // now return the goodies - x->amplification = amp; - x->samples_left = samplesleft; - - return (w+4); -} - - -#if 0 -static t_int *route_through(t_int *w) -{ - t_float *in = (t_float *)w[1]; - t_float *out = (t_float *)w[2]; - int n = (int)w[3]; - - while(n--) - { - *out++ = *in; - *in++ = 0; - } - - return (w+4); -} -#endif - -void limiter_dsp(t_limiter *x, t_signal **sp) -{ - int i = 0; - t_float* sig_buf = (t_float *)getbytes(sizeof(t_float) * sp[0]->s_n); - - x->s_n = sp[0]->s_n; - - if (x->amplification == 0) x->amplification = 0.0000001; - - if (x->val2->limit >= 1) x->mode = 0; - - while (i < x->number_of_inlets) - { - dsp_add(oversampling_maxima, 4, x, &(x->in[i]), sp[i]->s_vec, sig_buf); - i++; - } - - dsp_add(limiter_perform, 3, x, sig_buf, sp[i]->s_vec); -} - - - -/* ------------------------------------------------------------------------------------ */ -// finally do the creation - things - -void *limiter_new(t_symbol *s, int argc, t_atom *argv) -{ - t_limiter *x = (t_limiter *)pd_new(limiter_class); - - int i = 0; - - if (argc) set_bufsize(x, atom_getfloat(argv)); - else - { - argc = 1; - set_bufsize(x, 0); - } - - if (argc > 64) argc=64; - if (argc == 0) argc=1; - - x->number_of_inlets = argc--; - - while (argc--) - { - inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); - } - - outlet_new(&x->x_obj, &s_signal); - - x->in = (t_inbuf*)getbytes(sizeof(t_inbuf) * x->number_of_inlets); - while (i < x->number_of_inlets) - { - int n; - t_float* buf = (float *)getbytes(sizeof(float) * x->buf_size); - x->in[i].ringbuf = buf; - x->in[i].buf_position = 0; - for (n = 0; n < x->buf_size; n++) x->in[i].ringbuf[n] = 0.; - i++; - } - - x->val1 = (t_limctl *)getbytes(sizeof(t_limctl)); - x->val2 = (t_limctl *)getbytes(sizeof(t_limctl)); - x->cmp = (t_cmpctl *)getbytes(sizeof(t_cmpctl)); - - x->cmp->ratio = 1.; - x->cmp->treshold = 1; - - set1(x, 100, 30, 139); - set2(x, 110, 5, 14.2); - - x->amplification= 1; - x->samples_left = x->still_left = x->mode = 0; - - return (x); -} - -void limiter_free(t_limiter *x) -{ - int i=0; - - freebytes(x->val1, sizeof(t_limctl)); - freebytes(x->val2, sizeof(t_limctl)); - freebytes(x->cmp , sizeof(t_cmpctl)); - - while (i < x->number_of_inlets) freebytes(x->in[i++].ringbuf, x->buf_size * sizeof(t_float)); - - freebytes(x->in, x->number_of_inlets * sizeof(t_inbuf)); -} - - - -/* ------------------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------------------ */ - - - -void limiter_tilde_setup(void) -{ - limiter_class = class_new(gensym("limiter~"), (t_newmethod)limiter_new, (t_method)limiter_free, - sizeof(t_limiter), 0, A_GIMME, 0); - - class_addmethod(limiter_class, nullfn, gensym("signal"), 0); - class_addmethod(limiter_class, (t_method)limiter_dsp, gensym("dsp"), 0); - - class_addmethod(limiter_class, (t_method)helper, gensym("help"), 0); - class_addmethod(limiter_class, (t_method)status, gensym("print"), 0); - class_sethelpsymbol(limiter_class, gensym("zexy/limiter~")); - - class_addmethod(limiter_class, (t_method)set_mode, gensym("mode"), A_FLOAT, 0); - class_addmethod(limiter_class, (t_method)set_LIMIT, gensym("LIMIT"), 0); - class_addmethod(limiter_class, (t_method)set_CRACK, gensym("CRACK"), 0); - class_addmethod(limiter_class, (t_method)set_COMPRESS, gensym("COMPRESS"), 0); - - - class_addmethod(limiter_class, (t_method)set_treshold, gensym("tresh"), A_FLOAT, 0); - class_addmethod(limiter_class, (t_method)set_treshold, gensym("treshold"), A_FLOAT, 0); - class_addmethod(limiter_class, (t_method)set_ratio, gensym("ratio"), A_FLOAT, 0); - class_addmethod(limiter_class, (t_method)set1, gensym("set"), A_FLOAT, A_FLOAT, A_FLOAT, 0); - class_addmethod(limiter_class, (t_method)set2, gensym("set2"), A_FLOAT, A_FLOAT, A_FLOAT, 0); - class_addmethod(limiter_class, (t_method)set_compressor,gensym("compress"), A_FLOAT, A_FLOAT, A_FLOAT, 0); - - class_addmethod(limiter_class, (t_method)set_limits, gensym("limits"), A_FLOAT, A_FLOAT, 0); - class_addmethod(limiter_class, (t_method)set_limit, gensym("limit"), A_FLOAT, 0); - class_addfloat (limiter_class, set_limit); - - class_addmethod(limiter_class, (t_method)reset, gensym("reset"), 0); - - zexy_register("limiter~"); -} diff --git a/src/limiter~.c b/src/limiter~.c new file mode 100644 index 0000000..7a53d8d --- /dev/null +++ b/src/limiter~.c @@ -0,0 +1,719 @@ +/****************************************************** + * + * zexy - implementation file + * + * copyleft (c) IOhannes m zmölnig + * + * 1999:forum::für::umläute:2004 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + * + ******************************************************/ + + +/* + --------------------------------- limiter/compressor --------------------------------- + + for details on how it works watch out for "http://iem.kug.ac.at/~zmoelnig/pd" + ...and search for "limiter" + + mail2me4more!n4m8ion : zmoelnig@iem.kug.ac.at +*/ + +/* + this is a limiter/compressor-object + the limiter is based on Falkner's thesis + "Entwicklung eines digitalen Stereo-limiters mit Hilfe des Signalprozessors DSP56001" pp.14 + + 2108:forum::für::umläute:1999 all rights reserved and no warranties... + + see GNU-license for details +*/ + +#define LIMIT0 0 +#define LIMIT1 1 +#define COMPRESS 2 + +#include "zexy.h" +#include + +#define LN2 .69314718056 +#define SINC1 .822462987 +#define SINC2 .404460777 +#define SINC3 -.188874003 +#define SINC4 -.143239449 +#define SINC5 .087796546 +#define SINC6 .06917082 +#define SINC7 -.041349667 +#define SINC8 -.030578954 +#define SINC9 .013226276 + +#define BUFSIZE 128 +#define XTRASAMPS 9 +#define TABLESIZE 512 /* compressor table */ + +/* ------------------------------------------------------------------------------------ */ +// first define the structs... + +static t_class *limiter_class; + +typedef struct _limctl +{ // variables changed by user + float limit, hold_samples, change_of_amplification; +} t_limctl; + +typedef struct _cmpctl +{ + float treshold, ratio; // uclimit is the very same is the limiter1-limit (decalculated relative to our treshold) + float uclimit, climit_inverse; // climit == compressed limit (uclimit == uncompressed limit) + + float limiter_limit; // start limiting (stop compressing); == tresh/limit; + + float treshdB, oneminusratio; +} t_cmpctl; + +typedef struct _inbuf +{ + float* ringbuf; + int buf_position; +} t_inbuf; + +typedef struct _limiter +{ + t_object x_obj; + + int number_of_inlets, s_n; + + // variables changed by process + + float amplification; + float samples_left, still_left; + + int mode; + + t_limctl *val1, *val2; + t_cmpctl *cmp; + + // note : limit is not the same for val1 & val2 : + // at val1 it is the limit of the INPUT_VALUE + // at val2 it is the limit for the AMPLIFICATION (in fact it is abs_limit1/abs_limit2) + + t_inbuf* in; + int buf_size; + +} t_limiter; + +/* ------------------------------------------------------------------------------------ */ +// then do the message - thing + +// do the user settings + +// calcs +static t_float calc_holdsamples(t_float htime, int buf) +{ // hold_time must be greater than buffer_time to make sure that any peak_sample is amplified with its own factor + float min_hold = buf / sys_getsr(); + return (0.001 * sys_getsr() * ((htime > min_hold)?htime:((min_hold > 50)?min_hold:50))); +} + +static t_float calc_coa(t_float hlife) +{ + return (exp(LN2 * 1000 / (((hlife > 0)?hlife:15) * sys_getsr()))); +} + +static void set_uclimit(t_limiter *x) +{ + t_cmpctl *c = x->cmp; + t_float limit = x->val1->limit, limitdB = rmstodb(limit), ratio = c->ratio, tresh = c->treshold, treshdB = rmstodb(tresh); + + c->climit_inverse = limit / tresh; + c->uclimit = tresh / dbtorms(treshdB+(limitdB - treshdB)/ratio); + + c->treshdB = treshdB; + c->oneminusratio = 1. - ratio; +} + +// settings + +static void set_treshold(t_limiter *x, float treshold) +{ + t_cmpctl *c = x->cmp; + float tresh = dbtorms (treshold); + if (tresh > x->val1->limit) tresh = x->val1->limit; + + c->treshold = tresh; + + set_uclimit(x); +} + +static void set_ratio(t_limiter *x, float ratio) +{ + if (ratio < 0) ratio = 1; + x->cmp->ratio = ratio; + + set_uclimit(x); +} + +static void set_mode(t_limiter *x, float mode) +{ + int modus = mode; + + switch (modus) { + case LIMIT0: + x->mode = LIMIT0; + break; + case LIMIT1: + x->mode = LIMIT1; + break; + case COMPRESS: + x->mode = COMPRESS; + break; + default: + x->mode = LIMIT0; + break; + } + // post("mode set to %d", x->mode); +} + +static void set_LIMIT(t_limiter *x) +{ + set_mode(x, LIMIT0); +} + +static void set_CRACK(t_limiter *x) +{ + set_mode(x, LIMIT1); +} + +static void set_COMPRESS(t_limiter *x) +{ + set_mode(x, COMPRESS); +} + +static void set_bufsize(t_limiter *x, float size) +{ // this is really unneeded...and for historical reasons only + if (size < BUFSIZE) size = BUFSIZE; + x->buf_size = size + XTRASAMPS; +} + +static void set_limit(t_limiter *x, t_floatarg limit) +{ + if (limit < 0.00001) limit = 100; + x->val1->limit = dbtorms(limit); + + if (x->val1->limit < x->cmp->treshold) x->cmp->treshold = x->val1->limit; + set_uclimit(x); +} + +static void set_limits(t_limiter *x, t_floatarg limit1, t_floatarg limit2) +{ + t_float lim1, lim2; + + if (limit1 < 0.00001) limit1 = 100; + + lim1 = dbtorms(limit1); + lim2 = dbtorms(limit2); + + if (lim2 < lim1) + { + lim2 = 2*lim1; // this is to prevent lim2 (which should trigger the FAST regulation) + x->mode = 0; // to underrun the SLOW regulation; this would cause distortion + } + + x->val1->limit = lim1; + x->val2->limit = lim1/lim2; + + if (lim1 < x->cmp->treshold) x->cmp->treshold = lim1; + set_uclimit(x); +} + +static void set1(t_limiter *x, t_floatarg limit, t_floatarg hold, t_floatarg release) +{ + t_float lim = dbtorms(limit); + + x->val1->limit = (lim > 0)?lim:1; + x->val1->hold_samples = calc_holdsamples(hold, x->buf_size); + x->val1->change_of_amplification = calc_coa(release); + + if (lim < x->cmp->treshold) x->cmp->treshold = lim; + set_uclimit(x); +} + + +static void set2(t_limiter *x, t_floatarg limit, t_floatarg hold, t_floatarg release) +{ + t_float lim = dbtorms(limit); + x->val2->limit = (lim > x->val1->limit)?(x->val1->limit/lim):.5; + x->val2->hold_samples = calc_holdsamples(hold, x->buf_size); + x->val2->change_of_amplification = calc_coa(release); +} + + + +static void set_compressor(t_limiter *x, t_floatarg limit, t_floatarg treshold, t_floatarg ratio) +{ + t_cmpctl *c = x->cmp; + t_float lim = dbtorms(limit); + t_float tresh = dbtorms(treshold); + + if ((limit == 0) && (treshold == 0) && (ratio == 0)) {set_mode(x, COMPRESS); return;} + + if (tresh > lim) tresh = lim; + if (ratio < 0.) ratio = 1.; + + c->ratio = ratio; + x->val1->limit = lim; + c->treshold = tresh; + set_uclimit(x); + + set_mode(x, COMPRESS); +} + +static void reset(t_limiter *x) +{ + x->amplification = 1.; +} + +// verbose +static void status(t_limiter *x) +{ + t_limctl *v1 = x->val1; + t_limctl *v2 = x->val2; + t_cmpctl *c = x->cmp; + + t_float sr = sys_getsr() / 1000.; + + switch (x->mode) { + case LIMIT1: + post("%d-channel crack-limiter @ %fkHz\n" + "\noutput-limit\t= %fdB\nhold1\t\t= %fms\nrelease1\t= %fms\ncrack-limit\t= %fdB\nhold2\t\t= %fms\nrelease2\t= %fms\n" + "\namplify\t\t= %fdB\n", + x->number_of_inlets, sr, + rmstodb(v1->limit), (v1->hold_samples) / sr, LN2 / (log(v1->change_of_amplification) * sr), + rmstodb(v1->limit / v2->limit), (v2->hold_samples) / sr, LN2 / (log(v2->change_of_amplification) * sr), + x->amplification); + break; + case LIMIT0: + post("%d-channel limiter @ %fkHz\n" + "\noutput-limit\t= %fdB\nhold\t\t= %fms\nrelease\t\t= %fms\n" + "\namplify\t\t= %fdB\n", + x->number_of_inlets, sr, + rmstodb(v1->limit), (v1->hold_samples) / sr, LN2 / (log(v1->change_of_amplification) * sr), + rmstodb(x->amplification)); + break; + case COMPRESS: + post("%d-channel compressor @ %fkHz\n" + "\noutput-limit\t= %fdB\ntreshold\t= %fdB\ninput-limit\t= %f\nratio\t\t= 1:%f\n" + "\nhold\t\t= %fms\nrelease\t\t= %fms\n" + "\namplify\t\t= %fdB\n", + x->number_of_inlets, sr, + rmstodb(c->treshold * c->climit_inverse), rmstodb(c->treshold), rmstodb(c->treshold / c->uclimit), 1./c->ratio, + (v1->hold_samples) / sr, LN2 / (log(v1->change_of_amplification) * sr), + rmstodb(x->amplification)); + } +} + +static void helper(t_limiter *x) +{ + post("\n\n%c %d-channel limiter-object: mode %d", HEARTSYMBOL, x->number_of_inlets, x->mode); + poststring("\n'mode '\t\t\t: (0_limiter, 1_crack-limiter, 2_compressor)"); + poststring("\n'LIMIT'\t\t\t\t: set to LIMITer"); + poststring("\n'CRACK'\t\t\t\t: set to CRACK-limiter"); + poststring("\n'COMPRESS'\t\t\t\t: set to COMPRESSor"); + + switch (x->mode) { + case LIMIT0: + poststring("\n'limit '\t\t\t: set limit (in dB)" + "\n'set '\t: set limiter"); + break; + case LIMIT1: + poststring("\n'limits '\t: set limits (in dB)" + "\n'set '\t: set limiter 1" + "\n'set2 '\t: set crack-limiter"); + break; + case COMPRESS: + poststring("\n'ratio '\t\t: set compressratio (´0.5´ instead of ´1:2´)" + "\n'treshold '\t\t: set treshold of the compressor" + "\n'compress '\t: set compressor" + "\n..........note that is the same for COMPRESSOR and LIMITER.........."); + break; + default: + break; + } + poststring("\n'print'\t\t\t\t: view actual settings" + "\n'help'\t\t\t\t: view this\n"); + poststring("\ncreating arguments are :\n" + "\"limiter~ [ [ [ [...]]]]\": may be anything\n"); + endpost(); +} + + +/* ------------------------------------------------------------------------------------ */ +// now do the dsp - thing // +/* ------------------------------------------------------------------------------------ */ + +static t_int *oversampling_maxima(t_int *w) +{ + t_limiter *x = (t_limiter *)w[1]; + t_inbuf *buf = (t_inbuf *)w[2]; + t_float *in = (t_float *)w[3]; + t_float *out = (t_float *)w[4]; + + int n = x->s_n; + int bufsize = x->buf_size; + + int i = buf->buf_position; + + t_float *vp = buf->ringbuf, *ep = vp + bufsize, *bp = vp + XTRASAMPS + i; + + i += n; + + while (n--) + { + t_float os1, os2, max; + t_float last4, last3, last2, last1, sinccurrent, current, next1, next2, next3, next4; + + if (bp == ep) + { + vp[0] = bp[-9]; + vp[1] = bp[-8]; + vp[2] = bp[-7]; + vp[3] = bp[-6]; + vp[4] = bp[-5]; + vp[5] = bp[-4]; + vp[6] = bp[-3]; + vp[7] = bp[-2]; + vp[8] = bp[-1]; + + bp = vp + XTRASAMPS; + i -= bufsize - XTRASAMPS; + } + + os1= fabsf(SINC8 * (last4 = bp[-8]) + + SINC6 * (last3 = bp[-7]) + + SINC4 * (last2 = bp[-6]) + + SINC2 * (last1 = bp[-5]) + + (sinccurrent = SINC1 * (current = bp[-4])) + + SINC3 * (next1 = bp[-3]) + + SINC5 * (next2 = bp[-2]) + + SINC7 * (next3 = bp[-1]) + + SINC9 * (next4 = bp[0])); + + os2= fabsf(SINC8 * next4 + + SINC4 * next3 + + SINC6 * next2 + + SINC2 * next1 + + sinccurrent + + SINC3 * last1 + + SINC5 * last2 + + SINC7 * last3 + + SINC9 * last4); + + max = fabsf(current); + + if (max < os1) + { + max = os1; + } + if (max < os2) + { + max = os2; + } + + *bp++ = *in++; + if (*out++ < max) *(out-1) = max; + } + buf->buf_position = i; + + return (w+5); +} + + +static t_int *limiter_perform(t_int *w) +{ + t_limiter *x=(t_limiter *)w[1]; + int n = x->s_n; + + t_float *in = (t_float *)w[2]; + t_float *out= (t_float *)w[3]; + + t_limctl *v1 = (t_limctl *)(x->val1); + t_limctl *v2 = (t_limctl *)(x->val2); + t_cmpctl *c = (t_cmpctl *)(x->cmp); + + // now let's make things a little bit faster + + // these must not be changed by process + const t_float limit = v1->limit; + const t_float holdlong = v1->hold_samples; + const t_float coa_long = v1->change_of_amplification; + + const t_float alimit = v2->limit; + const t_float holdshort = v2->hold_samples; + const t_float coa_short = v2->change_of_amplification; + + t_float tresh = c->treshold; + t_float uclimit = c->uclimit; + t_float climit_inv = c->climit_inverse; + + t_float oneminusratio = c->oneminusratio; + + // these will be changed by process + t_float amp = x->amplification; + t_float samplesleft = x->samples_left; + t_float stillleft = x->still_left; + + // an intern variable... + t_float max_val; + + switch (x->mode) { + case LIMIT0: + while (n--) + { + max_val = *in; + + // the MAIN routine for the 1-treshold-limiter + + if ((max_val * amp) > limit) + { + amp = limit / max_val; + samplesleft = holdlong; + } else + { + if (samplesleft > 0) + { + samplesleft--; + } else + { + if ((amp *= coa_long) > 1) amp = 1; + } + } + + *out++ = amp; + *in++ = 0; + } + break; + case LIMIT1: + while (n--) + { + max_val = *in; + // the main routine 2 + + if ((max_val * amp) > limit) + { + samplesleft = ((amp = (limit / max_val)) < alimit)?holdshort:holdlong; + stillleft = holdlong; + } else + { + if (samplesleft > 0) + { + samplesleft--; + stillleft--; + } else + { + if (amp < alimit) + { + if ((amp *= coa_short) > 1) amp = 1; + } else + { + if (stillleft > 0) + { + samplesleft = stillleft; + } else + { + if ((amp *= coa_long) > 1) amp = 1; + } + } + } + } + *out++ = amp; + *in++ = 0; + } + x->still_left = stillleft; + break; + case COMPRESS: + while (n--) + { + max_val = *in; + + // the MAIN routine for the compressor (very similar to the 1-treshold-limiter) + + if (max_val * amp > tresh) { + amp = tresh / max_val; + samplesleft = holdlong; + } else + if (samplesleft > 0) samplesleft--; + else if ((amp *= coa_long) > 1) amp = 1; + + if (amp < 1.) + if (amp > uclimit) // amp is still UnCompressed uclimit==limitIN/tresh; + *out++ = pow(amp, oneminusratio); + else *out++ = amp * climit_inv; // amp must fit for limiting : amp(new) = limit/maxval; = amp(old)*limitOUT/tresh; + else *out++ = 1.; + + *in++ = 0.; + } + break; + default: + while (n--) *out++ = *in++ = 0.; + break; + } + + // now return the goodies + x->amplification = amp; + x->samples_left = samplesleft; + + return (w+4); +} + + +#if 0 +static t_int *route_through(t_int *w) +{ + t_float *in = (t_float *)w[1]; + t_float *out = (t_float *)w[2]; + int n = (int)w[3]; + + while(n--) + { + *out++ = *in; + *in++ = 0; + } + + return (w+4); +} +#endif + +void limiter_dsp(t_limiter *x, t_signal **sp) +{ + int i = 0; + t_float* sig_buf = (t_float *)getbytes(sizeof(t_float) * sp[0]->s_n); + + x->s_n = sp[0]->s_n; + + if (x->amplification == 0) x->amplification = 0.0000001; + + if (x->val2->limit >= 1) x->mode = 0; + + while (i < x->number_of_inlets) + { + dsp_add(oversampling_maxima, 4, x, &(x->in[i]), sp[i]->s_vec, sig_buf); + i++; + } + + dsp_add(limiter_perform, 3, x, sig_buf, sp[i]->s_vec); +} + + + +/* ------------------------------------------------------------------------------------ */ +// finally do the creation - things + +void *limiter_new(t_symbol *s, int argc, t_atom *argv) +{ + t_limiter *x = (t_limiter *)pd_new(limiter_class); + + int i = 0; + + if (argc) set_bufsize(x, atom_getfloat(argv)); + else + { + argc = 1; + set_bufsize(x, 0); + } + + if (argc > 64) argc=64; + if (argc == 0) argc=1; + + x->number_of_inlets = argc--; + + while (argc--) + { + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + } + + outlet_new(&x->x_obj, &s_signal); + + x->in = (t_inbuf*)getbytes(sizeof(t_inbuf) * x->number_of_inlets); + while (i < x->number_of_inlets) + { + int n; + t_float* buf = (float *)getbytes(sizeof(float) * x->buf_size); + x->in[i].ringbuf = buf; + x->in[i].buf_position = 0; + for (n = 0; n < x->buf_size; n++) x->in[i].ringbuf[n] = 0.; + i++; + } + + x->val1 = (t_limctl *)getbytes(sizeof(t_limctl)); + x->val2 = (t_limctl *)getbytes(sizeof(t_limctl)); + x->cmp = (t_cmpctl *)getbytes(sizeof(t_cmpctl)); + + x->cmp->ratio = 1.; + x->cmp->treshold = 1; + + set1(x, 100, 30, 139); + set2(x, 110, 5, 14.2); + + x->amplification= 1; + x->samples_left = x->still_left = x->mode = 0; + + return (x); +} + +void limiter_free(t_limiter *x) +{ + int i=0; + + freebytes(x->val1, sizeof(t_limctl)); + freebytes(x->val2, sizeof(t_limctl)); + freebytes(x->cmp , sizeof(t_cmpctl)); + + while (i < x->number_of_inlets) freebytes(x->in[i++].ringbuf, x->buf_size * sizeof(t_float)); + + freebytes(x->in, x->number_of_inlets * sizeof(t_inbuf)); +} + + + +/* ------------------------------------------------------------------------------------ */ +/* ------------------------------------------------------------------------------------ */ + + + +void limiter_tilde_setup(void) +{ + limiter_class = class_new(gensym("limiter~"), (t_newmethod)limiter_new, (t_method)limiter_free, + sizeof(t_limiter), 0, A_GIMME, 0); + + class_addmethod(limiter_class, nullfn, gensym("signal"), 0); + class_addmethod(limiter_class, (t_method)limiter_dsp, gensym("dsp"), 0); + + class_addmethod(limiter_class, (t_method)helper, gensym("help"), 0); + class_addmethod(limiter_class, (t_method)status, gensym("print"), 0); + class_sethelpsymbol(limiter_class, gensym("zexy/limiter~")); + + class_addmethod(limiter_class, (t_method)set_mode, gensym("mode"), A_FLOAT, 0); + class_addmethod(limiter_class, (t_method)set_LIMIT, gensym("LIMIT"), 0); + class_addmethod(limiter_class, (t_method)set_CRACK, gensym("CRACK"), 0); + class_addmethod(limiter_class, (t_method)set_COMPRESS, gensym("COMPRESS"), 0); + + + class_addmethod(limiter_class, (t_method)set_treshold, gensym("tresh"), A_FLOAT, 0); + class_addmethod(limiter_class, (t_method)set_treshold, gensym("treshold"), A_FLOAT, 0); + class_addmethod(limiter_class, (t_method)set_ratio, gensym("ratio"), A_FLOAT, 0); + class_addmethod(limiter_class, (t_method)set1, gensym("set"), A_FLOAT, A_FLOAT, A_FLOAT, 0); + class_addmethod(limiter_class, (t_method)set2, gensym("set2"), A_FLOAT, A_FLOAT, A_FLOAT, 0); + class_addmethod(limiter_class, (t_method)set_compressor,gensym("compress"), A_FLOAT, A_FLOAT, A_FLOAT, 0); + + class_addmethod(limiter_class, (t_method)set_limits, gensym("limits"), A_FLOAT, A_FLOAT, 0); + class_addmethod(limiter_class, (t_method)set_limit, gensym("limit"), A_FLOAT, 0); + class_addfloat (limiter_class, set_limit); + + class_addmethod(limiter_class, (t_method)reset, gensym("reset"), 0); + + zexy_register("limiter~"); +} diff --git a/src/multiline_tilde.c b/src/multiline_tilde.c deleted file mode 100644 index 2767df5..0000000 --- a/src/multiline_tilde.c +++ /dev/null @@ -1,263 +0,0 @@ -/****************************************************** - * - * zexy - implementation file - * - * copyleft (c) IOhannes m zmölnig - * - * 1999:forum::für::umläute:2004 - * - * institute of electronic music and acoustics (iem) - * - ****************************************************** - * - * license: GNU General Public License v.2 - * - ******************************************************/ - -/* - a multiline that MULTIplicates MULTIple signals with "ramped floats" (--> like "line~") - - this is kind of multiplying some streams with the square diagonal matrix : diag*~ - for smooth-results we do this line~ thing - - 1403:forum::für::umläute:2001 -*/ - - -/* i am not sure, whether there is a difference between loop-unrolling by hand or by compiler - * i somehow have the feeling, that doing it by hand increases(!) performance for about 2% - * anyhow, if you think that the compiler can do this job better, just disable the UNROLLED define below - */ -#define UNROLLED - -#include "zexy.h" - -/* --------------------------- multiline~ ---------------------------------- */ - -static t_class *mline_class; - -typedef struct _mline { - t_object x_obj; - - t_float time; - - int ticksleft; - int retarget; - - t_float msec2tick; - - t_float *value; - t_float *target; - t_float *increment; /* single precision is really a bad */ - - t_float **sigIN; - t_float **sigOUT; - t_float *sigBUF; - int sigNUM; - -} t_mline; - -/* the message thing */ - -static void mline_list(t_mline *x, t_symbol *s, int argc, t_atom *argv) -{ - if (argc>x->sigNUM)x->time=atom_getfloat(argv+argc-1); - - if (x->time <= 0) { - if (argc==1) { - t_float f = atom_getfloat(argv); - int i=x->sigNUM; - while(i--)x->target[i]=x->value[i]=f; - } else { - int offset = (argcsigNUM)?x->sigNUM-argc:0; - int i=offset?argc:x->sigNUM; - while(i--)x->target[i+offset]=x->value[i+offset]=atom_getfloat(argv++); - } - x->ticksleft=x->retarget=x->time=0; - } else { - if (argc==1) { - int i = x->sigNUM; - t_float f = atom_getfloat(argv); - for(i=0;isigNUM;i++)x->target[i]=f; - } else { - int offset = (argcsigNUM)?x->sigNUM-argc:0; - int i=offset?argc:x->sigNUM; - while(i--)x->target[i+offset]=atom_getfloat(argv++); - } - x->retarget = 1; - } -} - -static void mline_stop(t_mline *x) -{ - int i = x->sigNUM; - while (i--) x->target[i] = x->value[i]; - x->ticksleft = x->retarget = 0; -} - -/* the dsp thing */ - -static t_int *mline_perform(t_int *w) -{ - t_mline *x = (t_mline *)(w[1]); - int n = (int)(w[2]); - - t_float **out = x->sigOUT; - t_float **in = x->sigIN; - t_float *buf = x->sigBUF, *sigBUF = buf; - t_float *inc = x->increment, *increment = inc; - t_float *val = x->value, *value = val; - t_float *tgt = x->target, *target = tgt; - - int sigNUM = x->sigNUM; - - if (x->retarget) { - int nticks = x->time * x->msec2tick; - - if (!nticks) nticks = 1; - x->ticksleft = nticks; - - x->retarget = 0; - } - - if (x->ticksleft) { - int N=n-1; - t_float oneovernos = 1./(x->ticksleft*n); - - int i=sigNUM; - while(i--)*inc++=(*tgt++-*val++)*oneovernos; - - n=-1; - while (n++ticksleft) { - val = value; - tgt = target; - i = sigNUM; - while(i--)*val++=*tgt++; - } - - } else { /* no ticks left */ - int i = sigNUM; - while (n--) { - i = sigNUM; - val = value; - buf = sigBUF; - while (i--)*buf++=in[i][n]**val++; - i = sigNUM; - buf = sigBUF; - while (i--)out[i][n]=*buf++; - } - } - - return (w+3); -} - - - -static void mline_dsp(t_mline *x, t_signal **sp) -{ - int i = x->sigNUM, n = 0; - t_float **dummy = x->sigIN; - while(i--)*dummy++=sp[n++]->s_vec; - - i = x->sigNUM; - dummy =x->sigOUT; - while(i--)*dummy++=sp[n++]->s_vec; - - x->msec2tick = sp[0]->s_sr / (1000.f * sp[0]->s_n); - dsp_add(mline_perform, 2, x, sp[0]->s_n); -} - - -/* setup/setdown things */ - -static void mline_free(t_mline *x) -{ - freebytes(x->value, sizeof(x->value)); - freebytes(x->target, sizeof(x->target)); - freebytes(x->increment, sizeof(x->increment)); - - freebytes(x->sigIN, sizeof(x->sigIN)); - freebytes(x->sigOUT, sizeof(x->sigOUT)); - freebytes(x->sigBUF, sizeof(x->sigBUF)); -} - - -static void *mline_new(t_symbol *s, int argc, t_atom *argv) -{ - t_mline *x = (t_mline *)pd_new(mline_class); - int i; - - if (!argc) { - argc = 1; - x->time = 0; - } else { - x->time = atom_getfloat(argv+argc-1); - if (x->time < 0) x->time = 0; - - argc--; - if (!argc) argc = 1; - } - - x->sigNUM = argc; - - i = argc-1; - - outlet_new(&x->x_obj, &s_signal); - - while (i--) { - inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); - outlet_new(&x->x_obj, &s_signal); - } - - inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("")); - floatinlet_new(&x->x_obj, &x->time); - - x->sigIN = (t_float **)getbytes(x->sigNUM * sizeof(t_float **)); - x->sigOUT = (t_float **)getbytes(x->sigNUM * sizeof(t_float **)); - x->sigBUF = (t_float *)getbytes(x->sigNUM * sizeof(t_float *)); - - x->value = (t_float *)getbytes(x->sigNUM * sizeof(t_float *)); - x->target = (t_float *)getbytes(x->sigNUM * sizeof(t_float *)); - x->increment = (t_float *)getbytes(x->sigNUM * sizeof(t_float *)); - - i = x->sigNUM; - - while (i--) { - x->sigIN[i] = x->sigOUT[i] = 0; - x->increment[i] = 0; - x->value[x->sigNUM-i-1] = x->target[x->sigNUM-i-1] = atom_getfloat(argv+i); - } - - x->msec2tick = x->ticksleft = x->retarget = 0; - - return (x); -} - - - -void multiline_tilde_setup(void) -{ - mline_class = class_new(gensym("multiline~"), (t_newmethod)mline_new, (t_method)mline_free, - sizeof(t_mline), 0, A_GIMME, 0); - - class_addmethod(mline_class, (t_method)mline_dsp, gensym("dsp"), 0); - class_addmethod(mline_class, nullfn, gensym("signal"), 0); - - class_addmethod(mline_class, (t_method)mline_list, gensym(""), A_GIMME, 0); - class_addmethod(mline_class, (t_method)mline_stop, gensym("stop"), 0); - - class_sethelpsymbol(mline_class, gensym("zexy/multiline~")); - zexy_register("multiline_tilde"); -} diff --git a/src/multiline~.c b/src/multiline~.c new file mode 100644 index 0000000..2767df5 --- /dev/null +++ b/src/multiline~.c @@ -0,0 +1,263 @@ +/****************************************************** + * + * zexy - implementation file + * + * copyleft (c) IOhannes m zmölnig + * + * 1999:forum::für::umläute:2004 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + * + ******************************************************/ + +/* + a multiline that MULTIplicates MULTIple signals with "ramped floats" (--> like "line~") + + this is kind of multiplying some streams with the square diagonal matrix : diag*~ + for smooth-results we do this line~ thing + + 1403:forum::für::umläute:2001 +*/ + + +/* i am not sure, whether there is a difference between loop-unrolling by hand or by compiler + * i somehow have the feeling, that doing it by hand increases(!) performance for about 2% + * anyhow, if you think that the compiler can do this job better, just disable the UNROLLED define below + */ +#define UNROLLED + +#include "zexy.h" + +/* --------------------------- multiline~ ---------------------------------- */ + +static t_class *mline_class; + +typedef struct _mline { + t_object x_obj; + + t_float time; + + int ticksleft; + int retarget; + + t_float msec2tick; + + t_float *value; + t_float *target; + t_float *increment; /* single precision is really a bad */ + + t_float **sigIN; + t_float **sigOUT; + t_float *sigBUF; + int sigNUM; + +} t_mline; + +/* the message thing */ + +static void mline_list(t_mline *x, t_symbol *s, int argc, t_atom *argv) +{ + if (argc>x->sigNUM)x->time=atom_getfloat(argv+argc-1); + + if (x->time <= 0) { + if (argc==1) { + t_float f = atom_getfloat(argv); + int i=x->sigNUM; + while(i--)x->target[i]=x->value[i]=f; + } else { + int offset = (argcsigNUM)?x->sigNUM-argc:0; + int i=offset?argc:x->sigNUM; + while(i--)x->target[i+offset]=x->value[i+offset]=atom_getfloat(argv++); + } + x->ticksleft=x->retarget=x->time=0; + } else { + if (argc==1) { + int i = x->sigNUM; + t_float f = atom_getfloat(argv); + for(i=0;isigNUM;i++)x->target[i]=f; + } else { + int offset = (argcsigNUM)?x->sigNUM-argc:0; + int i=offset?argc:x->sigNUM; + while(i--)x->target[i+offset]=atom_getfloat(argv++); + } + x->retarget = 1; + } +} + +static void mline_stop(t_mline *x) +{ + int i = x->sigNUM; + while (i--) x->target[i] = x->value[i]; + x->ticksleft = x->retarget = 0; +} + +/* the dsp thing */ + +static t_int *mline_perform(t_int *w) +{ + t_mline *x = (t_mline *)(w[1]); + int n = (int)(w[2]); + + t_float **out = x->sigOUT; + t_float **in = x->sigIN; + t_float *buf = x->sigBUF, *sigBUF = buf; + t_float *inc = x->increment, *increment = inc; + t_float *val = x->value, *value = val; + t_float *tgt = x->target, *target = tgt; + + int sigNUM = x->sigNUM; + + if (x->retarget) { + int nticks = x->time * x->msec2tick; + + if (!nticks) nticks = 1; + x->ticksleft = nticks; + + x->retarget = 0; + } + + if (x->ticksleft) { + int N=n-1; + t_float oneovernos = 1./(x->ticksleft*n); + + int i=sigNUM; + while(i--)*inc++=(*tgt++-*val++)*oneovernos; + + n=-1; + while (n++ticksleft) { + val = value; + tgt = target; + i = sigNUM; + while(i--)*val++=*tgt++; + } + + } else { /* no ticks left */ + int i = sigNUM; + while (n--) { + i = sigNUM; + val = value; + buf = sigBUF; + while (i--)*buf++=in[i][n]**val++; + i = sigNUM; + buf = sigBUF; + while (i--)out[i][n]=*buf++; + } + } + + return (w+3); +} + + + +static void mline_dsp(t_mline *x, t_signal **sp) +{ + int i = x->sigNUM, n = 0; + t_float **dummy = x->sigIN; + while(i--)*dummy++=sp[n++]->s_vec; + + i = x->sigNUM; + dummy =x->sigOUT; + while(i--)*dummy++=sp[n++]->s_vec; + + x->msec2tick = sp[0]->s_sr / (1000.f * sp[0]->s_n); + dsp_add(mline_perform, 2, x, sp[0]->s_n); +} + + +/* setup/setdown things */ + +static void mline_free(t_mline *x) +{ + freebytes(x->value, sizeof(x->value)); + freebytes(x->target, sizeof(x->target)); + freebytes(x->increment, sizeof(x->increment)); + + freebytes(x->sigIN, sizeof(x->sigIN)); + freebytes(x->sigOUT, sizeof(x->sigOUT)); + freebytes(x->sigBUF, sizeof(x->sigBUF)); +} + + +static void *mline_new(t_symbol *s, int argc, t_atom *argv) +{ + t_mline *x = (t_mline *)pd_new(mline_class); + int i; + + if (!argc) { + argc = 1; + x->time = 0; + } else { + x->time = atom_getfloat(argv+argc-1); + if (x->time < 0) x->time = 0; + + argc--; + if (!argc) argc = 1; + } + + x->sigNUM = argc; + + i = argc-1; + + outlet_new(&x->x_obj, &s_signal); + + while (i--) { + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + outlet_new(&x->x_obj, &s_signal); + } + + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("")); + floatinlet_new(&x->x_obj, &x->time); + + x->sigIN = (t_float **)getbytes(x->sigNUM * sizeof(t_float **)); + x->sigOUT = (t_float **)getbytes(x->sigNUM * sizeof(t_float **)); + x->sigBUF = (t_float *)getbytes(x->sigNUM * sizeof(t_float *)); + + x->value = (t_float *)getbytes(x->sigNUM * sizeof(t_float *)); + x->target = (t_float *)getbytes(x->sigNUM * sizeof(t_float *)); + x->increment = (t_float *)getbytes(x->sigNUM * sizeof(t_float *)); + + i = x->sigNUM; + + while (i--) { + x->sigIN[i] = x->sigOUT[i] = 0; + x->increment[i] = 0; + x->value[x->sigNUM-i-1] = x->target[x->sigNUM-i-1] = atom_getfloat(argv+i); + } + + x->msec2tick = x->ticksleft = x->retarget = 0; + + return (x); +} + + + +void multiline_tilde_setup(void) +{ + mline_class = class_new(gensym("multiline~"), (t_newmethod)mline_new, (t_method)mline_free, + sizeof(t_mline), 0, A_GIMME, 0); + + class_addmethod(mline_class, (t_method)mline_dsp, gensym("dsp"), 0); + class_addmethod(mline_class, nullfn, gensym("signal"), 0); + + class_addmethod(mline_class, (t_method)mline_list, gensym(""), A_GIMME, 0); + class_addmethod(mline_class, (t_method)mline_stop, gensym("stop"), 0); + + class_sethelpsymbol(mline_class, gensym("zexy/multiline~")); + zexy_register("multiline_tilde"); +} diff --git a/src/multiplex_tilde.c b/src/multiplex_tilde.c deleted file mode 100644 index be141cd..0000000 --- a/src/multiplex_tilde.c +++ /dev/null @@ -1,112 +0,0 @@ -/****************************************************** - * zexy - implementation file - * - * copyleft (c) IOhannes m zmölnig - * - * 1999:forum::für::umläute:2004 - * - * institute of electronic music and acoustics (iem) - * - ****************************************************** - * - * license: GNU General Public License v.2 - * - ******************************************************/ - -#include "zexy.h" - - -/* ------------------------------------------------------------------------------ */ - -/* mux~ : multiplex a specified signal to the output */ - -static t_class *mux_class; - -typedef struct _mux { - t_object x_obj; - - int input; - - int n_in; - t_float **in; -} t_mux; - -static void mux_input(t_mux *x, t_floatarg f) -{ - if ((f>=0)&&(fn_in)){ - x->input=f; - } else - error("multiplex: %d is channel out of range (0..%d)", (int)f, x->n_in); - -} - -static t_int *mux_perform(t_int *w) -{ - t_mux *x = (t_mux *)(w[1]); - t_float *out = (t_float *)(w[2]); - int n = (int)(w[3]); - - t_float *in = x->in[x->input]; - - while(n--)*out++=*in++; - - return (w+4); -} - -static void mux_dsp(t_mux *x, t_signal **sp) -{ - int n = 0; - t_float **dummy=x->in; - - for(n=0;nn_in;n++)*dummy++=sp[n]->s_vec; - - dsp_add(mux_perform, 3, x, sp[n]->s_vec, sp[0]->s_n); -} - -static void mux_helper(void) -{ - post("\n%c mux~\t:: multiplex a one of various signals to one outlet", HEARTSYMBOL); - post("<#out>\t : the inlet-number (counting from 0) witch is routed to the outlet" - "'help'\t : view this"); - post("creation : \"mux~ [arg1 [arg2...]]\"\t: the number of arguments equals the number of inlets\n"); -} - -static void mux_free(t_mux *x) -{ - freebytes(x->in, x->n_in * sizeof(t_float *)); -} - -static void *mux_new(t_symbol *s, int argc, t_atom *argv) -{ - t_mux *x = (t_mux *)pd_new(mux_class); - int i; - - if (!argc)argc=2; - x->n_in=argc; - x->input=0; - - argc--; - while(argc--)inlet_new(&x->x_obj,&x->x_obj.ob_pd,&s_signal,&s_signal); - - x->in = (t_float **)getbytes(x->n_in * sizeof(t_float *)); - i=x->n_in; - while(i--)x->in[i]=0; - - outlet_new(&x->x_obj, gensym("signal")); - - return (x); -} - -void multiplex_tilde_setup(void) -{ - mux_class = class_new(gensym("multiplex~"), (t_newmethod)mux_new, (t_method)mux_free, sizeof(t_mux), 0, A_GIMME, 0); - class_addcreator((t_newmethod)mux_new, gensym("mux~"), A_GIMME, 0); - - class_addfloat(mux_class, mux_input); - class_addmethod(mux_class, (t_method)mux_dsp, gensym("dsp"), 0); - class_addmethod(mux_class, nullfn, gensym("signal"), 0); - - class_addmethod(mux_class, (t_method)mux_helper, gensym("help"), 0); - class_sethelpsymbol(mux_class, gensym("zexy/multiplex~")); - zexy_register("multiplex~"); -} diff --git a/src/multiplex~.c b/src/multiplex~.c new file mode 100644 index 0000000..be141cd --- /dev/null +++ b/src/multiplex~.c @@ -0,0 +1,112 @@ +/****************************************************** + * zexy - implementation file + * + * copyleft (c) IOhannes m zmölnig + * + * 1999:forum::für::umläute:2004 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + * + ******************************************************/ + +#include "zexy.h" + + +/* ------------------------------------------------------------------------------ */ + +/* mux~ : multiplex a specified signal to the output */ + +static t_class *mux_class; + +typedef struct _mux { + t_object x_obj; + + int input; + + int n_in; + t_float **in; +} t_mux; + +static void mux_input(t_mux *x, t_floatarg f) +{ + if ((f>=0)&&(fn_in)){ + x->input=f; + } else + error("multiplex: %d is channel out of range (0..%d)", (int)f, x->n_in); + +} + +static t_int *mux_perform(t_int *w) +{ + t_mux *x = (t_mux *)(w[1]); + t_float *out = (t_float *)(w[2]); + int n = (int)(w[3]); + + t_float *in = x->in[x->input]; + + while(n--)*out++=*in++; + + return (w+4); +} + +static void mux_dsp(t_mux *x, t_signal **sp) +{ + int n = 0; + t_float **dummy=x->in; + + for(n=0;nn_in;n++)*dummy++=sp[n]->s_vec; + + dsp_add(mux_perform, 3, x, sp[n]->s_vec, sp[0]->s_n); +} + +static void mux_helper(void) +{ + post("\n%c mux~\t:: multiplex a one of various signals to one outlet", HEARTSYMBOL); + post("<#out>\t : the inlet-number (counting from 0) witch is routed to the outlet" + "'help'\t : view this"); + post("creation : \"mux~ [arg1 [arg2...]]\"\t: the number of arguments equals the number of inlets\n"); +} + +static void mux_free(t_mux *x) +{ + freebytes(x->in, x->n_in * sizeof(t_float *)); +} + +static void *mux_new(t_symbol *s, int argc, t_atom *argv) +{ + t_mux *x = (t_mux *)pd_new(mux_class); + int i; + + if (!argc)argc=2; + x->n_in=argc; + x->input=0; + + argc--; + while(argc--)inlet_new(&x->x_obj,&x->x_obj.ob_pd,&s_signal,&s_signal); + + x->in = (t_float **)getbytes(x->n_in * sizeof(t_float *)); + i=x->n_in; + while(i--)x->in[i]=0; + + outlet_new(&x->x_obj, gensym("signal")); + + return (x); +} + +void multiplex_tilde_setup(void) +{ + mux_class = class_new(gensym("multiplex~"), (t_newmethod)mux_new, (t_method)mux_free, sizeof(t_mux), 0, A_GIMME, 0); + class_addcreator((t_newmethod)mux_new, gensym("mux~"), A_GIMME, 0); + + class_addfloat(mux_class, mux_input); + class_addmethod(mux_class, (t_method)mux_dsp, gensym("dsp"), 0); + class_addmethod(mux_class, nullfn, gensym("signal"), 0); + + class_addmethod(mux_class, (t_method)mux_helper, gensym("help"), 0); + class_sethelpsymbol(mux_class, gensym("zexy/multiplex~")); + zexy_register("multiplex~"); +} diff --git a/src/noish_tilde.c b/src/noish_tilde.c deleted file mode 100644 index 6374242..0000000 --- a/src/noish_tilde.c +++ /dev/null @@ -1,184 +0,0 @@ -/****************************************************** - * - * zexy - implementation file - * - * copyleft (c) IOhannes m zmölnig - * - * 1999:forum::für::umläute:2004 - * - * institute of electronic music and acoustics (iem) - * - ****************************************************** - * - * license: GNU General Public License v.2 - * - ******************************************************/ - -/* - 30041999 - - two bandlimited noise gnerators based on DODGE/JERSE "computer music" c3.9 : RANDI & RANDH - - I do not care for copyrights - (all in all, the used noise~-code (in fact, the pseude-random-code) is from Miller Puckette - and I made only very few modifications so look out for the LICENSE.TXT delivered with - puredata for further (c)-information - - forum für umläute 1999 - - this is in fact the very same as the late "NOISE.C", except that I tried to optimize the code a little bit - (by partially removing those very expensive if..then's in about 15 minutes, so there are thousands of new bugs very likely) - - 14071999 - finally added changing seeds, this is to prevent to noise~-units to output the very same, something quite unnatural even for pseudo-random-noise -*/ - -#include "zexy.h" - -/* general */ - -typedef struct _nois -{ - t_object x_obj; - int val; - t_float current; - t_float decrement; - t_float updater; - t_float to_go; -} t_nois; - - -static void set_freq(t_nois *x, t_floatarg freq) -{ - x->updater = (freq > 0) ? sys_getsr() / freq : 1; - if (x->updater < 1) - { - x->updater = 1; - } - x->to_go = 0; -} - - -/* ------------------------ noish~ ----------------------------- */ - -static t_class *noish_class; - -static t_int *noish_perform(t_int *w) -{ - t_nois *x = (t_nois *)(w[1]); - t_float *out = (t_float *)(w[2]); - int n = (int)(w[3]); - - int *vp = (int *)(&x->val); - int i_value = *vp; - t_float f_value = ((float)((i_value & 0x7fffffff) - 0x40000000)) * - (float)(1.0 / 0x40000000); - t_float all_to_go = x->updater; - t_float still_to_go = x->to_go; - - if (all_to_go == 1) - { /* this is "pure white" noise, so we have to calculate each sample */ - while (n--) - { - i_value *= 435898247; - i_value += 382842987; - *out++ = ((float)((i_value & 0x7fffffff) - 0x40000000)) * (float)(1.0 / 0x40000000); - } - } - else - if (n < still_to_go) - { /* signal won't change for the next 64 samples */ - still_to_go -= n; - while (n--) - { - *out++ = f_value; - } - } - else - if (all_to_go + still_to_go > n) - { /* only one update calculation necessary for 64 samples !!! */ - while (still_to_go-- > 0) - { - n--; - *out++ = f_value; - } - - still_to_go += all_to_go + 1; - - i_value *= 435898247; - i_value += 382842987; - f_value = ( (float)((i_value & 0x7fffffff) - 0x40000000) ) * (float)(1.0 / 0x40000000); - - while (n--) - { - still_to_go--; - *out++ = f_value; - } - } - else - { /* anything else */ - while (n--) - { - if (still_to_go-- <= 0) /* update only if all time has elapsed */ - { - still_to_go += all_to_go; - - i_value *= 435898247; - i_value += 382842987; - - f_value = ( (float)((i_value & 0x7fffffff) - 0x40000000) ) * (float)(1.0 / 0x40000000); - } - *out++ = f_value; - } - } - - - *vp = i_value; - x->updater = all_to_go; - x->to_go = still_to_go; - - return (w+4); -} - -static void noish_dsp(t_nois *x, t_signal **sp) -{ - post("sr=%f\nsn=%f", sp[0]->s_sr, sp[0]->s_n); - dsp_add(noish_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); -} - -static void noish_helper(void) -{ - post("\n%c noish~\t:: a bandlimited pseudo-noise generator", HEARTSYMBOL); - post("\t : sampling-frequency (in Hz)\n" - "'help'\t : view this"); - post("creation : \"noish~ []\"\t: ('0'(default) will produce 'white' noise)\n"); - post("note\t : the seed of the pseudo-noise generator changes from\n" - "\t instance to instance, so two noish~-objects created at the\n" - "\t same time will produce dífferent signals, something the original\n" - "\t noise~-object misses\n"); - post("for further details see DODGE/JERSE \"computer music\" c3.9\n"); -} - -static void *noish_new(t_floatarg f) -{ - t_nois *x = (t_nois *)pd_new(noish_class); - - static int init = 307; - x->val = (init *= 13); - - set_freq(x, f); - - outlet_new(&x->x_obj, gensym("signal")); - return (x); -} - -void noish_tilde_setup(void) -{ - noish_class = class_new(gensym("noish~"), (t_newmethod)noish_new, 0, sizeof(t_nois), 0, A_DEFFLOAT, 0); - - class_addfloat(noish_class, set_freq); - class_addmethod(noish_class, (t_method)noish_dsp, gensym("dsp"), 0); - - class_addmethod(noish_class, (t_method)noish_helper, gensym("help"), 0); - class_sethelpsymbol(noish_class, gensym("zexy/noish~")); -} diff --git a/src/noish~.c b/src/noish~.c new file mode 100644 index 0000000..6374242 --- /dev/null +++ b/src/noish~.c @@ -0,0 +1,184 @@ +/****************************************************** + * + * zexy - implementation file + * + * copyleft (c) IOhannes m zmölnig + * + * 1999:forum::für::umläute:2004 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + * + ******************************************************/ + +/* + 30041999 + + two bandlimited noise gnerators based on DODGE/JERSE "computer music" c3.9 : RANDI & RANDH + + I do not care for copyrights + (all in all, the used noise~-code (in fact, the pseude-random-code) is from Miller Puckette + and I made only very few modifications so look out for the LICENSE.TXT delivered with + puredata for further (c)-information + + forum für umläute 1999 + + this is in fact the very same as the late "NOISE.C", except that I tried to optimize the code a little bit + (by partially removing those very expensive if..then's in about 15 minutes, so there are thousands of new bugs very likely) + + 14071999 + finally added changing seeds, this is to prevent to noise~-units to output the very same, something quite unnatural even for pseudo-random-noise +*/ + +#include "zexy.h" + +/* general */ + +typedef struct _nois +{ + t_object x_obj; + int val; + t_float current; + t_float decrement; + t_float updater; + t_float to_go; +} t_nois; + + +static void set_freq(t_nois *x, t_floatarg freq) +{ + x->updater = (freq > 0) ? sys_getsr() / freq : 1; + if (x->updater < 1) + { + x->updater = 1; + } + x->to_go = 0; +} + + +/* ------------------------ noish~ ----------------------------- */ + +static t_class *noish_class; + +static t_int *noish_perform(t_int *w) +{ + t_nois *x = (t_nois *)(w[1]); + t_float *out = (t_float *)(w[2]); + int n = (int)(w[3]); + + int *vp = (int *)(&x->val); + int i_value = *vp; + t_float f_value = ((float)((i_value & 0x7fffffff) - 0x40000000)) * + (float)(1.0 / 0x40000000); + t_float all_to_go = x->updater; + t_float still_to_go = x->to_go; + + if (all_to_go == 1) + { /* this is "pure white" noise, so we have to calculate each sample */ + while (n--) + { + i_value *= 435898247; + i_value += 382842987; + *out++ = ((float)((i_value & 0x7fffffff) - 0x40000000)) * (float)(1.0 / 0x40000000); + } + } + else + if (n < still_to_go) + { /* signal won't change for the next 64 samples */ + still_to_go -= n; + while (n--) + { + *out++ = f_value; + } + } + else + if (all_to_go + still_to_go > n) + { /* only one update calculation necessary for 64 samples !!! */ + while (still_to_go-- > 0) + { + n--; + *out++ = f_value; + } + + still_to_go += all_to_go + 1; + + i_value *= 435898247; + i_value += 382842987; + f_value = ( (float)((i_value & 0x7fffffff) - 0x40000000) ) * (float)(1.0 / 0x40000000); + + while (n--) + { + still_to_go--; + *out++ = f_value; + } + } + else + { /* anything else */ + while (n--) + { + if (still_to_go-- <= 0) /* update only if all time has elapsed */ + { + still_to_go += all_to_go; + + i_value *= 435898247; + i_value += 382842987; + + f_value = ( (float)((i_value & 0x7fffffff) - 0x40000000) ) * (float)(1.0 / 0x40000000); + } + *out++ = f_value; + } + } + + + *vp = i_value; + x->updater = all_to_go; + x->to_go = still_to_go; + + return (w+4); +} + +static void noish_dsp(t_nois *x, t_signal **sp) +{ + post("sr=%f\nsn=%f", sp[0]->s_sr, sp[0]->s_n); + dsp_add(noish_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); +} + +static void noish_helper(void) +{ + post("\n%c noish~\t:: a bandlimited pseudo-noise generator", HEARTSYMBOL); + post("\t : sampling-frequency (in Hz)\n" + "'help'\t : view this"); + post("creation : \"noish~ []\"\t: ('0'(default) will produce 'white' noise)\n"); + post("note\t : the seed of the pseudo-noise generator changes from\n" + "\t instance to instance, so two noish~-objects created at the\n" + "\t same time will produce dífferent signals, something the original\n" + "\t noise~-object misses\n"); + post("for further details see DODGE/JERSE \"computer music\" c3.9\n"); +} + +static void *noish_new(t_floatarg f) +{ + t_nois *x = (t_nois *)pd_new(noish_class); + + static int init = 307; + x->val = (init *= 13); + + set_freq(x, f); + + outlet_new(&x->x_obj, gensym("signal")); + return (x); +} + +void noish_tilde_setup(void) +{ + noish_class = class_new(gensym("noish~"), (t_newmethod)noish_new, 0, sizeof(t_nois), 0, A_DEFFLOAT, 0); + + class_addfloat(noish_class, set_freq); + class_addmethod(noish_class, (t_method)noish_dsp, gensym("dsp"), 0); + + class_addmethod(noish_class, (t_method)noish_helper, gensym("help"), 0); + class_sethelpsymbol(noish_class, gensym("zexy/noish~")); +} diff --git a/src/noisi_tilde.c b/src/noisi_tilde.c deleted file mode 100644 index 14fb1be..0000000 --- a/src/noisi_tilde.c +++ /dev/null @@ -1,167 +0,0 @@ -/****************************************************** - * - * zexy - implementation file - * - * copyleft (c) IOhannes m zmölnig - * - * 1999:forum::für::umläute:2004 - * - * institute of electronic music and acoustics (iem) - * - ****************************************************** - * - * license: GNU General Public License v.2 - * - ******************************************************/ - -/* - 30041999 - - two bandlimited noise gnerators based on DODGE/JERSE "computer music" c3.9 : RANDI & RANDH - - I do not care for copyrights - (all in all, the used noise~-code (in fact, the pseude-random-code) is from Miller Puckette - and I made only very few modifications so look out for the LICENSE.TXT delivered with - puredata for further (c)-information - - forum für umläute 1999 - - this is in fact the very same as the late "NOISE.C", except that I tried to optimize the code a little bit - (by partially removing those very expensive if..then's in about 15 minutes, so there are thousands of new bugs very likely) - - 14071999 - finally added changing seeds, this is to prevent to noise~-units to output the very same, something quite unnatural even for pseudo-random-noise -*/ - -#include "zexy.h" - -/* general */ - -typedef struct _nois -{ - t_object x_obj; - int val; - t_float current; - t_float decrement; - t_float updater; - t_float to_go; -} t_nois; - - -static void set_noisfreq(t_nois *x, t_floatarg freq) -{ - x->updater = (freq > 0) ? sys_getsr() / freq : 1; - if (x->updater < 1) - { - x->updater = 1; - } - x->to_go = 0; -} - -/* ------------------------ noisi~ ----------------------------- */ - -static t_class *noisi_class; - -static t_int *noisi_perform(t_int *w){ - t_nois *x = (t_nois *)(w[1]); - t_float *out = (t_float *)(w[2]); - int n = (int)(w[3]); - - int *vp = (int *)(&x->val); /* what the ... */ - int i_value = *vp; - t_float f_value = x->current; - t_float decrement = x->decrement; - t_float all_to_go = x->updater; - t_float still_to_go = x->to_go; - - if (all_to_go == 1) { - /* this is "pure white" noise, so we have to calculate each sample */ - while (n--) { - i_value *= 435898247; - i_value += 382842987; - *out++ = ((t_sample)((i_value & 0x7fffffff) - 0x40000000)) * (t_sample)(1.0 / 0x40000000); - } - } else if (n < still_to_go) { - /* signal won't change for the next 64 samples */ - still_to_go -= n; - while (n--){ - *out++ = (f_value -= decrement); - } - } else if (all_to_go + still_to_go > n) { - /* only one update calculation necessary for 64 samples !!! */ - while (still_to_go-- > 0) { - n--; - *out++ = (f_value -= decrement); - } - still_to_go += all_to_go + 1; - decrement = ( - (f_value = - ((t_sample)((i_value & 0x7fffffff)-0x40000000))*(t_sample)(1.0 / 0x40000000)) - - ((t_sample)(((i_value = i_value * 435898247 + 382842987) & 0x7fffffff) - - 0x40000000)) * (t_sample)(1.0 / 0x40000000) - ) / all_to_go; - - while (n--) { - still_to_go--; - *out++ = (f_value -= decrement); - } - } else { - /* anything else */ - while (n--) { - if (still_to_go-- <= 0) { /* update only if all time has elapsed */ - still_to_go += all_to_go; - decrement = ( - (f_value = ((t_sample)((i_value & 0x7fffffff) - 0x40000000)) * (t_sample)(1.0 / 0x40000000)) - - ((t_sample)(((i_value = i_value * 435898247 + 382842987) & 0x7fffffff) - 0x40000000)) * (t_sample)(1.0 / 0x40000000) - ) / all_to_go; - } - *out++ = (f_value -= decrement); - } - } - - *vp = i_value; - x->current = f_value; - x->decrement = decrement; - x->to_go = still_to_go; - - return (w+4); -} - -static void noisi_dsp(t_nois *x, t_signal **sp){ - dsp_add(noisi_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); -} - - -static void noisi_helper(void){ - post("\n%c noisi~\t:: a bandlimited interpolating pseudo-noise generator", HEARTSYMBOL); - post("\t : sampling-frequency (in Hz)\n" - "'help'\t : view this"); - post("creation : \"noisi~ []\"\t: ('0'(default) will produce 'white' noise)\n"); - post("note\t : the seed of the pseudo-noise generator changes from\n" - "\t instance to instance, so two noisi~-objects created at the\n" - "\t same time will produce different signals, something the original\n" - "\t noise~-object misses\n"); - post("for further details see DODGE/JERSE \"computer music\" c3.9\n"); -} - -static void *noisi_new(t_floatarg f){ - t_nois *x = (t_nois *)pd_new(noisi_class); - - static int init = 4259; - x->val = (init *= 17); - - set_noisfreq (x, f); - - outlet_new(&x->x_obj, gensym("signal")); - return (x); -} - -void noisi_tilde_setup(void){ - noisi_class = class_new(gensym("noisi~"), (t_newmethod)noisi_new, 0, sizeof(t_nois), 0, A_DEFFLOAT, 0); - - class_addfloat(noisi_class, set_noisfreq); - class_addmethod(noisi_class, (t_method)noisi_dsp, gensym("dsp"), 0); - - class_addmethod(noisi_class, (t_method)noisi_helper, gensym("help"), 0); - class_sethelpsymbol(noisi_class, gensym("zexy/noisi~")); -} diff --git a/src/noisi~.c b/src/noisi~.c new file mode 100644 index 0000000..14fb1be --- /dev/null +++ b/src/noisi~.c @@ -0,0 +1,167 @@ +/****************************************************** + * + * zexy - implementation file + * + * copyleft (c) IOhannes m zmölnig + * + * 1999:forum::für::umläute:2004 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + * + ******************************************************/ + +/* + 30041999 + + two bandlimited noise gnerators based on DODGE/JERSE "computer music" c3.9 : RANDI & RANDH + + I do not care for copyrights + (all in all, the used noise~-code (in fact, the pseude-random-code) is from Miller Puckette + and I made only very few modifications so look out for the LICENSE.TXT delivered with + puredata for further (c)-information + + forum für umläute 1999 + + this is in fact the very same as the late "NOISE.C", except that I tried to optimize the code a little bit + (by partially removing those very expensive if..then's in about 15 minutes, so there are thousands of new bugs very likely) + + 14071999 + finally added changing seeds, this is to prevent to noise~-units to output the very same, something quite unnatural even for pseudo-random-noise +*/ + +#include "zexy.h" + +/* general */ + +typedef struct _nois +{ + t_object x_obj; + int val; + t_float current; + t_float decrement; + t_float updater; + t_float to_go; +} t_nois; + + +static void set_noisfreq(t_nois *x, t_floatarg freq) +{ + x->updater = (freq > 0) ? sys_getsr() / freq : 1; + if (x->updater < 1) + { + x->updater = 1; + } + x->to_go = 0; +} + +/* ------------------------ noisi~ ----------------------------- */ + +static t_class *noisi_class; + +static t_int *noisi_perform(t_int *w){ + t_nois *x = (t_nois *)(w[1]); + t_float *out = (t_float *)(w[2]); + int n = (int)(w[3]); + + int *vp = (int *)(&x->val); /* what the ... */ + int i_value = *vp; + t_float f_value = x->current; + t_float decrement = x->decrement; + t_float all_to_go = x->updater; + t_float still_to_go = x->to_go; + + if (all_to_go == 1) { + /* this is "pure white" noise, so we have to calculate each sample */ + while (n--) { + i_value *= 435898247; + i_value += 382842987; + *out++ = ((t_sample)((i_value & 0x7fffffff) - 0x40000000)) * (t_sample)(1.0 / 0x40000000); + } + } else if (n < still_to_go) { + /* signal won't change for the next 64 samples */ + still_to_go -= n; + while (n--){ + *out++ = (f_value -= decrement); + } + } else if (all_to_go + still_to_go > n) { + /* only one update calculation necessary for 64 samples !!! */ + while (still_to_go-- > 0) { + n--; + *out++ = (f_value -= decrement); + } + still_to_go += all_to_go + 1; + decrement = ( + (f_value = + ((t_sample)((i_value & 0x7fffffff)-0x40000000))*(t_sample)(1.0 / 0x40000000)) - + ((t_sample)(((i_value = i_value * 435898247 + 382842987) & 0x7fffffff) + - 0x40000000)) * (t_sample)(1.0 / 0x40000000) + ) / all_to_go; + + while (n--) { + still_to_go--; + *out++ = (f_value -= decrement); + } + } else { + /* anything else */ + while (n--) { + if (still_to_go-- <= 0) { /* update only if all time has elapsed */ + still_to_go += all_to_go; + decrement = ( + (f_value = ((t_sample)((i_value & 0x7fffffff) - 0x40000000)) * (t_sample)(1.0 / 0x40000000)) - + ((t_sample)(((i_value = i_value * 435898247 + 382842987) & 0x7fffffff) - 0x40000000)) * (t_sample)(1.0 / 0x40000000) + ) / all_to_go; + } + *out++ = (f_value -= decrement); + } + } + + *vp = i_value; + x->current = f_value; + x->decrement = decrement; + x->to_go = still_to_go; + + return (w+4); +} + +static void noisi_dsp(t_nois *x, t_signal **sp){ + dsp_add(noisi_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); +} + + +static void noisi_helper(void){ + post("\n%c noisi~\t:: a bandlimited interpolating pseudo-noise generator", HEARTSYMBOL); + post("\t : sampling-frequency (in Hz)\n" + "'help'\t : view this"); + post("creation : \"noisi~ []\"\t: ('0'(default) will produce 'white' noise)\n"); + post("note\t : the seed of the pseudo-noise generator changes from\n" + "\t instance to instance, so two noisi~-objects created at the\n" + "\t same time will produce different signals, something the original\n" + "\t noise~-object misses\n"); + post("for further details see DODGE/JERSE \"computer music\" c3.9\n"); +} + +static void *noisi_new(t_floatarg f){ + t_nois *x = (t_nois *)pd_new(noisi_class); + + static int init = 4259; + x->val = (init *= 17); + + set_noisfreq (x, f); + + outlet_new(&x->x_obj, gensym("signal")); + return (x); +} + +void noisi_tilde_setup(void){ + noisi_class = class_new(gensym("noisi~"), (t_newmethod)noisi_new, 0, sizeof(t_nois), 0, A_DEFFLOAT, 0); + + class_addfloat(noisi_class, set_noisfreq); + class_addmethod(noisi_class, (t_method)noisi_dsp, gensym("dsp"), 0); + + class_addmethod(noisi_class, (t_method)noisi_helper, gensym("help"), 0); + class_sethelpsymbol(noisi_class, gensym("zexy/noisi~")); +} diff --git a/src/pack_tilde.c b/src/pack_tilde.c deleted file mode 100644 index ca762c9..0000000 --- a/src/pack_tilde.c +++ /dev/null @@ -1,86 +0,0 @@ -/****************************************************** - * - * zexy - implementation file - * - * copyleft (c) IOhannes m zmölnig - * - * 1999:forum::für::umläute:2004 - * - * institute of electronic music and acoustics (iem) - * - ****************************************************** - * - * license: GNU General Public License v.2 - * - ******************************************************/ - -#include "zexy.h" - - -/* ------------------------ pack~ ----------------------------- */ -/* pack the signal-vector to a float-package */ - -static t_class *sigpack_class; - -typedef struct _sigpack -{ - t_object x_obj; - - int vector_length; - t_atom *buffer; - -} t_sigpack; - -static t_int *sigpack_perform(t_int *w) -{ - t_float *in = (t_float *)(w[1]); - t_sigpack *x = (t_sigpack *)w[2]; - int n = (int)(w[3]), i = 0; - t_atom *buf = x->buffer; - - while (n--) { - SETFLOAT(&buf[i], *in++); - i++; - } - outlet_list(x->x_obj.ob_outlet, &s_list, x->vector_length, x->buffer); - - return (w+4); -} - -static void sigpack_dsp(t_sigpack *x, t_signal **sp) -{ - if (x->vector_length != sp[0]->s_n) { - freebytes(x->buffer, x->vector_length * sizeof(t_atom)); - x->vector_length = sp[0]->s_n; - x->buffer = (t_atom *)getbytes(x->vector_length * sizeof(t_atom)); - } - dsp_add(sigpack_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); -} - -static void *sigpack_new(void) -{ - t_sigpack *x = (t_sigpack *)pd_new(sigpack_class); - x->vector_length = 0; - x->buffer = 0; - outlet_new(&x->x_obj, gensym("list")); - - return (x); -} - -static void sigpack_help(void) -{ - post("pack~\t:: outputs the signal-vectors as float-packages"); -} - -void pack_tilde_setup(void) -{ - sigpack_class = class_new(gensym("pack~"), (t_newmethod)sigpack_new, 0, - sizeof(t_sigpack), 0, A_DEFFLOAT, 0); - class_addmethod(sigpack_class, nullfn, gensym("signal"), 0); - class_addmethod(sigpack_class, (t_method)sigpack_dsp, gensym("dsp"), 0); - - class_addmethod(sigpack_class, (t_method)sigpack_help, gensym("help"), 0); - class_sethelpsymbol(sigpack_class, gensym("zexy/pack~")); - - zexy_register("pack~"); -} diff --git a/src/pack~.c b/src/pack~.c new file mode 100644 index 0000000..ca762c9 --- /dev/null +++ b/src/pack~.c @@ -0,0 +1,86 @@ +/****************************************************** + * + * zexy - implementation file + * + * copyleft (c) IOhannes m zmölnig + * + * 1999:forum::für::umläute:2004 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + * + ******************************************************/ + +#include "zexy.h" + + +/* ------------------------ pack~ ----------------------------- */ +/* pack the signal-vector to a float-package */ + +static t_class *sigpack_class; + +typedef struct _sigpack +{ + t_object x_obj; + + int vector_length; + t_atom *buffer; + +} t_sigpack; + +static t_int *sigpack_perform(t_int *w) +{ + t_float *in = (t_float *)(w[1]); + t_sigpack *x = (t_sigpack *)w[2]; + int n = (int)(w[3]), i = 0; + t_atom *buf = x->buffer; + + while (n--) { + SETFLOAT(&buf[i], *in++); + i++; + } + outlet_list(x->x_obj.ob_outlet, &s_list, x->vector_length, x->buffer); + + return (w+4); +} + +static void sigpack_dsp(t_sigpack *x, t_signal **sp) +{ + if (x->vector_length != sp[0]->s_n) { + freebytes(x->buffer, x->vector_length * sizeof(t_atom)); + x->vector_length = sp[0]->s_n; + x->buffer = (t_atom *)getbytes(x->vector_length * sizeof(t_atom)); + } + dsp_add(sigpack_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); +} + +static void *sigpack_new(void) +{ + t_sigpack *x = (t_sigpack *)pd_new(sigpack_class); + x->vector_length = 0; + x->buffer = 0; + outlet_new(&x->x_obj, gensym("list")); + + return (x); +} + +static void sigpack_help(void) +{ + post("pack~\t:: outputs the signal-vectors as float-packages"); +} + +void pack_tilde_setup(void) +{ + sigpack_class = class_new(gensym("pack~"), (t_newmethod)sigpack_new, 0, + sizeof(t_sigpack), 0, A_DEFFLOAT, 0); + class_addmethod(sigpack_class, nullfn, gensym("signal"), 0); + class_addmethod(sigpack_class, (t_method)sigpack_dsp, gensym("dsp"), 0); + + class_addmethod(sigpack_class, (t_method)sigpack_help, gensym("help"), 0); + class_sethelpsymbol(sigpack_class, gensym("zexy/pack~")); + + zexy_register("pack~"); +} diff --git a/src/pdf_tilde.c b/src/pdf_tilde.c deleted file mode 100644 index ef06a59..0000000 --- a/src/pdf_tilde.c +++ /dev/null @@ -1,140 +0,0 @@ -/****************************************************** - * - * zexy - implementation file - * - * copyleft (c) IOhannes m zmölnig - * - * 1999:forum::für::umläute:2004 - * - * institute of electronic music and acoustics (iem) - * - ****************************************************** - * - * license: GNU General Public License v.2 - * - ******************************************************/ - -/* get the ProbabilityDensityFunction of a signal */ - -#include "zexy.h" - -/* ------------------------ pdf~ ----------------------------- */ - -static t_class *pdf_class; - -typedef struct _pdf -{ - t_object x_obj; - - t_float *buf; - int size; - t_float halfsize; -} t_pdf; - -static void clear_pdfbuf(t_pdf *x) -{ - int n = x->size; - t_float *buf = x->buf; - - while (n--) *buf++=0.; -} - -static void pdf_bang(t_pdf *x) -{ - int n = x->size; - t_float *buf = x->buf, max = 0; - t_atom a[2]; - - while (n--) if (max < *buf++) max = buf[-1]; - - n=x->size; - buf = x->buf; - - if (max==0.) max=1.; - max = 1./max; - - while (n--) - { - SETFLOAT(a, *buf++*max); - SETFLOAT(a+1,x->size-n-1); - outlet_list(x->x_obj.ob_outlet, &s_list, 2, (t_atom*)&a); - } -} - -static void pdf_float(t_pdf *x, t_floatarg f) -{ - if (f) pdf_bang(x); else clear_pdfbuf(x); -} - -static t_int *pdf_perform(t_int *w) -{ - t_float *in = (t_float *)(w[1]); - t_pdf *x = (t_pdf *)(w[2]); - int n = (int)(w[3]); - - t_float *buf = x->buf; - t_float halfsize = x->halfsize; - - while (n--) - { - t_float f = *in++; - int iindex = ((f + 1.0) * halfsize)+0.5; - buf[(iindex<0)?0:((iindex>=x->size)?x->size-1:iindex)]+=1.; - } - return (w+4); -} - -static void pdf_dsp(t_pdf *x, t_signal **sp) -{ - x->halfsize = (x->size - 1) / 2.0; - - dsp_add(pdf_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); -} - -static void *pdf_new(t_floatarg f) -{ - int i = f; - t_pdf *x = (t_pdf *)pd_new(pdf_class); - t_float *buf; - - x->size = (i)?i:64; - x->buf = (t_float *)getbytes(x->size * sizeof(t_float)); - buf = x->buf; - clear_pdfbuf(x); - - outlet_new(&x->x_obj, &s_list); - - return (x); -} - -static void pdf_free(t_pdf *x) -{ - freebytes(x->buf, x->size*sizeof(t_float)); -} - -static void helper(void) -{ - post("\n%c pdf~\t:: get the probability density function of a signal (-1.0 to +1.0)", HEARTSYMBOL); - post("'bang'\t : output a list of the probabilities of 'n' function values" - "\n'clear'\t : clear the buffer (set all probabilities to zero)" - "\n<1/0>\t : short for 'bang' and 'clear'" - "\n'help'\t : view this"); - post("creation :: 'pdf~ []':: get the pdf for (default: 64) values"); -} - -void pdf_tilde_setup(void) -{ - pdf_class = class_new(gensym("pdf~"), (t_newmethod)pdf_new, (t_method)pdf_free, - sizeof(t_pdf), 0, A_DEFFLOAT, 0); - - class_addmethod(pdf_class, nullfn, gensym("signal"), 0); - class_addmethod(pdf_class, (t_method)pdf_dsp, gensym("dsp"), 0); - - class_addmethod(pdf_class, (t_method)pdf_bang, gensym("bang"), 0); - class_addmethod(pdf_class, (t_method)clear_pdfbuf, gensym("clear"), 0); - class_addfloat(pdf_class, pdf_float); - - class_addmethod(pdf_class, (t_method)helper, gensym("help"), 0); - class_sethelpsymbol(pdf_class, gensym("zexy/pdf~")); - zexy_register("pdf~"); -} diff --git a/src/pdf~.c b/src/pdf~.c new file mode 100644 index 0000000..ef06a59 --- /dev/null +++ b/src/pdf~.c @@ -0,0 +1,140 @@ +/****************************************************** + * + * zexy - implementation file + * + * copyleft (c) IOhannes m zmölnig + * + * 1999:forum::für::umläute:2004 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + * + ******************************************************/ + +/* get the ProbabilityDensityFunction of a signal */ + +#include "zexy.h" + +/* ------------------------ pdf~ ----------------------------- */ + +static t_class *pdf_class; + +typedef struct _pdf +{ + t_object x_obj; + + t_float *buf; + int size; + t_float halfsize; +} t_pdf; + +static void clear_pdfbuf(t_pdf *x) +{ + int n = x->size; + t_float *buf = x->buf; + + while (n--) *buf++=0.; +} + +static void pdf_bang(t_pdf *x) +{ + int n = x->size; + t_float *buf = x->buf, max = 0; + t_atom a[2]; + + while (n--) if (max < *buf++) max = buf[-1]; + + n=x->size; + buf = x->buf; + + if (max==0.) max=1.; + max = 1./max; + + while (n--) + { + SETFLOAT(a, *buf++*max); + SETFLOAT(a+1,x->size-n-1); + outlet_list(x->x_obj.ob_outlet, &s_list, 2, (t_atom*)&a); + } +} + +static void pdf_float(t_pdf *x, t_floatarg f) +{ + if (f) pdf_bang(x); else clear_pdfbuf(x); +} + +static t_int *pdf_perform(t_int *w) +{ + t_float *in = (t_float *)(w[1]); + t_pdf *x = (t_pdf *)(w[2]); + int n = (int)(w[3]); + + t_float *buf = x->buf; + t_float halfsize = x->halfsize; + + while (n--) + { + t_float f = *in++; + int iindex = ((f + 1.0) * halfsize)+0.5; + buf[(iindex<0)?0:((iindex>=x->size)?x->size-1:iindex)]+=1.; + } + return (w+4); +} + +static void pdf_dsp(t_pdf *x, t_signal **sp) +{ + x->halfsize = (x->size - 1) / 2.0; + + dsp_add(pdf_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); +} + +static void *pdf_new(t_floatarg f) +{ + int i = f; + t_pdf *x = (t_pdf *)pd_new(pdf_class); + t_float *buf; + + x->size = (i)?i:64; + x->buf = (t_float *)getbytes(x->size * sizeof(t_float)); + buf = x->buf; + clear_pdfbuf(x); + + outlet_new(&x->x_obj, &s_list); + + return (x); +} + +static void pdf_free(t_pdf *x) +{ + freebytes(x->buf, x->size*sizeof(t_float)); +} + +static void helper(void) +{ + post("\n%c pdf~\t:: get the probability density function of a signal (-1.0 to +1.0)", HEARTSYMBOL); + post("'bang'\t : output a list of the probabilities of 'n' function values" + "\n'clear'\t : clear the buffer (set all probabilities to zero)" + "\n<1/0>\t : short for 'bang' and 'clear'" + "\n'help'\t : view this"); + post("creation :: 'pdf~ []':: get the pdf for (default: 64) values"); +} + +void pdf_tilde_setup(void) +{ + pdf_class = class_new(gensym("pdf~"), (t_newmethod)pdf_new, (t_method)pdf_free, + sizeof(t_pdf), 0, A_DEFFLOAT, 0); + + class_addmethod(pdf_class, nullfn, gensym("signal"), 0); + class_addmethod(pdf_class, (t_method)pdf_dsp, gensym("dsp"), 0); + + class_addmethod(pdf_class, (t_method)pdf_bang, gensym("bang"), 0); + class_addmethod(pdf_class, (t_method)clear_pdfbuf, gensym("clear"), 0); + class_addfloat(pdf_class, pdf_float); + + class_addmethod(pdf_class, (t_method)helper, gensym("help"), 0); + class_sethelpsymbol(pdf_class, gensym("zexy/pdf~")); + zexy_register("pdf~"); +} diff --git a/src/quantize_tilde.c b/src/quantize_tilde.c deleted file mode 100644 index 15190e6..0000000 --- a/src/quantize_tilde.c +++ /dev/null @@ -1,113 +0,0 @@ -/****************************************************** - * - * zexy - implementation file - * - * copyleft (c) IOhannes m zmölnig - * - * 1999:forum::für::umläute:2004 - * - * institute of electronic music and acoustics (iem) - * - ****************************************************** - * - * license: GNU General Public License v.2 - * - ******************************************************/ - - -/* - the long waited for quantize~-object that quantizes in many possible (but equal) steps - of course, we´ll make a comfortable quantize of the float-signal for 16bit and 8bit - - 1110:forum::für::umläute:1999 -*/ - -#include "zexy.h" - -/* ------------------------ quantize~ ----------------------------- */ - -static t_class *quantize_class; - -typedef struct _quantize -{ - t_object x_obj; - t_float quantiz, dequantiz; -} t_quantize; - -static void quantize_float(t_quantize *x, t_floatarg f) -{ - x->quantiz = f; - x->dequantiz = 1./f; -} - -static void quantize_16bit(t_quantize *x) -{ - x->quantiz = 32768.; - x->dequantiz = 1./32768.; -} - -static void quantize_8bit(t_quantize *x) -{ - x->quantiz = 128.; - x->dequantiz = 1./128.; -} - -static t_int *quantize_perform(t_int *w) -{ - t_quantize *x = (t_quantize *)(w[1]); - t_float *in = (t_float *)(w[2]); - t_float *out = (t_float *)(w[3]); - int n = (int)(w[4]); - - t_float quantiz = x->quantiz, dequantiz = x->dequantiz; - - if (quantiz) - while (n--) *out++ = dequantiz*(int)(quantiz**in++); - else while (n--) *out++ = *in++; - - return (w+5); -} - -static void quantize_dsp(t_quantize *x, t_signal **sp) -{ - dsp_add(quantize_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); -} - -static void helper(t_quantize *x) -{ - post("%c quantize~-object\t:: used for quantizing signals by various degrees", HEARTSYMBOL); - post(" : quantize a signal into steps ('0' turns quantizing off)\n" - "'8bit' : quantize to 8 bit\n" - "'16bit' : quantize to 16 bit (default)\n" - "'float' : pass-through the signal unchanged\n" - "'help' : view this\n" - "signal~\n"); - post("creation:: \"quantize~ []\""); - -} - -static void *quantize_new(t_floatarg f) -{ - t_quantize *x = (t_quantize *)pd_new(quantize_class); - outlet_new(&x->x_obj, gensym("signal")); - if (f) quantize_float(x, f); - else quantize_16bit(x); - - return (x); -} - -void quantize_tilde_setup(void) -{ - quantize_class = class_new(gensym("quantize~"), (t_newmethod)quantize_new, 0, - sizeof(t_quantize), 0, A_DEFFLOAT, 0); - class_addmethod(quantize_class, nullfn, gensym("signal"), 0); - class_addmethod(quantize_class, (t_method)quantize_dsp, gensym("dsp"), 0); - - class_addfloat(quantize_class, quantize_float); - class_addmethod(quantize_class, (t_method)quantize_8bit, gensym("8bit"), 0); - class_addmethod(quantize_class, (t_method)quantize_16bit, gensym("16bit"), 0); - - class_addmethod(quantize_class, (t_method)helper, gensym("help"), 0); - class_sethelpsymbol(quantize_class, gensym("zexy/quantize~")); - zexy_register("quantize~"); -} diff --git a/src/quantize~.c b/src/quantize~.c new file mode 100644 index 0000000..15190e6 --- /dev/null +++ b/src/quantize~.c @@ -0,0 +1,113 @@ +/****************************************************** + * + * zexy - implementation file + * + * copyleft (c) IOhannes m zmölnig + * + * 1999:forum::für::umläute:2004 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + * + ******************************************************/ + + +/* + the long waited for quantize~-object that quantizes in many possible (but equal) steps + of course, we´ll make a comfortable quantize of the float-signal for 16bit and 8bit + + 1110:forum::für::umläute:1999 +*/ + +#include "zexy.h" + +/* ------------------------ quantize~ ----------------------------- */ + +static t_class *quantize_class; + +typedef struct _quantize +{ + t_object x_obj; + t_float quantiz, dequantiz; +} t_quantize; + +static void quantize_float(t_quantize *x, t_floatarg f) +{ + x->quantiz = f; + x->dequantiz = 1./f; +} + +static void quantize_16bit(t_quantize *x) +{ + x->quantiz = 32768.; + x->dequantiz = 1./32768.; +} + +static void quantize_8bit(t_quantize *x) +{ + x->quantiz = 128.; + x->dequantiz = 1./128.; +} + +static t_int *quantize_perform(t_int *w) +{ + t_quantize *x = (t_quantize *)(w[1]); + t_float *in = (t_float *)(w[2]); + t_float *out = (t_float *)(w[3]); + int n = (int)(w[4]); + + t_float quantiz = x->quantiz, dequantiz = x->dequantiz; + + if (quantiz) + while (n--) *out++ = dequantiz*(int)(quantiz**in++); + else while (n--) *out++ = *in++; + + return (w+5); +} + +static void quantize_dsp(t_quantize *x, t_signal **sp) +{ + dsp_add(quantize_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); +} + +static void helper(t_quantize *x) +{ + post("%c quantize~-object\t:: used for quantizing signals by various degrees", HEARTSYMBOL); + post(" : quantize a signal into steps ('0' turns quantizing off)\n" + "'8bit' : quantize to 8 bit\n" + "'16bit' : quantize to 16 bit (default)\n" + "'float' : pass-through the signal unchanged\n" + "'help' : view this\n" + "signal~\n"); + post("creation:: \"quantize~ []\""); + +} + +static void *quantize_new(t_floatarg f) +{ + t_quantize *x = (t_quantize *)pd_new(quantize_class); + outlet_new(&x->x_obj, gensym("signal")); + if (f) quantize_float(x, f); + else quantize_16bit(x); + + return (x); +} + +void quantize_tilde_setup(void) +{ + quantize_class = class_new(gensym("quantize~"), (t_newmethod)quantize_new, 0, + sizeof(t_quantize), 0, A_DEFFLOAT, 0); + class_addmethod(quantize_class, nullfn, gensym("signal"), 0); + class_addmethod(quantize_class, (t_method)quantize_dsp, gensym("dsp"), 0); + + class_addfloat(quantize_class, quantize_float); + class_addmethod(quantize_class, (t_method)quantize_8bit, gensym("8bit"), 0); + class_addmethod(quantize_class, (t_method)quantize_16bit, gensym("16bit"), 0); + + class_addmethod(quantize_class, (t_method)helper, gensym("help"), 0); + class_sethelpsymbol(quantize_class, gensym("zexy/quantize~")); + zexy_register("quantize~"); +} diff --git a/src/sigzero_tilde.c b/src/sigzero_tilde.c deleted file mode 100644 index de9584d..0000000 --- a/src/sigzero_tilde.c +++ /dev/null @@ -1,111 +0,0 @@ -/****************************************************** - * - * zexy - implementation file - * - * copyleft (c) IOhannes m zmölnig - * - * 1999:forum::für::umläute:2004 - * - * institute of electronic music and acoustics (iem) - * - ****************************************************** - * - * license: GNU General Public License v.2 - ******************************************************/ - -/* ------------------------ sigzero~ ----------------------------- */ -/* - a very useful function, which detects, whether a signal is zeroes-only this block or not - this is really great together with the "switch~"-object -*/ - -#include "zexy.h" - - -static t_class *sigzero_class; - -typedef struct _sigzero -{ - t_object x_obj; - int activate; - int current; /* 0 == (signalblock == 0); 1==(signalblock != 0) */ -} t_sigzero; - -static void sigzero_activate(t_sigzero *x, t_floatarg activate) -{ - x->activate = (activate)?1:0; -} - -static void sigzero_banged(t_sigzero *x, t_floatarg activate) -{ - x->activate = 1; -} - -static void sigzero_off(t_sigzero *x, t_floatarg activate) -{ - x->activate = 0; -} - -static t_int *sigzero_perform(t_int *w) -{ - t_float *in = (t_float *)w[1]; - t_sigzero *x = (t_sigzero *)w[2]; - int n = (int)w[3]; - - int non_zero = 0; - - if (x->activate) { - while (n--) - { - if (*in++ != 0.) { - non_zero = 1; - break; - } - } - if (non_zero != x->current) { - outlet_float(x->x_obj.ob_outlet, x->current = non_zero); - } -// else post("non_zero=%d\tcurrent=%d", non_zero, x->current); - } - - return (w+4); -} - -static void sigzero_dsp(t_sigzero *x, t_signal **sp) -{ - dsp_add(sigzero_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); -} - -static void helper(void) -{ - post("\n%c sigzero~-object :: for detecting whether a signal is currently zero or not", HEARTSYMBOL); - post("'bang'\t: turn the detector on\n" - "'off'\t: turn it off\n" - "<1/0>\t: turn it on/off\n" - "'help'\t: view this\n" - "signal~"); - post("outlet :: 1/0\t: signal turned to non-zero/zero\n"); -} - -static void *sigzero_new(t_symbol s) -{ - t_sigzero *x = (t_sigzero *)pd_new(sigzero_class); - outlet_new(&x->x_obj, &s_float); - return (x); -} - -void sigzero_tilde_setup(void) -{ - sigzero_class = class_new(gensym("sigzero~"), (t_newmethod)sigzero_new, 0, - sizeof(t_sigzero), 0, 0); - class_addfloat(sigzero_class, sigzero_activate); - class_addbang(sigzero_class, sigzero_banged); - class_addmethod(sigzero_class, (t_method)sigzero_off, gensym("off"), 0); - - class_addmethod(sigzero_class, nullfn, gensym("signal"), 0); - class_addmethod(sigzero_class, (t_method)sigzero_dsp, gensym("dsp"), 0); - - class_addmethod(sigzero_class, (t_method)helper, gensym("help"), 0); - class_sethelpsymbol(sigzero_class, gensym("zexy/sigzero~")); - zexy_register("sigzero~"); -} diff --git a/src/sigzero~.c b/src/sigzero~.c new file mode 100644 index 0000000..de9584d --- /dev/null +++ b/src/sigzero~.c @@ -0,0 +1,111 @@ +/****************************************************** + * + * zexy - implementation file + * + * copyleft (c) IOhannes m zmölnig + * + * 1999:forum::für::umläute:2004 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + ******************************************************/ + +/* ------------------------ sigzero~ ----------------------------- */ +/* + a very useful function, which detects, whether a signal is zeroes-only this block or not + this is really great together with the "switch~"-object +*/ + +#include "zexy.h" + + +static t_class *sigzero_class; + +typedef struct _sigzero +{ + t_object x_obj; + int activate; + int current; /* 0 == (signalblock == 0); 1==(signalblock != 0) */ +} t_sigzero; + +static void sigzero_activate(t_sigzero *x, t_floatarg activate) +{ + x->activate = (activate)?1:0; +} + +static void sigzero_banged(t_sigzero *x, t_floatarg activate) +{ + x->activate = 1; +} + +static void sigzero_off(t_sigzero *x, t_floatarg activate) +{ + x->activate = 0; +} + +static t_int *sigzero_perform(t_int *w) +{ + t_float *in = (t_float *)w[1]; + t_sigzero *x = (t_sigzero *)w[2]; + int n = (int)w[3]; + + int non_zero = 0; + + if (x->activate) { + while (n--) + { + if (*in++ != 0.) { + non_zero = 1; + break; + } + } + if (non_zero != x->current) { + outlet_float(x->x_obj.ob_outlet, x->current = non_zero); + } +// else post("non_zero=%d\tcurrent=%d", non_zero, x->current); + } + + return (w+4); +} + +static void sigzero_dsp(t_sigzero *x, t_signal **sp) +{ + dsp_add(sigzero_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); +} + +static void helper(void) +{ + post("\n%c sigzero~-object :: for detecting whether a signal is currently zero or not", HEARTSYMBOL); + post("'bang'\t: turn the detector on\n" + "'off'\t: turn it off\n" + "<1/0>\t: turn it on/off\n" + "'help'\t: view this\n" + "signal~"); + post("outlet :: 1/0\t: signal turned to non-zero/zero\n"); +} + +static void *sigzero_new(t_symbol s) +{ + t_sigzero *x = (t_sigzero *)pd_new(sigzero_class); + outlet_new(&x->x_obj, &s_float); + return (x); +} + +void sigzero_tilde_setup(void) +{ + sigzero_class = class_new(gensym("sigzero~"), (t_newmethod)sigzero_new, 0, + sizeof(t_sigzero), 0, 0); + class_addfloat(sigzero_class, sigzero_activate); + class_addbang(sigzero_class, sigzero_banged); + class_addmethod(sigzero_class, (t_method)sigzero_off, gensym("off"), 0); + + class_addmethod(sigzero_class, nullfn, gensym("signal"), 0); + class_addmethod(sigzero_class, (t_method)sigzero_dsp, gensym("dsp"), 0); + + class_addmethod(sigzero_class, (t_method)helper, gensym("help"), 0); + class_sethelpsymbol(sigzero_class, gensym("zexy/sigzero~")); + zexy_register("sigzero~"); +} diff --git a/src/step_tilde.c b/src/step_tilde.c deleted file mode 100644 index f1200e7..0000000 --- a/src/step_tilde.c +++ /dev/null @@ -1,141 +0,0 @@ -/****************************************************** - * - * zexy - implementation file - * - * copyleft (c) IOhannes m zmölnig - * - * 1999:forum::für::umläute:2004 - * - * institute of electronic music and acoustics (iem) - * - ****************************************************** - * - * license: GNU General Public License v.2 - ******************************************************/ - -/* -step~ : will make a unity step at a desired point in the signal-vector; the second input specifies a - length: after the so-specified time has elapsed, the step will toggle back to the previous - value; - the length can be passed as an argument when creating the object - with length==1 you might do the dirac~ thing a little bit more complicated - with length==0 the output just toggles between 0 and 1 every time you bang the object - -NOTE : the inlets do NOT specify any times but sample-NUMBERS; there are 64 samples in a signal-vector, - each "lasting" for 1/44100 secs. -*/ - -#include "zexy.h" - -/* ------------------------ step~ ----------------------------- */ - -static t_class *step_class; - -typedef struct _step -{ - t_object x_obj; - int position; - int length; - - int toggle; - - int wait4start; - int wait4stop; -} t_step; - -static void step_bang(t_step *x) -{ - x->wait4stop = x->length + (x->wait4start = x->position); -} - -static void step_float(t_step *x, t_float where) -{ - x->wait4stop = x->length + - (x->wait4start = - (x->position = (where>0)*where) - ); -} - -static void step_setlength(t_step *x, t_float arg) -{ - x->length = 1 + (arg>0)*arg; -} - - - -static t_int *step_perform(t_int *w) -{ - t_step *x = (t_step *)(w[1]); - t_float *out = (t_float *)(w[2]); - int n = (int)(w[3]); - - int toggle = x->toggle; - - int wait4start = x->wait4start, wait4stop = x->wait4stop; - - while (n--) - { - wait4stop--; - if (!wait4start--) toggle ^= 1; - else if (!wait4stop) toggle ^= 1; - - *out++ = toggle; - } - - x->wait4start = wait4start; - x->wait4stop = wait4stop; - - x->toggle = toggle; - return (w+4); -} - -static void step_dsp(t_step *x, t_signal **sp) -{ - dsp_add(step_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); -} - - -static void step_helper(void) -{ - post("%c step~-object :: generates a unity-step", HEARTSYMBOL); - post("creation : \"dirac~ [ []]\" : create a rectangular window\n" - "\t\t\tat specified position and with specified length (in samples)\n" - "inlet1\t: \t: create a rectangular window at new position\n" - "\t 'bang'\t: create a rectangular window at specified position\n" - "\t 'help'\t: view this\n" - "inlet2\t: \t: define new window length ('0' will make a unity-step)\n" - "outlet\t: signal~"); -} - - -static void *step_new(t_floatarg farg) -{ - t_step *x = (t_step *)pd_new(step_class); - - inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1")); - outlet_new(&x->x_obj, gensym("signal")); - - x->position = 0; - x->wait4start = x->wait4stop = 0; - x->toggle = 1; - - step_setlength(x, farg); - - return (x); -} - -void step_tilde_setup(void) -{ - step_class = class_new(gensym("step~"), (t_newmethod)step_new, 0, - sizeof(t_step), 0, A_DEFFLOAT, 0); - - class_addfloat(step_class, step_float); - class_addbang(step_class, step_bang); - class_addmethod(step_class, (t_method)step_setlength, gensym("ft1"), A_FLOAT, 0); - class_addmethod(step_class, (t_method)step_dsp, gensym("dsp"), 0); - - class_addmethod(step_class, (t_method)step_helper, gensym("help"), 0); - class_sethelpsymbol(step_class, gensym("zexy/step~")); - - zexy_register("step~"); -} diff --git a/src/step~.c b/src/step~.c new file mode 100644 index 0000000..f1200e7 --- /dev/null +++ b/src/step~.c @@ -0,0 +1,141 @@ +/****************************************************** + * + * zexy - implementation file + * + * copyleft (c) IOhannes m zmölnig + * + * 1999:forum::für::umläute:2004 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + ******************************************************/ + +/* +step~ : will make a unity step at a desired point in the signal-vector; the second input specifies a + length: after the so-specified time has elapsed, the step will toggle back to the previous + value; + the length can be passed as an argument when creating the object + with length==1 you might do the dirac~ thing a little bit more complicated + with length==0 the output just toggles between 0 and 1 every time you bang the object + +NOTE : the inlets do NOT specify any times but sample-NUMBERS; there are 64 samples in a signal-vector, + each "lasting" for 1/44100 secs. +*/ + +#include "zexy.h" + +/* ------------------------ step~ ----------------------------- */ + +static t_class *step_class; + +typedef struct _step +{ + t_object x_obj; + int position; + int length; + + int toggle; + + int wait4start; + int wait4stop; +} t_step; + +static void step_bang(t_step *x) +{ + x->wait4stop = x->length + (x->wait4start = x->position); +} + +static void step_float(t_step *x, t_float where) +{ + x->wait4stop = x->length + + (x->wait4start = + (x->position = (where>0)*where) + ); +} + +static void step_setlength(t_step *x, t_float arg) +{ + x->length = 1 + (arg>0)*arg; +} + + + +static t_int *step_perform(t_int *w) +{ + t_step *x = (t_step *)(w[1]); + t_float *out = (t_float *)(w[2]); + int n = (int)(w[3]); + + int toggle = x->toggle; + + int wait4start = x->wait4start, wait4stop = x->wait4stop; + + while (n--) + { + wait4stop--; + if (!wait4start--) toggle ^= 1; + else if (!wait4stop) toggle ^= 1; + + *out++ = toggle; + } + + x->wait4start = wait4start; + x->wait4stop = wait4stop; + + x->toggle = toggle; + return (w+4); +} + +static void step_dsp(t_step *x, t_signal **sp) +{ + dsp_add(step_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); +} + + +static void step_helper(void) +{ + post("%c step~-object :: generates a unity-step", HEARTSYMBOL); + post("creation : \"dirac~ [ []]\" : create a rectangular window\n" + "\t\t\tat specified position and with specified length (in samples)\n" + "inlet1\t: \t: create a rectangular window at new position\n" + "\t 'bang'\t: create a rectangular window at specified position\n" + "\t 'help'\t: view this\n" + "inlet2\t: \t: define new window length ('0' will make a unity-step)\n" + "outlet\t: signal~"); +} + + +static void *step_new(t_floatarg farg) +{ + t_step *x = (t_step *)pd_new(step_class); + + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1")); + outlet_new(&x->x_obj, gensym("signal")); + + x->position = 0; + x->wait4start = x->wait4stop = 0; + x->toggle = 1; + + step_setlength(x, farg); + + return (x); +} + +void step_tilde_setup(void) +{ + step_class = class_new(gensym("step~"), (t_newmethod)step_new, 0, + sizeof(t_step), 0, A_DEFFLOAT, 0); + + class_addfloat(step_class, step_float); + class_addbang(step_class, step_bang); + class_addmethod(step_class, (t_method)step_setlength, gensym("ft1"), A_FLOAT, 0); + class_addmethod(step_class, (t_method)step_dsp, gensym("dsp"), 0); + + class_addmethod(step_class, (t_method)step_helper, gensym("help"), 0); + class_sethelpsymbol(step_class, gensym("zexy/step~")); + + zexy_register("step~"); +} diff --git a/src/swap_tilde.c b/src/swap_tilde.c deleted file mode 100644 index 9f14310..0000000 --- a/src/swap_tilde.c +++ /dev/null @@ -1,101 +0,0 @@ -/****************************************************** - * - * zexy - implementation file - * - * copyleft (c) IOhannes m zmölnig - * - * 1999:forum::für::umläute:2004 - * - * institute of electronic music and acoustics (iem) - * - ****************************************************** - * - * license: GNU General Public License v.2 - ******************************************************/ - -/* - the long waited for swap~-object that does a byte swap - of course, we unfortunately have to quantize the float-signal to 16bit (to get bytes) - - 1110:forum::für::umläute:1999 -*/ - -#include "zexy.h" - -/* ------------------------ swap~ ----------------------------- */ -#define FLOAT2SHORT 32768. -#define SHORT2FLOAT 1./32768. - -static t_class *swap_class; - -typedef struct _swap -{ - t_object x_obj; - int swapper; -} t_swap; - -static void swap_float(t_swap *x, t_floatarg f) -{ - x->swapper = (f != 0); -} - -static void swap_bang(t_swap *x) -{ - x->swapper ^= 1; -} - -static t_int *swap_perform(t_int *w) -{ - t_swap *x = (t_swap *)(w[1]); - t_float *in = (t_float *)(w[2]); - t_float *out = (t_float *)(w[3]); - int n = (int)(w[4]); - - - if (x->swapper) - while (n--) { - short dummy = FLOAT2SHORT * *in++; - *out++ = SHORT2FLOAT * (short)( ((dummy & 0xFF) << 8) | ((dummy & 0xFF00) >> 8) ); - } - else while (n--) *out++ = *in++; - - return (w+5); -} - -static void swap_dsp(t_swap *x, t_signal **sp) -{ - dsp_add(swap_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); -} - -static void swap_helper(void) -{ - post("\n%c swap~-object for byteswapping a signal", HEARTSYMBOL); - post("<1/0> : turn the swapper on/off\n" - "'bang' : toggle the swapper on/off\n" - "'help' : view this\n" - "signal~"); - post("outlet : signal~"); -} - -static void *swap_new(void) -{ - t_swap *x = (t_swap *)pd_new(swap_class); - outlet_new(&x->x_obj, gensym("signal")); - x->swapper = 1; - return (x); -} - -void swap_tilde_setup(void) -{ - swap_class = class_new(gensym("swap~"), (t_newmethod)swap_new, 0, - sizeof(t_swap), 0, A_NULL); - class_addmethod(swap_class, nullfn, gensym("signal"), 0); - class_addmethod(swap_class, (t_method)swap_dsp, gensym("dsp"), 0); - - class_addfloat(swap_class, swap_float); - class_addbang(swap_class, swap_bang); - - class_addmethod(swap_class, (t_method)swap_helper, gensym("help"), 0); - class_sethelpsymbol(swap_class, gensym("zexy/swap~")); - zexy_register("swap~"); -} diff --git a/src/swap~.c b/src/swap~.c new file mode 100644 index 0000000..9f14310 --- /dev/null +++ b/src/swap~.c @@ -0,0 +1,101 @@ +/****************************************************** + * + * zexy - implementation file + * + * copyleft (c) IOhannes m zmölnig + * + * 1999:forum::für::umläute:2004 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + ******************************************************/ + +/* + the long waited for swap~-object that does a byte swap + of course, we unfortunately have to quantize the float-signal to 16bit (to get bytes) + + 1110:forum::für::umläute:1999 +*/ + +#include "zexy.h" + +/* ------------------------ swap~ ----------------------------- */ +#define FLOAT2SHORT 32768. +#define SHORT2FLOAT 1./32768. + +static t_class *swap_class; + +typedef struct _swap +{ + t_object x_obj; + int swapper; +} t_swap; + +static void swap_float(t_swap *x, t_floatarg f) +{ + x->swapper = (f != 0); +} + +static void swap_bang(t_swap *x) +{ + x->swapper ^= 1; +} + +static t_int *swap_perform(t_int *w) +{ + t_swap *x = (t_swap *)(w[1]); + t_float *in = (t_float *)(w[2]); + t_float *out = (t_float *)(w[3]); + int n = (int)(w[4]); + + + if (x->swapper) + while (n--) { + short dummy = FLOAT2SHORT * *in++; + *out++ = SHORT2FLOAT * (short)( ((dummy & 0xFF) << 8) | ((dummy & 0xFF00) >> 8) ); + } + else while (n--) *out++ = *in++; + + return (w+5); +} + +static void swap_dsp(t_swap *x, t_signal **sp) +{ + dsp_add(swap_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); +} + +static void swap_helper(void) +{ + post("\n%c swap~-object for byteswapping a signal", HEARTSYMBOL); + post("<1/0> : turn the swapper on/off\n" + "'bang' : toggle the swapper on/off\n" + "'help' : view this\n" + "signal~"); + post("outlet : signal~"); +} + +static void *swap_new(void) +{ + t_swap *x = (t_swap *)pd_new(swap_class); + outlet_new(&x->x_obj, gensym("signal")); + x->swapper = 1; + return (x); +} + +void swap_tilde_setup(void) +{ + swap_class = class_new(gensym("swap~"), (t_newmethod)swap_new, 0, + sizeof(t_swap), 0, A_NULL); + class_addmethod(swap_class, nullfn, gensym("signal"), 0); + class_addmethod(swap_class, (t_method)swap_dsp, gensym("dsp"), 0); + + class_addfloat(swap_class, swap_float); + class_addbang(swap_class, swap_bang); + + class_addmethod(swap_class, (t_method)swap_helper, gensym("help"), 0); + class_sethelpsymbol(swap_class, gensym("zexy/swap~")); + zexy_register("swap~"); +} diff --git a/src/tavg_tilde.c b/src/tavg_tilde.c deleted file mode 100644 index cddbd41..0000000 --- a/src/tavg_tilde.c +++ /dev/null @@ -1,99 +0,0 @@ -/****************************************************** - * - * zexy - implementation file - * - * copyleft (c) IOhannes m zmölnig - * - * 1999:forum::für::umläute:2004 - * - * institute of electronic music and acoustics (iem) - * - ****************************************************** - * - * license: GNU General Public License v.2 - * - ******************************************************/ - -#include "zexy.h" -#include - -#ifdef NT -#define sqrtf sqrt -#endif - -#ifdef MACOSX -#define sqrtf sqrt -#endif - - - -/* triggered average :: arithmetic mean between last and current BANG */ - -static t_class *tavg_class; - -typedef struct _tavg -{ - t_object x_obj; - t_float n_inv; - t_float buf; - int blocks; -} t_tavgtilde; - - -static void tavg_bang(t_tavgtilde *x) -{ - if (x->blocks) { - outlet_float(x->x_obj.ob_outlet, x->buf*x->n_inv/x->blocks); - x->blocks = 0; - x->buf = 0.; - } -} - -static t_int *tavg_perform(t_int *w) -{ - t_float *in = (t_float *)(w[1]); - t_tavgtilde *x = (t_tavgtilde *)w[2]; - int n = (int)(w[3]); - - t_float buf = x->buf; - - while (n--) buf += *in++; - - x->buf = buf; - x->blocks++; - - return (w+4); -} - -static void tavg_dsp(t_tavgtilde *x, t_signal **sp) -{ - x->n_inv=1./sp[0]->s_n; - dsp_add(tavg_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); -} - -static void *tavg_new(void) -{ - t_tavgtilde *x = (t_tavgtilde *)pd_new(tavg_class); - outlet_new(&x->x_obj, gensym("float")); - return (x); -} - -static void tavg_help(void) -{ - post("tavg~\t\t:: outputs the arithmetic mean of a signal when triggered"); - post("\t\t: triggers the output"); -} - -void tavg_tilde_setup(void) -{ - tavg_class = class_new(gensym("tavg~"), (t_newmethod)tavg_new, 0, - sizeof(t_tavgtilde), 0, A_DEFFLOAT, 0); - class_addmethod(tavg_class, nullfn, gensym("signal"), 0); - class_addmethod(tavg_class, (t_method)tavg_dsp, gensym("dsp"), 0); - - class_addbang(tavg_class, tavg_bang); - - class_addmethod(tavg_class, (t_method)tavg_help, gensym("help"), 0); - class_sethelpsymbol(tavg_class, gensym("zexy/tavg~")); - zexy_register("tavg~"); -} diff --git a/src/tavg~.c b/src/tavg~.c new file mode 100644 index 0000000..cddbd41 --- /dev/null +++ b/src/tavg~.c @@ -0,0 +1,99 @@ +/****************************************************** + * + * zexy - implementation file + * + * copyleft (c) IOhannes m zmölnig + * + * 1999:forum::für::umläute:2004 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + * + ******************************************************/ + +#include "zexy.h" +#include + +#ifdef NT +#define sqrtf sqrt +#endif + +#ifdef MACOSX +#define sqrtf sqrt +#endif + + + +/* triggered average :: arithmetic mean between last and current BANG */ + +static t_class *tavg_class; + +typedef struct _tavg +{ + t_object x_obj; + t_float n_inv; + t_float buf; + int blocks; +} t_tavgtilde; + + +static void tavg_bang(t_tavgtilde *x) +{ + if (x->blocks) { + outlet_float(x->x_obj.ob_outlet, x->buf*x->n_inv/x->blocks); + x->blocks = 0; + x->buf = 0.; + } +} + +static t_int *tavg_perform(t_int *w) +{ + t_float *in = (t_float *)(w[1]); + t_tavgtilde *x = (t_tavgtilde *)w[2]; + int n = (int)(w[3]); + + t_float buf = x->buf; + + while (n--) buf += *in++; + + x->buf = buf; + x->blocks++; + + return (w+4); +} + +static void tavg_dsp(t_tavgtilde *x, t_signal **sp) +{ + x->n_inv=1./sp[0]->s_n; + dsp_add(tavg_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); +} + +static void *tavg_new(void) +{ + t_tavgtilde *x = (t_tavgtilde *)pd_new(tavg_class); + outlet_new(&x->x_obj, gensym("float")); + return (x); +} + +static void tavg_help(void) +{ + post("tavg~\t\t:: outputs the arithmetic mean of a signal when triggered"); + post("\t\t: triggers the output"); +} + +void tavg_tilde_setup(void) +{ + tavg_class = class_new(gensym("tavg~"), (t_newmethod)tavg_new, 0, + sizeof(t_tavgtilde), 0, A_DEFFLOAT, 0); + class_addmethod(tavg_class, nullfn, gensym("signal"), 0); + class_addmethod(tavg_class, (t_method)tavg_dsp, gensym("dsp"), 0); + + class_addbang(tavg_class, tavg_bang); + + class_addmethod(tavg_class, (t_method)tavg_help, gensym("help"), 0); + class_sethelpsymbol(tavg_class, gensym("zexy/tavg~")); + zexy_register("tavg~"); +} diff --git a/src/unpack_tilde.c b/src/unpack_tilde.c deleted file mode 100644 index f65d745..0000000 --- a/src/unpack_tilde.c +++ /dev/null @@ -1,134 +0,0 @@ -/****************************************************** - * - * zexy - implementation file - * - * copyleft (c) IOhannes m zmölnig - * - * 1999:forum::für::umläute:2004 - * - * institute of electronic music and acoustics (iem) - * - ****************************************************** - * - * license: GNU General Public License v.2 - * - ******************************************************/ - -/* 0109:forum::für::umläute:2000 - unpack~ :: convert float-(package)-inputs to signals -*/ - -/* ---------------------------- unpack~ ----------------------------- */ -/* unpack a sequence of float-package to a signal-vector */ - - -#include "zexy.h" -#include - -static t_class *sigunpack_class; - -typedef struct _sigunpack -{ - t_object x_obj; - t_float *buffer; - t_float *rp, *wp; - int bufsize; - -} t_sigunpack; - -static void sigunpack_float(t_sigunpack *x, t_float f) -{ - if (x->wp + 1 != x->rp) { - *(x->wp)++ = f; - if (x->wp == x->buffer + x->bufsize) x->wp = x->buffer; - } -} - -static void sigunpack_list(t_sigunpack *x, t_symbol *s, int argc, t_atom *argv) -{ - t_atom *ap = argv; - int i; - - for (i = 0, ap = argv; i < argc; ap++, i++) { - // if (ap->a_type == A_FLOAT) { - if (x->wp + 1 != x->rp) { - *(x->wp)++ = atom_getfloat(ap); - if (x->wp == x->buffer + x->bufsize) x->wp = x->buffer; - } - // } - } -} - - -static t_int *sigunpack_perform(t_int *w) -{ - t_float *out = (t_float *)(w[1]); - t_sigunpack *x = (t_sigunpack *)w[2]; - int n = (int)(w[3]); - - t_float *buf = x->rp; - int hitchhike = 0; - - if ((x->wp >= x->rp) && (x->wp < x->rp+n)) hitchhike=1; - x->rp += n; - if (x->rp == x->buffer + x->bufsize) x->rp = x->buffer; - if (hitchhike) x->wp = x->rp; - - while (n--) { - *out++ = *buf; - *buf++ = 0; - } - - return (w+4); -} - -static void sigunpack_dsp(t_sigunpack *x, t_signal **sp) -{ - if (x->bufsize % sp[0]->s_n) { - int newsize = sp[0]->s_n*(1+(int)(x->bufsize/sp[0]->s_n)); - freebytes(x->buffer, x->bufsize * sizeof(t_float)); - x->buffer = (t_float *)getbytes(newsize * sizeof(t_float)); - - x->rp = x->wp = x->buffer; - x->bufsize = newsize; - } - - dsp_add(sigunpack_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); -} - -static void *sigunpack_new(t_floatarg f) -{ - t_sigunpack *x = (t_sigunpack *)pd_new(sigunpack_class); - - int suggestedsize = (int)f; - int bufsize; - if (!suggestedsize) bufsize = 64; - else bufsize = (suggestedsize % 64)?(64*(1+(int)(suggestedsize/64))):suggestedsize; - - x->buffer = (t_float *)getbytes(bufsize * sizeof(t_float)); - x->bufsize = bufsize; - x->rp = x->wp = x->buffer; - - outlet_new(&x->x_obj, gensym("signal")); - - return (x); -} - -static void sigunpack_help(void) -{ - post("unpack~\t:: outputs a sequence of floats as a signal"); -} - -void unpack_tilde_setup(void) -{ - sigunpack_class = class_new(gensym("unpack~"), (t_newmethod)sigunpack_new, 0, - sizeof(t_sigunpack), 0, A_DEFFLOAT, 0); - class_addmethod(sigunpack_class, (t_method)sigunpack_dsp, gensym("dsp"), 0); - class_addfloat(sigunpack_class, (t_method)sigunpack_float); - class_addlist (sigunpack_class, (t_method)sigunpack_list); - - - class_addmethod(sigunpack_class, (t_method)sigunpack_help, gensym("help"), 0); - class_sethelpsymbol(sigunpack_class, gensym("zexy/unpack~")); - zexy_register("unpack~"); -} diff --git a/src/unpack~.c b/src/unpack~.c new file mode 100644 index 0000000..f65d745 --- /dev/null +++ b/src/unpack~.c @@ -0,0 +1,134 @@ +/****************************************************** + * + * zexy - implementation file + * + * copyleft (c) IOhannes m zmölnig + * + * 1999:forum::für::umläute:2004 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + * + ******************************************************/ + +/* 0109:forum::für::umläute:2000 + unpack~ :: convert float-(package)-inputs to signals +*/ + +/* ---------------------------- unpack~ ----------------------------- */ +/* unpack a sequence of float-package to a signal-vector */ + + +#include "zexy.h" +#include + +static t_class *sigunpack_class; + +typedef struct _sigunpack +{ + t_object x_obj; + t_float *buffer; + t_float *rp, *wp; + int bufsize; + +} t_sigunpack; + +static void sigunpack_float(t_sigunpack *x, t_float f) +{ + if (x->wp + 1 != x->rp) { + *(x->wp)++ = f; + if (x->wp == x->buffer + x->bufsize) x->wp = x->buffer; + } +} + +static void sigunpack_list(t_sigunpack *x, t_symbol *s, int argc, t_atom *argv) +{ + t_atom *ap = argv; + int i; + + for (i = 0, ap = argv; i < argc; ap++, i++) { + // if (ap->a_type == A_FLOAT) { + if (x->wp + 1 != x->rp) { + *(x->wp)++ = atom_getfloat(ap); + if (x->wp == x->buffer + x->bufsize) x->wp = x->buffer; + } + // } + } +} + + +static t_int *sigunpack_perform(t_int *w) +{ + t_float *out = (t_float *)(w[1]); + t_sigunpack *x = (t_sigunpack *)w[2]; + int n = (int)(w[3]); + + t_float *buf = x->rp; + int hitchhike = 0; + + if ((x->wp >= x->rp) && (x->wp < x->rp+n)) hitchhike=1; + x->rp += n; + if (x->rp == x->buffer + x->bufsize) x->rp = x->buffer; + if (hitchhike) x->wp = x->rp; + + while (n--) { + *out++ = *buf; + *buf++ = 0; + } + + return (w+4); +} + +static void sigunpack_dsp(t_sigunpack *x, t_signal **sp) +{ + if (x->bufsize % sp[0]->s_n) { + int newsize = sp[0]->s_n*(1+(int)(x->bufsize/sp[0]->s_n)); + freebytes(x->buffer, x->bufsize * sizeof(t_float)); + x->buffer = (t_float *)getbytes(newsize * sizeof(t_float)); + + x->rp = x->wp = x->buffer; + x->bufsize = newsize; + } + + dsp_add(sigunpack_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); +} + +static void *sigunpack_new(t_floatarg f) +{ + t_sigunpack *x = (t_sigunpack *)pd_new(sigunpack_class); + + int suggestedsize = (int)f; + int bufsize; + if (!suggestedsize) bufsize = 64; + else bufsize = (suggestedsize % 64)?(64*(1+(int)(suggestedsize/64))):suggestedsize; + + x->buffer = (t_float *)getbytes(bufsize * sizeof(t_float)); + x->bufsize = bufsize; + x->rp = x->wp = x->buffer; + + outlet_new(&x->x_obj, gensym("signal")); + + return (x); +} + +static void sigunpack_help(void) +{ + post("unpack~\t:: outputs a sequence of floats as a signal"); +} + +void unpack_tilde_setup(void) +{ + sigunpack_class = class_new(gensym("unpack~"), (t_newmethod)sigunpack_new, 0, + sizeof(t_sigunpack), 0, A_DEFFLOAT, 0); + class_addmethod(sigunpack_class, (t_method)sigunpack_dsp, gensym("dsp"), 0); + class_addfloat(sigunpack_class, (t_method)sigunpack_float); + class_addlist (sigunpack_class, (t_method)sigunpack_list); + + + class_addmethod(sigunpack_class, (t_method)sigunpack_help, gensym("help"), 0); + class_sethelpsymbol(sigunpack_class, gensym("zexy/unpack~")); + zexy_register("unpack~"); +} diff --git a/src/z_tilde.c b/src/z_tilde.c deleted file mode 100644 index 7d786ca..0000000 --- a/src/z_tilde.c +++ /dev/null @@ -1,132 +0,0 @@ -/****************************************************** - * - * zexy - implementation file - * - * copyleft (c) IOhannes m zmölnig - * - * 1999:forum::für::umläute:2004 - * - * institute of electronic music and acoustics (iem) - * - ****************************************************** - * - * license: GNU General Public License v.2 - * - ******************************************************/ - -/* - here we do some sample-wise delay, so you can do your own FIR-filter-designs - here are :: "z^(-1)", "z^(-N)" - to do :: a "lattice~" section ... - - 1302:forum::für::umläute:2000 -*/ - -#include "zexy.h" - -/* ----------------------------------------------------- */ - -static t_class *zNdelay_class; - -typedef struct _zNdelay -{ - t_object x_obj; - - t_float *buf; - int bufsize, phase; - -} t_zNdelay; - -static void zdel_float(t_zNdelay *x, t_floatarg f) -{ - int i = f+1; - if (i<1)i=1; - if (i==x->bufsize)return; - freebytes(x->buf, x->bufsize*sizeof(t_float)); - x->bufsize=i; - x->buf=(t_float *)getbytes(x->bufsize*sizeof(t_float)); - x->phase=0; -} - -static t_int *zN_perform(t_int *w) -{ - t_float *in = (t_float *)(w[1]); - t_float *out = (t_float *)(w[2]); - t_zNdelay *x = (t_zNdelay *)(w[3]); - int n = (int)(w[4]); - - t_float *buf = x->buf; - int bufsize=x->bufsize, ph=x->phase; - - if (bufsize==1) { - if (in!=out)while(n--)*out++=*in++; - } else if (bufsize==2) { - register t_float f, last=*buf; - while(n--){ - f=*in++; - *out++=last; - last=f; - } - *buf=last; - } else { - while (n--) { - *(buf+ph++) = *in++; - *out++ = buf[ph%=bufsize]; - } - x->phase=ph; - } - return (w+5); -} - - -static void zNdelay_dsp(t_zNdelay *x, t_signal **sp) -{ - dsp_add(zN_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, sp[0]->s_n); -} - -static void *zNdelay_new(t_floatarg f) -{ - t_zNdelay *x = (t_zNdelay *)pd_new(zNdelay_class); - int i = f; - t_float *b; - - if (i<=0) i=1; - i++; - - x->bufsize = i; - x->buf = (t_float *)getbytes(sizeof(t_float) * x->bufsize); - b=x->buf; - while (i--) { - *b++=0; - } - x->phase = 0; - - outlet_new(&x->x_obj, gensym("signal")); - return (x); -} - -static void zNdelay_free(t_zNdelay *x) -{ - freebytes(x->buf, sizeof(t_float) * x->bufsize); -} - - -static void zdel_helper(void) -{ - post("\n%c z~\t:: samplewise delay", HEARTSYMBOL); - post("creation :: 'z~ []' : creates a -sample delay; default is 1"); -} - - -void z_tilde_setup(void) -{ - zNdelay_class = class_new(gensym("z~"), (t_newmethod)zNdelay_new, (t_method)zNdelay_free, - sizeof(t_zNdelay), 0, A_DEFFLOAT, 0); - class_addmethod(zNdelay_class, nullfn, gensym("signal"), 0); - class_addmethod(zNdelay_class, (t_method)zNdelay_dsp, gensym("dsp"), 0); - - class_addfloat(zNdelay_class, zdel_float); - class_addmethod(zNdelay_class, (t_method)zdel_helper, gensym("help"), 0); - class_sethelpsymbol(zNdelay_class, gensym("zexy/z~")); - zexy_register("z~"); -} diff --git a/src/z~.c b/src/z~.c new file mode 100644 index 0000000..7d786ca --- /dev/null +++ b/src/z~.c @@ -0,0 +1,132 @@ +/****************************************************** + * + * zexy - implementation file + * + * copyleft (c) IOhannes m zmölnig + * + * 1999:forum::für::umläute:2004 + * + * institute of electronic music and acoustics (iem) + * + ****************************************************** + * + * license: GNU General Public License v.2 + * + ******************************************************/ + +/* + here we do some sample-wise delay, so you can do your own FIR-filter-designs + here are :: "z^(-1)", "z^(-N)" + to do :: a "lattice~" section ... + + 1302:forum::für::umläute:2000 +*/ + +#include "zexy.h" + +/* ----------------------------------------------------- */ + +static t_class *zNdelay_class; + +typedef struct _zNdelay +{ + t_object x_obj; + + t_float *buf; + int bufsize, phase; + +} t_zNdelay; + +static void zdel_float(t_zNdelay *x, t_floatarg f) +{ + int i = f+1; + if (i<1)i=1; + if (i==x->bufsize)return; + freebytes(x->buf, x->bufsize*sizeof(t_float)); + x->bufsize=i; + x->buf=(t_float *)getbytes(x->bufsize*sizeof(t_float)); + x->phase=0; +} + +static t_int *zN_perform(t_int *w) +{ + t_float *in = (t_float *)(w[1]); + t_float *out = (t_float *)(w[2]); + t_zNdelay *x = (t_zNdelay *)(w[3]); + int n = (int)(w[4]); + + t_float *buf = x->buf; + int bufsize=x->bufsize, ph=x->phase; + + if (bufsize==1) { + if (in!=out)while(n--)*out++=*in++; + } else if (bufsize==2) { + register t_float f, last=*buf; + while(n--){ + f=*in++; + *out++=last; + last=f; + } + *buf=last; + } else { + while (n--) { + *(buf+ph++) = *in++; + *out++ = buf[ph%=bufsize]; + } + x->phase=ph; + } + return (w+5); +} + + +static void zNdelay_dsp(t_zNdelay *x, t_signal **sp) +{ + dsp_add(zN_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, sp[0]->s_n); +} + +static void *zNdelay_new(t_floatarg f) +{ + t_zNdelay *x = (t_zNdelay *)pd_new(zNdelay_class); + int i = f; + t_float *b; + + if (i<=0) i=1; + i++; + + x->bufsize = i; + x->buf = (t_float *)getbytes(sizeof(t_float) * x->bufsize); + b=x->buf; + while (i--) { + *b++=0; + } + x->phase = 0; + + outlet_new(&x->x_obj, gensym("signal")); + return (x); +} + +static void zNdelay_free(t_zNdelay *x) +{ + freebytes(x->buf, sizeof(t_float) * x->bufsize); +} + + +static void zdel_helper(void) +{ + post("\n%c z~\t:: samplewise delay", HEARTSYMBOL); + post("creation :: 'z~ []' : creates a -sample delay; default is 1"); +} + + +void z_tilde_setup(void) +{ + zNdelay_class = class_new(gensym("z~"), (t_newmethod)zNdelay_new, (t_method)zNdelay_free, + sizeof(t_zNdelay), 0, A_DEFFLOAT, 0); + class_addmethod(zNdelay_class, nullfn, gensym("signal"), 0); + class_addmethod(zNdelay_class, (t_method)zNdelay_dsp, gensym("dsp"), 0); + + class_addfloat(zNdelay_class, zdel_float); + class_addmethod(zNdelay_class, (t_method)zdel_helper, gensym("help"), 0); + class_sethelpsymbol(zNdelay_class, gensym("zexy/z~")); + zexy_register("z~"); +} -- cgit v1.2.1