{
   "name" : "Wave Field Synthesis",
   "author" : "miguel.negrao",
   "description" : "A simple synthdef for Wave Field Synthesis rendering.",
   "ancestor_list" : [],
   "labels" : [
      "wfs",
      "spatialization",
      "wave field synthesis"
   ],
   "is_private" : null,
   "id" : "1-4RS",
   "code" : "/*\r\nThe basic principles of WFS are very simple:\r\n\r\n    1 - calculate distance from virtual source to each speaker.\r\n    2 - calculate time that sound takes to travel that distance  t = d/340.\r\n    3 - calculate amplitude decay due to that distance a = 1/d\r\n    4 - delay sound by the delay time and multiply by amplitude.\r\n*/\r\n\r\n// your speaker positions\r\np = 112.collect{ |i| Point(i.linlin(0,111,-10.0,10.0), 5) };\r\n\r\n// now go, buy 112 speakers and play this synthdef :-)\r\n(\r\nSynthDef(\\minimalWFS,{\r\n    \r\n    var excitation = Dust.ar(20) * 0.2;\r\n    \r\n    var in = Klank.ar(`[20.collect{ exprand(100,3000) }], excitation);\r\n    \r\n    var x = MouseX.kr(-20,20);\r\n    \r\n    var y = MouseY.kr(-30,5); //this is in meters.\r\n    \r\n    var max = 2 ** ( (3 * 44100).log2.roundUp(1).max(0) );\r\n    \r\n    var buf = LocalBuf(max,1).clear;\r\n    \r\n    var dists = p.collect{ |point| Point(x,y).dist(point) };\r\n    \r\n    var delayTimes = dists / 340;\r\n    \r\n    var amps = dists.collect{ |d| d.reciprocal.min(1.0) };\r\n    \r\n    var delays = BufDelayL.ar(buf, in, delayTimes);\r\n    \r\n    Out.ar(0, delays * amps )\r\n    \r\n}).play\r\n)"
}
