hi,
after rereading my discussion with pix, I think there are few points I must clear up.
illustrate my general doubts, and not to be used as a nqpoly~ replacement. On the other hand, any Pd-instrument designer would welcome a simple access to poly~'s functionality.
a single voice to the free voices pool of PureData's poly would
cause an incompatibility with max. Even if we seriously cared
for such compatibility, clear' message to poly is PureData's extra addition to max-poly, which has only
stop' message.
But anyway I was right about simplicity of such addition. The
proof is in x_midi.c.diff attachment, which adds a float argument
to clear' message. If this argument's value $n$ is in the range [1..<number-of-voices>] then voice$_n$ is returned to the pool. In this version an argumentless
clear' works as it used to.
The question remains, if this simple addition does not introduce unnecessary ambiguity to the meaning of poly. Currently stopping a voice means stopping the oldest voice playing a note of a specified pitch, if there is any such voice. Stopping a voice number n is something conceptually different. Maybe it is better to add a separate object class `pool'? OK, there could be an extern...
#if 0 // this is hackery
3. ... or, if none of the above is available, the remaining
technique would be to cheat existing poly, forcing it to store
noteons with pitch always equal to voice number -- as I did in
notsocute.pd, and which is a very inefficient way of doing
something pretty simple. This trickery is factored out into the
attached abstraction pooly.pd'. The interface of poly remains in pooly (with quite the same functionality), and there are two extensions for handling the voice pool: a
bang' message to choose
a voice (in stealing mode or not), and a `clear <n>' message to
return voice n to the pool. But beware, this abstraction plays
nasty tricks...
#endif
necessarily directly interpreted as a single parameter of a note, but instead, for example, mapped to a parameter vector, or to any other mechanism of generating parameter values. A user of poly should think rather of playing/stopping a note of some arbitrarily choosen cathegory, which can be pitch or anything else.
abstraction is a dispatching scheme, since there is no `forward' object class in Pd. We need to feed the choosen voice with parameters. This voice's number is a variable. Since, of course, it is impossible to [route] into as many destinations as we wish, the only way is to use global send/receive. But if we wanted to choose send's destination dynamically, we are stuck with a message box, and the number of parameters must be kept constant -- we cannot dispatch anything. If, on the other hand, we need variable number of parameters, then they will have to be sent to all voices, preceded by another message opening a spigot in the voice being current destination (one can make variations of this theme, like passing a message through a chain of destinations, until it is spigoted into the proper one). This is clumsy, unreliable and highly inefficient.
Whoever knows of any other way (using max/forward excluded), please give me a clue.
Krzysztof
--- x_midi.c~ Sun May 20 05:50:52 2001 +++ x_midi.c Mon Oct 1 16:04:05 2001 @@ -1173,11 +1173,18 @@ } }
-static void poly_clear(t_poly *x) +static void poly_clear(t_poly *x, t_floatarg ndx) {
x->x_vec[i].v_used = 0;
x->x_vec[i].v_serial = x->x_serial++;
}
static void poly_free(t_poly *x) @@ -1192,7 +1199,7 @@ sizeof(t_poly), 0, A_DEFFLOAT, A_DEFFLOAT, 0); class_addfloat(poly_class, poly_float); class_addmethod(poly_class, (t_method)poly_stop, gensym("stop"), 0);
}
/* -------------------------- bag -------------------------- */
#N canvas 323 9 349 397 12; #X obj 123 28 inlet; #X obj 249 27 inlet; #X obj 148 249 outlet; #X obj 199 333 outlet; #X obj 173 292 outlet; #X obj 123 157 poly $1 $2; #N canvas 0 0 376 304 routing 0; #X obj 35 25 inlet; #X obj 35 227 outlet; #X obj 222 227 outlet; #X obj 104 108 route float; #X msg 133 189 $1 0; #X obj 104 146 t b 0 b; #X msg 279 189 0; #X msg 222 189 1; #X obj 133 227 outlet; #X obj 35 69 route bang clear; #X msg 198 146 clear; #X obj 279 109 t a b; #X connect 0 0 9 0; #X connect 3 0 5 0; #X connect 3 1 10 0; #X connect 4 0 8 0; #X connect 5 0 7 0; #X connect 5 1 4 0; #X connect 5 2 6 0; #X connect 6 0 2 0; #X connect 7 0 2 0; #X connect 9 0 1 0; #X connect 9 1 3 0; #X connect 9 2 11 0; #X connect 10 0 8 0; #X connect 11 0 8 0; #X connect 11 1 7 0; #X restore 123 71 pd routing; #N canvas 0 0 296 388 cheating 0; #X msg 103 234 $1 1; #X msg 164 234 0 0; #X obj 103 155 spigot; #X msg 152 111 1; #X msg 198 194 0; #X obj 103 194 t 0 b b; #X obj 103 34 inlet; #X obj 103 278 outlet; #X obj 164 318 outlet; #X obj 103 71 t b b; #X msg 103 111 0 1; #X obj 29 34 inlet; #X connect 0 0 7 0; #X connect 1 0 8 0; #X connect 2 0 5 0; #X connect 3 0 2 1; #X connect 4 0 2 1; #X connect 5 0 0 0; #X connect 5 1 1 0; #X connect 5 2 4 0; #X connect 6 0 9 0; #X connect 9 0 10 0; #X connect 9 1 3 0; #X connect 10 0 8 0; #X connect 11 0 2 0; #X restore 29 116 pd cheating; #N canvas 104 80 379 374 output 0; #X obj 88 251 outlet; #X obj 191 334 outlet; #X obj 139 293 outlet; #X obj 88 174 spigot; #X obj 55 121 pack 0 0 0; #X obj 88 213 unpack 0 0 0; #X obj 15 22 inlet; #X obj 97 22 inlet; #X obj 184 22 inlet; #X obj 15 213 outlet; #X obj 15 58 t 0 0; #X obj 15 174 spigot; #X obj 284 22 inlet; #X obj 97 58 t 0 0; #X obj 275 121 spigot; #X obj 284 58 t 0 0; #X obj 184 58 t 0 0; #X connect 3 0 5 0; #X connect 4 0 3 0; #X connect 5 0 0 0; #X connect 5 1 2 0; #X connect 5 2 1 0; #X connect 6 0 10 0; #X connect 7 0 13 0; #X connect 8 0 16 0; #X connect 10 0 11 0; #X connect 10 1 4 0; #X connect 11 0 9 0; #X connect 12 0 15 0; #X connect 13 0 4 1; #X connect 13 1 14 0; #X connect 14 0 3 1; #X connect 15 0 3 1; #X connect 15 1 14 1; #X connect 16 0 11 1; #X connect 16 1 4 2; #X restore 123 201 pd output; #X connect 0 0 6 0; #X connect 1 0 5 1; #X connect 5 0 8 0; #X connect 5 1 8 1; #X connect 5 2 8 2; #X connect 6 0 7 1; #X connect 6 1 5 0; #X connect 6 2 8 3; #X connect 7 0 6 0; #X connect 7 1 5 0; #X connect 8 0 7 0; #X connect 8 1 2 0; #X connect 8 2 4 0; #X connect 8 3 3 0;