Synth with retrigger cycle

Hi,

I’ve designed this Synth which goal is to play buffers and switch smoothly from one buffer to the other one. All of this within a single synth occurrence and without patterns.
In short, the synth has 2 BufRd and when the first one reached a threshold it triggers the second one, that triggers the first upon reaching a threshold, etc…

I’ve managed to trigger the 2nd BufRd upon “release” of the 1st one.
But not the re-trigger the 1st one upon release of the second one.

({
	var env1, sig1, rel1, gate1, idx1;
	var env2, sig2, /*rel2,*/ gate2, idx2;
	
	var dc1=DC.ar(0.4*336672); // 40% cue point
	var dc2=DC.ar(0.6*336672); // 60% cue point

	// The trigger of 1 should be a initial and unique trigger + all the rel2 events
	// How to define the initial rel2 ?
	// var rel2;
	//var rel2 =\rel2.kr(0);
	var rel2=0;
	var trig1=Impulse.ar(0)+rel2;

	idx1=Sweep.ar(trig1, 48000);
	rel1=Trig1.ar(idx1-dc1,0); // release at 40%
	
	// builds the envelope gate
	gate1=trig1+rel1; // a trig a 0, a trig at 40%
	gate1=PulseCount.ar(gate1,PulseDivider.ar(gate1,2)); // 1 / 0 / 1 / ... at each trig/DC
	
	env1=EnvGen.ar(Env.asr(0.1,3),gate1);
	sig1=SinOsc.ar(440)*0.2;

	idx2=Sweep.ar(rel1, 48000); // we start at release of synth1
	rel2=Trig1.ar(idx2-dc2,0); //release at 60%

	// builds the envelope gate
	gate2=rel1+rel2; // a trig a start, a trig at DC
	gate2=PulseCount.ar(gate2,PulseDivider.ar(gate2,2)); // 1 / 0 / 1 / ... at each trig/DC
	
	env2=EnvGen.ar(Env.asr(0.2),gate2);
	sig2=SinOsc.ar(220)*0.2;

	Pan2.ar(sig1*env1,-0.5)+Pan2.ar(sig2*env2,0.5);
}.play;
)

I feel like rel2 is not properly designed or revaluated…
Any idea to achieve that SinOsc1/SinOsc2/SinOsc1/… ?

({
	var env1, sig1, rel1, gate1, idx1, dc1;
	var env2, sig2, /*rel2,*/ gate2, idx2, dc2;

	// How to define the initial rel2 ?
	var rel2;
	//var rel2 =\rel2.kr(0);
	//var rel2=0;

	// The trigger of 1 should be a initial and unique trigger + all the rel2 events
	//var trig1=Impulse.ar(0)+LocalIn.ar(1,1);
	var trig1=LocalIn.kr(1,1);
	dc1=DC.kr(0.4*336672); // 40% cue point
	dc2=DC.kr(0.6*336672); // 60% cue point

	idx1=Sweep.ar(trig1, 48000);
	rel1=Trig1.kr(idx1-dc1,0); // release at 40%

	// builds the envelope gate
	gate1=trig1+rel1; // a trig a 0, a trig at 40%
	gate1=PulseCount.kr(gate1,PulseDivider.kr(gate1,2)); // 1 / 0 / 1 / ... at each trig/DC

	env1=EnvGen.kr(Env.asr(0.1,3),gate1);
	sig1=SinOsc.ar(440)*0.2;

	idx2=Sweep.ar(rel1, 48000); // we start at release of synth1
	rel2=Trig1.kr(idx2-dc2,0); //release at 60%
	LocalOut.kr([rel2]);

	// builds the envelope gate
	gate2=rel1+rel2; // a trig a start, a trig at DC
	gate2=PulseCount.kr(gate2,PulseDivider.kr(gate2,2)); // 1 / 0 / 1 / ... at each trig/DC

	env2=EnvGen.kr(Env.asr(0.2),gate2);
	sig2=SinOsc.ar(220)*0.2;

	Pan2.ar(sig1*env1,-0.5)+Pan2.ar(sig2*env2,0.5);
}.play;
)

I made this, using a LocalOut.kr(), LocalIn.kr() and it works.
But I don’t know if this is well-made…

You might check PlayBufCF from wslib and DX suite from miSCellaneous which is about multichannel xfade mixing and fanning. There are two PlayBuf switching examples included in DX suite: DXEnvFan help, Ex.5 and DXMix, Ex.4.
I’m not seeing clearly at the moment how the threshold and triggering would come into play, had to think about that.

… and if it’s about only two sources SelectX might suffice. Its restriction is that crossfading between non-adjacent sources is not directly possible.

Probably you’re best served with PlayBufCF or SelectX (the latter if applicable). Currently the implementation of DX ugens favors timed stepping over triggered stepping. I suppose it should be possible to add a further type of stepMode and pass the trigger to stepTime, will think about that on occasion.

1 Like

Thanks. I’ll investigate this.