-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsimplex.c
159 lines (140 loc) · 4.83 KB
/
simplex.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// original external created by Ben Wesch, 2024
// control rate version adapted by Cyrille Henry, 2024
#include "m_pd.h"
#include "simplex_common.h"
static t_class *simplex_class;
typedef struct _simplex {
t_object x_obj;
t_float *derivatives;
t_outlet *derivatives_outlet;
t_float persistence;
t_float octave_factors[MAX_OCTAVES];
t_atom derivative_list[MAX_DIMENSIONS];
t_float last_value;
t_int last_dim;
int normalize;
int octaves;
int dimensions;
unsigned char perm[512];
} t_simplex;
void simplex_list(t_simplex *x, t_symbol *s, int ac, t_atom *av) {
t_simplex_config cfg = {
.octave_factors = x->octave_factors,
.octaves = x->octaves,
.normalize = x->normalize,
.perm = x->perm
};
t_float out = 0.;
t_float pos[4] = {0};
int dim = ac;
if(dim==0) {
if (x->derivatives) {
outlet_list(x->derivatives_outlet, &s_list, x->last_dim, x->derivative_list);
}
outlet_float(x->x_obj.ob_outlet, x->last_value);
return;
}
if(dim>4) {
pd_error(x, "too much data, limiting to 4 dimensions");
dim = 4;
}
x->last_dim = dim;
for(int i=0; i<dim; i++) {
pos[i] = atom_getfloat(av+i);
}
out = generate_noise(&cfg, pos, x->persistence, dim-1, x->derivatives);
x->last_value = out;
if (x->derivatives) {
for (int i = 0; i < dim; i++) {
SETFLOAT(&(x->derivative_list[i]), x->derivatives[i]);
}
outlet_list(x->derivatives_outlet, &s_list, dim, x->derivative_list);
}
outlet_float(x->x_obj.ob_outlet, out);
(void)s;
}
static void simplex_octaves(t_simplex *x, t_floatarg f) {
x->octaves = (int)clamp(f, 1, MAX_OCTAVES);
init_octave_factors(x->octave_factors, x->octaves);
}
static void simplex_persistence(t_simplex *x, t_floatarg f) {
x->persistence = f;
}
static void simplex_normalize(t_simplex *x, t_symbol *s, int ac, t_atom *av) {
// activate normalization if no argument is given or anything that is not false
x->normalize = !ac || atom_getfloat(av);
(void)s;
}
static void simplex_seed(t_simplex *x, t_symbol *s, int ac, t_atom *av) {
if (ac)
init_permutation_with_seed(x->perm, atom_getfloat(av));
else
init_permutation(x->perm);
(void)s;
}
static void simplex_coeffs(t_simplex *x, t_symbol *s, int ac, t_atom *av) {
int i;
x->octaves = clamp(ac, 1, MAX_OCTAVES);
for (i = 0; i < x->octaves; i++) {
x->octave_factors[i] = atom_getfloat(av);
av++;
}
(void)s;
}
static void simplex_free(t_simplex *x) {
if (x->derivatives) {
freebytes(x->derivatives, MAX_DIMENSIONS * sizeof(t_float));
outlet_free(x->derivatives_outlet);
}
}
static void *simplex_new(t_symbol *s, int ac, t_atom *av) {
t_simplex *x = (t_simplex *)pd_new(simplex_class);
outlet_new(&x->x_obj, &s_float);
x->normalize = 0;
x->octaves = 1;
x->dimensions = 0;
x->last_value = 0.;
x->last_dim = 0;
int maj = 0, min = 0, bug = 0;
sys_getversion(&maj, &min, &bug);
init_permutation(x->perm);
while (ac && av->a_type == A_SYMBOL) {
if (atom_getsymbol(av) == gensym("-n"))
x->normalize = 1;
else if (atom_getsymbol(av) == gensym("-d"))
x->derivatives = (t_float *)getbytes(MAX_DIMENSIONS * sizeof(t_float));
else if (atom_getsymbol(av) == gensym("-dim")) {
ac--, av++;
x->dimensions = clamp((int)atom_getint(av), 1, MAX_DIMENSIONS);
} else if (atom_getsymbol(av) == gensym("-s")) {
ac--, av++;
init_permutation_with_seed(x->perm, (unsigned int)atom_getint(av));
} else
pd_error(x, "[simplex]: invalid argument");
ac--, av++;
}
if (ac) {
x->octaves = clamp(atom_getint(av), 1, MAX_OCTAVES);
ac--, av++;
}
x->persistence = ac ? atom_getfloat(av) : DEFAULT_PERSISTENCE;
init_octave_factors(x->octave_factors, x->octaves);
if (x->derivatives) {
x->derivatives_outlet = outlet_new(&x->x_obj, 0);
}
(void)s;
return x;
}
void simplex_setup(void) {
simplex_class = class_new(
gensym("simplex"),
(t_newmethod)simplex_new,
(t_method)simplex_free,
sizeof(t_simplex), CLASS_DEFAULT, A_GIMME, 0);
class_addmethod(simplex_class, (t_method)simplex_seed, gensym("seed"), A_GIMME, 0);
class_addmethod(simplex_class, (t_method)simplex_normalize, gensym("normalize"), A_GIMME, 0);
class_addmethod(simplex_class, (t_method)simplex_coeffs, gensym("coeffs"), A_GIMME, 0);
class_addmethod(simplex_class, (t_method)simplex_octaves, gensym("octaves"), A_FLOAT, 0);
class_addmethod(simplex_class, (t_method)simplex_persistence, gensym("persistence"), A_FLOAT, 0);
class_addmethod(simplex_class, (t_method)simplex_list, &s_list, A_GIMME, 0);
}