1
/* Copyright (c) 1997-1999 Miller Puckette and others.
2
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
19
int x_onset; /* playback position */
22
double x_whenclockset;
29
static void qlist_tick(t_qlist *x);
31
static t_class *qlist_class;
33
static void *qlist_new( void)
35
t_symbol *name, *filename = 0;
36
t_qlist *x = (t_qlist *)pd_new(qlist_class);
37
x->x_binbuf = binbuf_new();
38
x->x_clock = clock_new(x, (t_method)qlist_tick);
39
outlet_new(&x->x_ob, &s_list);
40
x->x_bangout = outlet_new(&x->x_ob, &s_bang);
41
x->x_onset = 0x7fffffff;
43
x->x_whenclockset = 0;
45
x->x_canvas = canvas_getcurrent();
50
static void qlist_rewind(t_qlist *x)
53
if (x->x_clock) clock_unset(x->x_clock);
54
x->x_whenclockset = 0;
58
static void qlist_donext(t_qlist *x, int drop, int automatic)
63
int argc = binbuf_getnatom(x->x_binbuf),
64
count, onset = x->x_onset, onset2, wasreentered;
65
t_atom *argv = binbuf_getvec(x->x_binbuf);
66
t_atom *ap = argv + onset, *ap2;
67
if (onset >= argc) goto end;
68
while (ap->a_type == A_SEMI || ap->a_type == A_COMMA)
70
if (ap->a_type == A_SEMI) target = 0;
72
if (onset >= argc) goto end;
75
if (!target && ap->a_type == A_FLOAT)
79
while (onset2 < argc && ap2->a_type == A_FLOAT)
84
clock_delay(x->x_clock,
85
x->x_clockdelay = ap->a_w.w_float * x->x_tempo);
86
x->x_whenclockset = clock_getsystime();
88
else outlet_list(x->x_ob.ob_outlet, 0, onset2-onset, ap);
93
while (onset2 < argc &&
94
(ap2->a_type == A_FLOAT || ap2->a_type == A_SYMBOL))
97
count = onset2 - onset;
100
if (ap->a_type != A_SYMBOL) continue;
101
else if (!(target = ap->a_w.w_symbol->s_thing))
103
pd_error(x, "qlist: %s: no such object",
104
ap->a_w.w_symbol->s_name);
116
wasreentered = x->x_reentered;
120
if (ap->a_type == A_FLOAT)
121
typedmess(target, &s_list, count, ap);
122
else if (ap->a_type == A_SYMBOL)
123
typedmess(target, ap->a_w.w_symbol, count-1, ap+1);
127
x->x_reentered = wasreentered;
128
} /* while (1); never falls through */
131
x->x_onset = 0x7fffffff;
132
outlet_bang(x->x_bangout);
133
x->x_whenclockset = 0;
136
static void qlist_next(t_qlist *x, t_floatarg drop)
138
qlist_donext(x, drop != 0, 0);
141
static void qlist_bang(t_qlist *x)
144
qlist_donext(x, 0, 1);
147
static void qlist_tick(t_qlist *x)
149
x->x_whenclockset = 0;
150
qlist_donext(x, 0, 1);
153
static void qlist_add(t_qlist *x, t_symbol *s, int ac, t_atom *av)
157
binbuf_add(x->x_binbuf, ac, av);
158
binbuf_add(x->x_binbuf, 1, &a);
161
static void qlist_add2(t_qlist *x, t_symbol *s, int ac, t_atom *av)
163
binbuf_add(x->x_binbuf, ac, av);
166
static void qlist_clear(t_qlist *x)
169
binbuf_clear(x->x_binbuf);
172
static void qlist_set(t_qlist *x, t_symbol *s, int ac, t_atom *av)
175
qlist_add(x, s, ac, av);
178
static void qlist_read(t_qlist *x, t_symbol *filename, t_symbol *format)
181
if (!strcmp(format->s_name, "cr"))
183
else if (*format->s_name)
184
pd_error(x, "qlist_read: unknown flag: %s", format->s_name);
186
if (binbuf_read_via_canvas(x->x_binbuf, filename->s_name, x->x_canvas, cr))
187
pd_error(x, "%s: read failed", filename->s_name);
188
x->x_onset = 0x7fffffff;
192
static void qlist_write(t_qlist *x, t_symbol *filename, t_symbol *format)
195
char buf[MAXPDSTRING];
196
canvas_makefilename(x->x_canvas, filename->s_name,
198
if (!strcmp(format->s_name, "cr"))
200
else if (*format->s_name)
201
pd_error(x, "qlist_read: unknown flag: %s", format->s_name);
202
if (binbuf_write(x->x_binbuf, buf, "", cr))
203
pd_error(x, "%s: write failed", filename->s_name);
206
static void qlist_print(t_qlist *x)
208
post("--------- textfile or qlist contents: -----------");
209
binbuf_print(x->x_binbuf);
212
static void qlist_tempo(t_qlist *x, t_float f)
215
if (f < 1e-20) f = 1e-20;
216
else if (f > 1e20) f = 1e20;
218
if (x->x_whenclockset != 0)
220
t_float elapsed = clock_gettimesince(x->x_whenclockset);
221
t_float left = x->x_clockdelay - elapsed;
222
if (left < 0) left = 0;
223
left *= newtempo / x->x_tempo;
224
clock_delay(x->x_clock, left);
226
x->x_tempo = newtempo;
229
static void qlist_free(t_qlist *x)
231
binbuf_free(x->x_binbuf);
232
if (x->x_clock) clock_free(x->x_clock);
235
/* -------------------- textfile ------------------------------- */
237
static t_class *textfile_class;
238
typedef t_qlist t_textfile;
240
static void *textfile_new( void)
242
t_symbol *name, *filename = 0;
243
t_textfile *x = (t_textfile *)pd_new(textfile_class);
244
x->x_binbuf = binbuf_new();
245
outlet_new(&x->x_ob, &s_list);
246
x->x_bangout = outlet_new(&x->x_ob, &s_bang);
247
x->x_onset = 0x7fffffff;
250
x->x_whenclockset = 0;
253
x->x_canvas = canvas_getcurrent();
257
static void textfile_bang(t_textfile *x)
259
int argc = binbuf_getnatom(x->x_binbuf),
260
count, onset = x->x_onset, onset2;
261
t_atom *argv = binbuf_getvec(x->x_binbuf);
262
t_atom *ap = argv + onset, *ap2;
263
while (onset < argc &&
264
(ap->a_type == A_SEMI || ap->a_type == A_COMMA))
268
while (onset2 < argc &&
269
(ap2->a_type != A_SEMI && ap2->a_type != A_COMMA))
274
if (ap->a_type == A_SYMBOL)
275
outlet_anything(x->x_ob.ob_outlet, ap->a_w.w_symbol,
276
onset2-onset-1, ap+1);
277
else outlet_list(x->x_ob.ob_outlet, 0, onset2-onset, ap);
281
x->x_onset = 0x7fffffff;
282
outlet_bang(x->x_bangout);
286
static void textfile_rewind(t_qlist *x)
291
static void textfile_free(t_textfile *x)
293
binbuf_free(x->x_binbuf);
296
/* ---------------- global setup function -------------------- */
298
void x_qlist_setup(void )
300
qlist_class = class_new(gensym("qlist"), (t_newmethod)qlist_new,
301
(t_method)qlist_free, sizeof(t_qlist), 0, 0);
302
class_addmethod(qlist_class, (t_method)qlist_rewind, gensym("rewind"), 0);
303
class_addmethod(qlist_class, (t_method)qlist_next,
304
gensym("next"), A_DEFFLOAT, 0);
305
class_addmethod(qlist_class, (t_method)qlist_set, gensym("set"),
307
class_addmethod(qlist_class, (t_method)qlist_clear, gensym("clear"), 0);
308
class_addmethod(qlist_class, (t_method)qlist_add, gensym("add"),
310
class_addmethod(qlist_class, (t_method)qlist_add2, gensym("add2"),
312
class_addmethod(qlist_class, (t_method)qlist_add, gensym("append"),
314
class_addmethod(qlist_class, (t_method)qlist_read, gensym("read"),
315
A_SYMBOL, A_DEFSYM, 0);
316
class_addmethod(qlist_class, (t_method)qlist_write, gensym("write"),
317
A_SYMBOL, A_DEFSYM, 0);
318
class_addmethod(qlist_class, (t_method)qlist_print, gensym("print"),
320
class_addmethod(qlist_class, (t_method)qlist_tempo,
321
gensym("tempo"), A_FLOAT, 0);
322
class_addbang(qlist_class, qlist_bang);
324
textfile_class = class_new(gensym("textfile"), (t_newmethod)textfile_new,
325
(t_method)textfile_free, sizeof(t_textfile), 0, 0);
326
class_addmethod(textfile_class, (t_method)textfile_rewind, gensym("rewind"),
328
class_addmethod(textfile_class, (t_method)qlist_set, gensym("set"),
330
class_addmethod(textfile_class, (t_method)qlist_clear, gensym("clear"), 0);
331
class_addmethod(textfile_class, (t_method)qlist_add, gensym("add"),
333
class_addmethod(textfile_class, (t_method)qlist_add2, gensym("add2"),
335
class_addmethod(textfile_class, (t_method)qlist_add, gensym("append"),
337
class_addmethod(textfile_class, (t_method)qlist_read, gensym("read"),
338
A_SYMBOL, A_DEFSYM, 0);
339
class_addmethod(textfile_class, (t_method)qlist_write, gensym("write"),
340
A_SYMBOL, A_DEFSYM, 0);
341
class_addmethod(textfile_class, (t_method)qlist_print, gensym("print"),
343
class_addbang(textfile_class, textfile_bang);