EnvGen / TDuty / Latch / Decay doesn't decay at first

I am not normally stumped by things like this, but this one, I’m running out of ideas.

(
{ |e1 = 0.05, e2 = 0.01, mp = 0.5, time = 0.2|
	var eg = EnvGen.ar(Env(
		[0.05, 0.007, 0.05],
		[0.5, 0.5],
		\exp
	), timeScale: time);
	var initTrig = Impulse.ar(0);
	var trig = TDuty.ar(eg, 0, 1).poll(initTrig);
	var dcy = Latch.ar(0.8 * eg, trig).poll(initTrig);
	Decay.ar(trig, dcy)
}.plot(0.2);
)

UGen(TDuty): 1
UGen(Latch): 0.0399836

Expected behavior: Decay’s response to the first trigger should be commensurate with the others: 0.8 * the envelope value at the moment of being triggered.

Actual behavior: The response to the first trigger takes decay = 0. Then all the others work as expected.

I think it must be a bug. But I checked several places related to UGen initialization, and I just don’t see it. (I suppose it must be Decay. At first I thought maybe Latch was outputting 0 at the beginning, instead of the first envelope value. Now I see that it’s getting a slightly late envelope value, which is weird, but 0.0399 * 0.8 is not 0, and from the plot, clearly the initial decay time is 0. So the datum is there but Decay is not acting upon it correctly… but Decay.ar(trig, dcy + 0.025) does decay at the start.)

It’s been awhile since I found bugs during normal SC usage… two in one day, today :wine_glass: (other one already logged)

hjh

Ah… a workaround, at least.

(
{ |e1 = 0.05, e2 = 0.01, mp = 0.5, time = 0.2|
	var eg = EnvGen.ar(Env(
		[0.05, 0.007, 0.05],
		[0.5, 0.5],
		\exp
	), timeScale: time);
	var initTrig = Impulse.ar(0);
	var trig = TDuty.ar(eg, 0, 1).poll(initTrig);
	var dcy = Latch.ar(0.8 * eg, trig).poll(initTrig);
	var zero = DC.ar(0);
	var coeff = Select.ar(dcy < 0.00001, [exp(log(0.001) / (dcy * SampleRate.ir)), zero]);
	FOS.ar(trig, DC.ar(1), zero, coeff);
}.plot(0.2);
)

… which I need anyway bc Decay’s decaytime is not audio-rate modulatable :sigh:

^^ Actually now I think that’s the key. If TDuty’s first trigger is one sample late (and this would explain the slightly-off envgen-latch poll result), then it would be in the middle of the first control block and Decay wouldn’t pick it up. But if I force FOS to read all coefficients at audio rate, then it works.

hjh