Fix pdbox makefile to actually take part in dependency generation
[kugel-rb.git] / apps / plugins / pdbox / PDa / intern / vline~.c
blobf1fa9d0cc3e9865550ef8a2bd4f0d81c43768fed
1 #ifdef ROCKBOX
2 #include "plugin.h"
3 #include "../../pdbox.h"
4 #endif
6 #include "../src/m_pd.h"
7 #include <../src/m_fixed.h>
11 static t_class *vline_tilde_class;
13 typedef struct _vseg
15 t_time s_targettime;
16 t_time s_starttime;
17 t_sample s_target;
18 struct _vseg *s_next;
19 } t_vseg;
21 typedef struct _vline
23 t_object x_obj;
24 t_sample x_value;
25 t_sample x_inc;
26 t_time x_referencetime;
27 t_time x_samppermsec;
28 t_time x_msecpersamp;
29 t_time x_targettime;
30 t_sample x_target;
31 float x_inlet1;
32 float x_inlet2;
33 t_vseg *x_list;
34 } t_vline;
36 static t_int *vline_tilde_perform(t_int *w)
38 t_vline *x = (t_vline *)(w[1]);
39 t_sample *out = (t_sample *)(w[2]);
40 int n = (int)(w[3]), i;
41 t_sample f = x->x_value;
42 t_sample inc = x->x_inc;
43 t_time msecpersamp = x->x_msecpersamp;
44 #ifndef ROCKBOX
45 t_time samppermsec = x->x_samppermsec;
46 #endif
47 t_time timenow = clock_gettimesince(x->x_referencetime) - n * msecpersamp;
48 t_vseg *s = x->x_list;
49 for (i = 0; i < n; i++)
51 t_time timenext = timenow + msecpersamp;
52 checknext:
53 if (s)
55 /* has starttime elapsed? If so update value and increment */
56 if (s->s_starttime < timenext)
58 if (x->x_targettime <= timenext)
59 f = x->x_target, inc = 0;
60 /* if zero-length segment bash output value */
61 if (s->s_targettime <= s->s_starttime)
63 f = s->s_target;
64 inc = 0;
66 else
68 t_time incpermsec = idiv((s->s_target - f),
69 (s->s_targettime - s->s_starttime));
70 f = mult(f + incpermsec,(timenext - s->s_starttime));
71 inc = mult(incpermsec,msecpersamp);
73 x->x_inc = inc;
74 x->x_target = s->s_target;
75 x->x_targettime = s->s_targettime;
76 x->x_list = s->s_next;
77 t_freebytes(s, sizeof(*s));
78 s = x->x_list;
79 goto checknext;
82 if (x->x_targettime <= timenext)
83 f = x->x_target, inc = 0;
84 *out++ = f;
85 f = f + inc;
86 timenow = timenext;
88 x->x_value = f;
89 return (w+4);
92 static void vline_tilde_stop(t_vline *x)
94 t_vseg *s1, *s2;
95 for (s1 = x->x_list; s1; s1 = s2)
96 s2 = s1->s_next, t_freebytes(s1, sizeof(*s1));
97 x->x_list = 0;
98 x->x_inc = 0;
99 x->x_inlet1 = x->x_inlet2 = 0;
102 static void vline_tilde_float(t_vline *x, t_float f)
104 t_time timenow = clock_gettimesince(x->x_referencetime);
105 t_sample inlet1 = (x->x_inlet1 < 0 ? 0 : (t_sample)x->x_inlet1);
106 t_sample inlet2 = (t_sample) x->x_inlet2;
107 t_time starttime = timenow + inlet2;
108 t_vseg *s1, *s2, *deletefrom = 0,
109 *snew = (t_vseg *)t_getbytes(sizeof(*snew));
110 if (PD_BADFLOAT(f))
111 f = 0;
113 /* negative delay input means stop and jump immediately to new value */
114 if (inlet2 < 0)
116 vline_tilde_stop(x);
117 x->x_value = ftofix(f);
118 return;
120 /* check if we supplant the first item in the list. We supplant
121 an item by having an earlier starttime, or an equal starttime unless
122 the equal one was instantaneous and the new one isn't (in which case
123 we'll do a jump-and-slide starting at that time.) */
124 if (!x->x_list || x->x_list->s_starttime > starttime ||
125 (x->x_list->s_starttime == starttime &&
126 (x->x_list->s_targettime > x->x_list->s_starttime || inlet1 <= 0)))
128 deletefrom = x->x_list;
129 x->x_list = snew;
131 else
133 for (s1 = x->x_list; (s2 = s1->s_next); s1 = s2)
135 if (s2->s_starttime > starttime ||
136 (s2->s_starttime == starttime &&
137 (s2->s_targettime > s2->s_starttime || inlet1 <= 0)))
139 deletefrom = s2;
140 s1->s_next = snew;
141 goto didit;
144 s1->s_next = snew;
145 deletefrom = 0;
146 didit: ;
148 while (deletefrom)
150 s1 = deletefrom->s_next;
151 t_freebytes(deletefrom, sizeof(*deletefrom));
152 deletefrom = s1;
154 snew->s_next = 0;
155 snew->s_target = f;
156 snew->s_starttime = starttime;
157 snew->s_targettime = starttime + inlet1;
158 x->x_inlet1 = x->x_inlet2 = 0;
161 static void vline_tilde_dsp(t_vline *x, t_signal **sp)
163 dsp_add(vline_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
164 x->x_samppermsec = idiv(ftofix(sp[0]->s_sr),ftofix(1000));
165 x->x_msecpersamp = idiv(ftofix(1000),ftofix(sp[0]->s_sr));
168 static void *vline_tilde_new(void)
170 t_vline *x = (t_vline *)pd_new(vline_tilde_class);
171 outlet_new(&x->x_obj, gensym("signal"));
172 floatinlet_new(&x->x_obj, &x->x_inlet1);
173 floatinlet_new(&x->x_obj, &x->x_inlet2);
174 x->x_inlet1 = x->x_inlet2 = 0;
175 x->x_value = x->x_inc = 0;
176 x->x_referencetime = clock_getlogicaltime();
177 x->x_list = 0;
178 x->x_samppermsec = 0;
179 return (x);
182 void vline_tilde_setup(void)
184 vline_tilde_class = class_new(gensym("vline~"), vline_tilde_new,
185 (t_method)vline_tilde_stop, sizeof(t_vline), 0, 0);
186 class_addfloat(vline_tilde_class, (t_method)vline_tilde_float);
187 class_addmethod(vline_tilde_class, (t_method)vline_tilde_dsp,
188 gensym("dsp"), 0);
189 class_addmethod(vline_tilde_class, (t_method)vline_tilde_stop,
190 gensym("stop"), 0);