PannerNode

PannerNode は音源の空間上の位置と振る舞いを表現したインターフェイスで、AudioNode の一種です。右手直交座標系に従って位置を表し、音源の動きは速度ベクトルと、向きを表すサウンドコーンを利用して表現します。

PannerNode は必ず 1 つの入力と、1 つの出力を持ちます。入力はモノラルでもステレオでも構いませんが、出力は必ずステレオとなります。つまりパンニングを行うには最低でも 2 チャンネルの音声チャンネルを必要です。

The PannerNode brings a spatial position and velocity and a directionality for a given signal.

入力数 1
出力数 1
チャンネルの数え方 "clamped-max"
チャンネル数 2
チャンネルの意味 "speakers"

コンストラクター

PannerNode.PannerNode
新しい PannerNode オブジェクトを作成します。

属性

親クラスである AudioNode の属性を継承しています。

向きと位置の設定と取得は異なる方法で行います。これは、これらの値が AudioParam として保存されてるためです。値の取得は  PannerNode.positionX のように行えますが、同じ属性に対して値を設定するには PannerNode.positionX.value のように行います。そのため、これらの値は、WebIDL にあるように、読み取り専用とは定義されていません。

PannerNode.coneInnerAngle
音量が低減しない範囲を内側にもつコーンの角度が、実数値 (倍精度) で参照できます。
PannerNode.coneOuterAngle
音量が一定値まで低減される範囲を外側に持つコーンの角度が、実数値 (倍精度) で参照できます。低減は  coneOuterGain 属性の値に従います。
PannerNode.coneOuterGain
coneOuterAngle の外で行われる音量の低減量を定義します。標準値は 0 で、これは音が聞こえなくなることを表します。
PannerNode.distanceModel
音量の低減計算に用いるアルゴリズムを定めます。アルゴリズムは定められたものの中から選択します。とりうる値は "linear""inverse""exponential"で、デフォルト値は "inverse"です。
PannerNode.maxDistance
音源と聴取者の最大距離を定義します。これを超えた場合、音量の低減計算がなされません。
PannerNode.orientationX
右手直交座標系における音源の向きを表すベクトルのうち、水平方向の値です。AudioParam は直接変更できないため、値の変更はvalue 属性を通して行います。初期値は 1 となっています。
PannerNode.orientationY
右手直交座標系における音源の向きを表すベクトルのうち、垂直方向の値です。AudioParam は直接変更できないため、値の変更はvalue 属性を通して行います。初期値は 0 となっています。
PannerNode.orientationZ
右手直交座標系における音源の向きを表すベクトルのうち、奥行き(前後)方向の値ですAudioParam は直接変更できないため、値の変更はvalue 属性を通して行います。初期値は 0 となっています。
PannerNode.panningModel

立体音響計算を行うアルゴリズムを定めます。アルゴリズムは定められたものの中から選びます。

PannerNode.positionX
右手直交座標系における音源の位置を表すベクトルのうち、水平方向の値ですAudioParam は直接変更できないため、値の変更はvalue 属性を通して行います。初期値は 0 となっています。
PannerNode.positionY
右手直交座標系における音源の位置を表すベクトルのうち、垂直方向の値ですAudioParam は直接変更できないため、値の変更はvalue 属性を通して行います。初期値は 0 となっています。
PannerNode.positionZ
右手直交座標系における音源の位置を表すベクトルのうち、奥行き(前後)方向の値ですAudioParam は直接変更できないため、値の変更はvalue 属性を通して行います。初期値は 0 となっています。
PannerNode.refDistance
音量の低減計算に用いる基準距離を表します。音源と聴取者との距離がこれを超えた場合、rolloffFactordistanceModel に基づいて音量の低減が起きます。
PannerNode.rolloffFactor
音源が聴取者から離れていく際に起きる音量の低減量を定めます。この値は、全ての距離モデルで利用されます。

メソッド

親クラスである AudioNode のメソッドを継承しています。

PannerNode.setPosition()
聴取者に対する音源の相対位置を設定します。聴取者の位置は AudioContext.listener  で参照されるAudioListener オブジェクトで表されています。
PannerNode.setOrientation()
音源が再生されている方向を設定します。
PannerNode.setVelocity()
音源の速度を表したベクトルです。移動する速さと方向を表しています。以前の仕様では下流に接続されたAudioBufferSourceNode のピッチを上げ下げするために、PannerNode は速度を表す属性を持っていました。この機能は明瞭に定義されておらず、問題も多かったため、現在の仕様からは削除されています。

