BaseAudioContext:createPanner() 方法

Baseline 已广泛支持

此特性已得到良好支持,可在多种设备和浏览器版本上使用。自 2021 年 4 月起,所有浏览器均已支持此特性。

BaseAudioContext 接口的 createPanner() 方法用于创建一个新的 PannerNode,它用于在 3D 空间中对传入的音频流进行空间化。

声像节点相对于 AudioContext 的 AudioListener (由 AudioContext.listener 属性定义) 进行空间化,该属性代表听音频的人的位置和朝向。

注意: PannerNode() 构造函数是创建 PannerNode 的推荐方法;请参阅 创建 AudioNode

语法

js
createPanner()

参数

无。

返回值

一个 PannerNode

示例

在下面的示例中,您可以看到 `createPanner()` 方法、AudioListenerPannerNode 如何用于控制音频空间化的示例。通常,您会定义音频监听者和声像器(源)最初在 3D 空间中的位置,然后在应用程序使用过程中更新其中一个或两个的位置。例如,您可能正在游戏中移动一个角色,并希望音频的传递效果能随着角色靠近或远离音乐播放器(如立体声音响)而真实地改变。在示例中,您可以看到这通过 `moveRight()`、`moveLeft()` 等函数进行控制,这些函数通过 `PositionPanner()` 函数为声像器的位置设置新值。

要查看完整的实现,请查看我们的 panner-node 示例查看源代码)— 此演示将您带到 2.5D 的“金属房间”,您可以在其中播放音响上的音轨,然后围绕音响走动,以观察声音如何变化!

请注意,我们使用了一些特性检测,以便如果浏览器支持较新的属性值(如用于设置位置等的 AudioListener.forwardX),则使用这些较新的属性,或者如果浏览器支持但不支持新属性,则使用旧方法(如 AudioListener.setOrientation())。

js
// set up listener and panner position information
const WIDTH = window.innerWidth;
const HEIGHT = window.innerHeight;

const xPos = Math.floor(WIDTH / 2);
const yPos = Math.floor(HEIGHT / 2);
const zPos = 295;

// define other variables

const audioCtx = new AudioContext();

const panner = audioCtx.createPanner();
panner.panningModel = "HRTF";
panner.distanceModel = "inverse";
panner.refDistance = 1;
panner.maxDistance = 10000;
panner.rolloffFactor = 1;
panner.coneInnerAngle = 360;
panner.coneOuterAngle = 0;
panner.coneOuterGain = 0;

if (panner.orientationX) {
  panner.orientationX.setValueAtTime(1, audioCtx.currentTime);
  panner.orientationY.setValueAtTime(0, audioCtx.currentTime);
  panner.orientationZ.setValueAtTime(0, audioCtx.currentTime);
} else {
  panner.setOrientation(1, 0, 0);
}

const listener = audioCtx.listener;

if (listener.forwardX) {
  listener.forwardX.setValueAtTime(0, audioCtx.currentTime);
  listener.forwardY.setValueAtTime(0, audioCtx.currentTime);
  listener.forwardZ.setValueAtTime(-1, audioCtx.currentTime);
  listener.upX.setValueAtTime(0, audioCtx.currentTime);
  listener.upY.setValueAtTime(1, audioCtx.currentTime);
  listener.upZ.setValueAtTime(0, audioCtx.currentTime);
} else {
  listener.setOrientation(0, 0, -1, 0, 1, 0);
}

let source;

const play = document.querySelector(".play");
const stop = document.querySelector(".stop");

const boomBox = document.querySelector(".boom-box");

const listenerData = document.querySelector(".listener-data");
const pannerData = document.querySelector(".panner-data");

leftBound = -xPos + 50;
rightBound = xPos - 50;

xIterator = WIDTH / 150;

// listener will always be in the same place for this demo

if (listener.positionX) {
  listener.positionX.setValueAtTime(xPos, audioCtx.currentTime);
  listener.positionY.setValueAtTime(yPos, audioCtx.currentTime);
  listener.positionZ.setValueAtTime(300, audioCtx.currentTime);
} else {
  listener.setPosition(xPos, yPos, 300);
}

listenerData.textContent = `Listener data: X ${xPos} Y ${yPos} Z 300`;

// panner will move as the boombox graphic moves around on the screen
function positionPanner() {
  if (panner.positionX) {
    panner.positionX.setValueAtTime(xPos, audioCtx.currentTime);
    panner.positionY.setValueAtTime(yPos, audioCtx.currentTime);
    panner.positionZ.setValueAtTime(zPos, audioCtx.currentTime);
  } else {
    panner.setPosition(xPos, yPos, zPos);
  }
  pannerData.textContent = `Panner data: X ${xPos} Y ${yPos} Z ${zPos}`;
}

注意: 在计算要应用于监听者和声像器的位置值,以使声音与屏幕上的视觉效果相匹配方面,涉及相当多的数学运算,但通过一些尝试和练习,您很快就会熟悉它。

规范

规范
Web Audio API
# dom-baseaudiocontext-createpanner

浏览器兼容性

另见