/* 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. */ /* send~, delread~, throw~, catch~ */ #include "m_pd.h" #include "delwrite~.h" static t_class *sigdelread_class; typedef struct _sigdelread { t_object x_obj; t_symbol *x_sym; t_float x_deltime; /* delay in msec */ int x_delsamps; /* delay in samples */ t_float x_sr; /* samples per msec */ t_float x_n; /* vector size */ int x_zerodel; /* 0 or vecsize depending on read/write order */ } t_sigdelread; static void sigdelread_float(t_sigdelread *x, t_float f); static void *sigdelread_new(t_symbol *s, t_floatarg f) { t_sigdelread *x = (t_sigdelread *)pd_new(sigdelread_class); x->x_sym = s; x->x_sr = 1; x->x_n = 1; x->x_zerodel = 0; sigdelread_float(x, f); outlet_new(&x->x_obj, &s_signal); return (x); } static void sigdelread_float(t_sigdelread *x, t_float f) { int samps; t_sigdelwrite *delwriter = (t_sigdelwrite *)pd_findbyclass(x->x_sym, sigdelwrite_class); x->x_deltime = f; if (delwriter) { int delsize = delwriter->x_cspace.c_n; x->x_delsamps = (int)(0.5 + x->x_sr * x->x_deltime) + x->x_n - x->x_zerodel; if (x->x_delsamps < x->x_n) x->x_delsamps = x->x_n; else if (x->x_delsamps > delwriter->x_cspace.c_n - DEFDELVS) x->x_delsamps = delwriter->x_cspace.c_n - DEFDELVS; } } static t_int *sigdelread_perform(t_int *w) { t_sample *out = (t_sample *)(w[1]); t_delwritectl *c = (t_delwritectl *)(w[2]); int delsamps = *(int *)(w[3]); int n = (int)(w[4]); int phase = c->c_phase - delsamps, nsamps = c->c_n; t_sample *vp = c->c_vec, *bp, *ep = vp + (c->c_n + XTRASAMPS); if (phase < 0) phase += nsamps; bp = vp + phase; while (n--) { *out++ = *bp++; if (bp == ep) bp -= nsamps; } return (w+5); } static void sigdelread_dsp(t_sigdelread *x, t_signal **sp) { t_sigdelwrite *delwriter = (t_sigdelwrite *)pd_findbyclass(x->x_sym, sigdelwrite_class); x->x_sr = sp[0]->s_sr * 0.001; x->x_n = sp[0]->s_n; if (delwriter) { sigdelwrite_checkvecsize(delwriter, sp[0]->s_n); x->x_zerodel = (delwriter->x_sortno == ugen_getsortno() ? 0 : delwriter->x_vecsize); sigdelread_float(x, x->x_deltime); dsp_add(sigdelread_perform, 4, sp[0]->s_vec, &delwriter->x_cspace, &x->x_delsamps, sp[0]->s_n); } else if (*x->x_sym->s_name) error("delread~: %s: no such delwrite~",x->x_sym->s_name); } void delread_tilde_setup(void) { sigdelread_class = class_new(gensym("delread~"), (t_newmethod)sigdelread_new, 0, sizeof(t_sigdelread), 0, A_DEFSYM, A_DEFFLOAT, 0); class_addmethod(sigdelread_class, (t_method)sigdelread_dsp, gensym("dsp"), 0); class_addfloat(sigdelread_class, (t_method)sigdelread_float); }