Multi-Channel Crossfade

Hi all -

I’d like to cross-fade between one set of 8 channels and another set of 8 channels.
Since XFader2 seems to be specifically for sets of stereo pairs, I have been trying to find another way around this problem.

I tried to make an abstraction that would take any size input and cross-fade with the alternating channels.
This didn’t quite work as expected, so I thought I’d share it here and see if anyone had any pointers.
Thanks!

VariFade{
	  *ar {
		arg signal, pan, level;
		var out, newSig;

		signal = signal.collect{|x, index|
			index = index+1;
			if (index%2==0,
				{pan = pan;},
				{pan = 0 - pan});
			x = x*pan;
		};
		out = signal;
		^out;
	}
}


And some quick code to run it:

s.meter;
s.options.numOutputBusChannels_(4);
s.reboot;

{
	VariFade.ar(
	[SinOsc.ar(400, mul:0.1), 
		SinOsc.ar(500, mul:0.1), 
		SinOsc.ar(405, mul:0.1), 
		SinOsc.ar(505, mul:0.1)], 
	SawDPW.ar(1).range(-1, 1))}.play;


I think the issue is that the abstraction doesn’t know how many channels to consolidate to…but I’m not sure how to fix that.

If you’re synthesizing the channels yourself, there’s no need to make them into a flat array. SC supports nested arrays, and XFade2 can multichannel expand:

(
{
	var snd;
	snd = [
		[SinOsc.ar(440), SinOsc.ar(1000), SinOsc.ar(100)],
		[Saw.ar(440), Saw.ar(300), Saw.ar(440)]
	];
	XFade2.ar(snd[0], snd[1], MouseX.kr(-1, 1));
}.play(fadeTime: 0);
)

If you are receiving the channels as an interleaved flat array, you can reshape them into a 2D array using snd.clump(2).flop or snd.unlace(2).

2 Likes

possibly also have a look at SelectX:

The output is mixed from an array of inputs, performing an equal power crossfade between two adjacent channels.

1 Like

Just one other question about clump, flop, unlace, etc…
Is there a simple command to expand an array as such?
[0, 1, 2] → [0, 0, 0], [1, 1, 1], [2, 2, 2]

Like this?

[0, 1, 2].dupEach(3).clump(3)

or

[0, 1, 2].collect { |item| item ! 3 }

You should have asked separately. I think one of the moderators will move the last two posts to a new thread.