diff options
Diffstat (limited to 'random_tw.c')
-rw-r--r-- | random_tw.c | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/random_tw.c b/random_tw.c new file mode 100644 index 0000000..6e7fba8 --- /dev/null +++ b/random_tw.c @@ -0,0 +1,181 @@ +/* + (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 int makeseed(void) +{ + static unsigned int random1_nextseed = 1489853723; + random1_nextseed = random1_nextseed * 435898247 + 938284287; + return (random1_nextseed & 0x7fffffff); +} + +/* -------------------------- 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); +} |