From faada59567f8cb252f4a909116595ce309ff5828 Mon Sep 17 00:00:00 2001 From: "N.N." Date: Fri, 23 May 2003 12:29:55 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r647, which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/miXed/; revision=648 --- cyclone/hammer/drunk.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 cyclone/hammer/drunk.c (limited to 'cyclone/hammer/drunk.c') diff --git a/cyclone/hammer/drunk.c b/cyclone/hammer/drunk.c new file mode 100644 index 0000000..e08800d --- /dev/null +++ b/cyclone/hammer/drunk.c @@ -0,0 +1,140 @@ +/* Copyright (c) 2002-2003 krzYszcz and others. + * For information on usage and redistribution, and for a DISCLAIMER OF ALL + * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +/* The first version of this code was written by Nicola Bernardini. + It was entirely reimplemented in the hope of adapting it to the + cyclone's guidelines. */ + +#include "m_pd.h" +#include "common/rand.h" + +#define DRUNK_DEFMAXVALUE 128 +#define DRUNK_DEFMAXSTEP 2 + +typedef struct _drunk +{ + t_object x_ob; + int x_value; + int x_maxvalue; + int x_maxstep; + int x_minstep; + unsigned int x_seed; + unsigned int x_bitseed; +} t_drunk; + +static t_class *drunk_class; + +static void drunk_set(t_drunk *x, t_floatarg f) +{ + int i = (int)f; /* CHECKED float silently truncated */ + if (i > x->x_maxvalue) + x->x_value = x->x_maxvalue; /* CHECKED */ + else if (i < 0) + x->x_value = 0; /* CHECKED */ + else x->x_value = i; +} + +/* CHECKED: this is a superposition of two rngs -- the random bit generator, + and the random integer generator, which is the same (CHECKED) as the one + used in the 'random' class (quite lame: period 35730773, nonuniform for + large ranges, so I would rather not RE it...) */ +#define RBIT1 1 +#define RBIT2 2 +#define RBIT5 16 +#define RBIT18 131072 +#define RBIT_MASK (RBIT1 + RBIT2 + RBIT5) + +static void drunk_bang(t_drunk *x) +{ + int rnd = rand_int(&x->x_seed, x->x_maxstep) + x->x_minstep; + int val; + if (x->x_bitseed & RBIT18) + { + x->x_bitseed = ((x->x_bitseed ^ RBIT_MASK) << 1) | RBIT1; + if ((val = x->x_value + rnd) > x->x_maxvalue) + val = x->x_value - rnd; /* CHECKED */ + if (val < 0) + val = 0; /* CHECKED (needed for maxstep > maxvalue) */ + } + else + { + x->x_bitseed <<= 1; + if ((val = x->x_value - rnd) < 0) + val = x->x_value + rnd; /* CHECKED */ + if (val > x->x_maxvalue) + val = x->x_maxvalue; /* CHECKED (needed for maxstep > maxvalue) */ + } + outlet_float(((t_object *)x)->ob_outlet, x->x_value = val); +} + +static void drunk_float(t_drunk *x, t_float f) +{ + drunk_set(x, f); + outlet_float(((t_object *)x)->ob_outlet, x->x_value); +} + +static void drunk_ft1(t_drunk *x, t_floatarg f) +{ + int i = (int)f; /* CHECKED float silently truncated */ + x->x_maxvalue = (i < 0 ? 1 : i); /* CHECKED zero allowed */ + /* CHECKED maxstep not updated */ +} + +static void drunk_ft2(t_drunk *x, t_floatarg f) +{ + int i = (int)f; /* CHECKED float silently truncated */ + if (i < 0) + { + x->x_minstep = 1; + i = -i; + } + else x->x_minstep = 0; + /* CHECKED maxstep not clipped to the maxvalue */ + x->x_maxstep = (x->x_minstep ? i - 1 : i); /* CHECKED zero allowed */ +} + +/* apparently, bitseed cannot be controlled, but LATER recheck */ +static void drunk_seed(t_drunk *x, t_floatarg f) +{ + int i = (int)f; /* CHECKED */ + if (i < 0) + i = 1; /* CHECKED */ + rand_seed(&x->x_seed, (unsigned int)i); +} + +static void *drunk_new(t_floatarg f1, t_floatarg f2) +{ + t_drunk *x = (t_drunk *)pd_new(drunk_class); + x->x_maxvalue = ((int)f1 > 0 ? (int)f1 : 128); /* CHECKED */ + x->x_maxstep = 2; + x->x_minstep = 0; + if ((int)f2) /* CHECKED */ + drunk_ft2(x, f2); + x->x_value = x->x_maxvalue / 2; /* CHECKED */ + rand_seed(&x->x_seed, 0); /* CHECKED third arg silently ignored */ + x->x_bitseed = 123456789; /* FIXME */ + inlet_new((t_object *)x, (t_pd *)x, &s_float, gensym("ft1")); + inlet_new((t_object *)x, (t_pd *)x, &s_float, gensym("ft2")); + outlet_new((t_object *)x, &s_float); + return (x); +} + +void drunk_setup(void) +{ + drunk_class = class_new(gensym("drunk"), + (t_newmethod)drunk_new, 0, + sizeof(t_drunk), 0, + A_DEFFLOAT, A_DEFFLOAT, 0); + class_addbang(drunk_class, drunk_bang); + class_addfloat(drunk_class, drunk_float); + class_addmethod(drunk_class, (t_method)drunk_ft1, + gensym("ft1"), A_FLOAT, 0); + class_addmethod(drunk_class, (t_method)drunk_ft2, + gensym("ft2"), A_FLOAT, 0); + /* CHECKED list is auto-unfolded */ + class_addmethod(drunk_class, (t_method)drunk_seed, + gensym("seed"), A_FLOAT, 0); /* CHECKED arg obligatory */ + class_addmethod(drunk_class, (t_method)drunk_set, + gensym("set"), A_FLOAT, 0); /* CHECKED arg obligatory */ +} -- cgit v1.2.1