~ubuntu-branches/ubuntu/wily/python-pyo/wily-proposed

« back to all changes in this revision

Viewing changes to embedded/puredata/pyo~.c

  • Committer: Package Import Robot
  • Author(s): Tiago Bortoletto Vaz
  • Date: 2014-04-13 00:15:48 UTC
  • mfrom: (1.1.8)
  • Revision ID: package-import@ubuntu.com-20140413001548-yz0sd86hboij8exu
Tags: 0.6.9-1
New upstream version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdlib.h>
 
2
#include "m_pd.h"
 
3
#include "Python.h"
 
4
#include "m_pyo.h"
 
5
 
 
6
static t_class *pyo_tilde_class;
 
7
 
 
8
typedef struct _pyo_tilde {
 
9
    t_object  obj;
 
10
    t_sample  f;
 
11
    int debug;
 
12
    int bs;
 
13
    int add;
 
14
    int chnls;
 
15
    float sr;
 
16
    char *file;
 
17
    t_sample **in;
 
18
    t_sample **out;
 
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 */
 
25
} t_pyo_tilde;
 
26
 
 
27
t_int *pyo_tilde_perform(t_int *w) {
 
28
    int i, j, n;
 
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;
 
33
    for (i=0; i<n; i++) {
 
34
        for (j=0; j<x->chnls; j++) {
 
35
            x->inbuf[i*x->chnls+j] = in[j][i];
 
36
        }
 
37
    }
 
38
    (*x->callback)(x->id);
 
39
    for (i=0; i<n; i++) {
 
40
        for (j=0; j<x->chnls; j++) {
 
41
            out[j][i] = x->outbuf[i*x->chnls+j];
 
42
        }
 
43
    }
 
44
    return (w+3);
 
45
}
 
46
 
 
47
void pyo_tilde_dsp(t_pyo_tilde *x, t_signal **sp) {
 
48
    int i, err;
 
49
    t_sample **dummy = x->in;
 
50
    for (i=0; i<x->chnls; i++)
 
51
        *dummy++ = sp[i]->s_vec;
 
52
    dummy = x->out;
 
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);
 
62
            if (err) {
 
63
                post("Unable to open file < %s >", x->file);
 
64
                x->file = NULL;
 
65
            }
 
66
        }
 
67
    }
 
68
    dsp_add(pyo_tilde_perform, 2, x, sp[0]->s_n);
 
69
}
 
70
 
 
71
void *pyo_tilde_new(t_floatarg f) {
 
72
    int i;
 
73
    t_pyo_tilde *x = (t_pyo_tilde *)pd_new(pyo_tilde_class);
 
74
 
 
75
    x->chnls = (f) ? f : 2;
 
76
    x->bs = -1;
 
77
    x->sr = -1.0;
 
78
    x->file = NULL;
 
79
    x->add = 0;
 
80
    x->debug = 0;
 
81
 
 
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);
 
88
 
 
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 *));
 
92
 
 
93
    for (i=0; i<x->chnls; i++)
 
94
        x->in[i] = x->out[i] = 0;
 
95
 
 
96
    x->interp = pyo_new_interpreter(x->chnls);
 
97
    
 
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);
 
102
 
 
103
    return (void *)x;
 
104
}
 
105
 
 
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);
 
111
}
 
112
 
 
113
void pyo_tilde_set_value(t_pyo_tilde *x, char *att, int argc, t_atom *argv) {
 
114
    int err, bracket = 0;
 
115
    char fchar[32];
 
116
    t_symbol *c = atom_getsymbol(argv);
 
117
    argc--; argv++;
 
118
    sprintf(x->msg, "%s%s=", c->s_name, att);
 
119
    if (argc > 1) {
 
120
        strcat(x->msg, "[");
 
121
        bracket = 1;    
 
122
    }
 
123
    while (argc-- > 0) {
 
124
        if (argv->a_type == A_SYMBOL) {
 
125
            strcat(x->msg, atom_getsymbol(argv)->s_name);
 
126
        }
 
127
        else if (argv->a_type == A_FLOAT) {
 
128
            sprintf(fchar, "%.6f", atom_getfloat(argv));
 
129
            strcat(x->msg, fchar);
 
130
        }
 
131
        if (argc > 0)
 
132
            strcat(x->msg, ",");
 
133
        argv++;
 
134
    }
 
135
    if (bracket)
 
136
        strcat(x->msg, "]");
 
137
    err = pyo_exec_statement(x->interp, x->msg, x->debug);
 
138
    if (err)
 
139
        post("pyo~: %s", x->msg);
 
140
}
 
