Voices are counting up

I never used the EnvGen adsr. , so I tried it
The env is set to doneaction :2 , yet the voices keep on stacking up when sequenced from a Pbind

(
SynthDef(\Sqwer,
   {| ampatt =0.001,ampdec=1,ampsus=0.2,amprel=0.3filtatt=0.001,filtdecay=0.500,filtsus=0.2,filtrel=0.2,osc1amp=0.3,osc2amp=0.3,osc3amp=0.3,offset1=0,offset2=0.2,offset3=(-0.2),filterfreq=600,res=1,freq=30,
   	filteramount=100,pan=0,vol=0.7,fsh=5,xfade=0|
   	var sig,sig1,sig2,sig3,ampenvelope,filterenvelope;
   	filterenvelope=EnvGen.ar(Env.adsr(filtatt,filtdecay,filtsus,filtrel),doneAction:0);
   	ampenvelope=EnvGen.ar(Env.adsr(ampatt,ampdec,ampsus,amprel,),doneAction:2);
   	sig1=Pulse.ar((freq+offset1).midicps,mul:osc1amp);
   	sig2=Pulse.ar((freq+offset2).midicps,mul:osc2amp);
   	sig3=Pulse.ar((freq+offset3).midicps,mul:osc3amp);
   	sig=sig1+sig2+sig3;
   	sig=RLPF.ar(sig,(filterfreq+(filterenvelope*filteramount)).clip(20,20000),rq:res);
   	sig=XFade2.ar(sig,FreqShift.ar(sig,fsh),pan:xfade);
   	sig=sig*vol;
   	sig=sig*ampenvelope;
   	sig=Pan2.ar(sig,pos:pan)!2;
   	Out.ar(0,sig);
}).add
)

Synth(\Sqwer,[\freq,58,\offset1,-24,\offset2,-0.3,\offset3,0.1,\filterfreq,800,\filteramount,600,\xfade,0,\fsh,3]);


(
Pdef(\bebe,
   Pbind(\instrument,
   	\Sqwer,
   	\dur,Pseq([1/4,1/4,1/4,1/4],inf),
   	\freq,Pseq([60,61,62,63,64,65,66],inf),
   	\offset1,0,
   	\offset2,0.2,
   	\offset3,-0.1,
   	\filterfreq,Prand([400,500,400,500],inf),
   	\filteramount,1800,
   	\filtatt,0.001,
   	\filtdecay,0.3,
   	\filtsus,0.2,
   	\filtrel,0.1,
   	\ampatt,0.001,
   	\ampdec,0.1,
   	\ampsus,0.0,
   	\amprel,0.1,
   	\vol,0.3,
   	\res,0.5,
   	\xfade,-1,
   	\fsh,Pwhite(2,5,inf),

   )
)
)

Pdef(\bebe).play(t)
Pdef(\bebe).stop(t)

t=TempoClock(124/60).permanent_(true);

ADSR needs a gate.

hjh

Hmmm you mean it needs a gate off , that is part of the Env. class ?
I always use EnvGen.ar(Env( [levels ],[times ], [ curves ]),doneAction:2) , and there the gate is ( I supppose ) always 1 by default

I has the same arguments as the Env.adsr , gate ,levelscale, levelbias , timescale ,doneAction .
Is it becasue the Env.adsr gate it tied to the sustain level ?
So why and more importantly how do I give a gate 0 from Pbind, pseq ?

I am probably doing something horribly wrong , I declared argument gate , sequenced it in a pbind (0,1,0,1,00and it makes no difference

See the Examples section of EnvGen help, specifically “// using a gated envelope to gate a sound” (this example uses an arg for doneAction, but usually we just hardcode doneAction: 2 – the gate handling is canonical in this example though).

hjh

OK, now I have a bit more time to add some detail.

You’re right that EnvGen’s default gate is a constant 1.

BUT the definition of an ADSR envelope is that it should proceed through the attack and decay phases, and hold at the sustain level until the gate closes.

How does the gate close?

SuperCollider defines “open” as gate > 0 (any positive value, even only slightly larger than 0), and “closed” as gate <= 0.

So the gate must be positive for some time, and then change to 0 to close it.

Closing the gate means that the value must change – hence, you can’t close an open gate with a constant signal – i.e. “always 1 by default” is not valid for ADSR. (Note that this is true in other synth software as well. If, in VCV Rack, you put a constant positive voltage into the gate input of an ADSR module, then likewise, you will find that the envelope will not close.)

That leads to the canonical way to do a gated envelope in SC.

  • SynthDef has a control input called ‘gate’ with default 1.
  • Use this in EnvGen’s gate input, with doneAction: 2.

I don’t think there’s a better way to do this – so my recommendation is to get comfortable with the canonical way and just repeat this pattern whenever you need it.

The default \note event type does it automatically, so you don’t have to.

s.boot;

// default synthdef is gated!
// you've used it before
// so you've been playing gated events
// many many times already, and it just worked
SynthDescLib.at(\default).hasGate
-> true

// this will hold for 2 beats, then release
(instrument: \default, sustain: 2).play;

There is one bit of fine print with gate in patterns: by default, events do not send a gate value at the beginning of a note, instead assuming that the SynthDef has specified a positive default. This is to save a little bit of CPU time.

This means that if you try to sequence gate, the synths won’t get the values from the pattern (at least not by default).

But normally, sequencing gate values is not necessary, because the main thing is just that the note begins to play.

The automatic release message from the \note event type is separate from this.

hjh