From 17ec1deb74e2e934dc11fb4d9a2f8c6cef34c5a7 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 9 Jul 2007 20:45:58 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r7949, which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/moonlib/; revision=7950 --- ssaw~.c | 213 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 ssaw~.c (limited to 'ssaw~.c') diff --git a/ssaw~.c b/ssaw~.c new file mode 100644 index 0000000..07454ef --- /dev/null +++ b/ssaw~.c @@ -0,0 +1,213 @@ +/* +Copyright (C) 2004 Antoine Rousseau +all material Copyright (c) 1997-1999 Miller Puckette. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +/* a "sweet" saw generator, as described in pddoc/3.audio/K05.bandlimited .*/ + +#include "m_pd.h" +#include "math.h" +#include + +#define UNITBIT32 1572864. /* 3*2^19; bit 32 has place value 1 */ + + /* machine-dependent definitions. These ifdefs really + should have been by CPU type and not by operating system! */ +#ifdef IRIX + /* big-endian. Most significant byte is at low address in memory */ +#define HIOFFSET 0 /* word offset to find MSB */ +#define LOWOFFSET 1 /* word offset to find LSB */ +#define int32 long /* a data type that has 32 bits */ +#else +#ifdef MSW + /* little-endian; most significant byte is at highest address */ +#define HIOFFSET 1 +#define LOWOFFSET 0 +#define int32 long +#else +#ifdef __FreeBSD__ +#include +#if BYTE_ORDER == LITTLE_ENDIAN +#define HIOFFSET 1 +#define LOWOFFSET 0 +#else +#define HIOFFSET 0 /* word offset to find MSB */ +#define LOWOFFSET 1 /* word offset to find LSB */ +#endif /* BYTE_ORDER */ +#include +#define int32 int32_t +#endif +#ifdef __linux__ + +#include + +#if !defined(__BYTE_ORDER) || !defined(__LITTLE_ENDIAN) +#error No byte order defined +#endif + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define HIOFFSET 1 +#define LOWOFFSET 0 +#else +#define HIOFFSET 0 /* word offset to find MSB */ +#define LOWOFFSET 1 /* word offset to find LSB */ +#endif /* __BYTE_ORDER */ + +#include +#define int32 int32_t + +#else +#ifdef MACOSX +#define HIOFFSET 0 /* word offset to find MSB */ +#define LOWOFFSET 1 /* word offset to find LSB */ +#define int32 int /* a data type that has 32 bits */ + +#endif /* MACOSX */ +#endif /* __linux__ */ +#endif /* MSW */ +#endif /* SGI */ + +union tabfudge +{ + double tf_d; + int32 tf_i[2]; +}; + + +/* -------------------------- ssaw~ ------------------------------ */ +static t_class *ssaw_class, *scalarssaw_class; +static float ssaw_array[1002]; +#define SAW_ARRAY_LEN 1002 + +typedef struct _ssaw +{ + t_object x_obj; + //from phasor~: + double x_phase; + float x_conv; + float x_f; /* scalar frequency */ + float x_band; /* band limit (Hertz)*/ +} t_ssaw; + +static void *ssaw_new(t_floatarg f) +{ + t_ssaw *x = (t_ssaw *)pd_new(ssaw_class); + x->x_f = f; + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1")); + x->x_phase = 0; + x->x_conv = 0; + x->x_band = 22000; + outlet_new(&x->x_obj, gensym("signal")); + return (x); +} + +static t_int *ssaw_perform(t_int *w) +{ + t_ssaw *x = (t_ssaw *)(w[1]); + t_float *in = (t_float *)(w[2]); + t_float *out = (t_float *)(w[3]); + int i,n = (int)(w[4]); + double dphase = x->x_phase + UNITBIT32; + union tabfudge tf; + int normhipart; + float conv = x->x_conv; + float band=x->x_band*.33; + float *buf = ssaw_array; + + tf.tf_d = UNITBIT32; + normhipart = tf.tf_i[HIOFFSET]; + tf.tf_d = dphase; + + for (i = 0; i < n; i++) + //while (n--) + { + float phase,band2,findex /*= *in++*/; + int index /*= findex*/; + float frac, a, b, c, d, cminusb, *fp; + + tf.tf_i[HIOFFSET] = normhipart; + band2=abs(*in); + if(band2>999999) band2=999999; else if(band2<1) band2=1; + band2=band/band2; + dphase += *in++ * conv; + /**out++*/phase = (tf.tf_d - UNITBIT32)-0.5; + tf.tf_d = dphase; + + findex=phase*band2; + if(findex>0.5) findex=0.5; else if(findex<-0.5) findex=-0.5; + + /*findex=findex*1000+501; + index=findex;*/ + /*if (index < 1) + index = 1, frac = 0; + else if (index > maxindex) + index = maxindex, frac = 1; + else*/ frac = findex - index; + /*fp = buf + index; + a = fp[-1]; + b = fp[0]; + c = fp[1]; + d = fp[2]; + cminusb = c-b; + *out++ = 0.5+ phase - ( + b + frac * ( cminusb - 0.1666667f * (1.-frac) * ( + (d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b))) + );*/ + *out++ = 0.5+ phase - buf[(int)(findex*1000+501)]; + } + + tf.tf_i[HIOFFSET] = normhipart; + x->x_phase = tf.tf_d - UNITBIT32; + return (w+5); +} + +static void ssaw_dsp(t_ssaw *x, t_signal **sp) +{ + x->x_conv = 1./sp[0]->s_sr; + dsp_add(ssaw_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); +} + +static void ssaw_ft1(t_ssaw *x, t_float f) +{ + x->x_phase = f; +} + +static void ssaw_initarray(void) +{ + int i; + float j; + + for(i=0;i<1002;i++){ + j=(i-1)*M_PI/1000.0; //period 2000 sample, 1 sample back phase + ssaw_array[i]= 0.57692* + (-1*cos(j) + 0.333333*cos(j*3.0) -0.2* cos(j*5.0)); + } +} + +void ssaw_tilde_setup(void) +{ + ssaw_class = class_new(gensym("ssaw~"), (t_newmethod)ssaw_new, 0, + sizeof(t_ssaw), 0, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(ssaw_class, t_ssaw, x_f); + class_addmethod(ssaw_class, (t_method)ssaw_dsp, gensym("dsp"), 0); + class_addmethod(ssaw_class, (t_method)ssaw_ft1, + gensym("ft1"), A_FLOAT, 0); + ssaw_initarray(); + +} + -- cgit v1.2.1