I think this qualifies as a literal Heisenbug – there’s an incorrect value, but if I try to observe the wrong value, then it magically becomes the right value.
So, working flip-flop envelopes:
(
p = { |trigRate = 20, trigRandMul = 1,
bufDur = 1.0, xfade = 0.008,
endAmp = 0.7, grainEndAmp = 0.25, rate = 1, advance = 0,
sustain = 1, beatsPerSec = 1|
var susTime = sustain / beatsPerSec;
var sr = SampleRate.ir;
var trig = Impulse.ar(trigRate);
var evenOdd = ToggleFF.ar(trig);
var trigs = [evenOdd, 1 - evenOdd];
var egs = EnvGen.ar(Env.adsr(xfade, trigRate.reciprocal.poll(Impulse.kr(0)), grainEndAmp, xfade), trigs);
[trigs, egs].flat
}.plot(duration: 1)
)
OK, now I would like to randomize the IOI and know the duration of each random segment… use TDuty to calculate the IOI and pass it forward for the duration calculation.
(
p = { |trigRate = 20, trigRandMul = 1,
bufDur = 1.0, xfade = 0.008,
endAmp = 0.7, grainEndAmp = 0.25, rate = 1, advance = 0,
sustain = 1, beatsPerSec = 1|
var susTime = sustain / beatsPerSec;
var sr = SampleRate.ir;
var durStream = Ddup(2, (trigRandMul ** Dwhite(-1.0, 1.0, inf)) / trigRate);
var trig = TDuty.ar(durStream, 0, durStream);
var evenOdd = ToggleFF.ar(trig);
var trigs = [evenOdd, 1 - evenOdd];
var durs = Latch.ar(trig, trigs);
var egs = trigs.collect { |t, i|
EnvGen.ar(Env.adsr(xfade, durs[i], grainEndAmp, xfade), t)
};
[trigs, egs].flat
}.plot(duration: 1)
)
Now the envelope decay is much more gradual than it ought to be, meaning that durs[0] and durs[1] are too high.
How high? I tried: 1/ durs[i].poll(0) in the EnvGen; 2/ plotting [trigs, egs, durs].flat; 3/ SendReply.ar(Impulse.ar(1), '/durs', durs) printing in the language. In all cases, the envelope magically behaves correctly (exactly the same as the first graph), and the correct value is printed.
poll inserts a new ugen into the chain, so the input into EnvGen is not the same. But for 2 and 3, the same Latch output is split off into different places but the EnvGen receives the input directly. For 2, the RecordBuf must naturally follow EnvGen; for 3, .trace shows me that the SendReply comes after EnvGen as well.
I can’t think of a good reason why a later operation on a UGen’s output would affect an earlier reference to it, particularly when that later operation is not modifying the value but only sending it somewhere else.
(Actually re: the “question,” I also just realized that EnvGen inputs are read only at control rate, not audio rate, so I will have to find another way anyway. But this is really weird behavior; atypically, I don’t have any sort of explanation for this. So I’m kicking it out to the community. What the F—ourier is going on here?)
hjh


