Only if you don’t change the list length because wrapAt
works modulo that.
Sometimes what you want, compositionally, is “add one more note to this sequence”. It’s actually not trivial to do this with PLseq either (especially when using an EnvirGui) because replacing the whole list that PLseq works of actually restarts it; you have to change only individual elements for PLseq to continue. What I mean is that if you do something “obvious” like
Pdef(\seq).set(\notelist, 50 + [2, 7, 12, 14, 17]);
(Pdef(\seq, Pbind(
\scale, Scale.chromatic,
\dur, 0.5, \legato, 2,
\midinote, PLseq(\notelist, envir: Pdef(\seq).envir))));
Pdef(\seq).gui // hit play in there then change list
whenever you change the list in the gui, the play will restart from the first element of the list. (You could put elements of the list individually in the gui/envir, but that is quite cumbersome, esp. with regards to list length changes.) Also cutItems: false
doesn’t make any difference here.
Plazy
will sorta fix this by playing one full iteration of the old array before switching, i.e.:
(Pdef(\seq, Pbind(
\scale, Scale.chromatic,
\dur, 0.5, \legato, 2,
\midinote, Pn(PlazyEnvir({|notelist| Pseq(notelist)})))));
But if you really, really want (to have your cake and eat it, i.e. replace the list right away and not restart it… I don’t effing know. You’d think that if you keep the same list in PLseq and only replace its elements it would do that, but that’s not reliable. It only seem to work if you shorten the list, but not if you lengthen it. I.e. the following will keep playing from the current note when you shorten the list in the gui and the list will end sooner, as you’d expect, but if you lengthen it instead, you get one extra full iteration of the current list, i.e. for lengthening it works like Pn(Plazy) above.
(Pdef(\seq, Plazy({var singl = List(); Pbind(
\scale, Scale.chromatic,
\dur, 0.5, \legato, 1,
\notelist, Pfuncn({|ev| singl.postln; singl.clear.addAll(ev[\notelist])}, inf),
\midinote, PLseq(singl))})));
It’s weird because the following simpler (non-event) list extension works as expected:
r = Plazy({var singl = List(); singl.add(55); PLseq(singl) <> Pfuncn({ singl.add(77) }, 2)}).asStream
r.nextN(3); // -> [ 55, 77, nil ]
// and so does clearing the list and rewriting it
r = Plazy({var singl = List(); singl.add(55); PLseq(singl) <> Pfuncn({ singl.clear.addAll([77, 88]) }, 2)}).asStream;
r.nextN(3); //-> [ 77, 88, nil ]
Edit: I’ll have to read the answers below carefully, but I that’s what’s happening in the live-edit example is that the list already got to start… Because otherwise the replacement seems to work as intended, even in a Pbind:
(r = Plazy({var singl = List(); singl.add(55);
Pbind(\midinote, PLseq(singl)) <> Pfuncn({ |ev| singl.clear.addAll([77, 88]); ev }, 3)}).asStream)
r.nextN(4, ()) // -> [ ( \midinote: 77 ), ( \midinote: 88 ), ( \midinote: 77 ), nil ]
But the live replacement is equivalent to doing something like
(r = Plazy({var singl = List(); singl.add(55);
Pbind(\midinote, PLseq(singl)) <> Pfuncn({ |ev| singl.clear.addAll(ev[\notelist]); ev }, 3)}).asStream)
r.nextN(1, (notelist: [22])) // -> [ ( \notelist: [ 22 ], \midinote: 22 ) ]
r.nextN(3, (notelist: [77, 88])) // -> [ ( \notelist: [ 77, 88 ], \midinote: 77 ), ( \notelist: [ 77, 88 ], \midinote: 88 ), nil ]
Note that the list restarts now on the second line…