-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcounter~.c
127 lines (111 loc) · 2.75 KB
/
counter~.c
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "MSPd.h"
static t_class *counter_class;
#define OBJECT_NAME "counter~"
#define COUNTER_UP (1)
#define COUNTER_DOWN (-1)
typedef struct _counter
{
t_object x_obj;
float x_f;
long current;
long min;
long max;
short direction;
} t_counter;
void *counter_new(t_symbol *s, int argc, t_atom *argv);
t_int *counter_perform(t_int *w);
void counter_dsp(t_counter *x, t_signal **sp);
void counter_setnext(t_counter *x, t_floatarg val);
void counter_direction(t_counter *x, t_floatarg d);
void counter_minmax(t_counter *x, t_floatarg min, t_floatarg max);
void counter_version(t_counter *x);
void counter_tilde_setup(void)
{
t_class *c;
c = class_new(gensym("counter~"), (t_newmethod)counter_new,0,sizeof(t_counter), 0,A_GIMME,0);
CLASS_MAINSIGNALIN(c, t_counter, x_f);
class_addmethod(c, (t_method)counter_minmax,gensym("minmax"),A_FLOAT,A_FLOAT,0);
class_addmethod(c, (t_method)counter_direction,gensym("direction"),A_FLOAT,0);
class_addmethod(c, (t_method)counter_setnext,gensym("setnext"),A_FLOAT,0);
class_addmethod(c, (t_method)counter_dsp, gensym("dsp"), 0);
counter_class = c;
potpourri_announce(OBJECT_NAME);
}
void counter_setnext(t_counter *x, t_floatarg val)
{
if( val < x->min || val > x->max)
return;
x->current = (long) val;
}
void counter_direction(t_counter *x, t_floatarg d)
{
if( (d != COUNTER_UP) && (d != COUNTER_DOWN) )
return;
x->direction = (short) d;
}
void counter_minmax(t_counter *x, t_floatarg min, t_floatarg max)
{
if(min < 1){
return;
}
if(min >= max){
return;
}
x->min = min;
x->max = max;
}
void *counter_new(t_symbol *s, int argc, t_atom *argv)
{
float farg;
t_symbol *fraud;
t_counter *x = (t_counter *)pd_new(counter_class);
fraud = s;
outlet_new(&x->x_obj, gensym("signal"));
x->direction = COUNTER_UP;
farg = 1.0;
atom_arg_getfloat(&farg,0,argc,argv);
x->min = farg;
farg = 10.0;
atom_arg_getfloat(&farg,1,argc,argv);
x->max = farg;
if(x->min <= 1)
x->min = 1;
if(x->max <= x->min)
x->max = 10;
return x;
}
t_int *counter_perform(t_int *w)
{
t_counter *x = (t_counter *) (w[1]);
t_float *in_vec = (t_float *)(w[2]);
t_float *out_vec = (t_float *)(w[3]);
t_int n = w[4];
int i;
long min = x->min;
long max = x->max;
long current = x->current;
short direction = x->direction;
for(i = 0; i < n; i++){
if(in_vec[i]){
out_vec[i] = current;
current = current + direction;
if( direction == COUNTER_UP ){
if( current > max ){
current = min;
}
} else if( direction == COUNTER_DOWN ){
if( current < min ){
current = max;
}
}
} else {
out_vec[i] = 0.0;
}
}
x->current = current;
return w + 5;
}
void counter_dsp(t_counter *x, t_signal **sp)
{
dsp_add(counter_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}