summaryrefslogtreecommitdiff
path: root/apps/plugins/pdbox/PDa/intern/env~.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/pdbox/PDa/intern/env~.c')
-rw-r--r--apps/plugins/pdbox/PDa/intern/env~.c254
1 files changed, 254 insertions, 0 deletions
diff --git a/apps/plugins/pdbox/PDa/intern/env~.c b/apps/plugins/pdbox/PDa/intern/env~.c
new file mode 100644
index 0000000000..a9bf6998e1
--- /dev/null
+++ b/apps/plugins/pdbox/PDa/intern/env~.c
@@ -0,0 +1,254 @@
1
2#define FIXEDPOINT
3#include <m_pd.h>
4#include <m_fixed.h>
5
6
7#define MAXOVERLAP 10
8#define MAXVSTAKEN 64
9
10typedef struct sigenv
11{
12 t_object x_obj; /* header */
13 void *x_outlet; /* a "float" outlet */
14 void *x_clock; /* a "clock" object */
15 t_sample *x_buf; /* a Hanning window */
16 int x_phase; /* number of points since last output */
17 int x_period; /* requested period of output */
18 int x_realperiod; /* period rounded up to vecsize multiple */
19 int x_npoints; /* analysis window size in samples */
20 t_float x_result; /* result to output */
21 t_sample x_sumbuf[MAXOVERLAP]; /* summing buffer */
22 t_float x_f;
23} t_sigenv;
24
25t_class *sigenv_class;
26static void sigenv_tick(t_sigenv *x);
27
28static void *sigenv_new(t_floatarg fnpoints, t_floatarg fperiod)
29{
30 int npoints = fnpoints;
31 int period = fperiod;
32 t_sigenv *x;
33 t_sample *buf;
34 int i;
35
36 if (npoints < 1) npoints = 1024;
37 if (period < 1) period = npoints/2;
38 if (period < npoints / MAXOVERLAP + 1)
39 period = npoints / MAXOVERLAP + 1;
40 if (!(buf = getbytes(sizeof(t_sample) * (npoints + MAXVSTAKEN))))
41 {
42 error("env: couldn't allocate buffer");
43 return (0);
44 }
45 x = (t_sigenv *)pd_new(sigenv_class);
46 x->x_buf = buf;
47 x->x_npoints = npoints;
48 x->x_phase = 0;
49 x->x_period = period;
50 for (i = 0; i < MAXOVERLAP; i++) x->x_sumbuf[i] = 0;
51 for (i = 0; i < npoints; i++)
52 buf[i] = ftofix((1. - cos((2 * 3.14159 * i) / npoints))/npoints);
53 for (; i < npoints+MAXVSTAKEN; i++) buf[i] = 0;
54 x->x_clock = clock_new(x, (t_method)sigenv_tick);
55 x->x_outlet = outlet_new(&x->x_obj, gensym("float"));
56 x->x_f = 0;
57 return (x);
58}
59
60static t_int *sigenv_perform(t_int *w)
61{
62 t_sigenv *x = (t_sigenv *)(w[1]);
63 t_sample *in = (t_sample *)(w[2]);
64 int n = (int)(w[3]);
65 int count;
66 t_sample *sump;
67 in += n;
68 for (count = x->x_phase, sump = x->x_sumbuf;
69 count < x->x_npoints; count += x->x_realperiod, sump++)
70 {
71 t_sample *hp = x->x_buf + count;
72 t_sample *fp = in;
73 t_sample sum = *sump;
74 int i;
75
76 for (i = 0; i < n; i++)
77 {
78 fp--;
79 sum += *hp++ * ((*fp * *fp)>>16)>>16;
80 }
81 *sump = sum;
82 }
83 sump[0] = 0;
84 x->x_phase -= n;
85 if (x->x_phase < 0)
86 {
87 x->x_result = x->x_sumbuf[0];
88 for (count = x->x_realperiod, sump = x->x_sumbuf;
89 count < x->x_npoints; count += x->x_realperiod, sump++)
90 sump[0] = sump[1];
91 sump[0] = 0;
92 x->x_phase = x->x_realperiod - n;
93 clock_delay(x->x_clock, 0L);
94 }
95 return (w+4);
96}
97
98static void sigenv_dsp(t_sigenv *x, t_signal **sp)
99{
100 if (x->x_period % sp[0]->s_n) x->x_realperiod =
101 x->x_period + sp[0]->s_n - (x->x_period % sp[0]->s_n);
102 else x->x_realperiod = x->x_period;
103 dsp_add(sigenv_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
104 if (sp[0]->s_n > MAXVSTAKEN) bug("sigenv_dsp");
105}
106
107static void sigenv_tick(t_sigenv *x) /* callback function for the clock */
108{
109 outlet_float(x->x_outlet, powtodb(x->x_result*3.051757e-05));
110}
111
112static void sigenv_ff(t_sigenv *x) /* cleanup on free */
113{
114 clock_free(x->x_clock);
115 freebytes(x->x_buf, (x->x_npoints + MAXVSTAKEN) * sizeof(float));
116}
117
118
119void env_tilde_setup(void )
120{
121 sigenv_class = class_new(gensym("env~"), (t_newmethod)sigenv_new,
122 (t_method)sigenv_ff, sizeof(t_sigenv), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
123 CLASS_MAINSIGNALIN(sigenv_class, t_sigenv, x_f);
124 class_addmethod(sigenv_class, (t_method)sigenv_dsp, gensym("dsp"), 0);
125}
126
127
128
129#define FIXEDPOINT
130#include <m_pd.h>
131#include <m_fixed.h>
132
133
134#define MAXOVERLAP 10
135#define MAXVSTAKEN 64
136
137typedef struct sigenv
138{
139 t_object x_obj; /* header */
140 void *x_outlet; /* a "float" outlet */
141 void *x_clock; /* a "clock" object */
142 t_sample *x_buf; /* a Hanning window */
143 int x_phase; /* number of points since last output */
144 int x_period; /* requested period of output */
145 int x_realperiod; /* period rounded up to vecsize multiple */
146 int x_npoints; /* analysis window size in samples */
147 t_float x_result; /* result to output */
148 t_sample x_sumbuf[MAXOVERLAP]; /* summing buffer */
149 t_float x_f;
150} t_sigenv;
151
152t_class *sigenv_class;
153static void sigenv_tick(t_sigenv *x);
154
155static void *sigenv_new(t_floatarg fnpoints, t_floatarg fperiod)
156{
157 int npoints = fnpoints;
158 int period = fperiod;
159 t_sigenv *x;
160 t_sample *buf;
161 int i;
162
163 if (npoints < 1) npoints = 1024;
164 if (period < 1) period = npoints/2;
165 if (period < npoints / MAXOVERLAP + 1)
166 period = npoints / MAXOVERLAP + 1;
167 if (!(buf = getbytes(sizeof(t_sample) * (npoints + MAXVSTAKEN))))
168 {
169 error("env: couldn't allocate buffer");
170 return (0);
171 }
172 x = (t_sigenv *)pd_new(sigenv_class);
173 x->x_buf = buf;
174 x->x_npoints = npoints;
175 x->x_phase = 0;
176 x->x_period = period;
177 for (i = 0; i < MAXOVERLAP; i++) x->x_sumbuf[i] = 0;
178 for (i = 0; i < npoints; i++)
179 buf[i] = ftofix((1. - cos((2 * 3.14159 * i) / npoints))/npoints);
180 for (; i < npoints+MAXVSTAKEN; i++) buf[i] = 0;
181 x->x_clock = clock_new(x, (t_method)sigenv_tick);
182 x->x_outlet = outlet_new(&x->x_obj, gensym("float"));
183 x->x_f = 0;
184 return (x);
185}
186
187static t_int *sigenv_perform(t_int *w)
188{
189 t_sigenv *x = (t_sigenv *)(w[1]);
190 t_sample *in = (t_sample *)(w[2]);
191 int n = (int)(w[3]);
192 int count;
193 t_sample *sump;
194 in += n;
195 for (count = x->x_phase, sump = x->x_sumbuf;
196 count < x->x_npoints; count += x->x_realperiod, sump++)
197 {
198 t_sample *hp = x->x_buf + count;
199 t_sample *fp = in;
200 t_sample sum = *sump;
201 int i;
202
203 for (i = 0; i < n; i++)
204 {
205 fp--;
206 sum += *hp++ * ((*fp * *fp)>>16)>>16;
207 }
208 *sump = sum;
209 }
210 sump[0] = 0;
211 x->x_phase -= n;
212 if (x->x_phase < 0)
213 {
214 x->x_result = x->x_sumbuf[0];
215 for (count = x->x_realperiod, sump = x->x_sumbuf;
216 count < x->x_npoints; count += x->x_realperiod, sump++)
217 sump[0] = sump[1];
218 sump[0] = 0;
219 x->x_phase = x->x_realperiod - n;
220 clock_delay(x->x_clock, 0L);
221 }
222 return (w+4);
223}
224
225static void sigenv_dsp(t_sigenv *x, t_signal **sp)
226{
227 if (x->x_period % sp[0]->s_n) x->x_realperiod =
228 x->x_period + sp[0]->s_n - (x->x_period % sp[0]->s_n);
229 else x->x_realperiod = x->x_period;
230 dsp_add(sigenv_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
231 if (sp[0]->s_n > MAXVSTAKEN) bug("sigenv_dsp");
232}
233
234static void sigenv_tick(t_sigenv *x) /* callback function for the clock */
235{
236 outlet_float(x->x_outlet, powtodb(x->x_result*3.051757e-05));
237}
238
239static void sigenv_ff(t_sigenv *x) /* cleanup on free */
240{
241 clock_free(x->x_clock);
242 freebytes(x->x_buf, (x->x_npoints + MAXVSTAKEN) * sizeof(float));
243}
244
245
246void env_tilde_setup(void )
247{
248 sigenv_class = class_new(gensym("env~"), (t_newmethod)sigenv_new,
249 (t_method)sigenv_ff, sizeof(t_sigenv), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
250 CLASS_MAINSIGNALIN(sigenv_class, t_sigenv, x_f);
251 class_addmethod(sigenv_class, (t_method)sigenv_dsp, gensym("dsp"), 0);
252}
253
254