AudioListener - 表示音频场景中听众的位置和方向

AudioListener 接口表示聆听音频场景的唯一人员的位置和方向,并用于音频空间化。所有 PannerNode 相对于存储在 BaseAudioContext.listener 属性中的 AudioListener 进行空间化。

重要的是要注意,每个上下文只有一个听众,并且它不是 AudioNode

属性

positionforwardup 值使用不同的语法设置和检索。例如,检索是通过访问 AudioListener.positionX 来完成的,而设置相同的属性是通过 AudioListener.positionX.value 来完成的。这就是为什么这些值未标记为只读的原因,这就是它们在规范的 IDL 中出现的方式。

AudioListener.positionX

表示听众在右手笛卡尔坐标系中的水平位置。默认值为 0。

AudioListener.positionY

表示听众在右手笛卡尔坐标系中的垂直位置。默认值为 0。

AudioListener.positionZ

表示听众在右手笛卡尔坐标系中的纵向(来回)位置。默认值为 0。

AudioListener.forwardX

表示与位置(positionXpositionYpositionZ)值相同的笛卡尔坐标系中听众的前进方向的水平位置。前向和向上值彼此线性独立。默认值为 0。

AudioListener.forwardY

表示与位置(positionXpositionYpositionZ)值相同的笛卡尔坐标系中听众的前进方向的垂直位置。前向和向上值彼此线性独立。默认值为 0。

AudioListener.forwardZ

表示与位置(positionXpositionYpositionZ)值相同的笛卡尔坐标系中听众的前进方向的纵向(来回)位置。前向和向上值彼此线性独立。默认值为 -1。

AudioListener.upX

表示与位置(positionXpositionYpositionZ)值相同的笛卡尔坐标系中听众头部的顶部的水平位置。前向和向上值彼此线性独立。默认值为 0。

AudioListener.upY

表示与位置(positionXpositionYpositionZ)值相同的笛卡尔坐标系中听众头部的顶部的垂直位置。前向和向上值彼此线性独立。预设值为 1。

AudioListener.upZ

表示与位置(positionXpositionYpositionZ)值相同的笛卡尔坐标系中听众头部顶部的纵向(来回)位置。前向和向上值彼此线性独立。默认值为 0。

方法

AudioListener.setOrientation()

设置听众的方向。

AudioListener.setPosition()

设置听众的位置。

注意:尽管不建议使用这些方法,但它们是当前在 Firefox,Internet Explorer 和 Safari 中设置方向和位置的唯一方法。

不推荐使用的功能

AudioListener.dopplerFactor

一个双精度值,表示渲染多普勒效果时要使用的音高偏移量。

AudioListener.speedOfSound

一个双精度值,表示声音的速度,以米/秒为单位。

在规范的先前版本中,可以使用 dopplerFactorspeedOfSound 属性以及 setPosition() 方法来控制应用于连接到下游的 AudioBufferSourceNode 的多普勒效果 - 这些将会根据 PannerNodeAudioListener 的相对速度上下倾斜。这些功能有很多问题:

由于这些问题,这些属性和方法已被删除。

setOrientation()setPosition() 方法已通过设置其属性值等效项而被替换。例如,可以通过分别设置 positionX.valuepositionY.valuepositionZ.value 来实现 setPosition(x, y, z)

The setOrientation() and setPosition() methods have been replaced by setting their property value equivilents.

实例

在下面的实例中,您将看到如何使用 createPanner() 方法、AudioListenerPannerNode} 来控制音频空间化的示例。通常,您将在 3D 空间中定义音频监听器和声像器(源)最初占据的位置,然后在使用该应用程序时更新其中一个或两个的位置。例如,您可能要在游戏世界中移动角色,并希望随着您的角色靠近或远离音乐播放器(例如立体声音响)而使音频的传递发生实际变化。在实例中,您可以看到它是由 moveRight()moveLeft() 等函数控制的,它们通过 PositionPanner() 函数设置了全景位置的新值。

要查看完整的实现,请查看我们的 panner-node 实例查看源代码)— 该演示将您带到 2.5D “金属房”,您可以在动臂箱上播放曲目,然后在动臂箱周围走动以查看声音如何变化!

请注意,我们如何使用某些功能检测为浏览器提供较新的属性值(例如 AudioListener.forwardX)来设置位置(如果支持的话),或者使用较旧的方法(例如 AudioListener.setOrientation())(如果浏览器支持这些属性,但不支持新属性)。

// 设置监听器和声像器的位置信息
var WIDTH = window.innerWidth;
var HEIGHT = window.innerHeight;

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

// 定义其他变量

var AudioContext = window.AudioContext || window.webkitAudioContext;
var audioCtx = new AudioContext();

var 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);
}

var 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);
}

var source;

var play = document.querySelector('.play');
var stop = document.querySelector('.stop');

var boomBox = document.querySelector('.boom-box');

var listenerData = document.querySelector('.listener-data');
var pannerData = document.querySelector('.panner-data');

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

xIterator = WIDTH/150;

// 收听者将始终在此演示的同一位置

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.innerHTML = '收听者数据:X ' + xPos + ' Y ' + yPos + ' Z ' + 300;

// 当音箱在屏幕上移动时,声像将移动
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.innerHTML = '声像数据:X ' + xPos + ' Y ' + yPos + ' Z ' + zPos;
}

注意:在确定要应用于监听器和声像器的位置值,使声音适合屏幕上的视觉效果方面,需要进行大量的数学运算,但是通过一些实验,您很快就会习惯了。

规范

规范 状态 备注
Web Audio API
AudioListener 的定义
工作草案 -

桌面浏览器兼容性

特性ChromeEdgeFirefoxInternet ExplorerOperaSafari
基础支持14≤1825 不支持156
dopplerFactor14 — 5612 — 7925 — 63 不支持15 — 436
forwardX52≤18 不支持1 不支持39 不支持
forwardY52≤18 不支持1 不支持39 不支持
forwardZ52≤18 不支持1 不支持39 不支持
positionX52≤18 不支持1 不支持39 不支持
positionY52≤18 不支持1 不支持39 不支持
positionZ52≤18 不支持1 不支持39 不支持
setOrientation141825 不支持156
setPosition141225 不支持156
speedOfSound14 — 5612 — 7925 — 63 不支持15 — 436
upX52≤18 不支持1 不支持39 不支持
upY52≤18 不支持1 不支持39 不支持
upZ52≤18 不支持1 不支持39 不支持

移动浏览器兼容性

特性AndroidChrome for AndroidEdge mobileFirefox for AndroidIE mobileOpera AndroidiOS Safari
基础支持 支持18 未知26 未知14 支持
dopplerFactor 支持 — 5618 — 56 未知26 — 63 未知14 — 43 未知
forwardX5252 未知 不支持1 未知41 未知
forwardY5252 未知 不支持1 未知41 未知
forwardZ5252 未知 不支持1 未知41 未知
positionX5252 未知 不支持1 未知41 未知
positionY5252 未知 不支持1 未知41 未知
positionZ5252 未知 不支持1 未知41 未知
setOrientation 支持18 未知26 未知14 支持
setPosition 支持18 未知26 未知14 支持
speedOfSound 支持 — 5618 — 56 未知26 — 63 未知14 — 43 未知
upX5252 未知 不支持1 未知41 未知
upY5252 未知 不支持1 未知41 未知
upZ5252 未知 不支持1 未知41 未知

1. 支持废弃的设置方向的方法 - setOrientation() 方法。