-
Notifications
You must be signed in to change notification settings - Fork 0
/
battito.c
executable file
·127 lines (108 loc) · 3.16 KB
/
battito.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
/**
@file
battito - a max object
@ingroup examples
*/
#include "ext.h" // standard Max include, always required
#include "ext_obex.h" // required for new style Max object
#include "ext_critical.h"
#include "battito_max.h"
#define DEFAULT_SUBDIVISION 1920
////////////////////////// object struct
typedef struct _battito
{
t_object ob;
long subdivision;
struct event* events;
long length;
bool should_be_freed;
void *m_outlet1;
void *m_outlet2;
void *m_outlet3;
} t_battito;
///////////////////////// function prototypes
//// standard set
void *battito_new(t_symbol *s, long argc, t_atom *argv);
void battito_free(t_battito *x);
void battito_int(t_battito *x, long n);
void battito_msg(t_battito *x, t_symbol *s);
void battito_reset(t_battito *x, t_symbol *s);
//////////////////////// global class pointer variable
void *battito_class;
void ext_main(void *r)
{
t_class *c;
c = class_new("battito", (method)battito_new, (method)battito_free, (long)sizeof(t_battito), 0L, A_GIMME, 0);
class_addmethod(c, (method)battito_int, "int", A_LONG, 0);
class_addmethod(c, (method)battito_msg, "text", A_SYM, 0);
class_addmethod(c, (method)battito_reset, "reset", A_SYM, 0);
class_register(CLASS_BOX, c);
battito_class = c;
}
void battito_int(t_battito *x, long n)
{
if (x->length > 0) {
critical_enter(0);
//long index = labs(n) % x->length;
long index;
if (n < 0) {
index = (x->length + (n % x->length)) % x->length;
} else {
index = n % x->length;
}
// post("index: %ld", index);
struct event event = x->events[index];
critical_exit(0);
uint32_t value = event.value;
uint32_t probability = event.probability;
// post("%d : %d", value, probability);
if (probability > 0) {
outlet_int(x->m_outlet2, probability);
outlet_int(x->m_outlet3, value);
}
}
}
void battito_msg(t_battito *x, t_symbol *s)
{
critical_enter(0);
if (x->events != NULL) {
//object_post((t_object *)x, "free: %p", x->events);
free(x->events);
x->events = NULL;
}
struct pattern pattern = transform(s->s_name, x->subdivision);
x->events = pattern.events;
x->length = pattern.length * x->subdivision;
critical_exit(0);
outlet_int(x->m_outlet1, x->length);
}
void battito_reset(t_battito *x, t_symbol *s)
{
x->events = NULL;
x->length = 0;
}
void battito_free(t_battito *x)
{
;
}
void *battito_new(t_symbol *s, long argc, t_atom *argv)
{
t_battito *x = NULL;
if ((x = (t_battito *)object_alloc(battito_class))) {
if (argc == 1 && (argv)->a_type == A_LONG) {
x->subdivision = atom_getlong(argv);
} else if (argc == 0){
x->subdivision = DEFAULT_SUBDIVISION;
} else {
object_error((t_object *)x, "Wrong arguments");
x->subdivision = DEFAULT_SUBDIVISION;
}
x->events = NULL;
x->length = 0;
x->should_be_freed = false;
x->m_outlet1 = intout((t_object *)x);
x->m_outlet2 = intout((t_object *)x);
x->m_outlet3 = intout((t_object *)x);
}
return (x);
}