From fc3d3c0a4f110a23335398c327ac0a4fc949d5cb Mon Sep 17 00:00:00 2001 From: Guenter Geiger Date: Mon, 17 Jun 2002 10:13:57 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r12, which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/ggee/; revision=13 --- experimental/Makefile | 47 +++++++ experimental/Object.h | 142 +++++++++++++++++++ experimental/fasor.pd | 10 ++ experimental/fasor~.c | 149 ++++++++++++++++++++ experimental/fofsynth.pd | 78 +++++++++++ experimental/fofsynth~.c | 354 +++++++++++++++++++++++++++++++++++++++++++++++ experimental/pvocfreq.c | 114 +++++++++++++++ experimental/stk.cpp | 207 +++++++++++++++++++++++++++ experimental/stk.h | 91 ++++++++++++ experimental/stk.pd | 76 ++++++++++ 10 files changed, 1268 insertions(+) create mode 100755 experimental/Makefile create mode 100755 experimental/Object.h create mode 100755 experimental/fasor.pd create mode 100755 experimental/fasor~.c create mode 100755 experimental/fofsynth.pd create mode 100755 experimental/fofsynth~.c create mode 100755 experimental/pvocfreq.c create mode 100755 experimental/stk.cpp create mode 100755 experimental/stk.h create mode 100755 experimental/stk.pd (limited to 'experimental') diff --git a/experimental/Makefile b/experimental/Makefile new file mode 100755 index 0000000..89ac9f7 --- /dev/null +++ b/experimental/Makefile @@ -0,0 +1,47 @@ +current: nt + + +# TARGETS += stk + +VERSION = \"0.16\" + +.SUFFIXES: .dll .obj +# ----------------------- NT ---------------------------- + +NTOBJECTS = *.obj +NTDLLS = *.dll + +PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo + +PDNTINCLUDE = /I. /I..\..\pd\src + +ProgramFiles = C:\Program Files +PDNTLDIR = "$(ProgramFiles)\Microsoft Visual Studio\Vc98\lib" +#PDNTLDIR = "C:\Programme\Msdev\Vc98\lib" + +PDNTLIB = $(PDNTLDIR)\libc.lib \ + $(PDNTLDIR)\oldnames.lib \ + $(PDNTLDIR)\wsock32.lib \ + $(PDNTLDIR)\kernel32.lib \ + $(PDNTLDIR)\uuid.lib \ + ..\..\pd\bin\pd.lib + +nt: $(NTOBJECTS) + -link /dll $(PDNTLIB) fofsynth~.obj /export:fofsynth_tilde_setup + -link /dll $(PDNTLIB) pvocfreq.obj /export:pvocfreq_setup + -link /dll $(PDNTLIB) fasor~.obj /export:fasor_tilde_setup + + +clean: + del *.obj + del *.dll + + +.c.obj: + -cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c + +.obj.dll: + + + + diff --git a/experimental/Object.h b/experimental/Object.h new file mode 100755 index 0000000..6b453c1 --- /dev/null +++ b/experimental/Object.h @@ -0,0 +1,142 @@ +/*********************************************/ +/* Object Class, by Perry R. Cook, 1995-99 */ +/* */ +/* This is mostly here for compatibility */ +/* with Objective C. We'll also stick */ +/* global defines here, so everyone will */ +/* see them. */ +/*********************************************/ + +#if !defined(__Object_h) +#define __Object_h + +#include +#include +#include +#include + +class Object +{ + public: + protected: + Object(); + virtual ~Object(); +}; + +/* The OS type definitions are made in the Makefile */ + +#if defined(__OS_NeXT_) /* For NeXTStep - Black or White Hardware */ + #define RANDLIMIT 2147483647 +#elif defined(__OS_IRIX_) /* For SGI */ + #define __STK_REALTIME_ + #define RANDLIMIT 2147483647 +#elif defined(__OS_Linux_) /* For Linux */ + #define __STK_REALTIME_ + #define __OSS_API_ /* Use OSS API */ +// #define __MIDIATOR_ /* Use special MIDIator support */ +// #define __ALSA_API_ /* Use ALSA API */ + #define __LITTLE_ENDIAN__ + #define RANDLIMIT 2147483647 +#elif defined(__OS_Win_) /* For WindowsXX or NT */ + #define __STK_REALTIME_ + #define __LITTLE_ENDIAN__ + #define RANDLIMIT 32767 +#endif + +/* + Real-time audio input and output buffer size. If clicks + are occuring in the input or output sound stream, a + larger buffer size may help. Larger buffer sizes, however, + produce more latency between input and output. +*/ +#define RT_BUFFER_SIZE 256 + +/* + The following definition is concatenated to the beginning + of all references to rawwave files in the various STK core + classes (ex. Clarinet.cpp). If you wish to move the + rawwaves directory to a different location in your file + system, you will need to set this path definition + appropriately. The current definition is a relative reference + that will work "out of the box" for the STK distribution. +*/ +#ifndef RAWWAVE_PATH +#define RAWWAVE_PATH "../../" +#endif + +/* Sampling Rate */ +#ifndef SRATE +#define SRATE (MY_FLOAT) 22050.0 +#endif + +/* Other SRATE derived defines */ +#define SRATE_OVER_TWO (MY_FLOAT) (SRATE / 2) +#define ONE_OVER_SRATE (MY_FLOAT) (1 / SRATE) +#define TWO_PI_OVER_SRATE (MY_FLOAT) (2 * PI / SRATE) + +/* Yer Basic Trigonometric constants */ +#if !defined(PI) + #define PI (MY_FLOAT) 3.14159265359 +#endif +#define TWO_PI (MY_FLOAT) (MY_FLOAT) (2 * PI) +#define ONE_OVER_TWO_PI (MY_FLOAT) (1.0 / PI) +#define SQRT_TWO 1.414213562 + +/* Useful random number generator values */ +#define ONE_OVER_RANDLIMIT (1.0/RANDLIMIT) +#define RANDLIMIT_OVER_TWO (int)(RANDLIMIT/2) + +/* FPU Underflow Limit + * The IEEE specification doesn't call for automatic + * zeroing of floating-point values when they reach + * their numerical limits. Instead, most processors + * switch to a much more computation-intensive mode + * when a FPU underflow occurs. We set a lower limit + * here for our own (not so efficient) checks. Here's + * a useful macro for limiting MY_FLOATs. At this time, + * no FPU underflow checks are being performed. + */ + +#define FPU_UFLOW_LIMIT 0.0000000001 +#define LIMIT_MY_FLOAT(j) ((((j)<(MY_FLOAT)FPU_UFLOW_LIMIT)&&((j)>(MY_FLOAT)-FPU_UFLOW_LIMIT))?(MY_FLOAT)0.0:(j)) + +/* States for Envelopes, etc. */ +#define ATTACK 0 +#define DECAY 1 +#define SUSTAIN 2 +#define RELEASE 3 + +/* Machine dependent stuff, possibly useful for optimization. + * For example, changing double to float here increases + * performance (speed) by a whopping 4-6% on 486-flavor machines. + * BUT!! a change from float to double here increases speed by + * 30% or so on SGI machines. +*/ +#define MY_FLOAT double +//#define MY_FLOAT float + +/* MY_MULTI is just a pointer to MY_FLOAT. This type is used + * to pass multichannel data back and forth within STK. +*/ +typedef MY_FLOAT *MY_MULTI; + +/* INT16 is just that ... a 16-bit signed integer. */ +typedef signed short INT16; + +/* INT32 is just that ... a 32-bit signed integer. */ +typedef int INT32; + +/* Boolean values */ +#define FALSE 0 +#define TRUE 1 + +/* Debugging define, causes massive printf's to come out. + * Also enables timing calculations in WaveOut class, other stuff. + * Uncomment to enable. + */ +//#define _debug_ 1 + +/* MIDI definitions */ +#define NORM_7 (MY_FLOAT) 0.0078125 /* this is 1/128 */ + +#endif diff --git a/experimental/fasor.pd b/experimental/fasor.pd new file mode 100755 index 0000000..8294558 --- /dev/null +++ b/experimental/fasor.pd @@ -0,0 +1,10 @@ +#N canvas 166 117 500 171 10; +#X obj 30 43 fasor~; +#X obj 21 90 dac~; +#X floatatom 30 14; +#X text 110 8 fasor is similar to phasor~ \, but changes it's frequency; +#X text 110 23 only at phase 0; +#X text 28 142 (C) 1999 - 2000 Guenter Geiger; +#X connect 0 0 1 0; +#X connect 0 0 1 1; +#X connect 2 0 0 0; diff --git a/experimental/fasor~.c b/experimental/fasor~.c new file mode 100755 index 0000000..ac9b4d3 --- /dev/null +++ b/experimental/fasor~.c @@ -0,0 +1,149 @@ +/* (C) Guenter Geiger */ + + +#include +#include "math.h" + +#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 NT + /* little-endian; most significant byte is at highest address */ +#define HIOFFSET 1 +#define LOWOFFSET 0 +#define int32 long +#else +#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 + +#endif /* __linux__ */ +#endif /* NT */ +#endif /* SGI */ + +union tabfudge +{ + double tf_d; + int32 tf_i[2]; +}; + +typedef struct fasor +{ + t_object x_obj; + double x_phase; + float x_conv; + float x_f; /* used for scalar only */ + float x_fnew; /* used for scalar only */ + double x_flast; /* used for scalar only */ +} t_fasor; + +static t_class *fasor_class; + +static void *fasor_new(t_symbol *s, int argc, t_atom *argv) +{ + t_fasor *x; + x = (t_fasor *)pd_new(fasor_class); + + if (argc) + x->x_f = atom_getfloatarg(0, argc, argv); + else + x->x_f = 0; + + + x->x_flast = 1.0; + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1")); + x->x_phase = 0; + x->x_conv = 0; + outlet_new(&x->x_obj, gensym("signal")); + return (x); +} + +static t_int *fasor_perform(t_int *w) +{ + t_fasor *x = (t_fasor *)(w[1]); + t_float *out = (t_float *)(w[2]); + int n = (int)(w[3]); + + double dphase = x->x_phase + UNITBIT32; + union tabfudge tf; + int normhipart; + float conv = x->x_conv; + double freq = x->x_f; + double flast = x->x_flast; + double fout; + + tf.tf_d = UNITBIT32; + normhipart = tf.tf_i[HIOFFSET]; + tf.tf_d = dphase; + fout = tf.tf_d; + + while (n--) + { + tf.tf_i[HIOFFSET] = normhipart; + dphase += freq * conv; + *out++ = (t_float) (fout = tf.tf_d - UNITBIT32); + tf.tf_d = dphase; + + if (fout <= flast) { + freq = x->x_f = x->x_fnew; /*!! performance if freq = 0 ?? */ + } + + flast = fout; + } + + x->x_flast = flast; + tf.tf_i[HIOFFSET] = normhipart; + x->x_phase = tf.tf_d - UNITBIT32; + return (w+4); +} + +static void fasor_dsp(t_fasor *x, t_signal **sp) +{ + + x->x_conv = 1.f/sp[0]->s_sr; + dsp_add(fasor_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); +} + +static void fasor_ft1(t_fasor *x, t_float f) +{ + x->x_phase = f; +} + +static void fasor_float(t_fasor *x, t_float f) +{ + x->x_fnew = (float) fabs(f); +} + + +void fasor_tilde_setup(void) +{ + fasor_class = class_new(gensym("fasor~"), (t_newmethod)fasor_new, 0, + sizeof(t_fasor), 0, A_GIMME, 0); + class_addmethod(fasor_class, nullfn, gensym("signal"), 0); + class_addmethod(fasor_class, (t_method)fasor_dsp, gensym("dsp"), 0); + class_addmethod(fasor_class, (t_method)fasor_ft1, + gensym("ft1"), A_FLOAT, 0); + class_addfloat(fasor_class,fasor_float); +} diff --git a/experimental/fofsynth.pd b/experimental/fofsynth.pd new file mode 100755 index 0000000..1689622 --- /dev/null +++ b/experimental/fofsynth.pd @@ -0,0 +1,78 @@ +#N canvas 82 59 828 630 8; +#X floatatom 103 48; +#X floatatom 222 82; +#X floatatom 235 117; +#X floatatom 249 179; +#X obj 202 403 dac~; +#X obj 209 237 fofsynth~; +#X text 262 232 fofsynth~ is the same as fof~; +#X text 101 31 fundamental frequency; +#X text 257 82 formant frequency; +#X text 273 116 raise time in percent; +#X text 26 611 (C) Guenter Geiger 1999; +#X obj 209 338 *~; +#X obj 219 285 dbtorms; +#X floatatom 219 267; +#X obj 14 204 osc~; +#X floatatom 14 173; +#X obj 14 223 *~; +#X obj 40 205 sig~ 3; +#X floatatom 54 172; +#X text 12 130 vibrato; +#X text 11 150 freq; +#X text 54 150 depth; +#X obj 103 210 line~; +#X obj 219 319 line~; +#X obj 219 302 pack 100 300; +#X obj 209 372 clip~ -1 1; +#X msg 183 196 debug; +#X msg 623 211 bang; +#X graph graph2 0 -1 10240 1 411 607 811 307; +#X array array1 10240 float; +#X pop; +#X obj 623 283 tabwrite~ array1; +#X msg 710 274 \; array1 resize 10240; +#X msg 151 68 200; +#X obj 542 268 *~; +#X obj 552 248 sig~ 0.2; +#X text 621 191 debug; +#X text 319 5 fof~ in its default mode; +#X text 298 17 =================================; +#X text 291 180 fall time in % of period; +#X floatatom 543 180; +#X text 334 43 THIS IS STILL NOT REALLY FINISHED; +#X msg 151 103 1; +#X obj 14 188 sig~ 4; +#X msg 153 165 200; +#X msg 47 34 120; +#X obj 103 191 pack 100 100; +#X connect 0 0 44 0; +#X connect 1 0 5 1; +#X connect 2 0 5 2; +#X connect 3 0 5 3; +#X connect 5 0 11 0; +#X connect 5 0 32 0; +#X connect 11 0 25 0; +#X connect 12 0 24 0; +#X connect 13 0 12 0; +#X connect 14 0 16 0; +#X connect 15 0 41 0; +#X connect 16 0 5 0; +#X connect 17 0 16 1; +#X connect 18 0 17 0; +#X connect 22 0 5 0; +#X connect 23 0 11 1; +#X connect 24 0 23 0; +#X connect 25 0 4 1; +#X connect 25 0 4 0; +#X connect 26 0 5 0; +#X connect 27 0 29 0; +#X connect 31 0 1 0; +#X connect 32 0 29 0; +#X connect 33 0 32 1; +#X connect 38 0 33 0; +#X connect 40 0 2 0; +#X connect 41 0 14 0; +#X connect 42 0 3 0; +#X connect 43 0 0 0; +#X connect 44 0 22 0; diff --git a/experimental/fofsynth~.c b/experimental/fofsynth~.c new file mode 100755 index 0000000..53df270 --- /dev/null +++ b/experimental/fofsynth~.c @@ -0,0 +1,354 @@ +/* (C) Guenter Geiger */ + + +#include +#include +#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(); +} diff --git a/experimental/pvocfreq.c b/experimental/pvocfreq.c new file mode 100755 index 0000000..4eb30ca --- /dev/null +++ b/experimental/pvocfreq.c @@ -0,0 +1,114 @@ +/* (C) Guenter Geiger */ + + +#include +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +/* ------------------------ shuffle ----------------------------- */ + +static t_class *shuffle_class; + + +typedef struct _shuffle +{ + t_object x_obj; + t_float x; +} t_shuffle; + + +void shuffle_float(t_shuffle *x, t_floatarg f) +{ + post("float %f",f); + x->x = f; +} + + + +static t_int *shuffle_perform(t_int *w) +{ + t_shuffle* x = (t_shuffle*)(w[1]); + t_float* in1 = (t_float*) w[2]; + t_float* in2 = (t_float*) w[3]; + t_float* out = (t_float*) w[4]; + int n = w[5]; + + if (x->x <= 0) { + while (n--) { + *out++ = *in1++; + } + return w+6; + } + + if (x->x < 0.5) { + t_int index = 1/x->x; + while (n--) { + if (n%index){ + *out++ = *in1++; + in2++; + } + else { + *out++ = *in2++; + in1++; + } + } + return w+6; + } + + if (x->x > 1.0) { + while (n--) { + *out++ = *in2++; + } + return w+6; + } + + if (x->x >= 0.5) { + t_int index = 1/(1.0- x->x); + while (n--) { + if (n%index) { + *out++ = *in2++; + in1++; + } + else { + *out++ = *in1++; + in2++; + } + } + } + + return w+6; +} + + +static void shuffle_dsp(t_shuffle *x, t_signal **sp) +{ + dsp_add(shuffle_perform, 5, x, sp[0]->s_vec, + sp[1]->s_vec,sp[2]->s_vec, sp[0]->s_n); + +} + +static void *shuffle_new() +{ + t_shuffle *x = (t_shuffle *)pd_new(shuffle_class); + + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + + + outlet_new(&x->x_obj, gensym("signal")); + return (x); +} + +void shuffle_setup(void) +{ + shuffle_class = class_new(gensym("shuffle~"), (t_newmethod)shuffle_new, 0, + sizeof(t_shuffle), 0,0); + + class_addmethod(shuffle_class, nullfn, gensym("signal"), 0); + class_addmethod(shuffle_class, (t_method) shuffle_dsp, gensym("dsp"), 0); + + class_addfloat(shuffle_class,shuffle_float); +} + + diff --git a/experimental/stk.cpp b/experimental/stk.cpp new file mode 100755 index 0000000..e6229f7 --- /dev/null +++ b/experimental/stk.cpp @@ -0,0 +1,207 @@ +#include +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +/* STK includes */ + +#include "stk.h" + +/* ------------------------ stk ----------------------------- */ + +static t_class *stk_class; + +typedef struct _stk +{ + t_object x_obj; + Instrmnt *instrument; + t_float x_velo; +} t_stk; + + +char* stk_instruments[255]; + +void stk_print(t_stk* x) { + int i=0; + + while (strncmp(stk_instruments[i],"LastInst",8)) { + post("%s",stk_instruments[i]); + i++; + } +} + + +#define DECL_INST(name) if ((stk_instruments[i++] = #name) && !strcmp(s->s_name, #name )) \ +{ x->instrument = new name;} + +#define DECL_INST2(name) if ((stk_instruments[i++] = #name) && !strcmp(s->s_name, #name )) \ +{ x->instrument = new name(80.);} + + +static void stk_set_instrument(t_stk* x,t_symbol* s) +{ + int i = 0; + if (!strcmp(s->s_name,"Simple")) x->instrument = new Simple; + DECL_INST2(Plucked) + DECL_INST2(Plucked2) + DECL_INST2(Mandolin) + DECL_INST2(Bowed) + DECL_INST2(Brass) + DECL_INST2(Clarinet) + DECL_INST2(BlowHole) + DECL_INST2(Flute) + DECL_INST(BowedBar) + DECL_INST(Modal4) + DECL_INST(ModalBar) + DECL_INST(FM4Op) + DECL_INST(FM4Alg3) + DECL_INST(FM4Alg4) + DECL_INST(FM4Alg5) + DECL_INST(FM4Alg6) + DECL_INST(FM4Alg8) + DECL_INST(HeavyMtl) + DECL_INST(PercFlut) + DECL_INST(Rhodey) + DECL_INST(Wurley) + DECL_INST(TubeBell) + DECL_INST(FMVoices) + DECL_INST(BeeThree) + DECL_INST(Sampler) + DECL_INST(SamplFlt) + DECL_INST(Moog1) + // DECL_INST(VoicForm) + DECL_INST(DrumSynt) + DECL_INST(Shakers) + DECL_INST2(Sitar1) + DECL_INST2(StrDrone) + else { + error("No such instrument %s",s->s_name); + } + stk_instruments[i] = "LastInst"; +} + + +static void stk_bang(t_stk *x) +{ + post("bang"); +} + + +static t_int *stk_perform(t_int *w) +{ + t_stk* x = (t_stk*)(w[1]); + t_float *out = (t_float *)(w[2]); + int n = (int)(w[3]); + + while (n--) { + *out++ = x->instrument->tick(); + } + + + return (w+4); +} + + +static void stk_dsp(t_stk *x, t_signal **sp) +{ + dsp_add(stk_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); +} + + +static void stk_noteOn(t_stk *x,t_float f) +{ + x->instrument->noteOn(f,x->x_velo); +} + + +static void stk_noteOff(t_stk *x) +{ + x->instrument->noteOff(0); +} + + +static void stk_control(t_stk *x,t_floatarg f1,t_floatarg f2) +{ + x->instrument->controlChange(f1,f2); +} + +static void stk_control1(t_stk *x,t_floatarg f1) +{ + x->instrument->controlChange(1,f1); +} + +static void stk_control2(t_stk *x,t_floatarg f1) +{ + x->instrument->controlChange(2,f1); +} + +static void stk_control3(t_stk *x,t_floatarg f1) +{ + x->instrument->controlChange(3,f1); +} + +static void stk_control4(t_stk *x,t_floatarg f1) +{ + x->instrument->controlChange(4,f1); +} + +static void stk_aftertouch(t_stk *x,t_floatarg f1) +{ + x->instrument->controlChange(128,f1); +} + +static void stk_pitchbend(t_stk *x,t_floatarg f1) +{ + x->instrument->setFreq(f1); +} + +static void stk_float(t_stk* x,t_floatarg f) +{ + if (f > 20) stk_noteOn(x,f); + else stk_noteOff(x); + +} + + +static void *stk_new(t_symbol* s) +{ + t_stk *x = (t_stk *)pd_new(stk_class); + + stk_set_instrument(x,s); + + if (x->instrument == NULL) { + post("stk: %s no such instrument",s->s_name); + return NULL; + } + floatinlet_new(&x->x_obj, &x->x_velo); + x->x_velo = 0.1; + + outlet_new(&x->x_obj, gensym("signal")); + + return (x); +} + + + +extern "C" { + void stk_setup(void) + { + stk_class = class_new(gensym("stk"), (t_newmethod)stk_new, 0, + sizeof(t_stk), 0,A_DEFSYM,A_NULL); + class_addmethod(stk_class, nullfn, gensym("signal"), A_NULL); + class_addmethod(stk_class, (t_method) stk_dsp, gensym("dsp"), A_NULL); + + class_addbang(stk_class,stk_bang); + class_addfloat(stk_class,stk_float); + class_addmethod(stk_class,(t_method) stk_control,gensym("control"),A_DEFFLOAT,A_DEFFLOAT,A_NULL); + class_addmethod(stk_class,(t_method) stk_control1,gensym("control1"),A_DEFFLOAT,A_NULL); + class_addmethod(stk_class,(t_method) stk_control2,gensym("control2"),A_DEFFLOAT,A_NULL); + class_addmethod(stk_class,(t_method) stk_control3,gensym("control3"),A_DEFFLOAT,A_NULL); + class_addmethod(stk_class,(t_method) stk_control4,gensym("control4"),A_DEFFLOAT,A_NULL); + class_addmethod(stk_class,(t_method) stk_aftertouch,gensym("aftertouch"),A_DEFFLOAT,A_NULL); + class_addmethod(stk_class,(t_method) stk_pitchbend,gensym("pitchbend"),A_DEFFLOAT,A_NULL); + class_addmethod(stk_class,(t_method) stk_print,gensym("print"),A_NULL); + + } +} diff --git a/experimental/stk.h b/experimental/stk.h new file mode 100755 index 0000000..2fa1ec0 --- /dev/null +++ b/experimental/stk.h @@ -0,0 +1,91 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/experimental/stk.pd b/experimental/stk.pd new file mode 100755 index 0000000..85c161c --- /dev/null +++ b/experimental/stk.pd @@ -0,0 +1,76 @@ +#N canvas 226 44 704 495 12; +#X obj 50 422 dac~; +#X obj 19 295 stk Rhodey; +#X obj 19 321 throw~ out1; +#X obj 61 379 catch~ out1; +#X obj 19 246 mtof; +#X floatatom 19 87 0 0 0; +#X msg 56 247 0; +#X floatatom 100 112 0 0 0; +#X msg 56 112 bang; +#X obj 56 134 pipe 600; +#X floatatom 97 230 0 0 0; +#X obj 97 254 * 0.01; +#X text 95 211 velocity; +#X obj 380 383 stk Flute; +#X obj 380 350 mtof; +#X floatatom 380 277 0 0 0; +#X msg 417 351 0; +#X floatatom 461 302 0 0 0; +#X msg 417 302 bang; +#X obj 417 324 pipe 600; +#X floatatom 483 331 0 0 0; +#X obj 483 355 * 0.01; +#X text 481 312 velocity; +#X obj 380 411 throw~ out1; +#X floatatom 557 299 0 0 0; +#X obj 130 319 throw~ out1; +#X floatatom 208 242 0 0 0; +#X obj 208 266 * 0.01; +#X text 206 223 velocity; +#X obj 130 293 stk BeeThree; +#X msg 557 323 control 1 \$1; +#X msg 161 97 print; +#X text 233 96 print: prints out all available stk instruments; +#X text 232 113 control f1 f2: sets the control channel f1 to the; +#X text 255 129 value of f2; +#X text 230 150 control1: short for control 1 f2; +#X text 28 14 PD interface to Perry Cook's STK; +#X text 231 48 Messages; +#X text 229 63 ===========; +#X text 231 79 float number: sets the frequency in Hz; +#X text 230 171 aftertouch \, pitchbend: MIDI values for aftertouch +and pitchbend; +#X msg 319 248 print; +#X text 317 224 click to see available instruments; +#X connect 1 0 2 0; +#X connect 3 0 0 0; +#X connect 3 0 0 1; +#X connect 4 0 1 0; +#X connect 4 0 29 0; +#X connect 5 0 4 0; +#X connect 5 0 8 0; +#X connect 6 0 1 0; +#X connect 6 0 29 0; +#X connect 7 0 9 1; +#X connect 8 0 9 0; +#X connect 9 0 6 0; +#X connect 10 0 11 0; +#X connect 11 0 1 1; +#X connect 13 0 23 0; +#X connect 14 0 13 0; +#X connect 15 0 14 0; +#X connect 15 0 18 0; +#X connect 16 0 13 0; +#X connect 17 0 19 1; +#X connect 18 0 19 0; +#X connect 19 0 16 0; +#X connect 20 0 21 0; +#X connect 21 0 13 1; +#X connect 24 0 30 0; +#X connect 26 0 27 0; +#X connect 27 0 29 1; +#X connect 29 0 25 0; +#X connect 30 0 13 0; +#X connect 31 0 1 0; +#X connect 41 0 13 0; -- cgit v1.2.1