1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
// random number generator from supercollider
// coded by matt barber
#include <m_pd.h>
#include "random.h"
static int instance_number = 0;
int cyrandom_get_id(void){
return(++instance_number);
}
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);
*s2 = ((*s2 & (uint32_t)- 8) << 4) ^ (((*s2 << 2) ^ *s2) >> 25);
*s3 = ((*s3 & (uint32_t)-16) << 17) ^ (((*s3 << 3) ^ *s3) >> 11);
return(*s1 ^ *s2 ^ *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 | (cyrandom_trand(s1, s2, s3) >> 9);
return(u.f - 3.f);
}
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 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;
if(*s2 < 8)
*s2 = 3093459404U;
*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));
}
|