Any plans for IEnvGen with a variable envelope?

I’m killing myself trying to do phase distortion.

It would be so easy if IEnvGen could modulate the envelope.

Just wondering if anyone has done, or plans to do, this?

Without that feature, I have to try to break up the phase into segments and separately apply lincurves to each. It’s… just not working. lincurve is giving me bad values which crash the server. I’ve tried taking apart the math and rebuilding it a bit more optimally and I’m just getting flat values, no moving phase.

Shaper would be another option but it’s also not readily modulatable.

Oh well, check my formulas on paper later I guess. Actually I did find the issue… can’t shake the feeling that this was much harder than it needed to be, though.

hjh

1 Like

Would WaveTerrain | SuperCollider 3.12.2 Help work?

Hm, potentially – it turns out that I do only have two variables (a phasor, and a stretch/squeeze factor – an offset is applied after that). Originally I had a curve factor too, but that ended up not sounding good, so I dropped it.

I’m thinking to release a quark with this eventually – I also worked out mipmapping to reduce aliasing somewhat.

hjh

I recently came across this post: Restart Envelopes without creating new SynthDef instance - #10 by scztt

Not sure how you’re planning to modulate the envelope, but @scztt’s fromArray Env extension seems to do this?

1 Like

One way (unrelated to IEnvGen but might still be useful) is to use phasor ** (2 ** squeezeStretch), where squeezeStretch of zero gives no phase distortion:

(
{
	var freq = 130;
	var phasor = Phasor.ar(0, freq / SampleRate.ir, 0, 1);
	var squeezeStretch = LFTri.ar(0.1, 0, 5, 0); // from -5 to 5
	var outPhase = phasor ** (2 ** squeezeStretch);
	SinOsc.ar(0, outPhase * 2pi, 0.1); 	
}.scope;
)

Best,
Paul

Oh that’s very nice – perhaps (((phasor * 2 - 1) ** (something)) * 0.5 + 0.5) * bufFrames (bipolar eliminates discontinuity in the slope when wrapping back around – though after the fact, I realize this depends on JMc’s funky definition of exponentiation in the server :wink: ).

Much more elegant than what I was trying.

hjh

I just tried out a bipolar version, which distorts in a more symmetrical way - and maybe sounds a bit nicer:

// bipolar version
(
{
	var freq = 130;
	var squeezeStretch = LFTri.ar(0.1, 0, 5, 0); // from -5 to 5
	var tri = LFTri.ar(freq, 1).unipolar;
	var pulse = LFPulse.ar(freq).bipolar;
	var outPhase = pulse * (tri ** (2 ** squeezeStretch));
	SinOsc.ar(0, outPhase * pi, 0.1);
}.scope;
)

Best,
Paul

Edit: I now realise that’s your way is much simpler!

1 Like

ive onced worked on these two phase shapers, maybe they are of interest to someone:

(
// Sinusoid with a variable-slope Triangular Phase

~phaseShaper_Tri = {
	var freq = \freq.kr(130);
	var width = LFTri.ar(0.1).linlin(-1, 1, 0.01, 0.99);
	var phasor, sine;
	phasor = Phasor.ar(0, freq * SampleDur.ir, width.neg, 1-width);
	phasor = phasor.bilin(0, width.neg, 1-width, 0, -1, 1);
	//phasor = (phasor.abs * 1.5 - 0.5).abs;
	phasor = (phasor.abs * 1.5).wrap(0,1);
	sine = (phasor * 2pi).sin;
	sine !2 * 0.1;
}.play;
)

(
// Sinusoid with a variable-slope Ramp Phase

~phaseShaper_Saw = {
	var freq = \freq.kr(130);
	var width = LFTri.ar(0.1).linlin(-1, 1, 0.01, 0.99);
	var phasor, sine;
	phasor = Phasor.ar(0, freq * SampleDur.ir, width.neg, 1-width, width.neg);
	phasor = phasor.bilin(0, width.neg, 1-width, 0, -0.5, 1);
	phasor = Select.ar(phasor > 0, [0.5 + phasor, phasor]);
	sine = (phasor * 2pi).sin;
	sine !2 * 0.1;
}.play;
)
2 Likes

after working some time with this:

(
var statelessWindow = { |levels, times, curve, phase|
	var x = 0;
	var window = times.size.collect{ |i|
		var x2 = x + times[i];
		var result = (phase >= x) * (phase < x2) * phase.lincurve(x, x2, levels[i], levels[i+1], curve[i]);
		x = x2;
		result;
	}.sum;
	window * (phase < 1);
};

{
	var phase = Sweep.ar;
	statelessWindow.([0, 1, 0], [0.5, 0.5], [2.0, -2.0], phase);
}.plot(1);
)

i would also be interested in attempts to write a more efficient C++ version. could someone help out with that?

2 Likes