PannerNode: orientationX 屬性

Baseline 已廣泛支援

此特性已得到良好支援,可在多種裝置和瀏覽器版本上使用。自 2021 年 4 月起,所有瀏覽器均已支援此特性。

PannerNode 介面的 orientationX 屬性指示了在 3D 笛卡爾座標空間中,音訊源所面向方向的 X(水平)分量。

完整的向量由音訊源的位置(表示為(positionX, positionY, positionZ))和音訊源的朝向(即它所面向的方向,表示為(orientationX, orientationY, orientationZ))定義。

根據聲音的方向性(由 coneInnerAngleconeOuterAngleconeOuterGain 屬性指定),聲音的朝向可能會改變正在播放的聲音的感知音量。如果聲音指向聽者,則比聲音背離聽者時聲音更響。

此屬性包含的 AudioParam 是隻讀的;但是,您仍然可以透過為其 AudioParam.value 屬性賦值來更改引數的值。

一個 AudioParam,其 value 是音訊源所面向方向的 X 分量,在 3D 笛卡爾座標空間中。

示例

在此示例中,我們將演示如何將 PannerNode 的朝向引數與 coneInnerAngleconeOuterAngle 結合使用來影響音量。為了幫助我們視覺化朝向向量如何影響,我們可以使用 右手定則

This chart visualizes how the PannerNode orientation vectors affect the direction of the sound cone.

首先,我們編寫一個實用函式來計算我們的朝向向量。 X 和 Z 分量始終相互成 90° 角,因此我們可以使用正弦和餘弦函式,它們在弧度上以相同的量偏移。但是,正常情況下這將意味著 0° 旋轉時,PannerNode 指向聽者的左側——因為 x = cos(0) = 1z = sin(0) = 0。將角度偏移 -90° 更有用,這意味著 0° 旋轉時,PannerNode直接指向聽者

js
// this utility converts amount of rotation around the Y axis
// (i.e. rotation in the 'horizontal plane') to an orientation vector
const yRotationToVector = (degrees) => {
  // convert degrees to radians and offset the angle so 0 points towards the listener
  const radians = (degrees - 90) * (Math.PI / 180);
  // using cosine and sine here ensures the output values are always normalized
  // i.e. they range between -1 and 1
  const x = Math.cos(radians);
  const z = Math.sin(radians);

  // we hard-code the Y component to 0, as Y is the axis of rotation
  return [x, 0, z];
};

現在我們可以建立我們的 AudioContext、一個振盪器和一個 PannerNode

js
const context = new AudioContext();

const osc = new OscillatorNode(context);
osc.type = "sawtooth";

const panner = new PannerNode(context);
panner.panningModel = "HRTF";

接下來,我們設定空間化聲音的錐形,確定其可聽區域。

js
// this value determines the size of the area in which the sound volume is constant
// if coneInnerAngle === 30, it means that when the sound is rotated
// by at most 15 (30/2) degrees either direction, the volume won't change
panner.coneInnerAngle = 30;
// this value determines the size of the area in which the sound volume decreases gradually
// if coneOuterAngle === 45 and coneInnerAngle === 30, it means that when the sound is rotated
// by between 15 (30/2) and 22.5 (45/2) degrees either direction,
// the volume will decrease gradually
panner.coneOuterAngle = 45;
// this value determines the volume of the sound outside of both inner and outer cone
// setting it to 0 means there is no sound, so we can clearly hear when we leave the cone
// 0 is also the default
panner.coneOuterGain = 0;
// increase the Z position to ensure the cone has an effect
// (otherwise the sound is located at the same position as the listener)
panner.positionZ.setValueAtTime(1, context.currentTime);

設定好 PannerNode 後,我們現在可以安排一些對其 Y 軸旋轉的更新。

js
// calculate the vector for no rotation
// this means the sound will play at full volume
const [x1, y1, z1] = yRotationToVector(0);
// schedule the no-rotation vector immediately
panner.orientationX.setValueAtTime(x1, context.currentTime);
panner.orientationY.setValueAtTime(y1, context.currentTime);
panner.orientationZ.setValueAtTime(z1, context.currentTime);

// calculate the vector for -22.4 degrees
// since our coneOuterAngle is 45, this will just about make the sound audible
// if we set it to +/-22.5, the sound volume will be 0, as the threshold is exclusive
const [x2, y2, z2] = yRotationToVector(-22.4);
panner.orientationX.setValueAtTime(x2, context.currentTime + 2);
panner.orientationY.setValueAtTime(y2, context.currentTime + 2);
panner.orientationZ.setValueAtTime(z2, context.currentTime + 2);

最後,讓我們連線所有節點並啟動振盪器!

js
osc.connect(panner).connect(context.destination);

osc.start(0);

規範

規範
Web Audio API
# dom-pannernode-orientationx

瀏覽器相容性

另見