How to get rid of popping sounds when jumping around Playbuf

Yes, crossfading by envelope is the right way to handle this.

The crossfaded segments should overlap during the fade in/out period, so you need two PlayBufs and two envelopes. If you don’t do it that way, you have a gap between the segments, which you probably don’t want.

Not really. The fades should overlap, meaning that you trigger A’s fade out and B’s fade in at the same time. So it’s enough to use gated envelopes, where the gate signals are the inverse:

{
	var trig = Impulse.ar(400),
	gate = ToggleFF.ar(trig),
	inverseGate = 1 - gate,
	envelopes = EnvGen.ar(Env.asr(0.001, 1, 0.001, [-4, 4]), [gate, inverseGate]);
	[gate, inverseGate] ++ envelopes
}.plot;

So:

b = Buffer.read(s, Platform.resourceDir +/+ "sounds/a11wlk01.wav");

a = {
	// could be Impulse or TDuty or other
	var trig = Dust.kr(3),
	// one segment is on at first trigger, off at second
	gate = ToggleFF.kr(trig),
	// the other is reversed
	gates = [gate, 1 - gate],
	// we need pairs of PlayBuf parameters, so: multichannel expansion
	// TRand.kr(..., gates) --> [TRand.kr(... gates[0]), TRand.kr(... gates[1])]
	// i.e. a new start frame when the segment fires but not otherwise
	startFrames = TRand.kr(0, BufFrames.kr(b) - 40000, gates),
	// similarly, 2 PlayBufs with alternating triggers
	signals = PlayBuf.ar(1, b, trigger: gates, startPos: startFrames),
	// alternating gate signals for 2 envelopes too
	egs = EnvGen.kr(Env.asr(0.01, 1, 0.01, [-4, 4]), gates),
	// apply envelopes to the 2 signals and mix before going further
	mix = (signals * egs).sum;
	// now it's 1 channel: final amp scaling and expand to stereo
	Out.ar(0, (mix * 0.1).dup);
}.play;

Is it a common theme in SuperCollider (and programmatic audio stuff in general) that it’s easy to make crazy noises with math, but hard to polish the “edges”?

It would be more accurate to say that VSTs handle the edge-polishing for you, so when you use VSTs, you are responsible for fewer of the details. (The plug-in developers handled them for you.) In SC, it’s up to you to handle a lot of things by yourself. So when you play sound file segments using Kontakt, Kontakt applies an envelope to every note and you don’t have to think about it. In SC, you do have to be aware that an envelope should be applied.

EDIT: PlayBufCF in wslib (quark) does it for you. But it’s worth taking apart the “how” in the example here.

hjh

5 Likes