Zack Scholl

zack.scholl@gmail.com

Faking ambisonics with SuperCollider

 / #supercollider #til 

There is a simple trick to make audio float around binaural headphones by using oscillating filters and delays on each channel.

SuperCollider has a pretty incredible Ambisonic Toolkit. However whenever I use it it gets very complicated, uses a bit too much CPU, and the result is not exactly what I hoped. The result I’m looking for is simply to project a stereo audio signal around the head so that it can appear to be randomly around you - to the left, to the right, and also behind and in front.

Turns out this can be done in a imprecise and coarse way that does have some semblance to random binaural positioning, by using slight delays between the two channels and some filtering. Here’s a small example:

(
b = Buffer.read(s, Platform.resourceDir +/+ "sounds/a11wlk01.wav");
{
	var snd=PlayBuf.ar(1,b,loop:1);
	var pan=SinOsc.kr(1/7.13,Rand(0,6))/1.5;
	var pan2=SinOsc.kr(1/12.123,Rand(0,6))/1.5;
	var pan3=SinOsc.kr(1/15.12354,Rand(0,6))/1.5;
	var amp=SinOsc.kr(1/17.123,Rand(0,6)).range(0.25,0.75);
	snd=Pan2.ar(snd,0);
	//snd=WhiteNoise.ar(0.1)!2;
	snd=[snd[0],snd[1]];
	snd=[
		LPF.ar(snd[0],LinExp.kr((pan2<0)*pan2.abs,0,1,4000,18000).poll),
		LPF.ar(snd[1],LinExp.kr((pan2>0)*pan2.abs,0,1,4000,18000).poll)
	];
	snd[0]=SelectX.ar(((pan>0)*pan.abs),[snd[0],DelayN.ar(snd[0],0.04,0.04)]);
	snd[1]=SelectX.ar(((pan<0)*pan.abs),[snd[1],DelayN.ar(snd[1],0.04,0.04)]);
	snd=Balance2.ar(snd[0],snd[1],pan3);
	Out.ar(0,snd*amp);
}.play;
)

In this example the channels are split and then each channel undergoes some random oscilation in its low-pass filter and the side of its small delay (40 ms). There is also a traditional equal-power pan at the end. Its certainly head-swirling, although not quite at the level of true ambisonics.