A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 316 lines 7.8 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/* send~, receive~, throw~, catch~ */ 6 7#ifdef ROCKBOX 8#include "plugin.h" 9#include "../../pdbox.h" 10#endif 11 12#include "m_pd.h" 13 14#ifndef ROCKBOX 15#include <string.h> 16#endif 17 18#define DEFSENDVS 64 /* LATER get send to get this from canvas */ 19 20/* ----------------------------- send~ ----------------------------- */ 21static t_class *sigsend_class; 22 23typedef struct _sigsend 24{ 25 t_object x_obj; 26 t_symbol *x_sym; 27 int x_n; 28 t_sample *x_vec; 29 float x_f; 30} t_sigsend; 31 32static void *sigsend_new(t_symbol *s) 33{ 34 t_sigsend *x = (t_sigsend *)pd_new(sigsend_class); 35 pd_bind(&x->x_obj.ob_pd, s); 36 x->x_sym = s; 37 x->x_n = DEFSENDVS; 38 x->x_vec = (t_sample *)getbytes(DEFSENDVS * sizeof(t_sample)); 39 memset((char *)(x->x_vec), 0, DEFSENDVS * sizeof(t_sample)); 40 x->x_f = 0; 41 return (x); 42} 43 44static t_int *sigsend_perform(t_int *w) 45{ 46 t_sample *in = (t_sample *)(w[1]); 47 t_sample *out = (t_sample *)(w[2]); 48 int n = (int)(w[3]); 49 while (n--) 50 { 51 *out = (PD_BIGORSMALL(*in) ? 0 : *in); 52 out++; 53 in++; 54 } 55 return (w+4); 56} 57 58static void sigsend_dsp(t_sigsend *x, t_signal **sp) 59{ 60 if (x->x_n == sp[0]->s_n) 61 dsp_add(sigsend_perform, 3, sp[0]->s_vec, x->x_vec, sp[0]->s_n); 62 else error("sigsend %s: unexpected vector size", x->x_sym->s_name); 63} 64 65static void sigsend_free(t_sigsend *x) 66{ 67 pd_unbind(&x->x_obj.ob_pd, x->x_sym); 68 freebytes(x->x_vec, x->x_n * sizeof(float)); 69} 70 71static void sigsend_setup(void) 72{ 73 sigsend_class = class_new(gensym("send~"), (t_newmethod)sigsend_new, 74 (t_method)sigsend_free, sizeof(t_sigsend), 0, A_DEFSYM, 0); 75 class_addcreator((t_newmethod)sigsend_new, gensym("s~"), A_DEFSYM, 0); 76 CLASS_MAINSIGNALIN(sigsend_class, t_sigsend, x_f); 77 class_addmethod(sigsend_class, (t_method)sigsend_dsp, gensym("dsp"), 0); 78} 79 80/* ----------------------------- receive~ ----------------------------- */ 81static t_class *sigreceive_class; 82 83typedef struct _sigreceive 84{ 85 t_object x_obj; 86 t_symbol *x_sym; 87 t_sample *x_wherefrom; 88 int x_n; 89} t_sigreceive; 90 91static void *sigreceive_new(t_symbol *s) 92{ 93 t_sigreceive *x = (t_sigreceive *)pd_new(sigreceive_class); 94 x->x_n = DEFSENDVS; /* LATER find our vector size correctly */ 95 x->x_sym = s; 96 x->x_wherefrom = 0; 97 outlet_new(&x->x_obj, &s_signal); 98 return (x); 99} 100 101static t_int *sigreceive_perform(t_int *w) 102{ 103 t_sigreceive *x = (t_sigreceive *)(w[1]); 104 t_sample *out = (t_sample *)(w[2]); 105 int n = (int)(w[3]); 106 t_sample *in = x->x_wherefrom; 107 if (in) 108 { 109 while (n--) 110 *out++ = *in++; 111 } 112 else 113 { 114 while (n--) 115 *out++ = 0; 116 } 117 return (w+4); 118} 119 120static void sigreceive_set(t_sigreceive *x, t_symbol *s) 121{ 122 t_sigsend *sender = (t_sigsend *)pd_findbyclass((x->x_sym = s), 123 sigsend_class); 124 if (sender) 125 { 126 if (sender->x_n == x->x_n) 127 x->x_wherefrom = sender->x_vec; 128 else 129 { 130 pd_error(x, "receive~ %s: vector size mismatch", x->x_sym->s_name); 131 x->x_wherefrom = 0; 132 } 133 } 134 else 135 { 136 pd_error(x, "receive~ %s: no matching send", x->x_sym->s_name); 137 x->x_wherefrom = 0; 138 } 139} 140 141static void sigreceive_dsp(t_sigreceive *x, t_signal **sp) 142{ 143 if (sp[0]->s_n != x->x_n) 144 { 145 pd_error(x, "receive~ %s: vector size mismatch", x->x_sym->s_name); 146 } 147 else 148 { 149 sigreceive_set(x, x->x_sym); 150 dsp_add(sigreceive_perform, 3, 151 x, sp[0]->s_vec, sp[0]->s_n); 152 } 153} 154 155static void sigreceive_setup(void) 156{ 157 sigreceive_class = class_new(gensym("receive~"), 158 (t_newmethod)sigreceive_new, 0, 159 sizeof(t_sigreceive), 0, A_DEFSYM, 0); 160 class_addcreator((t_newmethod)sigreceive_new, gensym("r~"), A_DEFSYM, 0); 161 class_addmethod(sigreceive_class, (t_method)sigreceive_set, gensym("set"), 162 A_SYMBOL, 0); 163 class_addmethod(sigreceive_class, (t_method)sigreceive_dsp, gensym("dsp"), 164 0); 165 class_sethelpsymbol(sigreceive_class, gensym("send~")); 166} 167 168/* ----------------------------- catch~ ----------------------------- */ 169static t_class *sigcatch_class; 170 171typedef struct _sigcatch 172{ 173 t_object x_obj; 174 t_symbol *x_sym; 175 int x_n; 176 t_sample *x_vec; 177} t_sigcatch; 178 179static void *sigcatch_new(t_symbol *s) 180{ 181 t_sigcatch *x = (t_sigcatch *)pd_new(sigcatch_class); 182 pd_bind(&x->x_obj.ob_pd, s); 183 x->x_sym = s; 184 x->x_n = DEFSENDVS; 185 x->x_vec = (t_sample *)getbytes(DEFSENDVS * sizeof(t_sample)); 186 memset((char *)(x->x_vec), 0, DEFSENDVS * sizeof(t_sample)); 187 outlet_new(&x->x_obj, &s_signal); 188 return (x); 189} 190 191static t_int *sigcatch_perform(t_int *w) 192{ 193 t_sample *in = (t_sample *)(w[1]); 194 t_sample *out = (t_sample *)(w[2]); 195 int n = (int)(w[3]); 196 while (n--) *out++ = *in, *in++ = 0; 197 return (w+4); 198} 199 200static void sigcatch_dsp(t_sigcatch *x, t_signal **sp) 201{ 202 if (x->x_n == sp[0]->s_n) 203 dsp_add(sigcatch_perform, 3, x->x_vec, sp[0]->s_vec, sp[0]->s_n); 204 else error("sigcatch %s: unexpected vector size", x->x_sym->s_name); 205} 206 207static void sigcatch_free(t_sigcatch *x) 208{ 209 pd_unbind(&x->x_obj.ob_pd, x->x_sym); 210 freebytes(x->x_vec, x->x_n * sizeof(float)); 211} 212 213static void sigcatch_setup(void) 214{ 215 sigcatch_class = class_new(gensym("catch~"), (t_newmethod)sigcatch_new, 216 (t_method)sigcatch_free, sizeof(t_sigcatch), CLASS_NOINLET, A_DEFSYM, 0); 217 class_addmethod(sigcatch_class, (t_method)sigcatch_dsp, gensym("dsp"), 0); 218 class_sethelpsymbol(sigcatch_class, gensym("throw~")); 219} 220 221/* ----------------------------- throw~ ----------------------------- */ 222static t_class *sigthrow_class; 223 224typedef struct _sigthrow 225{ 226 t_object x_obj; 227 t_symbol *x_sym; 228 t_sample *x_whereto; 229 int x_n; 230 t_float x_f; 231} t_sigthrow; 232 233static void *sigthrow_new(t_symbol *s) 234{ 235 t_sigthrow *x = (t_sigthrow *)pd_new(sigthrow_class); 236 x->x_sym = s; 237 x->x_whereto = 0; 238 x->x_n = DEFSENDVS; 239 x->x_f = 0; 240 return (x); 241} 242 243static t_int *sigthrow_perform(t_int *w) 244{ 245 t_sigthrow *x = (t_sigthrow *)(w[1]); 246 t_sample *in = (t_sample *)(w[2]); 247 int n = (int)(w[3]); 248 t_sample *out = x->x_whereto; 249 if (out) 250 { 251 while (n--) 252 { 253 *out += (PD_BIGORSMALL(*in) ? 0 : *in); 254 out++; 255 in++; 256 } 257 } 258 return (w+4); 259} 260 261static void sigthrow_set(t_sigthrow *x, t_symbol *s) 262{ 263 t_sigcatch *catcher = (t_sigcatch *)pd_findbyclass((x->x_sym = s), 264 sigcatch_class); 265 if (catcher) 266 { 267 if (catcher->x_n == x->x_n) 268 x->x_whereto = catcher->x_vec; 269 else 270 { 271 pd_error(x, "throw~ %s: vector size mismatch", x->x_sym->s_name); 272 x->x_whereto = 0; 273 } 274 } 275 else 276 { 277 pd_error(x, "throw~ %s: no matching catch", x->x_sym->s_name); 278 x->x_whereto = 0; 279 } 280} 281 282static void sigthrow_dsp(t_sigthrow *x, t_signal **sp) 283{ 284 if (sp[0]->s_n != x->x_n) 285 { 286 pd_error(x, "throw~ %s: vector size mismatch", x->x_sym->s_name); 287 } 288 else 289 { 290 sigthrow_set(x, x->x_sym); 291 dsp_add(sigthrow_perform, 3, 292 x, sp[0]->s_vec, sp[0]->s_n); 293 } 294} 295 296static void sigthrow_setup(void) 297{ 298 sigthrow_class = class_new(gensym("throw~"), (t_newmethod)sigthrow_new, 0, 299 sizeof(t_sigthrow), 0, A_DEFSYM, 0); 300 class_addcreator((t_newmethod)sigthrow_new, gensym("r~"), A_DEFSYM, 0); 301 class_addmethod(sigthrow_class, (t_method)sigthrow_set, gensym("set"), 302 A_SYMBOL, 0); 303 CLASS_MAINSIGNALIN(sigthrow_class, t_sigthrow, x_f); 304 class_addmethod(sigthrow_class, (t_method)sigthrow_dsp, gensym("dsp"), 0); 305} 306 307/* ----------------------- global setup routine ---------------- */ 308 309void d_global_setup(void) 310{ 311 sigsend_setup(); 312 sigreceive_setup(); 313 sigcatch_setup(); 314 sigthrow_setup(); 315} 316