diff options
Diffstat (limited to 'pd/src/x_misc.c')
-rw-r--r-- | pd/src/x_misc.c | 319 |
1 files changed, 319 insertions, 0 deletions
diff --git a/pd/src/x_misc.c b/pd/src/x_misc.c new file mode 100644 index 00000000..8ba5191f --- /dev/null +++ b/pd/src/x_misc.c @@ -0,0 +1,319 @@ +/* Copyright (c) 1997-1999 Miller Puckette. +* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +/* misc. */ + +#include "m_imp.h" +#include <math.h> +#include <stdio.h> +#include <string.h> +#ifdef UNIX +#include <sys/types.h> +#include <sys/time.h> +#include <sys/times.h> +#include <sys/param.h> +#endif +#ifdef NT +#include <wtypes.h> +#include <time.h> +#endif + +#if defined (MACOSX) || defined (__FreeBSD__) +#define HZ CLK_TCK +#endif + +/* -------------------------- random ------------------------------ */ +/* this is strictly homebrew and untested. */ + +static t_class *random_class; + +typedef struct _random +{ + t_object x_obj; + t_float x_f; + unsigned int x_state; +} t_random; + + +static int makeseed(void) +{ + static unsigned int random_nextseed = 1489853723; + random_nextseed = random_nextseed * 435898247 + 938284287; + return (random_nextseed & 0x7fffffff); +} + +static void *random_new(t_floatarg f) +{ + t_random *x = (t_random *)pd_new(random_class); + x->x_f = f; + x->x_state = makeseed(); + floatinlet_new(&x->x_obj, &x->x_f); + outlet_new(&x->x_obj, &s_float); + return (x); +} + +static void random_bang(t_random *x) +{ + int n = x->x_f, nval; + int range = (n < 1 ? 1 : n); + unsigned int randval = x->x_state; + x->x_state = randval = randval * 472940017 + 832416023; + nval = ((double)range) * ((double)randval) + * (1./4294967296.); + if (nval >= range) nval = range-1; + outlet_float(x->x_obj.ob_outlet, nval); +} + +static void random_seed(t_random *x, float f, float glob) +{ + x->x_state = f; +} + +static void random_setup(void) +{ + random_class = class_new(gensym("random"), (t_newmethod)random_new, 0, + sizeof(t_random), 0, A_DEFFLOAT, 0); + class_addbang(random_class, random_bang); + class_addmethod(random_class, (t_method)random_seed, + gensym("seed"), A_FLOAT, 0); +} + + +/* -------------------------- loadbang ------------------------------ */ +static t_class *loadbang_class; + +typedef struct _loadbang +{ + t_object x_obj; +} t_loadbang; + +static void *loadbang_new(void) +{ + t_loadbang *x = (t_loadbang *)pd_new(loadbang_class); + outlet_new(&x->x_obj, &s_bang); + return (x); +} + +static void loadbang_loadbang(t_loadbang *x) +{ + if (!sys_noloadbang) + outlet_bang(x->x_obj.ob_outlet); +} + +static void loadbang_setup(void) +{ + loadbang_class = class_new(gensym("loadbang"), (t_newmethod)loadbang_new, 0, + sizeof(t_loadbang), 0, 0); + class_addmethod(loadbang_class, (t_method)loadbang_loadbang, + gensym("loadbang"), 0); +} + +/* ------------- namecanvas (delete this later) --------------------- */ +static t_class *namecanvas_class; + +typedef struct _namecanvas +{ + t_object x_obj; + t_symbol *x_sym; + t_pd *x_owner; +} t_namecanvas; + +static void *namecanvas_new(t_symbol *s) +{ + t_namecanvas *x = (t_namecanvas *)pd_new(namecanvas_class); + x->x_owner = (t_pd *)canvas_getcurrent(); + x->x_sym = s; + if (*s->s_name) pd_bind(x->x_owner, s); + return (x); +} + +static void namecanvas_free(t_namecanvas *x) +{ + if (*x->x_sym->s_name) pd_unbind(x->x_owner, x->x_sym); +} + +static void namecanvas_setup(void) +{ + namecanvas_class = class_new(gensym("namecanvas"), + (t_newmethod)namecanvas_new, (t_method)namecanvas_free, + sizeof(t_namecanvas), CLASS_NOINLET, A_DEFSYM, 0); +} + +/* ---------------serial ports (NT only -- hack) ------------------------- */ +#define MAXSERIAL 100 + +static t_class *serial_class; + +typedef struct _serial +{ + t_object x_obj; + int x_portno; + int x_open; +} t_serial; + +static void serial_float(t_serial *x, t_float f) +{ + int n = f; + char message[MAXSERIAL * 4 + 100]; + if (!x->x_open) + { + sys_vgui("com%d_open\n", x->x_portno); + x->x_open = 1; + } + sprintf(message, "com%d_send \"\\%3.3o\"\n", x->x_portno, n); + sys_gui(message); +} + +static void *serial_new(t_floatarg fportno) +{ + int portno = fportno; + t_serial *x = (t_serial *)pd_new(serial_class); + if (!portno) portno = 1; + x->x_portno = portno; + x->x_open = 0; + return (x); +} + +static void serial_setup(void) +{ + serial_class = class_new(gensym("serial"), (t_newmethod)serial_new, 0, + sizeof(t_serial), 0, A_DEFFLOAT, 0); + class_addfloat(serial_class, serial_float); +} + +/* -------------------------- cputime ------------------------------ */ + +static t_class *cputime_class; + +typedef struct _cputime +{ + t_object x_obj; +#ifdef UNIX + struct tms x_setcputime; +#endif +#ifdef NT + LARGE_INTEGER x_kerneltime; + LARGE_INTEGER x_usertime; + int x_warned; +#endif +} t_cputime; + +static void cputime_bang(t_cputime *x) +{ +#ifdef UNIX + times(&x->x_setcputime); +#endif +#ifdef NT + FILETIME ignorethis, ignorethat; + BOOL retval; + retval = GetProcessTimes(GetCurrentProcess(), &ignorethis, &ignorethat, + (FILETIME *)&x->x_kerneltime, (FILETIME *)&x->x_usertime); + if (!retval) + { + if (!x->x_warned) + post("cputime is apparently not supported on your platform"); + x->x_warned = 1; + x->x_kerneltime.QuadPart = 0; + x->x_usertime.QuadPart = 0; + } +#endif +} + +static void cputime_bang2(t_cputime *x) +{ +#ifdef UNIX + float elapsedcpu; + struct tms newcputime; + times(&newcputime); + elapsedcpu = 1000 * ( + newcputime.tms_utime + newcputime.tms_stime - + x->x_setcputime.tms_utime - x->x_setcputime.tms_stime) / HZ; + outlet_float(x->x_obj.ob_outlet, elapsedcpu); +#endif +#ifdef NT + float elapsedcpu; + FILETIME ignorethis, ignorethat; + LARGE_INTEGER usertime, kerneltime; + BOOL retval; + + retval = GetProcessTimes(GetCurrentProcess(), &ignorethis, &ignorethat, + (FILETIME *)&kerneltime, (FILETIME *)&usertime); + if (retval) + elapsedcpu = 0.0001 * + ((kerneltime.QuadPart - x->x_kerneltime.QuadPart) + + (usertime.QuadPart - x->x_usertime.QuadPart)); + else elapsedcpu = 0; + outlet_float(x->x_obj.ob_outlet, elapsedcpu); +#endif +} + +static void *cputime_new(void) +{ + t_cputime *x = (t_cputime *)pd_new(cputime_class); + outlet_new(&x->x_obj, gensym("float")); + + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("bang"), gensym("bang2")); +#ifdef NT + x->x_warned = 0; +#endif + cputime_bang(x); + return (x); +} + +static void cputime_setup(void) +{ + cputime_class = class_new(gensym("cputime"), (t_newmethod)cputime_new, 0, + sizeof(t_cputime), 0, 0); + class_addbang(cputime_class, cputime_bang); + class_addmethod(cputime_class, (t_method)cputime_bang2, gensym("bang2"), 0); +} + +/* -------------------------- realtime ------------------------------ */ + +static t_class *realtime_class; + +typedef struct _realtime +{ + t_object x_obj; + double x_setrealtime; +} t_realtime; + +static void realtime_bang(t_realtime *x) +{ + x->x_setrealtime = sys_getrealtime(); +} + +static void realtime_bang2(t_realtime *x) +{ + outlet_float(x->x_obj.ob_outlet, + (sys_getrealtime() - x->x_setrealtime) * 1000.); +} + +static void *realtime_new(void) +{ + t_realtime *x = (t_realtime *)pd_new(realtime_class); + outlet_new(&x->x_obj, gensym("float")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("bang"), gensym("bang2")); + realtime_bang(x); + return (x); +} + +static void realtime_setup(void) +{ + realtime_class = class_new(gensym("realtime"), (t_newmethod)realtime_new, 0, + sizeof(t_realtime), 0, 0); + class_addbang(realtime_class, realtime_bang); + class_addmethod(realtime_class, (t_method)realtime_bang2, gensym("bang2"), + 0); +} + +void x_misc_setup(void) +{ + random_setup(); + loadbang_setup(); + namecanvas_setup(); + serial_setup(); + cputime_setup(); + realtime_setup(); +} |