PageRenderTime 57ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/PdLib/src/x_misc.c

https://github.com/bryansum/pdlib
C | 324 lines | 267 code | 46 blank | 11 comment | 11 complexity | 2c0b9b52f0458cdf374d7a3a47564fb6 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0
  1. /* Copyright (c) 1997-1999 Miller Puckette.
  2. * For information on usage and redistribution, and for a DISCLAIMER OF ALL
  3. * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
  4. /* misc. */
  5. #include "m_pd.h"
  6. #include "s_stuff.h"
  7. #include <math.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #ifdef UNISTD
  11. #include <sys/types.h>
  12. #include <sys/time.h>
  13. #include <sys/times.h>
  14. #include <sys/param.h>
  15. #include <unistd.h>
  16. #endif
  17. #ifdef MSW
  18. #include <wtypes.h>
  19. #include <time.h>
  20. #endif
  21. #if defined (__APPLE__) || defined (__FreeBSD__)
  22. #define CLOCKHZ CLK_TCK
  23. #endif
  24. #if defined (__linux__)
  25. #define CLOCKHZ sysconf(_SC_CLK_TCK)
  26. #endif
  27. /* -------------------------- random ------------------------------ */
  28. /* this is strictly homebrew and untested. */
  29. static t_class *random_class;
  30. typedef struct _random
  31. {
  32. t_object x_obj;
  33. t_float x_f;
  34. unsigned int x_state;
  35. } t_random;
  36. static int makeseed(void)
  37. {
  38. static unsigned int random_nextseed = 1489853723;
  39. random_nextseed = random_nextseed * 435898247 + 938284287;
  40. return (random_nextseed & 0x7fffffff);
  41. }
  42. static void *random_new(t_floatarg f)
  43. {
  44. t_random *x = (t_random *)pd_new(random_class);
  45. x->x_f = f;
  46. x->x_state = makeseed();
  47. floatinlet_new(&x->x_obj, &x->x_f);
  48. outlet_new(&x->x_obj, &s_float);
  49. return (x);
  50. }
  51. static void random_bang(t_random *x)
  52. {
  53. int n = x->x_f, nval;
  54. int range = (n < 1 ? 1 : n);
  55. unsigned int randval = x->x_state;
  56. x->x_state = randval = randval * 472940017 + 832416023;
  57. nval = ((double)range) * ((double)randval)
  58. * (1./4294967296.);
  59. if (nval >= range) nval = range-1;
  60. outlet_float(x->x_obj.ob_outlet, nval);
  61. }
  62. static void random_seed(t_random *x, t_float f, t_float glob)
  63. {
  64. x->x_state = f;
  65. }
  66. static void random_setup(void)
  67. {
  68. random_class = class_new(gensym("random"), (t_newmethod)random_new, 0,
  69. sizeof(t_random), 0, A_DEFFLOAT, 0);
  70. class_addbang(random_class, random_bang);
  71. class_addmethod(random_class, (t_method)random_seed,
  72. gensym("seed"), A_FLOAT, 0);
  73. }
  74. /* -------------------------- loadbang ------------------------------ */
  75. static t_class *loadbang_class;
  76. typedef struct _loadbang
  77. {
  78. t_object x_obj;
  79. } t_loadbang;
  80. static void *loadbang_new(void)
  81. {
  82. t_loadbang *x = (t_loadbang *)pd_new(loadbang_class);
  83. outlet_new(&x->x_obj, &s_bang);
  84. return (x);
  85. }
  86. static void loadbang_loadbang(t_loadbang *x)
  87. {
  88. if (!sys_noloadbang)
  89. outlet_bang(x->x_obj.ob_outlet);
  90. }
  91. static void loadbang_setup(void)
  92. {
  93. loadbang_class = class_new(gensym("loadbang"), (t_newmethod)loadbang_new, 0,
  94. sizeof(t_loadbang), CLASS_NOINLET, 0);
  95. class_addmethod(loadbang_class, (t_method)loadbang_loadbang,
  96. gensym("loadbang"), 0);
  97. }
  98. /* ------------- namecanvas (delete this later) --------------------- */
  99. static t_class *namecanvas_class;
  100. typedef struct _namecanvas
  101. {
  102. t_object x_obj;
  103. t_symbol *x_sym;
  104. t_pd *x_owner;
  105. } t_namecanvas;
  106. static void *namecanvas_new(t_symbol *s)
  107. {
  108. t_namecanvas *x = (t_namecanvas *)pd_new(namecanvas_class);
  109. x->x_owner = (t_pd *)canvas_getcurrent();
  110. x->x_sym = s;
  111. if (*s->s_name) pd_bind(x->x_owner, s);
  112. return (x);
  113. }
  114. static void namecanvas_free(t_namecanvas *x)
  115. {
  116. if (*x->x_sym->s_name) pd_unbind(x->x_owner, x->x_sym);
  117. }
  118. static void namecanvas_setup(void)
  119. {
  120. namecanvas_class = class_new(gensym("namecanvas"),
  121. (t_newmethod)namecanvas_new, (t_method)namecanvas_free,
  122. sizeof(t_namecanvas), CLASS_NOINLET, A_DEFSYM, 0);
  123. }
  124. /* ---------------serial ports (MSW only -- hack) ------------------------- */
  125. #define MAXSERIAL 100
  126. static t_class *serial_class;
  127. typedef struct _serial
  128. {
  129. t_object x_obj;
  130. int x_portno;
  131. int x_open;
  132. } t_serial;
  133. static void serial_float(t_serial *x, t_float f)
  134. {
  135. int n = f;
  136. char message[MAXSERIAL * 4 + 100];
  137. if (!x->x_open)
  138. {
  139. sys_vgui("com%d_open\n", x->x_portno);
  140. x->x_open = 1;
  141. }
  142. sprintf(message, "com%d_send \"\\%3.3o\"\n", x->x_portno, n);
  143. sys_gui(message);
  144. }
  145. static void *serial_new(t_floatarg fportno)
  146. {
  147. int portno = fportno;
  148. t_serial *x = (t_serial *)pd_new(serial_class);
  149. if (!portno) portno = 1;
  150. x->x_portno = portno;
  151. x->x_open = 0;
  152. return (x);
  153. }
  154. static void serial_setup(void)
  155. {
  156. serial_class = class_new(gensym("serial"), (t_newmethod)serial_new, 0,
  157. sizeof(t_serial), 0, A_DEFFLOAT, 0);
  158. class_addfloat(serial_class, serial_float);
  159. }
  160. /* -------------------------- cputime ------------------------------ */
  161. static t_class *cputime_class;
  162. typedef struct _cputime
  163. {
  164. t_object x_obj;
  165. #ifdef UNISTD
  166. struct tms x_setcputime;
  167. #endif
  168. #ifdef MSW
  169. LARGE_INTEGER x_kerneltime;
  170. LARGE_INTEGER x_usertime;
  171. int x_warned;
  172. #endif
  173. } t_cputime;
  174. static void cputime_bang(t_cputime *x)
  175. {
  176. #ifdef UNISTD
  177. times(&x->x_setcputime);
  178. #endif
  179. #ifdef MSW
  180. FILETIME ignorethis, ignorethat;
  181. BOOL retval;
  182. retval = GetProcessTimes(GetCurrentProcess(), &ignorethis, &ignorethat,
  183. (FILETIME *)&x->x_kerneltime, (FILETIME *)&x->x_usertime);
  184. if (!retval)
  185. {
  186. if (!x->x_warned)
  187. post("cputime is apparently not supported on your platform");
  188. x->x_warned = 1;
  189. x->x_kerneltime.QuadPart = 0;
  190. x->x_usertime.QuadPart = 0;
  191. }
  192. #endif
  193. }
  194. static void cputime_bang2(t_cputime *x)
  195. {
  196. #ifdef UNISTD
  197. t_float elapsedcpu;
  198. struct tms newcputime;
  199. times(&newcputime);
  200. elapsedcpu = 1000 * (
  201. newcputime.tms_utime + newcputime.tms_stime -
  202. x->x_setcputime.tms_utime - x->x_setcputime.tms_stime) / CLOCKHZ;
  203. outlet_float(x->x_obj.ob_outlet, elapsedcpu);
  204. #endif
  205. #ifdef MSW
  206. t_float elapsedcpu;
  207. FILETIME ignorethis, ignorethat;
  208. LARGE_INTEGER usertime, kerneltime;
  209. BOOL retval;
  210. retval = GetProcessTimes(GetCurrentProcess(), &ignorethis, &ignorethat,
  211. (FILETIME *)&kerneltime, (FILETIME *)&usertime);
  212. if (retval)
  213. elapsedcpu = 0.0001 *
  214. ((kerneltime.QuadPart - x->x_kerneltime.QuadPart) +
  215. (usertime.QuadPart - x->x_usertime.QuadPart));
  216. else elapsedcpu = 0;
  217. outlet_float(x->x_obj.ob_outlet, elapsedcpu);
  218. #endif
  219. }
  220. static void *cputime_new(void)
  221. {
  222. t_cputime *x = (t_cputime *)pd_new(cputime_class);
  223. outlet_new(&x->x_obj, gensym("float"));
  224. inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("bang"), gensym("bang2"));
  225. #ifdef MSW
  226. x->x_warned = 0;
  227. #endif
  228. cputime_bang(x);
  229. return (x);
  230. }
  231. static void cputime_setup(void)
  232. {
  233. cputime_class = class_new(gensym("cputime"), (t_newmethod)cputime_new, 0,
  234. sizeof(t_cputime), 0, 0);
  235. class_addbang(cputime_class, cputime_bang);
  236. class_addmethod(cputime_class, (t_method)cputime_bang2, gensym("bang2"), 0);
  237. }
  238. /* -------------------------- realtime ------------------------------ */
  239. static t_class *realtime_class;
  240. typedef struct _realtime
  241. {
  242. t_object x_obj;
  243. double x_setrealtime;
  244. } t_realtime;
  245. static void realtime_bang(t_realtime *x)
  246. {
  247. x->x_setrealtime = sys_getrealtime();
  248. }
  249. static void realtime_bang2(t_realtime *x)
  250. {
  251. outlet_float(x->x_obj.ob_outlet,
  252. (sys_getrealtime() - x->x_setrealtime) * 1000.);
  253. }
  254. static void *realtime_new(void)
  255. {
  256. t_realtime *x = (t_realtime *)pd_new(realtime_class);
  257. outlet_new(&x->x_obj, gensym("float"));
  258. inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("bang"), gensym("bang2"));
  259. realtime_bang(x);
  260. return (x);
  261. }
  262. static void realtime_setup(void)
  263. {
  264. realtime_class = class_new(gensym("realtime"), (t_newmethod)realtime_new, 0,
  265. sizeof(t_realtime), 0, 0);
  266. class_addbang(realtime_class, realtime_bang);
  267. class_addmethod(realtime_class, (t_method)realtime_bang2, gensym("bang2"),
  268. 0);
  269. }
  270. void x_misc_setup(void)
  271. {
  272. random_setup();
  273. loadbang_setup();
  274. namecanvas_setup();
  275. serial_setup();
  276. cputime_setup();
  277. realtime_setup();
  278. }