diff options
Diffstat (limited to 'apps/plugins/pdbox/PDa/intern/vline~.c')
-rw-r--r-- | apps/plugins/pdbox/PDa/intern/vline~.c | 368 |
1 files changed, 368 insertions, 0 deletions
diff --git a/apps/plugins/pdbox/PDa/intern/vline~.c b/apps/plugins/pdbox/PDa/intern/vline~.c new file mode 100644 index 0000000000..74edb83bc6 --- /dev/null +++ b/apps/plugins/pdbox/PDa/intern/vline~.c | |||
@@ -0,0 +1,368 @@ | |||
1 | #include <m_pd.h> | ||
2 | #include <m_fixed.h> | ||
3 | |||
4 | |||
5 | |||
6 | static t_class *vline_tilde_class; | ||
7 | |||
8 | typedef struct _vseg | ||
9 | { | ||
10 | t_time s_targettime; | ||
11 | t_time s_starttime; | ||
12 | t_sample s_target; | ||
13 | struct _vseg *s_next; | ||
14 | } t_vseg; | ||
15 | |||
16 | typedef struct _vline | ||
17 | { | ||
18 | t_object x_obj; | ||
19 | t_sample x_value; | ||
20 | t_sample x_inc; | ||
21 | t_time x_referencetime; | ||
22 | t_time x_samppermsec; | ||
23 | t_time x_msecpersamp; | ||
24 | t_time x_targettime; | ||
25 | t_sample x_target; | ||
26 | float x_inlet1; | ||
27 | float x_inlet2; | ||
28 | t_vseg *x_list; | ||
29 | } t_vline; | ||
30 | |||
31 | static t_int *vline_tilde_perform(t_int *w) | ||
32 | { | ||
33 | t_vline *x = (t_vline *)(w[1]); | ||
34 | t_sample *out = (t_sample *)(w[2]); | ||
35 | int n = (int)(w[3]), i; | ||
36 | t_sample f = x->x_value; | ||
37 | t_sample inc = x->x_inc; | ||
38 | t_time msecpersamp = x->x_msecpersamp; | ||
39 | t_time samppermsec = x->x_samppermsec; | ||
40 | t_time timenow = clock_gettimesince(x->x_referencetime) - n * msecpersamp; | ||
41 | t_vseg *s = x->x_list; | ||
42 | for (i = 0; i < n; i++) | ||
43 | { | ||
44 | t_time timenext = timenow + msecpersamp; | ||
45 | checknext: | ||
46 | if (s) | ||
47 | { | ||
48 | /* has starttime elapsed? If so update value and increment */ | ||
49 | if (s->s_starttime < timenext) | ||
50 | { | ||
51 | if (x->x_targettime <= timenext) | ||
52 | f = x->x_target, inc = 0; | ||
53 | /* if zero-length segment bash output value */ | ||
54 | if (s->s_targettime <= s->s_starttime) | ||
55 | { | ||
56 | f = s->s_target; | ||
57 | inc = 0; | ||
58 | } | ||
59 | else | ||
60 | { | ||
61 | t_time incpermsec = div((s->s_target - f), | ||
62 | (s->s_targettime - s->s_starttime)); | ||
63 | f = mult(f + incpermsec,(timenext - s->s_starttime)); | ||
64 | inc = mult(incpermsec,msecpersamp); | ||
65 | } | ||
66 | x->x_inc = inc; | ||
67 | x->x_target = s->s_target; | ||
68 | x->x_targettime = s->s_targettime; | ||
69 | x->x_list = s->s_next; | ||
70 | t_freebytes(s, sizeof(*s)); | ||
71 | s = x->x_list; | ||
72 | goto checknext; | ||
73 | } | ||
74 | } | ||
75 | if (x->x_targettime <= timenext) | ||
76 | f = x->x_target, inc = 0; | ||
77 | *out++ = f; | ||
78 | f = f + inc; | ||
79 | timenow = timenext; | ||
80 | } | ||
81 | x->x_value = f; | ||
82 | return (w+4); | ||
83 | } | ||
84 | |||
85 | static void vline_tilde_stop(t_vline *x) | ||
86 | { | ||
87 | t_vseg *s1, *s2; | ||
88 | for (s1 = x->x_list; s1; s1 = s2) | ||
89 | s2 = s1->s_next, t_freebytes(s1, sizeof(*s1)); | ||
90 | x->x_list = 0; | ||
91 | x->x_inc = 0; | ||
92 | x->x_inlet1 = x->x_inlet2 = 0; | ||
93 | } | ||
94 | |||
95 | static void vline_tilde_float(t_vline *x, t_float f) | ||
96 | { | ||
97 | t_time timenow = clock_gettimesince(x->x_referencetime); | ||
98 | t_sample inlet1 = (x->x_inlet1 < 0 ? 0 : (t_sample)x->x_inlet1); | ||
99 | t_sample inlet2 = (t_sample) x->x_inlet2; | ||
100 | t_time starttime = timenow + inlet2; | ||
101 | t_vseg *s1, *s2, *deletefrom = 0, | ||
102 | *snew = (t_vseg *)t_getbytes(sizeof(*snew)); | ||
103 | if (PD_BADFLOAT(f)) | ||
104 | f = 0; | ||
105 | |||
106 | /* negative delay input means stop and jump immediately to new value */ | ||
107 | if (inlet2 < 0) | ||
108 | { | ||
109 | vline_tilde_stop(x); | ||
110 | x->x_value = ftofix(f); | ||
111 | return; | ||
112 | } | ||
113 | /* check if we supplant the first item in the list. We supplant | ||
114 | an item by having an earlier starttime, or an equal starttime unless | ||
115 | the equal one was instantaneous and the new one isn't (in which case | ||
116 | we'll do a jump-and-slide starting at that time.) */ | ||
117 | if (!x->x_list || x->x_list->s_starttime > starttime || | ||
118 | (x->x_list->s_starttime == starttime && | ||
119 | (x->x_list->s_targettime > x->x_list->s_starttime || inlet1 <= 0))) | ||
120 | { | ||
121 | deletefrom = x->x_list; | ||
122 | x->x_list = snew; | ||
123 | } | ||
124 | else | ||
125 | { | ||
126 | for (s1 = x->x_list; s2 = s1->s_next; s1 = s2) | ||
127 | { | ||
128 | if (s2->s_starttime > starttime || | ||
129 | (s2->s_starttime == starttime && | ||
130 | (s2->s_targettime > s2->s_starttime || inlet1 <= 0))) | ||
131 | { | ||
132 | deletefrom = s2; | ||
133 | s1->s_next = snew; | ||
134 | goto didit; | ||
135 | } | ||
136 | } | ||
137 | s1->s_next = snew; | ||
138 | deletefrom = 0; | ||
139 | didit: ; | ||
140 | } | ||
141 | while (deletefrom) | ||
142 | { | ||
143 | s1 = deletefrom->s_next; | ||
144 | t_freebytes(deletefrom, sizeof(*deletefrom)); | ||
145 | deletefrom = s1; | ||
146 | } | ||
147 | snew->s_next = 0; | ||
148 | snew->s_target = f; | ||
149 | snew->s_starttime = starttime; | ||
150 | snew->s_targettime = starttime + inlet1; | ||
151 | x->x_inlet1 = x->x_inlet2 = 0; | ||
152 | } | ||
153 | |||
154 | static void vline_tilde_dsp(t_vline *x, t_signal **sp) | ||
155 | { | ||
156 | dsp_add(vline_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); | ||
157 | x->x_samppermsec = idiv(ftofix(sp[0]->s_sr),ftofix(1000)); | ||
158 | x->x_msecpersamp = idiv(ftofix(1000),ftofix(sp[0]->s_sr)); | ||
159 | } | ||
160 | |||
161 | static void *vline_tilde_new(void) | ||
162 | { | ||
163 | t_vline *x = (t_vline *)pd_new(vline_tilde_class); | ||
164 | outlet_new(&x->x_obj, gensym("signal")); | ||
165 | floatinlet_new(&x->x_obj, &x->x_inlet1); | ||
166 | floatinlet_new(&x->x_obj, &x->x_inlet2); | ||
167 | x->x_inlet1 = x->x_inlet2 = 0; | ||
168 | x->x_value = x->x_inc = 0; | ||
169 | x->x_referencetime = clock_getlogicaltime(); | ||
170 | x->x_list = 0; | ||
171 | x->x_samppermsec = 0; | ||
172 | return (x); | ||
173 | } | ||
174 | |||
175 | void vline_tilde_setup(void) | ||
176 | { | ||
177 | vline_tilde_class = class_new(gensym("vline~"), vline_tilde_new, | ||
178 | (t_method)vline_tilde_stop, sizeof(t_vline), 0, 0); | ||
179 | class_addfloat(vline_tilde_class, (t_method)vline_tilde_float); | ||
180 | class_addmethod(vline_tilde_class, (t_method)vline_tilde_dsp, | ||
181 | gensym("dsp"), 0); | ||
182 | class_addmethod(vline_tilde_class, (t_method)vline_tilde_stop, | ||
183 | gensym("stop"), 0); | ||
184 | } | ||
185 | #include <m_pd.h> | ||
186 | #include <m_fixed.h> | ||
187 | |||
188 | |||
189 | |||
190 | static t_class *vline_tilde_class; | ||
191 | |||
192 | typedef struct _vseg | ||
193 | { | ||
194 | t_time s_targettime; | ||
195 | t_time s_starttime; | ||
196 | t_sample s_target; | ||
197 | struct _vseg *s_next; | ||
198 | } t_vseg; | ||
199 | |||
200 | typedef struct _vline | ||
201 | { | ||
202 | t_object x_obj; | ||
203 | t_sample x_value; | ||
204 | t_sample x_inc; | ||
205 | t_time x_referencetime; | ||
206 | t_time x_samppermsec; | ||
207 | t_time x_msecpersamp; | ||
208 | t_time x_targettime; | ||
209 | t_sample x_target; | ||
210 | float x_inlet1; | ||
211 | float x_inlet2; | ||
212 | t_vseg *x_list; | ||
213 | } t_vline; | ||
214 | |||
215 | static t_int *vline_tilde_perform(t_int *w) | ||
216 | { | ||
217 | t_vline *x = (t_vline *)(w[1]); | ||
218 | t_sample *out = (t_sample *)(w[2]); | ||
219 | int n = (int)(w[3]), i; | ||
220 | t_sample f = x->x_value; | ||
221 | t_sample inc = x->x_inc; | ||
222 | t_time msecpersamp = x->x_msecpersamp; | ||
223 | t_time samppermsec = x->x_samppermsec; | ||
224 | t_time timenow = clock_gettimesince(x->x_referencetime) - n * msecpersamp; | ||
225 | t_vseg *s = x->x_list; | ||
226 | for (i = 0; i < n; i++) | ||
227 | { | ||
228 | t_time timenext = timenow + msecpersamp; | ||
229 | checknext: | ||
230 | if (s) | ||
231 | { | ||
232 | /* has starttime elapsed? If so update value and increment */ | ||
233 | if (s->s_starttime < timenext) | ||
234 | { | ||
235 | if (x->x_targettime <= timenext) | ||
236 | f = x->x_target, inc = 0; | ||
237 | /* if zero-length segment bash output value */ | ||
238 | if (s->s_targettime <= s->s_starttime) | ||
239 | { | ||
240 | f = s->s_target; | ||
241 | inc = 0; | ||
242 | } | ||
243 | else | ||
244 | { | ||
245 | t_time incpermsec = div((s->s_target - f), | ||
246 | (s->s_targettime - s->s_starttime)); | ||
247 | f = mult(f + incpermsec,(timenext - s->s_starttime)); | ||
248 | inc = mult(incpermsec,msecpersamp); | ||
249 | } | ||
250 | x->x_inc = inc; | ||
251 | x->x_target = s->s_target; | ||
252 | x->x_targettime = s->s_targettime; | ||
253 | x->x_list = s->s_next; | ||
254 | t_freebytes(s, sizeof(*s)); | ||
255 | s = x->x_list; | ||
256 | goto checknext; | ||
257 | } | ||
258 | } | ||
259 | if (x->x_targettime <= timenext) | ||
260 | f = x->x_target, inc = 0; | ||
261 | *out++ = f; | ||
262 | f = f + inc; | ||
263 | timenow = timenext; | ||
264 | } | ||
265 | x->x_value = f; | ||
266 | return (w+4); | ||
267 | } | ||
268 | |||
269 | static void vline_tilde_stop(t_vline *x) | ||
270 | { | ||
271 | t_vseg *s1, *s2; | ||
272 | for (s1 = x->x_list; s1; s1 = s2) | ||
273 | s2 = s1->s_next, t_freebytes(s1, sizeof(*s1)); | ||
274 | x->x_list = 0; | ||
275 | x->x_inc = 0; | ||
276 | x->x_inlet1 = x->x_inlet2 = 0; | ||
277 | } | ||
278 | |||
279 | static void vline_tilde_float(t_vline *x, t_float f) | ||
280 | { | ||
281 | t_time timenow = clock_gettimesince(x->x_referencetime); | ||
282 | t_sample inlet1 = (x->x_inlet1 < 0 ? 0 : (t_sample)x->x_inlet1); | ||
283 | t_sample inlet2 = (t_sample) x->x_inlet2; | ||
284 | t_time starttime = timenow + inlet2; | ||
285 | t_vseg *s1, *s2, *deletefrom = 0, | ||
286 | *snew = (t_vseg *)t_getbytes(sizeof(*snew)); | ||
287 | if (PD_BADFLOAT(f)) | ||
288 | f = 0; | ||
289 | |||
290 | /* negative delay input means stop and jump immediately to new value */ | ||
291 | if (inlet2 < 0) | ||
292 | { | ||
293 | vline_tilde_stop(x); | ||
294 | x->x_value = ftofix(f); | ||
295 | return; | ||
296 | } | ||
297 | /* check if we supplant the first item in the list. We supplant | ||
298 | an item by having an earlier starttime, or an equal starttime unless | ||
299 | the equal one was instantaneous and the new one isn't (in which case | ||
300 | we'll do a jump-and-slide starting at that time.) */ | ||
301 | if (!x->x_list || x->x_list->s_starttime > starttime || | ||
302 | (x->x_list->s_starttime == starttime && | ||
303 | (x->x_list->s_targettime > x->x_list->s_starttime || inlet1 <= 0))) | ||
304 | { | ||
305 | deletefrom = x->x_list; | ||
306 | x->x_list = snew; | ||
307 | } | ||
308 | else | ||
309 | { | ||
310 | for (s1 = x->x_list; s2 = s1->s_next; s1 = s2) | ||
311 | { | ||
312 | if (s2->s_starttime > starttime || | ||
313 | (s2->s_starttime == starttime && | ||
314 | (s2->s_targettime > s2->s_starttime || inlet1 <= 0))) | ||
315 | { | ||
316 | deletefrom = s2; | ||
317 | s1->s_next = snew; | ||
318 | goto didit; | ||
319 | } | ||
320 | } | ||
321 | s1->s_next = snew; | ||
322 | deletefrom = 0; | ||
323 | didit: ; | ||
324 | } | ||
325 | while (deletefrom) | ||
326 | { | ||
327 | s1 = deletefrom->s_next; | ||
328 | t_freebytes(deletefrom, sizeof(*deletefrom)); | ||
329 | deletefrom = s1; | ||
330 | } | ||
331 | snew->s_next = 0; | ||
332 | snew->s_target = f; | ||
333 | snew->s_starttime = starttime; | ||
334 | snew->s_targettime = starttime + inlet1; | ||
335 | x->x_inlet1 = x->x_inlet2 = 0; | ||
336 | } | ||
337 | |||
338 | static void vline_tilde_dsp(t_vline *x, t_signal **sp) | ||
339 | { | ||
340 | dsp_add(vline_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); | ||
341 | x->x_samppermsec = idiv(ftofix(sp[0]->s_sr),ftofix(1000)); | ||
342 | x->x_msecpersamp = idiv(ftofix(1000),ftofix(sp[0]->s_sr)); | ||
343 | } | ||
344 | |||
345 | static void *vline_tilde_new(void) | ||
346 | { | ||
347 | t_vline *x = (t_vline *)pd_new(vline_tilde_class); | ||
348 | outlet_new(&x->x_obj, gensym("signal")); | ||
349 | floatinlet_new(&x->x_obj, &x->x_inlet1); | ||
350 | floatinlet_new(&x->x_obj, &x->x_inlet2); | ||
351 | x->x_inlet1 = x->x_inlet2 = 0; | ||
352 | x->x_value = x->x_inc = 0; | ||
353 | x->x_referencetime = clock_getlogicaltime(); | ||
354 | x->x_list = 0; | ||
355 | x->x_samppermsec = 0; | ||
356 | return (x); | ||
357 | } | ||
358 | |||
359 | void vline_tilde_setup(void) | ||
360 | { | ||
361 | vline_tilde_class = class_new(gensym("vline~"), vline_tilde_new, | ||
362 | (t_method)vline_tilde_stop, sizeof(t_vline), 0, 0); | ||
363 | class_addfloat(vline_tilde_class, (t_method)vline_tilde_float); | ||
364 | class_addmethod(vline_tilde_class, (t_method)vline_tilde_dsp, | ||
365 | gensym("dsp"), 0); | ||
366 | class_addmethod(vline_tilde_class, (t_method)vline_tilde_stop, | ||
367 | gensym("stop"), 0); | ||
368 | } | ||