6
static t_class *pyo_tilde_class;
8
typedef struct _pyo_tilde {
19
int id; /* pyo server id */
20
float *inbuf; /* pyo input buffer */
21
float *outbuf; /* pyo output buffer */
22
char *msg; /* preallocated string to construct message for pyo */
23
void (*callback)(int); /* pointer to pyo embedded server callback */
24
PyThreadState *interp; /* Python thread state linked to this sub interpreter */
27
t_int *pyo_tilde_perform(t_int *w) {
29
t_pyo_tilde *x = (t_pyo_tilde *)(w[1]); /* pointer to instance struct */
30
n = (int)(w[2]); /* vector size */
31
t_sample **in = x->in;
32
t_sample **out = x->out;
34
for (j=0; j<x->chnls; j++) {
35
x->inbuf[i*x->chnls+j] = in[j][i];
38
(*x->callback)(x->id);
40
for (j=0; j<x->chnls; j++) {
41
out[j][i] = x->outbuf[i*x->chnls+j];
47
void pyo_tilde_dsp(t_pyo_tilde *x, t_signal **sp) {
49
t_sample **dummy = x->in;
50
for (i=0; i<x->chnls; i++)
51
*dummy++ = sp[i]->s_vec;
53
for (i=x->chnls; i<x->chnls*2; i++)
54
*dummy++ = sp[i]->s_vec;
55
/* reset pyo only if sampling rate or buffer size have changed */
56
if ((float)sp[0]->s_sr != x->sr || (int)sp[0]->s_n != x->bs) {
57
x->sr = (float)sp[0]->s_sr;
58
x->bs = (int)sp[0]->s_n;
59
pyo_set_server_params(x->interp, x->sr, x->bs);
60
if (x->file != NULL) {
61
err = pyo_exec_file(x->interp, x->file, x->msg, x->add);
63
post("Unable to open file < %s >", x->file);
68
dsp_add(pyo_tilde_perform, 2, x, sp[0]->s_n);
71
void *pyo_tilde_new(t_floatarg f) {
73
t_pyo_tilde *x = (t_pyo_tilde *)pd_new(pyo_tilde_class);
75
x->chnls = (f) ? f : 2;
82
/* create signal inlets (first is done in pyo_tilde_setup) */
83
for (i=1; i<x->chnls; i++)
84
inlet_new(&x->obj, &x->obj.ob_pd, &s_signal, &s_signal);
85
/* create signal outlets */
86
for (i=0; i<x->chnls; i++)
87
outlet_new(&x->obj, &s_signal);
89
x->in = (t_sample **)getbytes(x->chnls * sizeof(t_sample **));
90
x->out = (t_sample **)getbytes(x->chnls * sizeof(t_sample **));
91
x->msg = (char *)getbytes(262144 * sizeof(char *));
93
for (i=0; i<x->chnls; i++)
94
x->in[i] = x->out[i] = 0;
96
x->interp = pyo_new_interpreter(x->chnls);
98
x->inbuf = (float *)pyo_get_input_buffer_address(x->interp);
99
x->outbuf = (float *)pyo_get_output_buffer_address(x->interp);
100
x->callback = (void *)pyo_get_embedded_callback_address(x->interp);
101
x->id = pyo_get_server_id(x->interp);
106
void pyo_tilde_free(t_pyo_tilde *x) {
107
freebytes(x->in, sizeof(x->in));
108
freebytes(x->out, sizeof(x->out));
109
freebytes(x->msg, sizeof(x->msg));
110
pyo_end_interpreter(x->interp);
113
void pyo_tilde_set_value(t_pyo_tilde *x, char *att, int argc, t_atom *argv) {
114
int err, bracket = 0;
116
t_symbol *c = atom_getsymbol(argv);
118
sprintf(x->msg, "%s%s=", c->s_name, att);
124
if (argv->a_type == A_SYMBOL) {
125
strcat(x->msg, atom_getsymbol(argv)->s_name);
127
else if (argv->a_type == A_FLOAT) {
128
sprintf(fchar, "%.6f", atom_getfloat(argv));
129
strcat(x->msg, fchar);
137
err = pyo_exec_statement(x->interp, x->msg, x->debug);
139
post("pyo~: %s", x->msg);
142
void pyo_tilde_value(t_pyo_tilde *x, t_symbol *s, int argc, t_atom *argv) {
143
char *att = ".value";
144
pyo_tilde_set_value(x, att, argc, argv);
146
void pyo_tilde_set(t_pyo_tilde *x, t_symbol *s, int argc, t_atom *argv) {
148
pyo_tilde_set_value(x, att, argc, argv);
151
void pyo_tilde_create(t_pyo_tilde *x, t_symbol *s, int argc, t_atom *argv) {
153
char *varname, *object;
155
t_symbol *c = atom_getsymbol(argv);
158
c = atom_getsymbol(argv);
161
sprintf(x->msg, "%s=%s(", varname, object);
163
if (argv->a_type == A_SYMBOL) {
164
strcat(x->msg, atom_getsymbol(argv)->s_name);
166
else if (argv->a_type == A_FLOAT) {
167
sprintf(fchar, "%f", atom_getfloat(argv));
168
strcat(x->msg, fchar);
175
err = pyo_exec_statement(x->interp, x->msg, x->debug);
177
post("pyo~: %s", x->msg);
180
void pyo_tilde_clear(t_pyo_tilde *x) {
181
pyo_server_reboot(x->interp);
184
void pyo_tilde_debug(t_pyo_tilde *x, t_float debug) {
185
x->debug = debug <= 0 ? 0 : 1;
188
void pyo_tilde_read(t_pyo_tilde *x, t_symbol *s, int argc, t_atom *argv) {
193
x->file = atom_getsymbol(argv)->s_name;
196
x->add = strcmp(atom_getsymbol(argv++)->s_name, "-a") == 0 ? 1 : 0;
197
x->file = atom_getsymbol(argv)->s_name;
200
if (pyo_is_server_started(x->interp)) {
201
err = pyo_exec_file(x->interp, x->file, x->msg, x->add);
203
post("Unable to open file < %s >", x->file);
209
void pyo_tilde_call(t_pyo_tilde *x, t_symbol *s, int argc, t_atom *argv) {
212
sprintf(x->msg, "%s(", atom_getsymbol(argv)->s_name);
215
if (argv->a_type == A_SYMBOL) {
216
strcat(x->msg, atom_getsymbol(argv)->s_name);
218
else if (argv->a_type == A_FLOAT) {
219
sprintf(fchar, "%f", atom_getfloat(argv));
220
strcat(x->msg, fchar);
223
strcat(x->msg, ", ");
227
err = pyo_exec_statement(x->interp, x->msg, x->debug);
229
post("pyo~: %s", x->msg);
232
void pyo_tilde_setup(void) {
233
pyo_tilde_class = class_new(gensym("pyo~"), (t_newmethod)pyo_tilde_new,
234
(t_method)pyo_tilde_free, sizeof(t_pyo_tilde), CLASS_DEFAULT, A_DEFFLOAT, 0);
235
class_addmethod(pyo_tilde_class, (t_method)pyo_tilde_dsp, gensym("dsp"), 0);
236
class_addmethod(pyo_tilde_class, (t_method)pyo_tilde_clear, gensym("clear"), 0);
237
class_addmethod(pyo_tilde_class, (t_method)pyo_tilde_value, gensym("value"),
238
A_GIMME, 0); /* send value(s) to a Sig or SigTo object */
239
class_addmethod(pyo_tilde_class, (t_method)pyo_tilde_set, gensym("set"),
240
A_GIMME, 0); /* send value(s) to any object's attribute */
241
class_addmethod(pyo_tilde_class, (t_method)pyo_tilde_read, gensym("read"),
242
A_GIMME, 0); /* read a script file */
243
class_addmethod(pyo_tilde_class, (t_method)pyo_tilde_call, gensym("call"),
244
A_GIMME, 0); /* call a function or a method */
245
class_addmethod(pyo_tilde_class, (t_method)pyo_tilde_create, gensym("create"),
246
A_GIMME, 0); /* create a python object */
247
class_addmethod(pyo_tilde_class, (t_method)pyo_tilde_debug, gensym("debug"),
248
A_DEFFLOAT, 0); /* set the debug (verbose) mode */
249
CLASS_MAINSIGNALIN(pyo_tilde_class, t_pyo_tilde, f);