diff options
Diffstat (limited to 'randomix.c')
-rw-r--r-- | randomix.c | 874 |
1 files changed, 0 insertions, 874 deletions
diff --git a/randomix.c b/randomix.c deleted file mode 100644 index 4700766..0000000 --- a/randomix.c +++ /dev/null @@ -1,874 +0,0 @@ -/* - (c) 2002:cxc@web.fm - randomix: various PRNG's - code taken from: http://remus.rutgers.edu/%7Erhoads/Code/code.html - let's check it out - */ - -#include <m_pd.h> -#include <stdlib.h> -#include <math.h> - -#define SMALLEST_RANGE .0001 - -#ifndef RAND_MAX -#define RAND_MAX 2147483647 -#endif - -static unsigned random_icg_INVERSE_seed (); -static int makeseed(void); -static int rand_random1(int); -static int rand_random_fl(int); -static int rand_random_icg(int, int); -static unsigned int rand_random_icg_INVERSE_seed(int, int); -//static void random_tw_rand_seed(t_class, int, int, int); - -static int makeseed(void) -{ - static unsigned int random1_nextseed = 1489853723; - random1_nextseed = random1_nextseed * 435898247 + 938284287; - return (random1_nextseed & 0x7fffffff); -} - -/* -------------------------- random1 ------------------------------ */ -/* linear congruential generator. Generator x[n+1] = a * x[n] mod m */ -static int rand_random1(seed) -{ - int state; - - //unsigned int a = 1588635695, m = 4294967291U, q = 2, r = 1117695901; - // unsigned int a = 1588635695, m = (RAND_MAX * 2), q = 2, r = 1117695901; - - /* static unsigned int a = 1223106847, m = 4294967291U, q = 3, r = 625646750;*/ - /* static unsigned int a = 279470273, m = 4294967291U, q = 15, r = 102913196;*/ - //static unsigned int a = 1583458089, m = 2147483647, q = 1, r = 564025558; - static unsigned int a = 784588716, m = 2147483647, q = 2, r = 578306215; - /* static unsigned int a = 16807, m = 2147483647, q = 127773, r = 2836; */ - /* static unsigned int a = 950706376, m = 2147483647, q = 2, r = 246070895; */ - - //state = (seed) ? seed : makeseed(); - state = seed; - state = a*(state % q) - r*(state / q); - return (state); -} - -static int rand_random_fl(seed) { - int q; - double state; - - /* The following parameters are recommended settings based on research - uncomment the one you want. */ - - double a = 1389796, m = RAND_MAX; - /* static double a = 950975, m = 2147483647; */ - /* static double a = 3467255, m = 21474836472; */ - /* static double a = 657618, m = 4294967291; */ - /* static double a = 93167, m = 4294967291; */ - /* static double a = 1345659, m = 4294967291; */ - - state = seed; - state *= a; - q = state / m; - state -= q*m; - return state; -} - -static int rand_random_icg(seed, p) -{ - static int a, b, q, r; - int state; - unsigned int inv; - a = 22211, b = 11926380,q = 96685, r = 12518; - /* static int p = 2147483053, a = 858993221, b = 1,q = 2, r = 429496611;*/ - /* static int p = 2147483053, a = 579, b = 24456079, q = 3708951, r = 424;*/ - /* static int p = 2147483053, a = 11972, b = 62187060,q = 179375, r = 5553;*/ - /* static int p = 2147483053, a = 21714, b = 94901263,q = 98898, r = 11881;*/ - /* static int p = 2147483053, a = 4594, b = 44183289,q = 467453, r = 3971;*/ - /* static int p = 2147483647, a = 1288490188, b = 1, q = 1, r = 858993459;*/ - /* static int p = 2147483647, a = 9102, b = 36884165, q = 235935, r =3277;*/ - /* static int p = 2147483647, a = 14288, b = 758634, q = 150299, r = 11535;*/ - /* static int p = 2147483647, a = 21916, b = 71499791, q = 97987, r = 555;*/ - /* static int p = 2147483647, a = 28933, b = 59217914, q = 74222, r = 18521;*/ - /* static int p = 2147483647, a = 31152, b = 48897674, q = 68935, r = 20527;*/ - - // state = seed; - - inv = rand_random_icg_INVERSE_seed(seed, p); - - state = a*(inv % q) - r*(inv / q) + b; - - if (state < 0) state += p; - else if (state >= state) state -= p; - - return state; -} - -/* Modular Inversion using the extended Euclidean alg. for GCD */ -/***************************************************************/ -static unsigned rand_random_icg_INVERSE_seed (int state, int p) -{ - unsigned int q,d; - signed int u,v,inv,t; - - if (state <= 1) return(state); - - d = p; inv = 0; v = 1; u = state; - - do { - q = d / u; - t = d % u; - d = u; - u = t; - t = inv - q*v; - inv = v; - v = t; - } while (u != 0); - - if (inv < 0 ) inv += p; - -/* if (1 != d) */ -/* post ("inverse_iter: Can't invert !"); */ - - return(inv); -} - -/* -------------------------- random1 ------------------------------ */ -/* linear congruential generator. Generator x[n+1] = a * x[n] mod m */ - -static t_class *random1_class; - -typedef struct _random1 -{ - t_object x_obj; - t_float x_f; // lower limit - t_float x_g; // upper limit - unsigned int x_state; // current seed -} t_random1; - -static void *random1_new(t_floatarg f, t_floatarg g) -{ - t_random1 *x = (t_random1 *)pd_new(random1_class); - x->x_f = (f) ? f : 0; - x->x_g = (g) ? g : RAND_MAX; - //post("cxc/randomix.c: lolim: %f - %f, uplim: %f - %f", x->x_f, f, x->x_g, g); - x->x_state = makeseed(); - inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("fl1")); - inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("fl2")); - outlet_new(&x->x_obj, &s_float); - return (x); -} - -/* -------------------------- random_fl ------------------------------ */ -/* An improved (faster) implementation of the Linear Congruential Generator. Has parameters for 6 separate */ -/* linear congruence formulas. These formulas are different than those above because the previous formulas won't work */ -/* correctly in this implementation. Also, this method only works if your floating point mantissa has at least 53 bits. */ - -/* linear congruential generator. Generator x[n+1] = a * x[n] mod m */ -/* works if your floating pt. mantissa has at least 53 bits. - faster than other versions */ -static void random1_bang(t_random1 *x) -{ - int n = x->x_f; - double nval; - unsigned int m; - // this seems weird? - m = (RAND_MAX * 2); - // unsigned int a = 1588635695, m = 4294967291U, q = 2, r = 1117695901; - - // post("cxc/randomix.c: x_state: %d",x->x_state); - x->x_state = rand_random1(x->x_state); - nval = ((double)x->x_state / (double)m) * (double)(x->x_g - x->x_f) + (double)x->x_f; - // post("cxc/randomix.c: lolim: %f, uplim: %f", x->x_f, x->x_g); - // post("cxc/randomix.c: nval: %f",nval); - outlet_float(x->x_obj.ob_outlet, nval); -} - -void random1_low(t_random1 *x, t_floatarg f) -{ - if(f >= x->x_g) { - post("cxc/randomix.c: lower larger than upper, setting to upper - %f = %f", - SMALLEST_RANGE, - x->x_g - SMALLEST_RANGE); - x->x_f = x->x_g - SMALLEST_RANGE; - } else x->x_f = f; -} - -void random1_upp(t_random1 *x, t_floatarg f) -{ - if(f <= x->x_f) { - post("cxc/randomix.c: upper smaller than lower, setting to lower + %f = %f", - SMALLEST_RANGE, - x->x_f + SMALLEST_RANGE); - x->x_g = x->x_f + SMALLEST_RANGE; - } else x->x_g = f; -} - -static void random1_seed(t_random1 *x, float f, float glob) -{ - x->x_state = f; -} - -void random1_setup(void) -{ - random1_class = class_new(gensym("random1"), (t_newmethod)random1_new, 0, - sizeof(t_random1), 0, A_DEFFLOAT, A_DEFFLOAT, 0); - class_addbang(random1_class, random1_bang); - class_addmethod(random1_class, (t_method)random1_low, gensym("fl1"), A_FLOAT, 0); - class_addmethod(random1_class, (t_method)random1_upp, gensym("fl2"), A_FLOAT, 0); - - class_addmethod(random1_class, (t_method)random1_seed, - gensym("seed"), A_FLOAT, 0); -} - - -/* -------------------------- random1 ------------------------------ */ -/* linear congruential generator. Generator x[n+1] = a * x[n] mod m */ -/* signal version */ - -static t_class *random1_tilde_class; - -typedef struct _random1_tilde -{ - t_object x_obj; - unsigned int x_state; // current seed -} t_random1_tilde; - -static void *random1_tilde_new() -{ - t_random1_tilde *x = (t_random1_tilde *)pd_new(random1_tilde_class); - x->x_state = makeseed(); - outlet_new(&x->x_obj, gensym("signal")); - return (x); -} - -static void random1_tilde_seed(t_random1_tilde *x, float f, float glob) -{ - x->x_state = f; -} - -static t_int *random1_tilde_perform(t_int *w) -{ - t_random1_tilde *x = (t_random1_tilde *)(w[1]); - t_float *out = (t_float *)(w[2]); - int n = (int)(w[3]); - - while (n--) { - // generate new noise sample - x->x_state = rand_random1(x->x_state); - *out++ = (t_float)x->x_state / RAND_MAX - 1; - } - - return (w+4); -} - -static void random1_tilde_dsp(t_random1_tilde *x, t_signal **sp) -{ - dsp_add(random1_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); -} - -void random1_tilde_setup(void) -{ - random1_tilde_class = class_new(gensym("random1~"), - (t_newmethod)random1_tilde_new, - 0, sizeof(t_random1_tilde), 0, 0); - class_addmethod(random1_tilde_class, (t_method)random1_tilde_seed,gensym("seed"), A_FLOAT, 0); - class_addmethod(random1_tilde_class, (t_method)random1_tilde_dsp, gensym("dsp"), 0); -} - - - -/* -------------------------- random_fl ------------------------------ */ -/* An improved (faster) implementation of the Linear Congruential Generator. Has parameters for 6 separate */ -/* linear congruence formulas. These formulas are different than those above because the previous formulas won't work */ -/* correctly in this implementation. Also, this method only works if your floating point mantissa has at least 53 bits. */ - -/* linear congruential generator. Generator x[n+1] = a * x[n] mod m */ -/* works if your floating pt. mantissa has at least 53 bits. - faster than other versions */ - -static t_class *random_fl_class; - -typedef struct _random_fl -{ - t_object x_obj; - t_float x_f; // lower limit - t_float x_g; // upper limit - unsigned int x_state; // current seed -} t_random_fl; - -static void *random_fl_new(t_floatarg f, t_floatarg g) -{ - t_random_fl *x = (t_random_fl *)pd_new(random_fl_class); - x->x_f = (f) ? f : 0; - x->x_g = (g) ? g : RAND_MAX; - //post("cxc/randomix.c: lolim: %f - %f, uplim: %f - %f", x->x_f, f, x->x_g, g); - x->x_state = makeseed(); - inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("fl1")); - inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("fl2")); - outlet_new(&x->x_obj, &s_float); - return (x); -} - -void random_fl_bang(t_random_fl *x) -{ - int n = x->x_f; - int q; - double nval; - double m; - - m = RAND_MAX; - x->x_state = rand_random_fl(x->x_state); - nval = ((x->x_state / m) * (double)(x->x_g - x->x_f) + (double)x->x_f); - outlet_float(x->x_obj.ob_outlet, nval); -} - -void random_fl_low(t_random_fl *x, t_floatarg f) -{ - if(f >= x->x_g) { - post("cxc/randomix.c: lower larger than upper, setting to upper - %f = %f", - SMALLEST_RANGE, - x->x_g - SMALLEST_RANGE); - x->x_f = x->x_g - SMALLEST_RANGE; - } else x->x_f = f; -} - -void random_fl_upp(t_random_fl *x, t_floatarg f) -{ - if(f <= x->x_f) { - post("cxc/randomix.c: upper smaller than lower, setting to lower + %f = %f", - SMALLEST_RANGE, - x->x_f + SMALLEST_RANGE); - x->x_g = x->x_f + SMALLEST_RANGE; - } else x->x_g = f; -} - -static void random_fl_seed(t_random_fl *x, float f, float glob) -{ - x->x_state = f; -} - -void random_fl_setup(void) -{ - random_fl_class = class_new(gensym("random_fl"), (t_newmethod)random_fl_new, 0, - sizeof(t_random_fl), 0, A_DEFFLOAT, A_DEFFLOAT, 0); - class_addbang(random_fl_class, random_fl_bang); - class_addmethod(random_fl_class, (t_method)random_fl_low, gensym("fl1"), A_FLOAT, 0); - class_addmethod(random_fl_class, (t_method)random_fl_upp, gensym("fl2"), A_FLOAT, 0); - - class_addmethod(random_fl_class, (t_method)random_fl_seed, - gensym("seed"), A_FLOAT, 0); -} - -/* ------------------------------- random_fl signal version -------------------- */ - -static t_class *random_fl_tilde_class; - -typedef struct _random_fl_tilde -{ - t_object x_obj; - unsigned int x_state; // current seed -} t_random_fl_tilde; - -static void *random_fl_tilde_new() -{ - t_random_fl_tilde *x = (t_random_fl_tilde *)pd_new(random_fl_tilde_class); - x->x_state = makeseed(); - outlet_new(&x->x_obj, gensym("signal")); - return (x); -} - -static void random_fl_tilde_seed(t_random_fl_tilde *x, float f, float glob) -{ - x->x_state = f; -} - -static t_int *random_fl_tilde_perform(t_int *w) -{ - t_random_fl_tilde *x = (t_random_fl_tilde *)(w[1]); - t_float *out = (t_float *)(w[2]); - int n = (int)(w[3]); - - while (n--) { - // generate new noise sample - x->x_state = rand_random_fl(x->x_state); - *out++ = (t_float)x->x_state / RAND_MAX * 2 - 1; - } - - return (w+4); -} - -static void random_fl_tilde_dsp(t_random_fl_tilde *x, t_signal **sp) -{ - dsp_add(random_fl_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); -} - -void random_fl_tilde_setup(void) -{ - random_fl_tilde_class = class_new(gensym("random_fl~"), - (t_newmethod)random_fl_tilde_new, 0, - sizeof(t_random_fl_tilde), 0, 0); - class_addmethod(random_fl_tilde_class, (t_method)random_fl_tilde_seed, - gensym("seed"), A_FLOAT, 0); - class_addmethod(random_fl_tilde_class, (t_method)random_fl_tilde_dsp, gensym("dsp"), 0); -} - - - - -/* -------------------------- random_icg ------------------------------ */ -/* Inverse Congruential generator. This generator is quite a bit slower than the other ones on this page. and it */ -/* fails some statistical tests. The main factor in its favor is that its properties tend to be the opposite of linear congruential */ -/* generators. I.e. this generator is very likely to be good for those applications where linear congruential generators are */ -/* bad. You can choose among several parameters. */ - -/* inversive congruential generator. */ - -static t_class *random_icg_class; - -typedef struct _random_icg -{ - t_object x_obj; - t_float x_f; // lower limit - t_float x_g; // upper limit - t_float x_p; // 1st shared parameter of iter function .. - unsigned int x_state; // current seed -} t_random_icg; - -static void *random_icg_new(t_floatarg f, t_floatarg g) -{ - t_random_icg *x = (t_random_icg *)pd_new(random_icg_class); - x->x_f = (f) ? f : 0; - x->x_g = (g) ? g : RAND_MAX; - x->x_p = 2147483053; - //post("cxc/randomix.c: lolim: %f - %f, uplim: %f - %f", x->x_f, f, x->x_g, g); - x->x_state = makeseed(); - inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("fl1")); - inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("fl2")); - outlet_new(&x->x_obj, &s_float); - return (x); -} - -static void random_icg_bang(t_random_icg *x) -{ - double nval; - - x->x_state = rand_random_icg(x->x_state, x->x_p); - - nval = (((x->x_state / x->x_p) - 1) * (double)(x->x_g - x->x_f) + (double)x->x_f); - - // hakc, why is it out of range? - if(nval < (double)x->x_f) { - random_icg_bang(x); - } else { - outlet_float(x->x_obj.ob_outlet, nval); - } -} - -void random_icg_low(t_random_icg *x, t_floatarg f) -{ - if(f >= x->x_g) { - post("cxc/randomix.c: lower larger than upper, setting to upper - %f = %f", - SMALLEST_RANGE, - x->x_g - SMALLEST_RANGE); - x->x_f = x->x_g - SMALLEST_RANGE; - } else x->x_f = f; -} - -void random_icg_upp(t_random_icg *x, t_floatarg f) -{ - if(f <= x->x_f) { - post("cxc/randomix.c: upper smaller than lower, setting to lower + %f = %f", - SMALLEST_RANGE, - x->x_f + SMALLEST_RANGE); - x->x_g = x->x_f + SMALLEST_RANGE; - } else x->x_g = f; -} - -static void random_icg_seed(t_random_icg *x, float f, float glob) -{ - x->x_state = f; -} - -void random_icg_setup(void) -{ - random_icg_class = class_new(gensym("random_icg"), (t_newmethod)random_icg_new, 0, - sizeof(t_random_icg), 0, A_DEFFLOAT, A_DEFFLOAT, 0); - class_addbang(random_icg_class, random_icg_bang); - class_addmethod(random_icg_class, (t_method)random_icg_low, gensym("fl1"), A_FLOAT, 0); - class_addmethod(random_icg_class, (t_method)random_icg_upp, gensym("fl2"), A_FLOAT, 0); - - class_addmethod(random_icg_class, (t_method)random_icg_seed, - gensym("seed"), A_FLOAT, 0); -} - - -/* -------------------------- random_icg ------------------------------ */ -/* inverse congruential generator. */ - -static t_class *random_icg_tilde_class; - -typedef struct _random_icg_tilde -{ - t_object x_obj; - t_float x_f; // lower limit - t_float x_g; // upper limit - t_float x_p; // 1st shared parameter of iter function .. - unsigned int x_state; // current seed -} t_random_icg_tilde; - -static void *random_icg_tilde_new() -{ - t_random_icg_tilde *x = (t_random_icg_tilde *)pd_new(random_icg_tilde_class); -/* x->x_f = (f) ? f : 0; */ -/* x->x_g = (g) ? g : RAND_MAX; */ - x->x_p = 2147483053; - //post("cxc/randomix.c: lolim: %f - %f, uplim: %f - %f", x->x_f, f, x->x_g, g); - x->x_state = makeseed(); - outlet_new(&x->x_obj, gensym("signal")); - return (x); -} - -static void random_icg_tilde_bang(t_random_icg_tilde *x) -{ - double nval; - - x->x_state = rand_random_icg(x->x_state, x->x_p); - - nval = (((x->x_state / x->x_p) - 1) * (double)(x->x_g - x->x_f) + (double)x->x_f); - - // hakc, why is it out of range? - if(nval < (double)x->x_f) { - random_icg_tilde_bang(x); - } else { - outlet_float(x->x_obj.ob_outlet, nval); - } -} - -static void random_icg_tilde_seed(t_random_icg_tilde *x, float f, float glob) -{ - x->x_state = f; -} - -static t_int *random_icg_tilde_perform(t_int *w) -{ - t_random_icg_tilde *x = (t_random_icg_tilde *)(w[1]); - t_float *out = (t_float *)(w[2]); - int n = (int)(w[3]); - - while (n--) { - // generate new noise sample - x->x_state = rand_random_icg(x->x_state, x->x_p); - *out++ = (t_float)(x->x_state / x->x_p - 1) * 2 - 1; - } - - return (w+4); -} - - -static void random_icg_tilde_dsp(t_random_icg_tilde *x, t_signal **sp) -{ - dsp_add(random_icg_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); -} - - -void random_icg_tilde_setup(void) -{ - random_icg_tilde_class = class_new(gensym("random_icg~"), (t_newmethod)random_icg_tilde_new, 0, - sizeof(t_random_icg_tilde), 0, A_DEFFLOAT, A_DEFFLOAT, 0); - class_addmethod(random_icg_tilde_class, (t_method)random_icg_tilde_seed, - gensym("seed"), A_FLOAT, 0); - class_addmethod(random_icg_tilde_class, (t_method)random_icg_tilde_dsp, gensym("dsp"), 0); -} - - - -/* -------------------------- random_tw ------------------------------ */ -/* Combination of three tausworth generators. Has parameters for two different generators. Fast and excellent. */ -/* Combination of 3 tausworth generators -- assumes 32-bit integers */ - -static t_class *random_tw_class; - -typedef struct _random_tw -{ - t_object x_obj; - t_float x_f; // lower limit - t_float x_g; // upper limit - - t_int x_s1; - t_int x_s2; - t_int x_s3; - - t_int x_mask1; - t_int x_mask2; - t_int x_mask3; - - t_int x_shft1; - t_int x_shft2; - t_int x_shft3; - t_int x_k1; - t_int x_k2; - t_int x_k3; - - t_int x_q1; - t_int x_q2; - t_int x_q3; - t_int x_p1; - t_int x_p2; - t_int x_p3; - - unsigned int x_state; // current seed -} t_random_tw; - -void random_tw_rand_seed (t_random_tw *x, unsigned int a, unsigned int b, unsigned int c) -{ - static unsigned int zf = 4294967295U; - - x->x_shft1 = x->x_k1 - x->x_p1; - x->x_shft2=x->x_k2-x->x_p2; - x->x_shft3=x->x_k3-x->x_p3; - x->x_mask1 = zf << (32-x->x_k1); - x->x_mask2 = zf << (32-x->x_k2); - x->x_mask3 = zf << (32-x->x_k3); - if (a > (unsigned int)(1<<x->x_shft1)) x->x_s1 = a; - if (b > (unsigned int)(1<<x->x_shft2)) x->x_s2 = b; - if (c > (unsigned int)(1<<x->x_shft3)) x->x_s3 = c; - // rand(); -} - -static void *random_tw_new(t_floatarg f, t_floatarg g) -{ - t_random_tw *x = (t_random_tw *)pd_new(random_tw_class); - - x->x_f = (f) ? f : 0; - x->x_g = (g) ? g : RAND_MAX; - //post("cxc/randomix.c: lolim: %f - %f, uplim: %f - %f", x->x_f, f, x->x_g, g); - x->x_state = makeseed(); - - x->x_s1=390451501; - x->x_s2=613566701; - x->x_s3=858993401; - - x->x_k1=31; - x->x_k2=29; - x->x_k3=28; - - x->x_q1=13; - x->x_q2=2; - x->x_q3=3; - x->x_p1=12; - x->x_p2=4; - x->x_p3=17; - -/* x->x_q1=3; */ -/* x->x_q2=2; */ -/* x->x_q3=13; */ -/* x->x_p1=20; */ -/* x->x_p2=16; */ -/* x->x_p3=7; */ - - random_tw_rand_seed(x, makeseed(),makeseed(),makeseed()); - inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("fl1")); - inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("fl2")); - outlet_new(&x->x_obj, &s_float); - return (x); -} - - -static void random_tw_bang(t_random_tw *x) -{ - unsigned int b; - double nval; - static unsigned int zf = 4294967295U; - - b = ((x->x_s1 << x->x_q1)^x->x_s1) >> x->x_shft1; - x->x_s1 = ((x->x_s1 & x->x_mask1) << x->x_p1) ^ b; - b = ((x->x_s2 << x->x_q2) ^ x->x_s2) >> x->x_shft2; - x->x_s2 = ((x->x_s2 & x->x_mask2) << x->x_p2) ^ b; - b = ((x->x_s3 << x->x_q3) ^ x->x_s3) >> x->x_shft3; - x->x_s3 = ((x->x_s3 & x->x_mask3) << x->x_p3) ^ b; - nval = (((double)(x->x_s1 ^ x->x_s2 ^ x->x_s3) / (double)(zf) + 0.5) * (double)(x->x_g - x->x_f) + (double)x->x_f); - - //nval = ((x->x_state / (double)m) * (double)(x->x_g - x->x_f) + (double)x->x_f); - //post("cxc/randomix.c: current rand: %f", nval); - outlet_float(x->x_obj.ob_outlet, nval); -} - -void random_tw_low(t_random_tw *x, t_floatarg f) -{ - if(f >= x->x_g) { - post("cxc/randomix.c: lower larger than upper, setting to upper - %f = %f", - SMALLEST_RANGE, - x->x_g - SMALLEST_RANGE); - x->x_f = x->x_g - SMALLEST_RANGE; - } else x->x_f = f; -} - -void random_tw_upp(t_random_tw *x, t_floatarg f) -{ - if(f <= x->x_f) { - post("cxc/randomix.c: upper smaller than lower, setting to lower + %f = %f", - SMALLEST_RANGE, - x->x_f + SMALLEST_RANGE); - x->x_g = x->x_f + SMALLEST_RANGE; - } else x->x_g = f; -} - -static void random_tw_seed(t_random_tw *x, float f, float glob) -{ - //x->x_state = f; - // questionable .. dont quite get how this one's seeded .. - random_tw_rand_seed(x, (int)f, (int)(f*0.455777), (int)f); -} - -static void random_tw_help(t_random_tw *x) -{ - post("RAND_MAX: %d",RAND_MAX); - post("range: %f - %f", x->x_f, x->x_g); -} - -void random_tw_setup(void) -{ - random_tw_class = class_new(gensym("random_tw"), (t_newmethod)random_tw_new, 0, - sizeof(t_random_tw), 0, A_DEFFLOAT, A_DEFFLOAT, 0); - class_addbang(random_tw_class, random_tw_bang); - class_addmethod(random_tw_class, (t_method)random_tw_low, gensym("fl1"), A_FLOAT, 0); - class_addmethod(random_tw_class, (t_method)random_tw_upp, gensym("fl2"), A_FLOAT, 0); - - class_addmethod(random_tw_class, (t_method)random_tw_seed, - gensym("seed"), A_FLOAT, 0); - class_addmethod(random_tw_class, (t_method)random_tw_help, - gensym("help"), 0, 0); -} - - - - -/* -------------------------- dist_normal ------------------------------ */ -/* Generate a normal random variable with mean 0 and standard deviation - of 1. To adjust to some other distribution, multiply by the standard - deviation and add the mean. Box-Muller method - note: rand() is a function that returns a uniformly distributed random - number from 0 to RAND_MAX -*/ - -static t_class *dist_normal_class; - -typedef struct _dist_normal -{ - t_object x_obj; - t_float x_mn; // mean - t_float x_dv; // deviation - t_float x_u1; - t_float x_u2; - - t_float x_f; // lower limit - t_float x_g; // upper limit - unsigned int x_state; // current seed -} t_dist_normal; - -static void *dist_normal_new(t_floatarg mn, t_floatarg dv) -{ - t_dist_normal *x = (t_dist_normal *)pd_new(dist_normal_class); - x->x_mn = (mn) ? mn : 0; - x->x_dv = (dv) ? dv : 1; - x->x_u1 = 13; - x->x_u2 = 1000; - x->x_f = 0; - x->x_g = RAND_MAX; - //post("cxc/randomix.c: lolim: %f - %f, uplim: %f - %f", x->x_f, f, x->x_g, g); - x->x_state = makeseed(); - inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("fl1")); - // inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("fl2")); - //outlet_new(&x->x_obj, &s_float); - outlet_new(&x->x_obj, 0); - return (x); -} - -static double dist_normal_rand(t_dist_normal *x) -{ - int n = x->x_f; - double nval; - double m; - - m = (double)RAND_MAX * 2; - - // post("cxc/randomix.c: x_state: %d",x->x_state); - x->x_state = rand_random_fl(x->x_state); - //nval = ((double)x->x_state / m) * (double)(x->x_g - x->x_f) + (double)x->x_f; - nval = (double)x->x_state; - return (nval); -} - -static void dist_normal_doit(t_dist_normal *x) -{ - static double V2, fac; - static int phase = 0; - double S, Z, U1, U2, V1; - - if (phase) - Z = V2 * fac; - else - { - do { -/* U1 = (double)rand() / RAND_MAX; */ -/* U2 = (double)rand() / RAND_MAX; */ - U1 = (double)dist_normal_rand(x) / RAND_MAX; - U2 = (double)dist_normal_rand(x) / RAND_MAX; - - // post("cxc/randomix.c: test %f %f %f %f", x->x_u1, x->x_u2, U1, U2); - - V1 = 2 * U1 - 1; - V2 = 2 * U2 - 1; - S = V1 * V1 + V2 * V2; - } while(S >= 1); - - fac = sqrt (-2 * log(S) / S); - Z = V1 * fac; - } - - phase = 1 - phase; - - //return Z; - outlet_float(x->x_obj.ob_outlet, Z); -} - -static void dist_normal_bang(t_dist_normal *x) -{ -/* post("cxc/randomix.c: dist_normal banged"); */ -/* post("cxc/randomix.c: RAND_MAX: %d",RAND_MAX); */ -/* post("cxc/randomix.c: test: %f %f", x->x_u1, x->x_u2); */ - dist_normal_doit(x); -} - -void dist_normal_low(t_dist_normal *x, t_floatarg mn) -{ - x->x_mn = mn; -} - -void dist_normal_upp(t_dist_normal *x, t_floatarg dv) -{ - x->x_dv = dv; -} - -void dist_normal_float(t_dist_normal *x, t_floatarg r) -{ - outlet_float(x->x_obj.ob_outlet, r); -} - -void dist_normal_list(t_dist_normal *x, t_symbol *s, int argc, t_atom *argv) -{ - outlet_list(x->x_obj.ob_outlet, s, argc, argv); -} - -void dist_normal_setup(void) -{ - dist_normal_class = class_new(gensym("dist_normal"), (t_newmethod)dist_normal_new, 0, - sizeof(t_dist_normal), 0, A_DEFFLOAT, A_DEFFLOAT, 0); - class_addbang(dist_normal_class, dist_normal_bang); - class_addmethod(dist_normal_class, (t_method)dist_normal_low, gensym("fl1"), A_FLOAT, 0); - // class_addmethod(dist_normal_class, (t_method)dist_normal_upp, gensym("fl2"), A_FLOAT, 0); - class_addlist (dist_normal_class, dist_normal_list); - -/* class_addmethod(dist_normal_class, (t_method)dist_normal_seed, */ -/* gensym("seed"), A_FLOAT, 0); */ -} |