This seems wrong to me.
(
var last = 0;
e = (type: \rest, dur: 1);
p = Ppar([
Pfunc {
(thisThread.clock.beats - last).postln;
last = thisThread.clock.beats;
e.put(\dur, exprand(0.1, 5)).debug("yielding")
}
], 1).play
)
249.5030743 // first value is junk
yielding: ( 'type': rest, 'dur': 1.3232252066859 )
1.3232252066859 // matches last yielded dur
yielding: ( 'delta': 1.3232252066859, 'dur': 1.2520146424567, 'type': rest, 'server': localhost )
1.3232252066859 // uhm... I overwrote \dur, why is it using the old dur?
yielding: ( 'delta': 1.3232252066859, 'dur': 0.29091392633264, 'type': rest, 'server': localhost )
1.3232252066859 // and that continues
Yeah, I know, I shouldnât reuse the Event here. But Iâd have assumed it would use the last given value and I have no idea how itâs getting latched into old data â except that itâs something in Ppar.
hjh
It seems like adding an arg to Pfunc solves it, even though the name of the arg is unrelated to the rest of the code, here using âevâ which is not used elsewhere. I have no idea why, just an observation.
(
var last = 0;
e = (type: \rest, dur: 1);
p = Ppar([
Pfunc {|ev|
(thisThread.clock.beats - last).postln;
last = thisThread.clock.beats;
e.put(\dur, exprand(0.1, 5)).debug("yielding")
}
], 1).play
)
yielding: ( 'delta': 0.9976023755152, 'dur': 0.84764440158663, 'type': rest, 'server': localhost )
0.99760237551527
yielding: ( 'delta': 0.9976023755152, 'dur': 0.81589205263499, 'type': rest, 'server': localhost )
0.99760237551527
yielding: ( 'delta': 0.9976023755152, 'dur': 1.0318768187614, 'type': rest, 'server': localhost )
Except that the Pfunc body generates a new dur for every event, and the âadd an argâ approach ignores that and has the same dur for every event.
Ppar must be copying the event somewhere internally and then not handling identical events properly⌠but I donât have time to dig into it.
One of those where I thought âI can save a bit of garbage collection load by reusing an event objectâ and then a zero duration burned me pretty hard. At least 20 minutes and multiple force-quits of the interpreter to find out where the problem was.
hjh
Ok, I think I understand now. If for instance dur is swapped for freq, then the pattern does update the freq, whereas in your example the dur key is not updated. I was surprised that it worked with the freq key, I did not not know that âeâ is played with this syntax, I just expected it to update e not play the values in e. Is this kind of pattern pattern behavior described anywhere in the help files?
The only type of pattern that can be played is an event pattern (a pattern that yields events). Each event returned from an event pattern will be played.
A Pfunc that returns events is an event pattern. So there is no reason to expect that events from a Pfunc would not be played.
Sometimes pattern usage âfetishizesâ Pbind a bit, in the sense that we sometimes think playing a Pbind is different from playing other types of patterns, but thereâs nothing special about Pbind. An event produced by Pbind is no different from an equivalent event written directly in a Pfunc, and the calling EventStreamPlayer has no way to distinguish the source that produced the events â so the syntax that produced the events doesnât matter.
Thatâs interesting, that freq
changes per event but dur
doesnât. Will ponder tomorrow.
hjh
I think this happens because Ppar
overwrites each eventâs \delta
in order to merge streams and maintain correct timing. The problem goes away if you use \delta
instead of \dur
:
(
var last = 0;
e = (type: \rest, delta: 1);
p = Ppar([
Pfunc {
(thisThread.clock.beats - last).postln;
last = thisThread.clock.beats;
e.put(\delta, exprand(0.1, 5)).debug("yielding")
}
], 1).play
)
1 Like
Ah yes, itâs got to be that â overriding delta so that it doesnât look at dur again.
If I have time later, Iâll add a note to the docs.
Thanks for the analysis â I had been doing code integration for a couple hours before that and was just tired, appreciate the extra pair of eyes.
hjh