How to create very basic left/right equal power panning with createPanner();

南笙酒味 提交于 2019-11-28 08:46:05

I can still get a panning effect by changing only the first argument to setPosition() and keeping other arguments zero.

<!DOCTYPE html>
<html>
<head>
<script>
var c = new webkitAudioContext();
var s = c.createBufferSource();
var g = c.createGainNode();
var p = c.createPanner();
s.connect(g);
g.connect(p);   
p.connect(c.destination);

function play(e) {
  var fr = new FileReader();
  var file = document.getElementById("file").files[0];
  fr.onload = function(e) {
    c.decodeAudioData(e.target.result, 
      function (buf) {
        s.buffer = buf;
        g.gain.value = 0.5;
        s.noteOn(0)
      },
      function () {
        console.error('decodeAudioData failed.');
      }
    );
  };
  fr.readAsArrayBuffer(file);
}

function pan(range) {
  var x = Math.sin(range.value * (Math.PI / 180));
  p.setPosition(x, 0, 0);
}
</script>
</head>
<body>
  Choose your MP3 file:<br>
  <input type="file" id="file" name="file" /><br>
  <input type="submit" id="go" onclick="play()" value="Play" /><br>
  L<input type="range" min="-45" max="45" value="0" onchange="pan(this);">R
</body>
</html>

But to get a natural panning effect, you need to specify the third argument as well.

function pan(range) {
  var xDeg = parseInt(range.value);
  var zDeg = xDeg + 90;
  if (zDeg > 90) {
    zDeg = 180 - zDeg;
  }
  var x = Math.sin(xDeg * (Math.PI / 180));
  var z = Math.sin(zDeg * (Math.PI / 180));
  p.setPosition(x, 0, z);
}

here's an even simpler (less formulaic?) way to achieve 2D panning:

( full code here )

<input type="range" name="pan" id="pan" min="-1" max="1" step="any" />
<script>
var panner = context.createPanner();
panner.panningModel = 'equalpower';

function pan(event) {
    var x = this.valueAsNumber,
        y = 0,
        z = 1 - Math.abs(x);
    panner.setPosition(x,y,z);
}

document.getElementById('pan').addEventListener(pan);
</script>

The panner node defaults to "HRTF" (Head Related Transfer Function) which is a stereo convolution engine and it is designed for 3D sound.

In order to have basic panning functionality and lower resource usage you need to set panningModel attribute to "equalpower".

var panner = context.createPanner();
panner.panningModel = "equalpower";
panner.setPosition(1,0,0);

Check the documentation for more details.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!