Equal power XOut

I have several questions.

  1. Is there an equal power version of XOut readily available?
    If there isnt, then id like to ask the following questions.
  2. How are the 2 channel equalpower ugens in supercollider implemented? Is it just by taking the quare root of the linear scaling factors? When i try something like that neither channels fully dip to 0.
(
//my implementation
{
	var t = SinOsc.ar(0.1);

	var sig1, sig2, cf1, cf2;
	cf1 = 1/2 * (1 + t);
	cf1 = cf1.sqrt;
	cf2 = 1/2 * (1 - t);
	cf2 = cf2.sqrt;
	sig1 = SinOsc.ar(100);
	sig2 = SinOsc.ar(366);
	
	(sig1 * cf1) + (sig2 * cf2) * 0.5;
}.play
)
//compare it to the XFade2 ugen
(
{
	var t = SinOsc.ar(0.1)

	var sig1, sig2;
	sig1 = SinOsc.ar(100);
	sig2 = SinOsc.ar(366);
	
	XFade2.ar(sig1, sig2, t)*0.5;
}.play
)
  1. How in general can you see how Ugens are implemented? When i check the source code i see something like this. Where should i look?
XFade2 : UGen {
	// equal power two channel cross fade
	*ar { arg inA, inB = 0.0, pan = 0.0, level = 1.0;
		^this.multiNew('audio', inA, inB, pan, level)
	}
	*kr { arg inA, inB = 0.0, pan = 0.0, level = 1.0;
		^this.multiNew('control', inA, inB, pan, level)
	}
	checkInputs { ^this.checkNInputs(2) }
}

How in general can you see how Ugens are implemented?

Ugens are written in C, see:

https://github.com/supercollider/supercollider/blob/develop/server/plugins/PanUGens.cpp

1 Like

No, but you can make one:

XOut.ar(bus, xfade, signal)

-->

ReplaceOut.ar(
	bus,
	XFade2.ar(
		In.ar(bus, max(1, signal.size)),
		signal,
		xfade * 2 - 1
	)
)

If that’s too much typing for daily use, you could make a pseudo-UGen out of it:

EDIT: Bad copy/paste, fixed now.

XOutEqualPower : UGen {
	*ar { |bus, xfade, signal|
		^ReplaceOut.ar(bus, XFade2.ar(
			In.ar(bus, max(1, signal.size)),
			signal,
			xfade * 2 - 1
		))
	}
}

(Note, the * 2 - 1 is to preserve compatibility with XOut’s xfade input. XOut’s xfade is 0.0 - 1.0, while XFade2 is -1.0 to 1.0. You could save a UGen by requiring a bipolar xfade in XOutEqualPower, and deleting the * 2 - 1.)

How are the 2 channel equalpower ugens in supercollider implemented?

I believe it’s sinusoidal, not square-root.

{
	var xfade = Line.ar(-1, 1, 0.01);
	[
		XFade2.ar(DC.ar(0), DC.ar(1), xfade),
		sqrt(xfade * 0.5 + 0.5)
	]
}.plot;

hjh

1 Like