3 #include "../../pdbox.h"
6 #include "../src/m_pd.h"
7 #include <../src/m_fixed.h>
11 static t_class
*vline_tilde_class
;
26 t_time x_referencetime
;
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
;
45 t_time samppermsec
= x
->x_samppermsec
;
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
;
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
)
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
);
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
));
82 if (x
->x_targettime
<= timenext
)
83 f
= x
->x_target
, inc
= 0;
92 static void vline_tilde_stop(t_vline
*x
)
95 for (s1
= x
->x_list
; s1
; s1
= s2
)
96 s2
= s1
->s_next
, t_freebytes(s1
, sizeof(*s1
));
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
));
113 /* negative delay input means stop and jump immediately to new value */
117 x
->x_value
= ftofix(f
);
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
;
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)))
150 s1
= deletefrom
->s_next
;
151 t_freebytes(deletefrom
, sizeof(*deletefrom
));
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();
178 x
->x_samppermsec
= 0;
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
,
189 class_addmethod(vline_tilde_class
, (t_method
)vline_tilde_stop
,