diff --git a/cyclone_objects/binaries/audio/pink.c b/cyclone_objects/binaries/audio/pink.c index 2030339f..ec9e4777 100644 --- a/cyclone_objects/binaries/audio/pink.c +++ b/cyclone_objects/binaries/audio/pink.c @@ -1,4 +1,4 @@ -// matt barber and porres (2018) for ELSE and here borrowed to Cyclone +// matt barber and porres (2018) for ELSE and it's here lent to Cyclone // based on SuperCollider's pink UGen #include "m_pd.h" @@ -16,19 +16,19 @@ typedef struct _pink{ float x_sr; int x_octaves; int x_octaves_set; - t_cyclone_random_state x_rstate; + t_cyrandom_state x_rstate; int x_id; }t_pink; static void pink_init(t_pink *x){ float *signals = x->x_signals; float total = 0; - t_cyclone_random_state *rstate = &x->x_rstate; + t_cyrandom_state *rstate = &x->x_rstate; uint32_t *s1 = &rstate->s1; uint32_t *s2 = &rstate->s2; uint32_t *s3 = &rstate->s3; for(int i = 0; i < x->x_octaves - 1; ++i){ - float noise = (cyclone_random_frand(s1, s2, s3)); + float noise = (cyrandom_frand(s1, s2, s3)); total += noise; signals[i] = noise; } @@ -36,7 +36,7 @@ static void pink_init(t_pink *x){ } static void pink_seed(t_pink *x, t_symbol *s, int ac, t_atom *av){ - cyclone_random_init(&x->x_rstate, cyclone_random_get_seed(s, ac, av, x->x_id)); + cyrandom_init(&x->x_rstate, cyget_seed(s, ac, av, x->x_id)); pink_init(x); } @@ -49,7 +49,7 @@ static void pink_oct(t_pink *x, t_floatarg f){ static t_int *pink_perform(t_int *w){ t_pink *x = (t_pink *)(w[1]); int n = (t_int)(w[2]); - t_cyclone_random_state *rstate = (t_cyclone_random_state *)(w[3]); + t_cyrandom_state *rstate = (t_cyrandom_state *)(w[3]); float *signals = (float*)(w[4]); t_sample *out = (t_sample *)(w[5]); float total = x->x_total; @@ -57,15 +57,15 @@ static t_int *pink_perform(t_int *w){ uint32_t *s2 = &rstate->s2; uint32_t *s3 = &rstate->s3; while(n--){ - uint32_t rcounter = cyclone_random_trand(s1, s2, s3); - float newrand = cyclone_random_frand(s1, s2, s3); + uint32_t rcounter = cyrandom_trand(s1, s2, s3); + float newrand = cyrandom_frand(s1, s2, s3); int k = (CLZ(rcounter)); if(k < (x->x_octaves-1)){ float prevrand = signals[k]; signals[k] = newrand; total += (newrand - prevrand); } - newrand = (cyclone_random_frand(s1, s2, s3)); + newrand = (cyrandom_frand(s1, s2, s3)); *out++ = (t_float)(total+newrand)/x->x_octaves; } x->x_total = total; @@ -87,7 +87,7 @@ static void pink_dsp(t_pink *x, t_signal **sp){ static void *pink_new(t_symbol *s, int ac, t_atom *av){ t_pink *x = (t_pink *)pd_new(pink_class); - x->x_id = cyclone_random_get_id(); + x->x_id = cyrandom_get_id(); outlet_new(&x->x_obj, &s_signal); x->x_sr = 0; if(ac >= 2 && (atom_getsymbol(av) == gensym("-seed"))){ diff --git a/cyclone_objects/binaries/audio/rand.c b/cyclone_objects/binaries/audio/rand.c index 1dc58619..b7f41aa7 100644 --- a/cyclone_objects/binaries/audio/rand.c +++ b/cyclone_objects/binaries/audio/rand.c @@ -16,7 +16,7 @@ typedef struct _rand{ float x_sr; float x_target; float x_scaling; // LATER use phase increment - unsigned int x_seed; + t_cyrandom_state x_rstate; int x_id; }t_rand; @@ -38,15 +38,16 @@ static t_int *rand_perform(t_int *w){ float scaling = x->x_scaling; wrappy.w_d = SHARED_UNITBIT32; normhipart = wrappy.w_i[SHARED_HIOFFSET]; + t_cyrandom_state *rstate = &x->x_rstate; + uint32_t *s1 = &rstate->s1; + uint32_t *s2 = &rstate->s2; + uint32_t *s3 = &rstate->s3; while (nblock--){ float rate = *rin++; if(rate < 0) rate = 0; if(ph > lastph){ - unsigned int state = x->x_seed; - float newtarget = ((float)((state & 0x7fffffff) - 0x40000000)) - * (float)(1.0 / 0x40000000); - x->x_seed = state * 435898247 + 382842987; + t_float newtarget = (t_float)(cyrandom_frand(s1, s2, s3)); x->x_scaling = scaling = target - newtarget; x->x_target = target = newtarget; } @@ -72,11 +73,15 @@ static void rand_dsp(t_rand *x, t_signal **sp){ dsp_add(rand_perform, 4, x, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec); } +static void rand_seed(t_rand *x, t_symbol *s, int ac, t_atom *av){ + cyrandom_init(&x->x_rstate, cyget_seed(s, ac, av, x->x_id)); +} + static void *rand_new(t_floatarg f){ t_rand *x = (t_rand *)pd_new(rand_class); - x->x_id = cyclone_random_get_id(); - x->x_seed = (unsigned int)(time(NULL) * x->x_id * 1319); - x->x_seed = x->x_seed * 435898247 + 382842987; + x->x_id = cyrandom_get_id(); + t_symbol *s = NULL; + rand_seed(x, s, 0, NULL); x->x_lastphase = 0.; x->x_nextphase = 1.; /* start from 0, force retargetting */ x->x_target = x->x_scaling = 0; diff --git a/cyclone_objects/binaries/control/decide.c b/cyclone_objects/binaries/control/decide.c index 5d97ac14..6643ae2a 100644 --- a/cyclone_objects/binaries/control/decide.c +++ b/cyclone_objects/binaries/control/decide.c @@ -8,35 +8,55 @@ typedef struct _decide{ t_object x_ob; - unsigned int x_seed; - int x_id; + t_cyrandom_state x_rstate; + int x_id; }t_decide; static t_class *decide_class; static void decide_bang(t_decide *x){ - unsigned int state = x->x_seed; - float rand = ((float)((state & 0x7fffffff) - 0x40000000)) - * (float)(1.0 / 0x40000000); - x->x_seed = state * 435898247 + 382842987; - outlet_float(((t_object *)x)->ob_outlet, rand > 0); + t_cyrandom_state *rstate = &x->x_rstate; + uint32_t *s1 = &rstate->s1; + uint32_t *s2 = &rstate->s2; + uint32_t *s3 = &rstate->s3; + t_float random = (t_float)(cyrandom_frand(s1, s2, s3)); + outlet_float(((t_object *)x)->ob_outlet, random > 0); } +static void decide_init(t_decide *x){ + t_cyrandom_state *rstate = &x->x_rstate; + uint32_t *s1 = &rstate->s1; + uint32_t *s2 = &rstate->s2; + uint32_t *s3 = &rstate->s3; + cyrandom_frand(s1, s2, s3); +} + +static void decide_seed(t_decide *x, t_symbol *s, int ac, t_atom *av){ + cyrandom_init(&x->x_rstate, cyget_seed(s, ac, av, x->x_id)); + decide_init(x); +} static void decide_ft1(t_decide *x, t_floatarg f){ - x->x_seed = (int)f; - if(x->x_seed == 0) - x->x_seed = (int)(time(NULL)*x->x_id); - x->x_seed *= x->x_id; + if((unsigned int)f > 0){ + t_atom at[1]; + SETFLOAT(at, f); + decide_seed(x, NULL, 1, at); + } + else + decide_seed(x, NULL, 0, NULL); + decide_init(x); } static void *decide_new(t_floatarg f){ t_decide *x = (t_decide *)pd_new(decide_class); - x->x_id = cyclone_random_get_id() * 1319; - x->x_seed = (int)f; - if(x->x_seed == 0) - x->x_seed = (int)(time(NULL)); - x->x_seed *= x->x_id; - x->x_seed = x->x_seed * 435898247 + 382842987; + x->x_id = cyrandom_get_id(); + if((unsigned int)f > 0){ + t_atom at[1]; + SETFLOAT(at, f); + decide_seed(x, NULL, 1, at); + } + else + decide_seed(x, NULL, 0, NULL); + decide_init(x); inlet_new((t_object *)x, (t_pd *)x, &s_float, gensym("ft1")); outlet_new((t_object *)x, &s_float); return(x); diff --git a/shared/common/random.c b/shared/common/random.c index 279d6cff..12ac8485 100644 --- a/shared/common/random.c +++ b/shared/common/random.c @@ -4,47 +4,14 @@ #include #include "random.h" -static int instance_number = 0; - - -static int makeseed(void){ - static PERTHREAD unsigned int seed = 0; - if(!seed) - seed = time(NULL); - seed = seed * 435898247 + 938284287; - return(seed & 0x7fffffff); -} - - -static int32_t random_hash(int32_t inKey){ - // Thomas Wang's integer hash (a faster hash for integers, also very good). - // http://www.concentric.net/~Ttwang/tech/inthash.htm - uint32_t hash = (uint32_t)inKey; - hash += ~(hash << 15); - hash ^= hash >> 10; - hash += hash << 3; - hash ^= hash >> 6; - hash += ~(hash << 11); - hash ^= hash >> 16; - return((int32_t)hash); -} - -unsigned int cyclone_random_get_seed(t_symbol *s, int ac, t_atom *av, int n){ - s = NULL; - unsigned int timeval; - if(ac && av->a_type == A_FLOAT) - timeval = (unsigned int)(atom_getfloat(av)); - else - timeval = (unsigned int)(time(NULL)*151*n); - return(timeval); -} +static int instance_number = 0; -int cyclone_random_get_id(void){ +int cyrandom_get_id(void){ return(++instance_number); } - -uint32_t cyclone_random_trand(uint32_t *s1, uint32_t *s2, uint32_t *s3){ + +uint32_t cyrandom_trand(uint32_t *s1, uint32_t *s2, uint32_t *s3){ // Provided for speed in inner loops where the state variables are loaded into registers. // Thus updating the instance variables can be postponed until the end of the loop. *s1 = ((*s1 & (uint32_t)- 2) << 12) ^ (((*s1 << 13) ^ *s1) >> 19); @@ -53,34 +20,46 @@ uint32_t cyclone_random_trand(uint32_t *s1, uint32_t *s2, uint32_t *s3){ return(*s1 ^ *s2 ^ *s3); } -float cyclone_random_frand(uint32_t *s1, uint32_t *s2, uint32_t *s3){ +float cyrandom_frand(uint32_t *s1, uint32_t *s2, uint32_t *s3){ // return a float from -1.0 to +0.999... union { uint32_t i; float f; } u; // union for floating point conversion of result - u.i = 0x40000000 | (cyclone_random_trand(s1, s2, s3) >> 9); + u.i = 0x40000000 | (cyrandom_trand(s1, s2, s3) >> 9); return(u.f - 3.f); } -int cyclone_rand_int(unsigned int *statep, int range){ // from [random] - *statep = *statep * 472940017 + 832416023; - int result = ((double)range) * ((double)*statep) * (1./4294967296.); - return(result < range ? result : range - 1); +int32_t cyrandom_hash(int32_t inKey){ + // Thomas Wang's integer hash (a faster hash for integers, also very good). + // http://www.concentric.net/~Ttwang/tech/inthash.htm + uint32_t hash = (uint32_t)inKey; + hash += ~(hash << 15); + hash ^= hash >> 10; + hash += hash << 3; + hash ^= hash >> 6; + hash += ~(hash << 11); + hash ^= hash >> 16; + return((int32_t)hash); } -void cyclone_random_init(t_cyclone_random_state* rstate, float f){ - // humans tend to use small seeds - mess up the bits - uint32_t seedval = (uint32_t)random_hash((int)f); - uint32_t *s1 = &rstate->s1; - uint32_t *s2 = &rstate->s2; - uint32_t *s3 = &rstate->s3; - // initialize seeds using the given seed value taking care of - // the requirements. The constants below are arbitrary otherwise - *s1 = 1243598713U ^ seedval; +void cyrandom_init(t_cyrandom_state* rstate, int seed){ + // humans tend to use small seeds - mess up the bits + uint32_t seedval = (uint32_t)cyrandom_hash(seed); + uint32_t *s1 = &rstate->s1; + uint32_t *s2 = &rstate->s2; + uint32_t *s3 = &rstate->s3; + // initialize seeds using the given seed value taking care of + // the requirements. The constants below are arbitrary otherwise + *s1 = 1243598713U ^ seedval; if(*s1 < 2) *s1 = 1243598713U; - *s2 = 3093459404U ^ seedval; + *s2 = 3093459404U ^ seedval; if(*s2 < 8) *s2 = 3093459404U; - *s3 = 1821928721U ^ seedval; + *s3 = 1821928721U ^ seedval; if(*s3 < 16) *s3 = 1821928721U; } + +int cyget_seed(t_symbol *s, int ac, t_atom *av, int n){ + s = NULL; + return(ac ? atom_getint(av) : (int)(time(NULL)*n)); +} diff --git a/shared/common/random.h b/shared/common/random.h index 255065cd..6612b31c 100644 --- a/shared/common/random.h +++ b/shared/common/random.h @@ -4,20 +4,19 @@ #include #include -typedef struct _cyclone_random_state{ +typedef struct _cyrandom_state{ uint32_t s1; uint32_t s2; uint32_t s3; -}t_cyclone_random_state; +}t_cyrandom_state; -int cyclone_random_get_id(void); -void cyclone_random_init(t_cyclone_random_state* rstate, float f); -unsigned int cyclone_random_get_seed(t_symbol *s, int ac, t_atom *av, int n); -int cyclone_rand_int(unsigned int *statep, int range); -float cyclone_random_frand(uint32_t* s1, uint32_t* s2, uint32_t* s3); -uint32_t cyclone_random_trand(uint32_t* s1, uint32_t* s2, uint32_t* s3); +int cyrandom_get_id(void); +void cyrandom_init(t_cyrandom_state* rstate, int seed); +int cyget_seed(t_symbol *s, int ac, t_atom *av, int n); +uint32_t cyrandom_trand(uint32_t* s1, uint32_t* s2, uint32_t* s3); +float cyrandom_frand(uint32_t* s1, uint32_t* s2, uint32_t* s3); -////////////// these are for pinknoise~ +// These are for [pink~] #if defined(__GNUC__) @@ -35,53 +34,53 @@ static __inline__ int32_t CLZ(int32_t arg){ #pragma intrinsic(_BitScanReverse) __forceinline static int32_t CLZ(int32_t arg){ - unsigned long idx; - if(_BitScanReverse(&idx, (unsigned long)arg)) - return((int32_t)(31-idx)); - return(32); + unsigned long idx; + if(_BitScanReverse(&idx, (unsigned long)arg)) + return((int32_t)(31-idx)); + return(32); } #elif defined(__ppc__) || defined(__powerpc__) || defined(__PPC__) static __inline__ int32_t CLZ(int32_t arg){ - __asm__ volatile("cntlzw %0, %1" : "=r" (arg) : "r" (arg)); - return(arg); + __asm__ volatile("cntlzw %0, %1" : "=r" (arg) : "r" (arg)); + return(arg); } #elif defined(__i386__) || defined(__x86_64__) static __inline__ int32_t CLZ(int32_t arg){ - if(arg) - __asm__ volatile("bsrl %0, %0\nxorl $31, %0\n" : "=r" (arg) : "0" (arg)); - else - arg = 32; - return(arg); + if(arg) + __asm__ volatile("bsrl %0, %0\nxorl $31, %0\n" : "=r" (arg) : "0" (arg)); + else + arg = 32; + return(arg); } #else static __inline__ int32_t CLZ(int32_t arg){ - if(!arg) - return(32); - int32_t n = 0; - if(!(arg & 0xFFFF0000)){ - n += 16; - arg <<= 16; - } - if(!(arg & 0xFF000000)){ - n += 8; - arg <<= 8; - } - if(!(arg & 0xF0000000)){ - n += 4; - arg <<= 4; - } - if(!(arg & 0xC0000000)){ - n += 2; - arg <<= 2; - } - if(!(arg & 0x80000000)) - n++; - return(n); + if(!arg) + return(32); + int32_t n = 0; + if(!(arg & 0xFFFF0000)){ + n += 16; + arg <<= 16; + } + if(!(arg & 0xFF000000)){ + n += 8; + arg <<= 8; + } + if(!(arg & 0xF0000000)){ + n += 4; + arg <<= 4; + } + if(!(arg & 0xC0000000)){ + n += 2; + arg <<= 2; + } + if(!(arg & 0x80000000)) + n++; + return(n); } #endif