From da1f0065d07250b86b9a761b012987e4825f491f Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 28 Nov 2005 16:53:25 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r4068, which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/smlib/; revision=4069 --- source/deltas.c | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 source/deltas.c (limited to 'source/deltas.c') diff --git a/source/deltas.c b/source/deltas.c new file mode 100644 index 0000000..edc3cb0 --- /dev/null +++ b/source/deltas.c @@ -0,0 +1,181 @@ +#include "defines.h" + +/*--------------- deltas ---------------*/ + +static t_class *deltas_class; + +typedef struct _deltas +{ + t_object x_obj; + float m_lo; + float m_hi; + int m_buffer_size; + int m_buffer_index; + float *m_buffer; // circular buffer +} t_deltas; + + +static void deltas_perform_float(t_deltas *x, t_float f) +{ + int index; + index=x->m_buffer_index+1; + index=(index==x->m_buffer_size)?0:index; + x->m_buffer_index=index; + x->m_buffer[index]=f; +} + +static void deltas_bang(t_deltas *x) +{ + int lo,hi,n,index,size; + t_atom *ap,*app; + float last; + float *buffer, *bp; + + lo=(int)x->m_lo; + hi=(int)x->m_hi; + + n=hi-lo; + size=x->m_buffer_size; + index=x->m_buffer_index; + ap = (t_atom *)getbytes(sizeof(t_atom)*n); + app=ap; + buffer=x->m_buffer; + last=buffer[index]; + bp=buffer+index-lo; + bp=(bp>=buffer)?bp:bp+size; // wrap + + if (bp-buffer>=n) + { // no wrap-around needed + index=n; + while(index--){ + SETFLOAT(app, last-*bp--); + app++; + } +// post("not wrapped, app-ap=%i",app-ap); + } + else // need to wrap + { + int ps, nn; + ps = bp-buffer; + nn=n; +// post(" nn=%i",nn); + for(;ps>=0;ps--) // don't we miss one sample in signal??? + { +// post("ps=%i",ps); + SETFLOAT(app, last-buffer[ps]); + app++; + nn--; + } + ps=size-1; +// post(" nn=%i",nn); + for(;nn>0;nn--) + { +// post("ps=%i",ps); + SETFLOAT(app, last-buffer[ps--]); + app++; + } + +/* + int i2; + index=bp-buffer; + i2=index; + post("first part %i",index); + while(index--){ + SETFLOAT(app, last-*bp--); + app++; + } + index=n-i2; + post("2nd part %i",index); + bp=buffer+size-1; + while(index--){ + SETFLOAT(app, last-*bp--); + app++; + } +*/ +// post("wrapped, app-ap=%i",app-ap); + } + + outlet_list(x->x_obj.ob_outlet,gensym("list"),n,ap); + freebytes(ap, sizeof(t_atom)*n); +} + +static void deltas_clear(t_deltas *x) +{ + int i,s; + float *f; + f=x->m_buffer; + s=x->m_buffer_size; + for (i=0;isize) + { + post("deltas: higher bound cannot be higher than the buffer size..."); + hi=size; + } + if (lo<0) + { + post("deltas: lower bound cannot be negative..."); + lo=0; + } + if (hi<1) + { + post("deltas: higher bound cannot be smaller than one..."); + hi=1; + } + if (hi<=lo) + { + post("deltas: higher bound must be higher than lower bound..."); + lo=hi-1.0f; + } + + freebytes(x->m_buffer, x->m_buffer_size); + + x->m_hi=(float)((int)hi); + x->m_lo=(float)((int)lo); + x->m_buffer_size=(int)size; + x->m_buffer = (float*)getbytes(sizeof(float)*x->m_buffer_size); + deltas_clear(x); + x->m_buffer_index=0; +} + +static void *deltas_new(t_float lo, t_float hi, t_float size) +{ + t_deltas *x=(t_deltas *)pd_new(deltas_class); + outlet_new(&x->x_obj, gensym("list")); + x->m_buffer_size=0; + x->m_buffer=0; + deltas_set(x, lo, hi, size); + + floatinlet_new(&x->x_obj, &x->m_lo); + floatinlet_new(&x->x_obj, &x->m_hi); + + return (void *)x; +} + +static void deltas_free(t_deltas *x) +{ + freebytes(x->m_buffer, x->m_buffer_size); +} + +void deltas_setup(void) +{ + deltas_class = class_new(gensym("deltas"), + (t_newmethod)deltas_new, (t_method)deltas_free, + sizeof(t_deltas), + CLASS_DEFAULT, + A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT,0); + + class_addmethod(deltas_class, (t_method)deltas_clear, gensym("clear"),0); + class_addfloat(deltas_class, (t_method)deltas_perform_float); + class_addbang(deltas_class, (t_method)deltas_bang); +} + -- cgit v1.2.1