summaryrefslogtreecommitdiff
path: root/apps/plugins/pdbox/PDa/src/d_delay.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/d_delay.c')
-rw-r--r--apps/plugins/pdbox/PDa/src/d_delay.c319
1 files changed, 0 insertions, 319 deletions
diff --git a/apps/plugins/pdbox/PDa/src/d_delay.c b/apps/plugins/pdbox/PDa/src/d_delay.c
index 37fb90ea5b..d04ded9e90 100644
--- a/apps/plugins/pdbox/PDa/src/d_delay.c
+++ b/apps/plugins/pdbox/PDa/src/d_delay.c
@@ -317,322 +317,3 @@ void d_delay_setup(void)
317 sigvd_setup(); 317 sigvd_setup();
318} 318}
319 319
320/* Copyright (c) 1997-1999 Miller Puckette.
321* For information on usage and redistribution, and for a DISCLAIMER OF ALL
322* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
323
324/* send~, delread~, throw~, catch~ */
325
326#include "m_pd.h"
327extern int ugen_getsortno(void);
328
329#define DEFDELVS 64 /* LATER get this from canvas at DSP time */
330static int delread_zero = 0; /* four bytes of zero for delread~, vd~ */
331
332/* ----------------------------- delwrite~ ----------------------------- */
333static t_class *sigdelwrite_class;
334
335typedef struct delwritectl
336{
337 int c_n;
338 float *c_vec;
339 int c_phase;
340} t_delwritectl;
341
342typedef struct _sigdelwrite
343{
344 t_object x_obj;
345 t_symbol *x_sym;
346 t_delwritectl x_cspace;
347 int x_sortno; /* DSP sort number at which this was last put on chain */
348 int x_rsortno; /* DSP sort # for first delread or write in chain */
349 int x_vecsize; /* vector size for delread~ to use */
350 float x_f;
351} t_sigdelwrite;
352
353#define XTRASAMPS 4
354#define SAMPBLK 4
355
356 /* routine to check that all delwrites/delreads/vds have same vecsize */
357static void sigdelwrite_checkvecsize(t_sigdelwrite *x, int vecsize)
358{
359 /*
360 LATER this should really check sample rate and blocking, once that is
361 supported. Probably we don't actually care about vecsize.
362 For now just suppress this check... */
363#if 0
364 if (x->x_rsortno != ugen_getsortno())
365 {
366 x->x_vecsize = vecsize;
367 x->x_rsortno = ugen_getsortno();
368 }
369 else if (vecsize != x->x_vecsize)
370 pd_error(x, "delread/delwrite/vd vector size mismatch");
371#endif
372}
373
374static void *sigdelwrite_new(t_symbol *s, t_floatarg msec)
375{
376 int nsamps;
377 t_sigdelwrite *x = (t_sigdelwrite *)pd_new(sigdelwrite_class);
378 if (!*s->s_name) s = gensym("delwrite~");
379 pd_bind(&x->x_obj.ob_pd, s);
380 x->x_sym = s;
381 nsamps = msec * sys_getsr() * (float)(0.001f);
382 if (nsamps < 1) nsamps = 1;
383 nsamps += ((- nsamps) & (SAMPBLK - 1));
384 nsamps += DEFDELVS;
385 x->x_cspace.c_n = nsamps;
386 x->x_cspace.c_vec =
387 (float *)getbytes((nsamps + XTRASAMPS) * sizeof(float));
388 x->x_cspace.c_phase = XTRASAMPS;
389 x->x_sortno = 0;
390 x->x_vecsize = 0;
391 x->x_f = 0;
392 return (x);
393}
394
395static t_int *sigdelwrite_perform(t_int *w)
396{
397 t_float *in = (t_float *)(w[1]);
398 t_delwritectl *c = (t_delwritectl *)(w[2]);
399 int n = (int)(w[3]);
400 int phase = c->c_phase, nsamps = c->c_n;
401 float *vp = c->c_vec, *bp = vp + phase, *ep = vp + (c->c_n + XTRASAMPS);
402 phase += n;
403 while (n--)
404 {
405 float f = *in++;
406 if (PD_BIGORSMALL(f))
407 f = 0;
408 *bp++ = f;
409 if (bp == ep)
410 {
411 vp[0] = ep[-4];
412 vp[1] = ep[-3];
413 vp[2] = ep[-2];
414 vp[3] = ep[-1];
415 bp = vp + XTRASAMPS;
416 phase -= nsamps;
417 }
418 }
419 c->c_phase = phase;
420 return (w+4);
421}
422
423static void sigdelwrite_dsp(t_sigdelwrite *x, t_signal **sp)
424{
425 dsp_add(sigdelwrite_perform, 3, sp[0]->s_vec, &x->x_cspace, sp[0]->s_n);
426 x->x_sortno = ugen_getsortno();
427 sigdelwrite_checkvecsize(x, sp[0]->s_n);
428}
429
430static void sigdelwrite_free(t_sigdelwrite *x)
431{
432 pd_unbind(&x->x_obj.ob_pd, x->x_sym);
433 freebytes(x->x_cspace.c_vec,
434 (x->x_cspace.c_n + XTRASAMPS) * sizeof(float));
435}
436
437static void sigdelwrite_setup(void)
438{
439 sigdelwrite_class = class_new(gensym("delwrite~"),
440 (t_newmethod)sigdelwrite_new, (t_method)sigdelwrite_free,
441 sizeof(t_sigdelwrite), 0, A_DEFSYM, A_DEFFLOAT, 0);
442 CLASS_MAINSIGNALIN(sigdelwrite_class, t_sigdelwrite, x_f);
443 class_addmethod(sigdelwrite_class, (t_method)sigdelwrite_dsp,
444 gensym("dsp"), 0);
445}
446
447/* ----------------------------- delread~ ----------------------------- */
448static t_class *sigdelread_class;
449
450typedef struct _sigdelread
451{
452 t_object x_obj;
453 t_symbol *x_sym;
454 t_float x_deltime; /* delay in msec */
455 int x_delsamps; /* delay in samples */
456 t_float x_sr; /* samples per msec */
457 t_float x_n; /* vector size */
458 int x_zerodel; /* 0 or vecsize depending on read/write order */
459} t_sigdelread;
460
461static void sigdelread_float(t_sigdelread *x, t_float f);
462
463static void *sigdelread_new(t_symbol *s, t_floatarg f)
464{
465 t_sigdelread *x = (t_sigdelread *)pd_new(sigdelread_class);
466 x->x_sym = s;
467 x->x_sr = 1;
468 x->x_n = 1;
469 x->x_zerodel = 0;
470 sigdelread_float(x, f);
471 outlet_new(&x->x_obj, &s_signal);
472 return (x);
473}
474
475static void sigdelread_float(t_sigdelread *x, t_float f)
476{
477 int samps;
478 t_sigdelwrite *delwriter =
479 (t_sigdelwrite *)pd_findbyclass(x->x_sym, sigdelwrite_class);
480 x->x_deltime = f;
481 if (delwriter)
482 {
483 int delsize = delwriter->x_cspace.c_n;
484 x->x_delsamps = (int)(0.5 + x->x_sr * x->x_deltime)
485 + x->x_n - x->x_zerodel;
486 if (x->x_delsamps < x->x_n) x->x_delsamps = x->x_n;
487 else if (x->x_delsamps > delwriter->x_cspace.c_n - DEFDELVS)
488 x->x_delsamps = delwriter->x_cspace.c_n - DEFDELVS;
489 }
490}
491
492static t_int *sigdelread_perform(t_int *w)
493{
494 t_float *out = (t_float *)(w[1]);
495 t_delwritectl *c = (t_delwritectl *)(w[2]);
496 int delsamps = *(int *)(w[3]);
497 int n = (int)(w[4]);
498 int phase = c->c_phase - delsamps, nsamps = c->c_n;
499 float *vp = c->c_vec, *bp, *ep = vp + (c->c_n + XTRASAMPS);
500
501 if (phase < 0) phase += nsamps;
502 bp = vp + phase;
503 while (n--)
504 {
505 *out++ = *bp++;
506 if (bp == ep) bp -= nsamps;
507 }
508 return (w+5);
509}
510
511static void sigdelread_dsp(t_sigdelread *x, t_signal **sp)
512{
513 t_sigdelwrite *delwriter =
514 (t_sigdelwrite *)pd_findbyclass(x->x_sym, sigdelwrite_class);
515 x->x_sr = sp[0]->s_sr * 0.001;
516 x->x_n = sp[0]->s_n;
517 if (delwriter)
518 {
519 sigdelwrite_checkvecsize(delwriter, sp[0]->s_n);
520 x->x_zerodel = (delwriter->x_sortno == ugen_getsortno() ?
521 0 : delwriter->x_vecsize);
522 sigdelread_float(x, x->x_deltime);
523 dsp_add(sigdelread_perform, 4,
524 sp[0]->s_vec, &delwriter->x_cspace, &x->x_delsamps, sp[0]->s_n);
525 }
526 else if (*x->x_sym->s_name)
527 error("delread~: %s: no such delwrite~",x->x_sym->s_name);
528}
529
530static void sigdelread_setup(void)
531{
532 sigdelread_class = class_new(gensym("delread~"),
533 (t_newmethod)sigdelread_new, 0,
534 sizeof(t_sigdelread), 0, A_DEFSYM, A_DEFFLOAT, 0);
535 class_addmethod(sigdelread_class, (t_method)sigdelread_dsp,
536 gensym("dsp"), 0);
537 class_addfloat(sigdelread_class, (t_method)sigdelread_float);
538}
539
540
541/* ----------------------------- vd~ ----------------------------- */
542static t_class *sigvd_class;
543
544typedef struct _sigvd
545{
546 t_object x_obj;
547 t_symbol *x_sym;
548 t_float x_sr; /* samples per msec */
549 int x_zerodel; /* 0 or vecsize depending on read/write order */
550 float x_f;
551} t_sigvd;
552
553static void *sigvd_new(t_symbol *s)
554{
555 t_sigvd *x = (t_sigvd *)pd_new(sigvd_class);
556 if (!*s->s_name) s = gensym("vd~");
557 x->x_sym = s;
558 x->x_sr = 1;
559 x->x_zerodel = 0;
560 outlet_new(&x->x_obj, &s_signal);
561 x->x_f = 0;
562 return (x);
563}
564
565static t_int *sigvd_perform(t_int *w)
566{
567 t_float *in = (t_float *)(w[1]);
568 t_float *out = (t_float *)(w[2]);
569 t_delwritectl *ctl = (t_delwritectl *)(w[3]);
570 t_sigvd *x = (t_sigvd *)(w[4]);
571 int n = (int)(w[5]);
572
573 int nsamps = ctl->c_n;
574 float limit = nsamps - n - 1;
575 float fn = n-1;
576 float *vp = ctl->c_vec, *bp, *wp = vp + ctl->c_phase;
577 float zerodel = x->x_zerodel;
578 while (n--)
579 {
580 float delsamps = x->x_sr * *in++ - zerodel, frac;
581 int idelsamps;
582 float a, b, c, d, cminusb;
583 if (delsamps < 1.00001f) delsamps = 1.00001f;
584 if (delsamps > limit) delsamps = limit;
585 delsamps += fn;
586 fn = fn - 1.0f;
587 idelsamps = delsamps;
588 frac = delsamps - (float)idelsamps;
589 bp = wp - idelsamps;
590 if (bp < vp + 4) bp += nsamps;
591 d = bp[-3];
592 c = bp[-2];
593 b = bp[-1];
594 a = bp[0];
595 cminusb = c-b;
596 *out++ = b + frac * (
597 cminusb - 0.1666667f * (1.-frac) * (
598 (d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b)
599 )
600 );
601 }
602 return (w+6);
603}
604
605static void sigvd_dsp(t_sigvd *x, t_signal **sp)
606{
607 t_sigdelwrite *delwriter =
608 (t_sigdelwrite *)pd_findbyclass(x->x_sym, sigdelwrite_class);
609 x->x_sr = sp[0]->s_sr * 0.001;
610 if (delwriter)
611 {
612 sigdelwrite_checkvecsize(delwriter, sp[0]->s_n);
613 x->x_zerodel = (delwriter->x_sortno == ugen_getsortno() ?
614 0 : delwriter->x_vecsize);
615 dsp_add(sigvd_perform, 5,
616 sp[0]->s_vec, sp[1]->s_vec,
617 &delwriter->x_cspace, x, sp[0]->s_n);
618 }
619 else error("vd~: %s: no such delwrite~",x->x_sym->s_name);
620}
621
622static void sigvd_setup(void)
623{
624 sigvd_class = class_new(gensym("vd~"), (t_newmethod)sigvd_new, 0,
625 sizeof(t_sigvd), 0, A_DEFSYM, 0);
626 class_addmethod(sigvd_class, (t_method)sigvd_dsp, gensym("dsp"), 0);
627 CLASS_MAINSIGNALIN(sigvd_class, t_sigvd, x_f);
628}
629
630/* ----------------------- global setup routine ---------------- */
631
632void d_delay_setup(void)
633{
634 sigdelwrite_setup();
635 sigdelread_setup();
636 sigvd_setup();
637}
638