Normal behavior for Ppar is to end when the last of the patterns in its list ends. However, in my current experiment, I’d like a version of Ppar that ends as soon as one of its patterns end. Am I missing the obvious way to do it? If so, I’d appreciate a hint. If not, what would be an approach to accomplish this?
I’m aware of Pfindur and Pfin but in my use case I cannot easily know exactly how long each of the patterns will take (they are dynamically “compiled” from external data).
I’m somewhat surprised that nothing like it seems to exist yet.
I was surprised too. I roughly remember that there are other Patterns, that end if one stream ends, but I couldn’t find them. However when dealing with subpatterns Pspawner is your best friend:
p = Pbind(\note, Pn(0, 3));
q = Pbind(\note, 2);
r = [p, q];
// you can emulate Ppar's behaviour like this
Pspawner { |sp|
sp.par(p);
sp.par(q)
}.play
// this finishes in the special case when first stream ends
Pspawner { |sp|
sp.par(Pseq([p, Prout { sp.suspendAll } ]));
sp.par(q)
}.play
// for an arbitrary number of patterns
Pspawner { |sp|
r.do { |p| sp.par(Pseq([p, Prout { sp.suspendAll }])) }
}.play
You could write a little helper class or Function for this. A further advantage of Pspawner is that you can easily adapt the finishing behaviour in special cases.