A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 351 lines 8.3 kB view raw
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 5/* misc. */ 6 7#ifdef ROCKBOX 8#include "plugin.h" 9#include "../../pdbox.h" 10#include "m_pd.h" 11#include "s_stuff.h" 12extern uint64_t runningtime; 13#else /* ROCKBOX */ 14#include "m_pd.h" 15#include "s_stuff.h" 16#include <math.h> 17#include <stdio.h> 18#include <string.h> 19#ifdef UNIX 20#include <sys/types.h> 21#include <sys/time.h> 22#include <sys/times.h> 23//#include <sys/param.h> 24#endif 25#ifdef MSW 26#include <wtypes.h> 27#include <time.h> 28#endif 29#endif /* ROCKBOX */ 30 31#if defined (MACOSX) || defined (__FreeBSD__) 32#define HZ CLK_TCK 33#endif 34 35/* -------------------------- random ------------------------------ */ 36/* this is strictly homebrew and untested. */ 37 38static t_class *random_class; 39 40typedef struct _random 41{ 42 t_object x_obj; 43 t_float x_f; 44 unsigned int x_state; 45} t_random; 46 47 48static int makeseed(void) 49{ 50 static unsigned int random_nextseed = 1489853723; 51 random_nextseed = random_nextseed * 435898247 + 938284287; 52 return (random_nextseed & 0x7fffffff); 53} 54 55static void *random_new(t_floatarg f) 56{ 57 t_random *x = (t_random *)pd_new(random_class); 58 x->x_f = f; 59 x->x_state = makeseed(); 60 floatinlet_new(&x->x_obj, &x->x_f); 61 outlet_new(&x->x_obj, &s_float); 62 return (x); 63} 64 65static void random_bang(t_random *x) 66{ 67 int n = x->x_f, nval; 68 int range = (n < 1 ? 1 : n); 69 unsigned int randval = x->x_state; 70 x->x_state = randval = randval * 472940017 + 832416023; 71 nval = ((double)range) * ((double)randval) 72 * (1./4294967296.); 73 if (nval >= range) nval = range-1; 74 outlet_float(x->x_obj.ob_outlet, nval); 75} 76 77static void random_seed(t_random *x, float f, float glob) 78{ 79#ifdef ROCKBOX 80 (void) glob; 81#endif 82 x->x_state = f; 83} 84 85static void random_setup(void) 86{ 87 random_class = class_new(gensym("random"), (t_newmethod)random_new, 0, 88 sizeof(t_random), 0, A_DEFFLOAT, 0); 89 class_addbang(random_class, random_bang); 90 class_addmethod(random_class, (t_method)random_seed, 91 gensym("seed"), A_FLOAT, 0); 92} 93 94 95/* -------------------------- loadbang ------------------------------ */ 96static t_class *loadbang_class; 97 98typedef struct _loadbang 99{ 100 t_object x_obj; 101} t_loadbang; 102 103static void *loadbang_new(void) 104{ 105 t_loadbang *x = (t_loadbang *)pd_new(loadbang_class); 106 outlet_new(&x->x_obj, &s_bang); 107 return (x); 108} 109 110static void loadbang_loadbang(t_loadbang *x) 111{ 112 if (!sys_noloadbang) 113 outlet_bang(x->x_obj.ob_outlet); 114} 115 116static void loadbang_setup(void) 117{ 118 loadbang_class = class_new(gensym("loadbang"), (t_newmethod)loadbang_new, 0, 119 sizeof(t_loadbang), 0, 0); 120 class_addmethod(loadbang_class, (t_method)loadbang_loadbang, 121 gensym("loadbang"), 0); 122} 123 124/* ------------- namecanvas (delete this later) --------------------- */ 125static t_class *namecanvas_class; 126 127typedef struct _namecanvas 128{ 129 t_object x_obj; 130 t_symbol *x_sym; 131 t_pd *x_owner; 132} t_namecanvas; 133 134static void *namecanvas_new(t_symbol *s) 135{ 136 t_namecanvas *x = (t_namecanvas *)pd_new(namecanvas_class); 137 x->x_owner = (t_pd *)canvas_getcurrent(); 138 x->x_sym = s; 139 if (*s->s_name) pd_bind(x->x_owner, s); 140 return (x); 141} 142 143static void namecanvas_free(t_namecanvas *x) 144{ 145 if (*x->x_sym->s_name) pd_unbind(x->x_owner, x->x_sym); 146} 147 148static void namecanvas_setup(void) 149{ 150 namecanvas_class = class_new(gensym("namecanvas"), 151 (t_newmethod)namecanvas_new, (t_method)namecanvas_free, 152 sizeof(t_namecanvas), CLASS_NOINLET, A_DEFSYM, 0); 153} 154 155/* ---------------serial ports (MSW only -- hack) ------------------------- */ 156#define MAXSERIAL 100 157 158static t_class *serial_class; 159 160typedef struct _serial 161{ 162 t_object x_obj; 163 int x_portno; 164 int x_open; 165} t_serial; 166 167static void serial_float(t_serial *x, t_float f) 168{ 169#ifdef ROCKBOX 170 (void) x; 171 (void) f; 172#else /* ROCKBOX */ 173 int n = f; 174 char message[MAXSERIAL * 4 + 100]; 175 if (!x->x_open) 176 { 177 sys_vgui("com%d_open\n", x->x_portno); 178 x->x_open = 1; 179 } 180 sprintf(message, "com%d_send \"\\%3.3o\"\n", x->x_portno, n); 181 sys_gui(message); 182#endif /* ROCKBOX */ 183} 184 185static void *serial_new(t_floatarg fportno) 186{ 187 int portno = fportno; 188 t_serial *x = (t_serial *)pd_new(serial_class); 189 if (!portno) portno = 1; 190 x->x_portno = portno; 191 x->x_open = 0; 192 return (x); 193} 194 195static void serial_setup(void) 196{ 197 serial_class = class_new(gensym("serial"), (t_newmethod)serial_new, 0, 198 sizeof(t_serial), 0, A_DEFFLOAT, 0); 199 class_addfloat(serial_class, serial_float); 200} 201 202/* -------------------------- cputime ------------------------------ */ 203 204static t_class *cputime_class; 205 206typedef struct _cputime 207{ 208 t_object x_obj; 209#ifdef ROCKBOX 210 uint64_t x_runningtime; 211#endif 212#ifdef UNIX 213 struct tms x_setcputime; 214#endif 215#ifdef MSW 216 LARGE_INTEGER x_kerneltime; 217 LARGE_INTEGER x_usertime; 218 int x_warned; 219#endif 220} t_cputime; 221 222static void cputime_bang(t_cputime *x) 223{ 224#ifdef ROCKBOX 225 x->x_runningtime = runningtime; 226#endif 227#ifdef UNIX 228 times(&x->x_setcputime); 229#endif 230#ifdef MSW 231 FILETIME ignorethis, ignorethat; 232 BOOL retval; 233 retval = GetProcessTimes(GetCurrentProcess(), &ignorethis, &ignorethat, 234 (FILETIME *)&x->x_kerneltime, (FILETIME *)&x->x_usertime); 235 if (!retval) 236 { 237 if (!x->x_warned) 238 post("cputime is apparently not supported on your platform"); 239 x->x_warned = 1; 240 x->x_kerneltime.QuadPart = 0; 241 x->x_usertime.QuadPart = 0; 242 } 243#endif 244} 245 246#ifndef ROCKBOX 247#define HZ 100 248#endif 249static void cputime_bang2(t_cputime *x) 250{ 251#ifdef ROCKBOX 252 float elapsedcpu = 1000 * 253 (runningtime - x->x_runningtime) / HZ; 254 outlet_float(x->x_obj.ob_outlet, elapsedcpu); 255#endif 256#ifdef UNIX 257 float elapsedcpu; 258 struct tms newcputime; 259 times(&newcputime); 260 elapsedcpu = 1000 * ( 261 newcputime.tms_utime + newcputime.tms_stime - 262 x->x_setcputime.tms_utime - x->x_setcputime.tms_stime) / HZ; 263 outlet_float(x->x_obj.ob_outlet, elapsedcpu); 264#endif 265#ifdef MSW 266 float elapsedcpu; 267 FILETIME ignorethis, ignorethat; 268 LARGE_INTEGER usertime, kerneltime; 269 BOOL retval; 270 271 retval = GetProcessTimes(GetCurrentProcess(), &ignorethis, &ignorethat, 272 (FILETIME *)&kerneltime, (FILETIME *)&usertime); 273 if (retval) 274 elapsedcpu = 0.0001 * 275 ((kerneltime.QuadPart - x->x_kerneltime.QuadPart) + 276 (usertime.QuadPart - x->x_usertime.QuadPart)); 277 else elapsedcpu = 0; 278 outlet_float(x->x_obj.ob_outlet, elapsedcpu); 279#endif 280} 281 282static void *cputime_new(void) 283{ 284 t_cputime *x = (t_cputime *)pd_new(cputime_class); 285 outlet_new(&x->x_obj, gensym("float")); 286 287 inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("bang"), gensym("bang2")); 288#ifdef MSW 289 x->x_warned = 0; 290#endif 291 cputime_bang(x); 292 return (x); 293} 294 295static void cputime_setup(void) 296{ 297 cputime_class = class_new(gensym("cputime"), (t_newmethod)cputime_new, 0, 298 sizeof(t_cputime), 0, 0); 299 class_addbang(cputime_class, cputime_bang); 300 class_addmethod(cputime_class, (t_method)cputime_bang2, gensym("bang2"), 0); 301} 302 303/* -------------------------- realtime ------------------------------ */ 304 305static t_class *realtime_class; 306 307typedef struct _realtime 308{ 309 t_object x_obj; 310 double x_setrealtime; 311} t_realtime; 312 313static void realtime_bang(t_realtime *x) 314{ 315 x->x_setrealtime = sys_getrealtime(); 316} 317 318static void realtime_bang2(t_realtime *x) 319{ 320 outlet_float(x->x_obj.ob_outlet, 321 (sys_getrealtime() - x->x_setrealtime) * 1000.); 322} 323 324static void *realtime_new(void) 325{ 326 t_realtime *x = (t_realtime *)pd_new(realtime_class); 327 outlet_new(&x->x_obj, gensym("float")); 328 inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("bang"), gensym("bang2")); 329 realtime_bang(x); 330 return (x); 331} 332 333static void realtime_setup(void) 334{ 335 realtime_class = class_new(gensym("realtime"), (t_newmethod)realtime_new, 0, 336 sizeof(t_realtime), 0, 0); 337 class_addbang(realtime_class, realtime_bang); 338 class_addmethod(realtime_class, (t_method)realtime_bang2, gensym("bang2"), 339 0); 340} 341 342void x_misc_setup(void) 343{ 344 random_setup(); 345 loadbang_setup(); 346 namecanvas_setup(); 347 serial_setup(); 348 cputime_setup(); 349 realtime_setup(); 350} 351