141
 
 
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);
 
145
}
 
146
void pyo_tilde_set(t_pyo_tilde *x, t_symbol *s, int argc, t_atom *argv) {
 
147
    char *att = "";
 
148
    pyo_tilde_set_value(x, att, argc, argv);
 
149
}
 
150
 
 
151
void pyo_tilde_create(t_pyo_tilde *x, t_symbol *s, int argc, t_atom *argv) {
 
152
    int err;
 
153
    char *varname, *object;
 
154
    char fchar[32];
 
155
    t_symbol *c = atom_getsymbol(argv);
 
156
    varname = c->s_name;
 
157
    argc--; argv++;
 
158
    c = atom_getsymbol(argv);
 
159
    object = c->s_name;
 
160
    argc--; argv++;
 
161
    sprintf(x->msg, "%s=%s(", varname, object);
 
162
    while (argc-- > 0) {
 
163
        if (argv->a_type == A_SYMBOL) {
 
164
            strcat(x->msg, atom_getsymbol(argv)->s_name);
 
165
        }
 
166
        else if (argv->a_type == A_FLOAT) {
 
167
            sprintf(fchar, "%f", atom_getfloat(argv));
 
168
            strcat(x->msg, fchar);
 
169
        }
 
170
        if (argc > 0)
 
171
            strcat(x->msg, ",");
 
172
        argv++;
 
173
    }
 
174
    strcat(x->msg, ")");
 
175
    err = pyo_exec_statement(x->interp, x->msg, x->debug);
 
176
    if (err)
 
177
        post("pyo~: %s", x->msg);
 
178
}
 
179
 
 
180
void pyo_tilde_clear(t_pyo_tilde *x) {
 
181
    pyo_server_reboot(x->interp);
 
182
}
 
183
 
 
184
void pyo_tilde_debug(t_pyo_tilde *x, t_float debug) {
 
185
    x->debug = debug <= 0 ? 0 : 1;
 
186
}
 
187
 
 
188
void pyo_tilde_read(t_pyo_tilde *x, t_symbol *s, int argc, t_atom *argv) {
 
189
    int err;
 
190
    switch (argc) {
 
191
        case 1:
 
192
            x->add = 0;
 
193
            x->file = atom_getsymbol(argv)->s_name;
 
194
            break;
 
195
        case 2:
 
196
            x->add = strcmp(atom_getsymbol(argv++)->s_name, "-a") == 0 ? 1 : 0;
 
197
            x->file = atom_getsymbol(argv)->s_name;
 
198
            break;
 
199
    }
 
200
    if (pyo_is_server_started(x->interp)) { 
 
201
        err = pyo_exec_file(x->interp, x->file, x->msg, x->add);
 
202
        if (err) {
 
203
            post("Unable to open file < %s >", x->file);
 
204
            x->file = NULL;
 
205
        }
 
206
    }
 
207
}
 
208
 
 
209
void pyo_tilde_call(t_pyo_tilde *x, t_symbol *s, int argc, t_atom *argv) {
 
210
    int err;
 
211
    char fchar[32];
 
212
    sprintf(x->msg, "%s(", atom_getsymbol(argv)->s_name);
 
213
    argc--; argv++;
 
214
    while (argc-- > 0) {
 
215
        if (argv->a_type == A_SYMBOL) {
 
216
            strcat(x->msg, atom_getsymbol(argv)->s_name);
 
217
        }
 
218
        else if (argv->a_type == A_FLOAT) {
 
219
            sprintf(fchar, "%f", atom_getfloat(argv));
 
220
            strcat(x->msg, fchar);
 
221
        }
 
222
        if (argc > 0)
 
223
            strcat(x->msg, ", ");
 
224
        argv++;
 
225
    }
 
226
    strcat(x->msg, ")");
 
227
    err = pyo_exec_statement(x->interp, x->msg, x->debug);
 
228
    if (err)
 
229
        post("pyo~: %s", x->msg);
 
230
}
 
231
 
 
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);
 
250
}