aboutsummaryrefslogtreecommitdiff
path: root/experimental/fofsynth~.c
diff options
context:
space:
mode:
authorHans-Christoph Steiner <eighthave@users.sourceforge.net>2005-11-14 21:59:09 +0000
committerHans-Christoph Steiner <eighthave@users.sourceforge.net>2005-11-14 21:59:09 +0000
commitc1419b43ea354fa04360450ae4f64612df065099 (patch)
tree8c38d7338e9df7e889a18dceeedb3509adbbf423 /experimental/fofsynth~.c
parent76be9508936fa53fe661d378ee2fc41cc9baebf3 (diff)
these pragmas are only used for MSVC, not MinGW or Cygwin, therefore changing the define from NT to _MSC_VER
svn path=/trunk/externals/ggee/; revision=3903
Diffstat (limited to 'experimental/fofsynth~.c')
-rwxr-xr-xexperimental/fofsynth~.c708
1 files changed, 354 insertions, 354 deletions
diff --git a/experimental/fofsynth~.c b/experimental/fofsynth~.c
index 53df270..5a9de5b 100755
--- a/experimental/fofsynth~.c
+++ b/experimental/fofsynth~.c
@@ -1,354 +1,354 @@
-/* (C) Guenter Geiger <geiger@epy.co.at> */
-
-
-#include <m_pd.h>
-#include <math.h>
-#ifdef NT
-#pragma warning( disable : 4244 )
-#pragma warning( disable : 4305 )
-#endif
-
-/* ------------------------ fofsynth~ ----------------------------- */
-
-#ifndef NT
-void garray_usedindsp(t_garray *x);
-#endif
-
-#define DEBUG(a,b) if (x->debug) post(a,b);
-
-#define MAXGRAINS 1000
-#define PD_PI 3.14159
-
-static float* cos_table;
-static float* halfcos_table;
-static float* exp_table;
-
-static void cos_maketable(void)
-{
- int i;
- float *fp, phase, phsinc = (2. * PD_PI) / COSTABSIZE;
-
- if (cos_table) return;
- cos_table = (float *)getbytes(sizeof(float) * (COSTABSIZE+1));
-
- for (i = COSTABSIZE + 1, fp = cos_table, phase = 0; i--;
- fp++, phase += phsinc)
- *fp = cos(phase);
-
-}
-
-static void halfcos_maketable(void)
-{
- int i;
- float *fp, phase, phsinc = (PD_PI) / COSTABSIZE;
-
- if (halfcos_table) return;
- halfcos_table = (float *)getbytes(sizeof(float) * (COSTABSIZE+1));
-
- for (i = COSTABSIZE + 1, fp = halfcos_table, phase = PD_PI; i--;
- fp++, phase += phsinc)
- *fp = 0.5*(cos(phase) + 1.0);
-}
-
-
-static void exp_maketable(void)
-{
- int i;
- float *fp, phase, phsinc = (2 * PD_PI) / COSTABSIZE;
-
- if (exp_table) return;
- exp_table = (float *)getbytes(sizeof(float) * (COSTABSIZE+1));
-
- for (i = COSTABSIZE + 1, fp = exp_table, phase = 0; i--;
- fp++, phase += phsinc)
- *fp = exp(-phase);
-}
-
-
-static t_class *fofsynth_class;
-
-typedef struct _grain
-{
- struct _grain *next;
- t_float formph; /* 0 ... 1 */
- t_float formphinc;
- t_float envph;
- int falling;
-} t_grain;
-
-
-typedef struct _fofsynth
-{
- t_object x_obj;
-
- /* it is possible to use 2 array, prob change this one
- int the future */
-
- t_symbol* x_arrayname;
-
- /* template */
-
- int x_npoints;
- t_float *x_vec;
-
- /* fof */
- int debug;
-
- int maxgrains;
- int numgrains;
-
- float* x_envelope;
-
- /* the queue of grains */
-
- t_grain* grainbase;
- t_grain* grainstart;
- t_grain* grainend;
-
-
- t_float fundph; /* 0 to 1; if 1 -> add a new grain */
-
- t_float fundfreq; /* input parameter 1 */
- t_float formfreq; /* input paramter 2 */
- t_float risedur; /* input parameter 3 ( in % of total duration )*/
- t_float falldur; /* input parameter 5 ( in % of total duration */
-
- /* other */
- int neednewgrain;
-} t_fofsynth;
-
-
-
-
-/* build a cyclic list */
-static t_grain* grain_makecyclic(t_grain* base,int num)
-{
- t_grain* cur = base;
- while (--num) {
- cur->next = cur+1;
- cur++;
- }
- cur->next = base;
- return base;
-}
-
-
-
-
-
-static t_int *fofsynth_perform(t_int *w)
-{
- t_fofsynth* x = (t_fofsynth*) (w[1]);
- t_float *in = (t_float *)(w[2]);
- t_float *out = (t_float *)(w[3]);
- int n = (int)(w[4]);
-
- float totaldur = (x->risedur+ x->falldur)*0.01/ *in;
-
- float srate = 44100.0; /*((t_signal*)w[2])->s_sr;*/
- float israte = 1.0/srate;
-
- float fundphase = x->fundph;
- float numperiods = totaldur*x->formfreq;
- float formphinc = (x->formfreq/srate);
-
- float risinc;
- float fallinc;
-
- t_grain* cur;
-
- risinc = (x->risedur == 0) ? 1.0 : 1.0/ (srate*totaldur*0.01*x->risedur);
- fallinc = (x->falldur == 0.0) ? 1.0 :1.0/ (srate*totaldur*0.01*x->falldur);
-
- DEBUG(" fundph %3.2f",x->fundph);
- DEBUG(" fundfreq %3.2f",x->fundfreq);
- DEBUG(" formfreq %3.2f",x->formfreq);
- DEBUG(" risedur %3.2f %",x->risedur);
- DEBUG(" falldur %3.2f %",x->falldur);
- DEBUG(" totaldur %3.2f s",totaldur);
- DEBUG(" risinc %0.6f",risinc);
- DEBUG(" fallinc %0.6f",fallinc);
- DEBUG(" formant increase %3.2f",formphinc);
- DEBUG(" numgrains %d",x->numgrains);
-
- while (n--)
- {
- fundphase+=*++in*israte;
- *out = 0.0;
-
- if (x->neednewgrain) { /* new grain, they are deleted separetely */
- t_grain* newgrain = x->grainend;
-/* DEBUG("new grain created",0); */
- if (newgrain->next == x->grainstart) {
- post("fof: grain overflow");
- x->neednewgrain = 0;
- }
- else {
- x->numgrains++;
- x->grainend = newgrain->next;
- newgrain->formphinc = formphinc;
- newgrain->falling = 0;
- newgrain->formph = newgrain->envph = 0.0;
- x->neednewgrain = 0;
- }
- }
-
- cur = x->grainstart;
- while (cur != x->grainend) {
- float formphase = cur->formph;
- float envelope;
-
- float tph = (formphase - (float)((int) formphase));
- float val = *(x->x_vec + (int) (tph * x->x_npoints));
-
- /* Apply the envelope */
-
- if (!cur->falling && (cur->envph <= 1.0)) {
- envelope = *(halfcos_table + (int) (cur->envph * COSTABSIZE));
- cur->envph+=risinc;
- val *= envelope;
- }
- else if (!cur->falling)
- {
- cur->falling = 1;
- cur->envph = 0;
- }
-
-
- if (cur->falling) {
- envelope = *(exp_table + (int) (cur->envph * COSTABSIZE));
- cur->envph+=fallinc;
- val *= envelope;
- }
-
- /* end of envelope code */
-
-
- formphase+=cur->formphinc;
- cur->formph = formphase;
-
- if (formphase >= numperiods) { /* dead */
- DEBUG("grain died",0);
- x->grainstart = cur->next;
- x->numgrains--;/* not needed */
- }
-
- cur = cur->next;
- *out += val;
- }
-
-
- if (fundphase > 1.0) {
- fundphase -= 1.0;
- x->neednewgrain=1;
- }
- out++;
- }
-
- x->fundph=fundphase;
- x->debug = 0;
-
-
- return (w+5);
-}
-
-void fofsynth_usearray(t_symbol* s,int* points,t_float** vec)
-{
- t_garray *a;
- if (!(a = (t_garray *)pd_findbyclass(s, garray_class)))
- error("%s: no such array", s->s_name);
- else if (!garray_getfloatarray(a,points,vec))
- error("%s: bad template for fof~", s->s_name);
- else
- garray_usedindsp(a);
-}
-
-static void fofsynth_dsp(t_fofsynth *x, t_signal **sp)
-{
-
- if (x->x_arrayname)
- fofsynth_usearray(x->x_arrayname,&x->x_npoints, &x->x_vec);
- else {
- x->x_npoints=COSTABSIZE;
- x->x_vec = cos_table;
- }
-
- dsp_add(fofsynth_perform, 4, x,
- sp[0]->s_vec,sp[1]->s_vec, sp[0]->s_n);
-}
-
-
-static void fofsynth_free(t_fofsynth *x)
-{
- freebytes(x->grainbase,sizeof(t_grain)*x->maxgrains);
-}
-
-
-static void fofsynth_debug(t_fofsynth* x)
-{
- x->debug = 1;
-}
-
-
-static void fofsynth_float(t_fofsynth* x,t_float f)
-{
- x->fundfreq = f > 0.0 ? f : -f;
-}
-
-
-static void *fofsynth_new(t_symbol* s,t_float a,t_float b,t_float c,t_float d)
-{
- int maxgrains = MAXGRAINS;
- t_fofsynth *x = (t_fofsynth *)pd_new(fofsynth_class);
-
- x->debug = 0;
- x->x_arrayname = s;
-
- if (s == &s_)
- x->x_arrayname = NULL;
-
- /* setup the grain queue */
-
- x->grainbase = getbytes(sizeof(t_grain)*maxgrains);
- x->maxgrains = maxgrains;
- grain_makecyclic(x->grainbase,maxgrains);
- x->grainstart = x->grainbase;
- x->grainend = x->grainbase;
- x->numgrains = 0;
-
- /* some of them could be signals too */
-
- floatinlet_new(&x->x_obj, &x->formfreq);
- floatinlet_new(&x->x_obj, &x->risedur);
- floatinlet_new(&x->x_obj, &x->falldur);
-
- x->fundph = 0.0;
- x->fundfreq = 200.0;
- x->formfreq = 600.0;
- x->risedur = 5.0;
- x->falldur = 140.0;
-
- if (a) x->fundfreq = a;
- if (b) x->formfreq = b;
- if (c) x->risedur = c;
- if (d) x->falldur = d;
-
- outlet_new(&x->x_obj, &s_signal);
- return (x);
-}
-
-void fofsynth_tilde_setup(void)
-{
- cos_table = NULL;
- halfcos_table = NULL;
- fofsynth_class = class_new(gensym("fof~"), (t_newmethod) fofsynth_new,(t_method) fofsynth_free,
- sizeof(t_fofsynth), 0,A_DEFSYM, A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
- class_addcreator((t_newmethod)fofsynth_new,gensym("fofsynth~"),A_DEFSYM, A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
- class_addmethod(fofsynth_class, nullfn, gensym("signal"), 0);
- class_addmethod(fofsynth_class, (t_method) fofsynth_dsp, gensym("dsp"), 0);
- class_addfloat(fofsynth_class, (t_method) fofsynth_float);
- class_addmethod(fofsynth_class,(t_method) fofsynth_debug, gensym("debug"),0);
- cos_maketable();
- halfcos_maketable();
- exp_maketable();
-}
+/* (C) Guenter Geiger <geiger@epy.co.at> */
+
+
+#include <m_pd.h>
+#include <math.h>
+#ifdef _MSC_VER
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+/* ------------------------ fofsynth~ ----------------------------- */
+
+#ifndef NT
+void garray_usedindsp(t_garray *x);
+#endif
+
+#define DEBUG(a,b) if (x->debug) post(a,b);
+
+#define MAXGRAINS 1000
+#define PD_PI 3.14159
+
+static float* cos_table;
+static float* halfcos_table;
+static float* exp_table;
+
+static void cos_maketable(void)
+{
+ int i;
+ float *fp, phase, phsinc = (2. * PD_PI) / COSTABSIZE;
+
+ if (cos_table) return;
+ cos_table = (float *)getbytes(sizeof(float) * (COSTABSIZE+1));
+
+ for (i = COSTABSIZE + 1, fp = cos_table, phase = 0; i--;
+ fp++, phase += phsinc)
+ *fp = cos(phase);
+
+}
+
+static void halfcos_maketable(void)
+{
+ int i;
+ float *fp, phase, phsinc = (PD_PI) / COSTABSIZE;
+
+ if (halfcos_table) return;
+ halfcos_table = (float *)getbytes(sizeof(float) * (COSTABSIZE+1));
+
+ for (i = COSTABSIZE + 1, fp = halfcos_table, phase = PD_PI; i--;
+ fp++, phase += phsinc)
+ *fp = 0.5*(cos(phase) + 1.0);
+}
+
+
+static void exp_maketable(void)
+{
+ int i;
+ float *fp, phase, phsinc = (2 * PD_PI) / COSTABSIZE;
+
+ if (exp_table) return;
+ exp_table = (float *)getbytes(sizeof(float) * (COSTABSIZE+1));
+
+ for (i = COSTABSIZE + 1, fp = exp_table, phase = 0; i--;
+ fp++, phase += phsinc)
+ *fp = exp(-phase);
+}
+
+
+static t_class *fofsynth_class;
+
+typedef struct _grain
+{
+ struct _grain *next;
+ t_float formph; /* 0 ... 1 */
+ t_float formphinc;
+ t_float envph;
+ int falling;
+} t_grain;
+
+
+typedef struct _fofsynth
+{
+ t_object x_obj;
+
+ /* it is possible to use 2 array, prob change this one
+ int the future */
+
+ t_symbol* x_arrayname;
+
+ /* template */
+
+ int x_npoints;
+ t_float *x_vec;
+
+ /* fof */
+ int debug;
+
+ int maxgrains;
+ int numgrains;
+
+ float* x_envelope;
+
+ /* the queue of grains */
+
+ t_grain* grainbase;
+ t_grain* grainstart;
+ t_grain* grainend;
+
+
+ t_float fundph; /* 0 to 1; if 1 -> add a new grain */
+
+ t_float fundfreq; /* input parameter 1 */
+ t_float formfreq; /* input paramter 2 */
+ t_float risedur; /* input parameter 3 ( in % of total duration )*/
+ t_float falldur; /* input parameter 5 ( in % of total duration */
+
+ /* other */
+ int neednewgrain;
+} t_fofsynth;
+
+
+
+
+/* build a cyclic list */
+static t_grain* grain_makecyclic(t_grain* base,int num)
+{
+ t_grain* cur = base;
+ while (--num) {
+ cur->next = cur+1;
+ cur++;
+ }
+ cur->next = base;
+ return base;
+}
+
+
+
+
+
+static t_int *fofsynth_perform(t_int *w)
+{
+ t_fofsynth* x = (t_fofsynth*) (w[1]);
+ t_float *in = (t_float *)(w[2]);
+ t_float *out = (t_float *)(w[3]);
+ int n = (int)(w[4]);
+
+ float totaldur = (x->risedur+ x->falldur)*0.01/ *in;
+
+ float srate = 44100.0; /*((t_signal*)w[2])->s_sr;*/
+ float israte = 1.0/srate;
+
+ float fundphase = x->fundph;
+ float numperiods = totaldur*x->formfreq;
+ float formphinc = (x->formfreq/srate);
+
+ float risinc;
+ float fallinc;
+
+ t_grain* cur;
+
+ risinc = (x->risedur == 0) ? 1.0 : 1.0/ (srate*totaldur*0.01*x->risedur);
+ fallinc = (x->falldur == 0.0) ? 1.0 :1.0/ (srate*totaldur*0.01*x->falldur);
+
+ DEBUG(" fundph %3.2f",x->fundph);
+ DEBUG(" fundfreq %3.2f",x->fundfreq);
+ DEBUG(" formfreq %3.2f",x->formfreq);
+ DEBUG(" risedur %3.2f %",x->risedur);
+ DEBUG(" falldur %3.2f %",x->falldur);
+ DEBUG(" totaldur %3.2f s",totaldur);
+ DEBUG(" risinc %0.6f",risinc);
+ DEBUG(" fallinc %0.6f",fallinc);
+ DEBUG(" formant increase %3.2f",formphinc);
+ DEBUG(" numgrains %d",x->numgrains);
+
+ while (n--)
+ {
+ fundphase+=*++in*israte;
+ *out = 0.0;
+
+ if (x->neednewgrain) { /* new grain, they are deleted separetely */
+ t_grain* newgrain = x->grainend;
+/* DEBUG("new grain created",0); */
+ if (newgrain->next == x->grainstart) {
+ post("fof: grain overflow");
+ x->neednewgrain = 0;
+ }
+ else {
+ x->numgrains++;
+ x->grainend = newgrain->next;
+ newgrain->formphinc = formphinc;
+ newgrain->falling = 0;
+ newgrain->formph = newgrain->envph = 0.0;
+ x->neednewgrain = 0;
+ }
+ }
+
+ cur = x->grainstart;
+ while (cur != x->grainend) {
+ float formphase = cur->formph;
+ float envelope;
+
+ float tph = (formphase - (float)((int) formphase));
+ float val = *(x->x_vec + (int) (tph * x->x_npoints));
+
+ /* Apply the envelope */
+
+ if (!cur->falling && (cur->envph <= 1.0)) {
+ envelope = *(halfcos_table + (int) (cur->envph * COSTABSIZE));
+ cur->envph+=risinc;
+ val *= envelope;
+ }
+ else if (!cur->falling)
+ {
+ cur->falling = 1;
+ cur->envph = 0;
+ }
+
+
+ if (cur->falling) {
+ envelope = *(exp_table + (int) (cur->envph * COSTABSIZE));
+ cur->envph+=fallinc;
+ val *= envelope;
+ }
+
+ /* end of envelope code */
+
+
+ formphase+=cur->formphinc;
+ cur->formph = formphase;
+
+ if (formphase >= numperiods) { /* dead */
+ DEBUG("grain died",0);
+ x->grainstart = cur->next;
+ x->numgrains--;/* not needed */
+ }
+
+ cur = cur->next;
+ *out += val;
+ }
+
+
+ if (fundphase > 1.0) {
+ fundphase -= 1.0;
+ x->neednewgrain=1;
+ }
+ out++;
+ }
+
+ x->fundph=fundphase;
+ x->debug = 0;
+
+
+ return (w+5);
+}
+
+void fofsynth_usearray(t_symbol* s,int* points,t_float** vec)
+{
+ t_garray *a;
+ if (!(a = (t_garray *)pd_findbyclass(s, garray_class)))
+ error("%s: no such array", s->s_name);
+ else if (!garray_getfloatarray(a,points,vec))
+ error("%s: bad template for fof~", s->s_name);
+ else
+ garray_usedindsp(a);
+}
+
+static void fofsynth_dsp(t_fofsynth *x, t_signal **sp)
+{
+
+ if (x->x_arrayname)
+ fofsynth_usearray(x->x_arrayname,&x->x_npoints, &x->x_vec);
+ else {
+ x->x_npoints=COSTABSIZE;
+ x->x_vec = cos_table;
+ }
+
+ dsp_add(fofsynth_perform, 4, x,
+ sp[0]->s_vec,sp[1]->s_vec, sp[0]->s_n);
+}
+
+
+static void fofsynth_free(t_fofsynth *x)
+{
+ freebytes(x->grainbase,sizeof(t_grain)*x->maxgrains);
+}
+
+
+static void fofsynth_debug(t_fofsynth* x)
+{
+ x->debug = 1;
+}
+
+
+static void fofsynth_float(t_fofsynth* x,t_float f)
+{
+ x->fundfreq = f > 0.0 ? f : -f;
+}
+
+
+static void *fofsynth_new(t_symbol* s,t_float a,t_float b,t_float c,t_float d)
+{
+ int maxgrains = MAXGRAINS;
+ t_fofsynth *x = (t_fofsynth *)pd_new(fofsynth_class);
+
+ x->debug = 0;
+ x->x_arrayname = s;
+
+ if (s == &s_)
+ x->x_arrayname = NULL;
+
+ /* setup the grain queue */
+
+ x->grainbase = getbytes(sizeof(t_grain)*maxgrains);
+ x->maxgrains = maxgrains;
+ grain_makecyclic(x->grainbase,maxgrains);
+ x->grainstart = x->grainbase;
+ x->grainend = x->grainbase;
+ x->numgrains = 0;
+
+ /* some of them could be signals too */
+
+ floatinlet_new(&x->x_obj, &x->formfreq);
+ floatinlet_new(&x->x_obj, &x->risedur);
+ floatinlet_new(&x->x_obj, &x->falldur);
+
+ x->fundph = 0.0;
+ x->fundfreq = 200.0;
+ x->formfreq = 600.0;
+ x->risedur = 5.0;
+ x->falldur = 140.0;
+
+ if (a) x->fundfreq = a;
+ if (b) x->formfreq = b;
+ if (c) x->risedur = c;
+ if (d) x->falldur = d;
+
+ outlet_new(&x->x_obj, &s_signal);
+ return (x);
+}
+
+void fofsynth_tilde_setup(void)
+{
+ cos_table = NULL;
+ halfcos_table = NULL;
+ fofsynth_class = class_new(gensym("fof~"), (t_newmethod) fofsynth_new,(t_method) fofsynth_free,
+ sizeof(t_fofsynth), 0,A_DEFSYM, A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
+ class_addcreator((t_newmethod)fofsynth_new,gensym("fofsynth~"),A_DEFSYM, A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,A_DEFFLOAT,0);
+ class_addmethod(fofsynth_class, nullfn, gensym("signal"), 0);
+ class_addmethod(fofsynth_class, (t_method) fofsynth_dsp, gensym("dsp"), 0);
+ class_addfloat(fofsynth_class, (t_method) fofsynth_float);
+ class_addmethod(fofsynth_class,(t_method) fofsynth_debug, gensym("debug"),0);
+ cos_maketable();
+ halfcos_maketable();
+ exp_maketable();
+}