In the following example, you can see an example of how the createPanner() method, AudioListener  and PannerNode would be used to control audio spatialisation. Generally you will define the position in 3D space that your audio listener and panner (source) occupy initially, and then update the position of one or both of these as the application is used. You might be moving a character around inside a game world for example, and wanting delivery of audio to change realistically as your character moves closer to or further away from a music player such as a stereo. In the example you can see this being controlled by the functions moveRight(), moveLeft(), etc., which set new values for the panner position via the PositionPanner() function.

To see a complete implementation, check out our panner-node example (view the source code) — this demo transports you to the 2.5D "Room of metal", where you can play a track on a boom box and then walk around the boom box to see how the sound changes!

Note how we have used some feature detection to either give the browser the newer property values (like AudioListener.forwardX) for setting position, etc. if it supports those, or older methods (like AudioListener.setOrientation()) if it still supports those but not the new properties.

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

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

// define other variables

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;

// 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.innerHTML = '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.innerHTML = 'Panner data: X ' + xPos + ' Y ' + yPos + ' Z ' + zPos;
}

Note: In terms of working out what position values to apply to the listener and panner, to make the sound appropriate to what the visuals are doing on screen, there is quite a bit of math involved, but you will soon get used to it with a bit of experimentation.

仕様

仕様 状況 コメント
Web Audio API
PannerNode の定義
草案

ブラウザー実装状況

