1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
/* Copyright (c) 2002-2003 krzYszcz and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
#include <string.h>
#include "m_pd.h"
#include "sickle/sic.h"
typedef struct _delay
{
t_sic x_sic;
t_float *x_buf;
t_float *x_bufend;
t_float *x_whead;
int x_maxsize;
int x_delsize;
} t_delay;
static t_class *delay_class;
#define DELAY_DEFMAXSIZE 512
static void delay_ft1(t_delay *x, t_floatarg f)
{
x->x_delsize = (f > 0 ? (int)f : 0);
if (x->x_delsize > x->x_maxsize)
x->x_delsize = x->x_maxsize; /* CHECKED */
/* CHECKED: all buffered values should be available */
}
static t_int *delay_perform(t_int *w)
{
t_delay *x = (t_delay *)(w[1]);
int nblock = (int)(w[2]);
t_float *in = (t_float *)(w[3]);
t_float *out = (t_float *)(w[4]);
t_float *buf = x->x_buf;
t_float *ep = x->x_bufend;
t_float *wp = x->x_whead;
if (x->x_delsize)
{
t_float *rp = wp - x->x_delsize;
if (rp < buf) rp += x->x_maxsize;
while (nblock--)
{
float f = *in++;
*out++ = *rp;
if (rp++ == ep) rp = buf;
*wp = f;
if (wp++ == ep) wp = buf;
}
}
else while (nblock--)
{
*out++ = *wp = *in++;
if (wp++ == ep) wp = buf;
}
x->x_whead = wp;
return (w + 5);
}
static void delay_dsp(t_delay *x, t_signal **sp)
{
memset(x->x_buf, 0, x->x_maxsize * sizeof(*x->x_buf)); /* CHECKED */
x->x_whead = x->x_buf;
dsp_add(delay_perform, 4, x, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec);
}
static void *delay_new(t_floatarg f1, t_floatarg f2)
{
t_delay *x;
int maxsize = (f1 > 0 ? (int)f1 : DELAY_DEFMAXSIZE);
t_float *buf = (t_float *)getbytes(maxsize * sizeof(*buf));
if (!buf)
return (0);
x = (t_delay *)pd_new(delay_class);
x->x_maxsize = maxsize;
x->x_buf = x->x_whead = buf;
x->x_bufend = buf + maxsize - 1;
x->x_delsize = (f2 > 0 ? (int)f2 : 0);
if (x->x_delsize > maxsize)
x->x_delsize = maxsize;
inlet_new((t_object *)x, (t_pd *)x, &s_float, gensym("ft1"));
outlet_new((t_object *)x, &s_signal);
return (x);
}
static void delay_free(t_delay *x)
{
if (x->x_buf) freebytes(x->x_buf, x->x_maxsize * sizeof(*x->x_buf));
}
void delay_tilde_setup(void)
{
delay_class = class_new(gensym("delay~"),
(t_newmethod)delay_new, (t_method)delay_free,
sizeof(t_delay), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
sic_setup(delay_class, delay_dsp, SIC_FLOATTOSIGNAL);
class_addmethod(delay_class, (t_method)delay_ft1,
gensym("ft1"), A_FLOAT, 0);
}
|