Faking ambisonics with SuperCollider
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.
← Emulating a JP-8000 supersaw in SuperCollider Generating automatically tuned drums for OP-Z and OP-1→