Update compatibility data on GitHub
デスクトップモバイル
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeAndroid 版 FirefoxAndroid 版 OperaiOSのSafariSamsung Internet
PannerNodeChrome 完全対応 14Edge 完全対応 ≤18Firefox 完全対応 25IE 未対応 なしOpera 完全対応 15Safari 完全対応 6WebView Android 完全対応 ありChrome Android 完全対応 18Firefox Android 完全対応 26Opera Android 完全対応 14Safari iOS ? Samsung Internet Android 完全対応 1.0
PannerNode() constructorChrome 完全対応 55
補足
完全対応 55
補足
補足 Before Chrome 59, the default values were not supported.
Edge 完全対応 ≤79Firefox 完全対応 53IE 未対応 なしOpera 完全対応 42Safari ? WebView Android 完全対応 55
補足
完全対応 55
補足
補足 Before version 59, the default values were not supported.
Chrome Android 完全対応 55
補足
完全対応 55
補足
補足 Before Chrome 59, the default values were not supported.
Firefox Android 完全対応 53Opera Android 完全対応 42Safari iOS ? Samsung Internet Android 完全対応 6.0
補足
完全対応 6.0
補足
補足 Before Samsung Internet 7.0, the default values were not supported.
coneInnerAngleChrome 完全対応 14Edge 完全対応 12Firefox 完全対応 25IE 未対応 なしOpera 完全対応 15Safari 完全対応 6WebView Android 完全対応 ありChrome Android 完全対応 18Firefox Android 完全対応 26Opera Android 完全対応 14Safari iOS ? Samsung Internet Android 完全対応 1.0
coneOuterAngleChrome 完全対応 14Edge 完全対応 12Firefox 完全対応 25IE 未対応 なしOpera 完全対応 15Safari 完全対応 6WebView Android 完全対応 ありChrome Android 完全対応 18Firefox Android 完全対応 26Opera Android 完全対応 14Safari iOS ? Samsung Internet Android 完全対応 1.0
coneOuterGainChrome 完全対応 14Edge 完全対応 12Firefox 完全対応 25IE 未対応 なしOpera 完全対応 15Safari 完全対応 6WebView Android 完全対応 ありChrome Android 完全対応 18Firefox Android 完全対応 26Opera Android 完全対応 14Safari iOS ? Samsung Internet Android 完全対応 1.0
distanceModelChrome 完全対応 14Edge 完全対応 12Firefox 完全対応 25IE 未対応 なしOpera 完全対応 15Safari 完全対応 6WebView Android 完全対応 ありChrome Android 完全対応 18Firefox Android 完全対応 26Opera Android 完全対応 14Safari iOS ? Samsung Internet Android 完全対応 1.0
maxDistanceChrome 完全対応 14Edge 完全対応 12Firefox 完全対応 25IE 未対応 なしOpera 完全対応 15Safari 完全対応 6WebView Android 完全対応 ありChrome Android 完全対応 18Firefox Android 完全対応 26Opera Android 完全対応 14Safari iOS ? Samsung Internet Android 完全対応 1.0
orientationXChrome 完全対応 ありEdge 完全対応 ≤18Firefox 完全対応 50IE 未対応 なしOpera 完全対応 ありSafari 未対応 なしWebView Android 完全対応 ありChrome Android 完全対応 ありFirefox Android 完全対応 50Opera Android 完全対応 ありSafari iOS 未対応 なしSamsung Internet Android 完全対応 あり
orientationYChrome 完全対応 ありEdge 完全対応 ≤18Firefox 完全対応 50IE 未対応 なしOpera 完全対応 ありSafari 未対応 なしWebView Android 完全対応 ありChrome Android 完全対応 ありFirefox Android 完全対応 50Opera Android 完全対応 ありSafari iOS 未対応 なしSamsung Internet Android 完全対応 あり
orientationZChrome 完全対応 ありEdge 完全対応 ≤18Firefox 完全対応 50IE 未対応 なしOpera 完全対応 ありSafari 未対応 なしWebView Android 完全対応 ありChrome Android 完全対応 ありFirefox Android 完全対応 50Opera Android 完全対応 ありSafari iOS 未対応 なしSamsung Internet Android 完全対応 あり
panningModelChrome 完全対応 14Edge 完全対応 12Firefox 完全対応 25IE 未対応 なしOpera 完全対応 15Safari 完全対応 6WebView Android 完全対応 ありChrome Android 完全対応 18Firefox Android 完全対応 26Opera Android 完全対応 14Safari iOS ? Samsung Internet Android 完全対応 1.0
positionXChrome 完全対応 ありEdge 完全対応 ≤18Firefox 完全対応 50IE 未対応 なしOpera 完全対応 ありSafari 未対応 なしWebView Android 完全対応 ありChrome Android 完全対応 ありFirefox Android 完全対応 50Opera Android 完全対応 ありSafari iOS 未対応 なしSamsung Internet Android 完全対応 あり
positionYChrome 完全対応 ありEdge 完全対応 ≤18Firefox 完全対応 50IE 未対応 なしOpera 完全対応 ありSafari 未対応 なしWebView Android 完全対応 ありChrome Android 完全対応 ありFirefox Android 完全対応 50Opera Android 完全対応 ありSafari iOS 未対応 なしSamsung Internet Android 完全対応 あり
positionZChrome 完全対応 ありEdge 完全対応 ≤18Firefox 完全対応 50IE 未対応 なしOpera 完全対応 ありSafari 未対応 なしWebView Android 完全対応 ありChrome Android 完全対応 ありFirefox Android 完全対応 50Opera Android 完全対応 ありSafari iOS 未対応 なしSamsung Internet Android 完全対応 あり
refDistanceChrome 完全対応 14Edge 完全対応 12Firefox 完全対応 25IE 未対応 なしOpera 完全対応 15Safari 完全対応 6WebView Android 完全対応 ありChrome Android 完全対応 18Firefox Android 完全対応 26Opera Android 完全対応 14Safari iOS ? Samsung Internet Android 完全対応 1.0
rolloffFactorChrome 完全対応 14Edge 完全対応 12Firefox 完全対応 25IE 未対応 なしOpera 完全対応 15Safari 完全対応 6WebView Android 完全対応 ありChrome Android 完全対応 18Firefox Android 完全対応 26Opera Android 完全対応 14Safari iOS ? Samsung Internet Android 完全対応 1.0
setOrientationChrome 完全対応 14Edge 完全対応 12Firefox 完全対応 25IE 未対応 なしOpera 完全対応 15Safari 完全対応 6WebView Android 完全対応 ありChrome Android 完全対応 18Firefox Android 完全対応 26Opera Android 完全対応 14Safari iOS ? Samsung Internet Android 完全対応 1.0
setPositionChrome 完全対応 14Edge 完全対応 12Firefox 完全対応 25IE 未対応 なしOpera 完全対応 15Safari 完全対応 6WebView Android 完全対応 ありChrome Android 完全対応 18Firefox Android 完全対応 26Opera Android 完全対応 14Safari iOS ? Samsung Internet Android 完全対応 1.0
setVelocity
非推奨
Chrome 未対応 14 — 56Edge 未対応 12 — 79Firefox 未対応 25 — 63IE 未対応 なしOpera 未対応 15 — 43Safari 完全対応 6WebView Android 未対応 ? — 56Chrome Android 未対応 18 — 56Firefox Android 未対応 26 — 63Opera Android 未対応 14 — 43Safari iOS ? Samsung Internet Android 未対応 1.0 — 6.0

凡例

完全対応  
完全対応
未対応  
未対応
実装状況不明  
実装状況不明
非推奨。新しいウェブサイトでは使用しないでください。
非推奨。新しいウェブサイトでは使用しないでください。
実装ノートを参照してください。
実装ノートを参照してください。

関連情報