Trigger a pitch envelope without re-triggering the amplitude envelope


#1

Hello,

In a SynthDef, I would like to be able to trigger a portamento without re-triggering the amplitude envelope of the sound. To change the pitch envelope height (envPitch in my example), I must first send a gate = 0, then a gate = 1 at the same time as the pitch change:

(
SynthDef(\pitch, {
	var env, envPitch, sig;
	env = EnvGen.ar(Env.adsr(0.01, 0.3, 0.3, 1), \gate.kr(1), doneAction:2);
	envPitch = EnvGen.ar(Env([\pitch1.kr, \pitch2.kr], [0.5]), \gatePitch.kr(0));
	sig = SinOsc.ar(envPitch)*env*0.3;
	Out.ar(0, Pan2.ar(sig));
}).add;
)
~s = Synth(\pitch, [\pitch1, 440, \pitch2, 220, \gate, 1, \gatePitch, 1]);
~s.set(\gatePitch, 0);
~s.set(\gatePitch, 1, \pitch2, 300);
~s.set(\gatePitch, 0);
~s.set(\gatePitch, 1, \pitch2, 110);

~s.set(\gate, 0);

How to automate this in the SynthDef? I can not do it.


#2

Hi, could you use lag instead of an envelope? Something like this:

(
SynthDef(\pitch, {
	var env, sig;
	env = EnvGen.ar(Env.adsr(0.01, 0.3, 0.3, 1), \gate.kr(1), doneAction:2);
	sig = SinOsc.ar(\freq.kr(440).lag(0.5))*env*0.3;
	Out.ar(0, Pan2.ar(sig));
}).add;
)
(
fork {
	~s = Synth(\pitch, [\freq, 440, \gate, 1, \gatePitch, 1]);
    //Use s.sync to allow synth to start playing before setting the frequency again
	s.sync;
	~s.set(\freq, 220).postln;
}
)
~s.set(\freq, 110);

#3

A trigger arg for gatePitch would be one possibility

(
SynthDef(\pitch_2, {
    var env, envPitch, sig;
    env = EnvGen.ar(Env.adsr(0.01, 0.3, 0.3, 1), \gate.kr(1), doneAction:2);
    envPitch = EnvGen.ar(Env([\pitch1.kr, \pitch2.kr], [0.5]), \gatePitch.tr(1));
    sig = SinOsc.ar(envPitch)*env*0.3;
    Out.ar(0, Pan2.ar(sig));
}).add;
)
// gate is 1 by default
~s = Synth(\pitch_2, [\pitch1, 440, \pitch2, 220, \gatePitch, 1]);

~s.set(\gatePitch, 1, \pitch2, 300);

~s.set(\gatePitch, 1, \pitch2, 110);

~s.set(\gate, 0);

But, more comfortable, you could also derive the trigger form the change. Then convential arg style would be better for pitches.

SynthDef(\pitch_3, { |pitch1, pitch2|
    var env, envPitch, gatePitch, sig;
    env = EnvGen.ar(Env.adsr(0.01, 0.3, 0.3, 1), \gate.kr(1), doneAction:2);
    
    // Changed checks for change of pitch, Impulse delivers trigger at start
    gatePitch = Changed.kr(pitch2) + Impulse.kr(0);
    envPitch = EnvGen.ar(Env([pitch1, pitch2], [0.5]), gatePitch);
    sig = SinOsc.ar(envPitch)*env*0.3;
    Out.ar(0, Pan2.ar(sig));
}).add;
)

~s = Synth(\pitch_3, [\pitch1, 440, \pitch2, 220]);

~s.set(\pitch2, 300);

~s.set(\pitch2, 110);

~s.set(\gate, 0);

This related thread on sc-list gives some other options of retriggering.

https://www.listarc.bham.ac.uk/lists/sc-users/msg63487.html


#4

@jpburstrom: In the case that concerns me now, lag suits me very well. I just simplified a little, since there is a lag argument in a .kr :

(
SynthDef(\pitch, {
	var env, envPitch, sig;
	env = EnvGen.ar(Env.adsr(0.01, 0.3, 0.3, 1), \gate.kr(1), doneAction:2);
	sig = SinOsc.ar(\pitch.kr(440, \pitchLag.kr(1)))*env*0.3;
	Out.ar(0, Pan2.ar(sig));
}).add;
)

~s = Synth(\pitch, 220);
~s.set(\pitch, 110, \pitchLag, 0.2);
~s.set(\pitch, 330, \pitchLag, 1);
~s.set(\gate, 0);

@dkmayer : Thank you for all these ideas; great study themes for me :slight_smile: