mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 808876 - Implement PannerNode; r=bzbarsky
This commit is contained in:
parent
11df4b5740
commit
45ebdb31e5
@ -14,6 +14,7 @@
|
||||
#include "AudioBuffer.h"
|
||||
#include "GainNode.h"
|
||||
#include "DelayNode.h"
|
||||
#include "PannerNode.h"
|
||||
#include "AudioListener.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -107,6 +108,13 @@ AudioContext::CreateDelay(float aMaxDelayTime)
|
||||
return delayNode.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<PannerNode>
|
||||
AudioContext::CreatePanner()
|
||||
{
|
||||
nsRefPtr<PannerNode> pannerNode = new PannerNode(this);
|
||||
return pannerNode.forget();
|
||||
}
|
||||
|
||||
AudioListener*
|
||||
AudioContext::Listener()
|
||||
{
|
||||
|
@ -29,6 +29,7 @@ class AudioDestinationNode;
|
||||
class AudioListener;
|
||||
class DelayNode;
|
||||
class GainNode;
|
||||
class PannerNode;
|
||||
|
||||
class AudioContext MOZ_FINAL : public nsWrapperCache,
|
||||
public EnableWebAudioCheck
|
||||
@ -72,6 +73,9 @@ public:
|
||||
already_AddRefed<DelayNode>
|
||||
CreateDelay(float aMaxDelayTime);
|
||||
|
||||
already_AddRefed<PannerNode>
|
||||
CreatePanner();
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIDOMWindow> mWindow;
|
||||
nsRefPtr<AudioDestinationNode> mDestination;
|
||||
|
@ -26,6 +26,7 @@ CPPSRCS := \
|
||||
DelayNode.cpp \
|
||||
EnableWebAudioCheck.cpp \
|
||||
GainNode.cpp \
|
||||
PannerNode.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS_NAMESPACES := mozilla/dom
|
||||
@ -39,6 +40,7 @@ EXPORTS_mozilla/dom := \
|
||||
AudioSourceNode.h \
|
||||
DelayNode.h \
|
||||
GainNode.h \
|
||||
PannerNode.h \
|
||||
$(NULL)
|
||||
|
||||
PARALLEL_DIRS := test
|
||||
|
56
content/media/webaudio/PannerNode.cpp
Normal file
56
content/media/webaudio/PannerNode.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "PannerNode.h"
|
||||
#include "mozilla/dom/PannerNodeBinding.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(PannerNode)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PannerNode, AudioNode)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mConeGain)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDistanceGain)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PannerNode, AudioNode)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mConeGain, AudioParam, "cone gain value")
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mDistanceGain, AudioParam, "distance gain value")
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(PannerNode)
|
||||
NS_INTERFACE_MAP_END_INHERITING(AudioNode)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(PannerNode, AudioNode)
|
||||
NS_IMPL_RELEASE_INHERITED(PannerNode, AudioNode)
|
||||
|
||||
PannerNode::PannerNode(AudioContext* aContext)
|
||||
: AudioNode(aContext)
|
||||
, mPanningModel(PanningModelEnum::HRTF)
|
||||
, mDistanceModel(DistanceModelEnum::INVERSE_DISTANCE)
|
||||
, mPosition()
|
||||
, mOrientation(1.f, 0.f, 0.f)
|
||||
, mVelocity()
|
||||
, mRefDistance(1.f)
|
||||
, mMaxDistance(10000.f)
|
||||
, mRolloffFactor(1.f)
|
||||
, mConeInnerAngle(360.f)
|
||||
, mConeOuterAngle(360.f)
|
||||
, mConeOuterGain(0.f)
|
||||
, mConeGain(new AudioParam(aContext, 1.f, 0.f, 1.f))
|
||||
, mDistanceGain(new AudioParam(aContext, 1.f, 0.f, 1.f))
|
||||
{
|
||||
}
|
||||
|
||||
JSObject*
|
||||
PannerNode::WrapObject(JSContext* aCx, JSObject* aScope,
|
||||
bool* aTriedToWrap)
|
||||
{
|
||||
return PannerNodeBinding::Wrap(aCx, aScope, this, aTriedToWrap);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
189
content/media/webaudio/PannerNode.h
Normal file
189
content/media/webaudio/PannerNode.h
Normal file
@ -0,0 +1,189 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef PannerNode_h_
|
||||
#define PannerNode_h_
|
||||
|
||||
#include "AudioNode.h"
|
||||
#include "AudioParam.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "ThreeDPoint.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class AudioContext;
|
||||
|
||||
MOZ_BEGIN_ENUM_CLASS(PanningModelEnum, uint16_t)
|
||||
EQUALPOWER = 0,
|
||||
HRTF = 1,
|
||||
SOUNDFIELD = 2,
|
||||
Max = 2
|
||||
MOZ_END_ENUM_CLASS(PanningModelEnum)
|
||||
MOZ_BEGIN_ENUM_CLASS(DistanceModelEnum, uint16_t)
|
||||
LINEAR_DISTANCE = 0,
|
||||
INVERSE_DISTANCE = 1,
|
||||
EXPONENTIAL_DISTANCE = 2,
|
||||
Max = 2
|
||||
MOZ_END_ENUM_CLASS(DistanceModelEnum)
|
||||
|
||||
class PannerNode : public AudioNode
|
||||
{
|
||||
public:
|
||||
explicit PannerNode(AudioContext* aContext);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PannerNode, AudioNode)
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope,
|
||||
bool* aTriedToWrap);
|
||||
|
||||
virtual uint32_t MaxNumberOfInputs() const MOZ_FINAL MOZ_OVERRIDE
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
virtual uint32_t MaxNumberOfOutputs() const MOZ_FINAL MOZ_OVERRIDE
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint16_t PanningModel() const
|
||||
{
|
||||
return static_cast<uint16_t> (mPanningModel);
|
||||
}
|
||||
void SetPanningModel(uint16_t aPanningModel, ErrorResult& aRv)
|
||||
{
|
||||
PanningModelEnum panningModel =
|
||||
static_cast<PanningModelEnum> (aPanningModel);
|
||||
if (panningModel > PanningModelEnum::Max) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||
} else {
|
||||
mPanningModel = panningModel;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t DistanceModel() const
|
||||
{
|
||||
return static_cast<uint16_t> (mDistanceModel);
|
||||
}
|
||||
void SetDistanceModel(uint16_t aDistanceModel, ErrorResult& aRv)
|
||||
{
|
||||
DistanceModelEnum distanceModel =
|
||||
static_cast<DistanceModelEnum> (aDistanceModel);
|
||||
if (distanceModel > DistanceModelEnum::Max) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||
} else {
|
||||
mDistanceModel = distanceModel;
|
||||
}
|
||||
}
|
||||
|
||||
void SetPosition(float aX, float aY, float aZ)
|
||||
{
|
||||
mPosition.x = aX;
|
||||
mPosition.y = aY;
|
||||
mPosition.z = aZ;
|
||||
}
|
||||
|
||||
void SetOrientation(float aX, float aY, float aZ)
|
||||
{
|
||||
mOrientation.x = aX;
|
||||
mOrientation.y = aY;
|
||||
mOrientation.z = aZ;
|
||||
}
|
||||
|
||||
void SetVelocity(float aX, float aY, float aZ)
|
||||
{
|
||||
mVelocity.x = aX;
|
||||
mVelocity.y = aY;
|
||||
mVelocity.z = aZ;
|
||||
}
|
||||
|
||||
float RefDistance() const
|
||||
{
|
||||
return mRefDistance;
|
||||
}
|
||||
void SetRefDistance(float aRefDistance)
|
||||
{
|
||||
mRefDistance = aRefDistance;
|
||||
}
|
||||
|
||||
float MaxDistance() const
|
||||
{
|
||||
return mMaxDistance;
|
||||
}
|
||||
void SetMaxDistance(float aMaxDistance)
|
||||
{
|
||||
mMaxDistance = aMaxDistance;
|
||||
}
|
||||
|
||||
float RolloffFactor() const
|
||||
{
|
||||
return mRolloffFactor;
|
||||
}
|
||||
void SetRolloffFactor(float aRolloffFactor)
|
||||
{
|
||||
mRolloffFactor = aRolloffFactor;
|
||||
}
|
||||
|
||||
float ConeInnerAngle() const
|
||||
{
|
||||
return mConeInnerAngle;
|
||||
}
|
||||
void SetConeInnerAngle(float aConeInnerAngle)
|
||||
{
|
||||
mConeInnerAngle = aConeInnerAngle;
|
||||
}
|
||||
|
||||
float ConeOuterAngle() const
|
||||
{
|
||||
return mConeOuterAngle;
|
||||
}
|
||||
void SetConeOuterAngle(float aConeOuterAngle)
|
||||
{
|
||||
mConeOuterAngle = aConeOuterAngle;
|
||||
}
|
||||
|
||||
float ConeOuterGain() const
|
||||
{
|
||||
return mConeOuterGain;
|
||||
}
|
||||
void SetConeOuterGain(float aConeOuterGain)
|
||||
{
|
||||
mConeOuterGain = aConeOuterGain;
|
||||
}
|
||||
|
||||
AudioParam* ConeGain() const
|
||||
{
|
||||
return mConeGain;
|
||||
}
|
||||
|
||||
AudioParam* DistanceGain() const
|
||||
{
|
||||
return mDistanceGain;
|
||||
}
|
||||
|
||||
private:
|
||||
PanningModelEnum mPanningModel;
|
||||
DistanceModelEnum mDistanceModel;
|
||||
ThreeDPoint mPosition;
|
||||
ThreeDPoint mOrientation;
|
||||
ThreeDPoint mVelocity;
|
||||
float mRefDistance;
|
||||
float mMaxDistance;
|
||||
float mRolloffFactor;
|
||||
float mConeInnerAngle;
|
||||
float mConeOuterAngle;
|
||||
float mConeOuterGain;
|
||||
nsRefPtr<AudioParam> mConeGain;
|
||||
nsRefPtr<AudioParam> mDistanceGain;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -18,6 +18,7 @@ MOCHITEST_FILES := \
|
||||
test_badConnect.html \
|
||||
test_delayNode.html \
|
||||
test_gainNode.html \
|
||||
test_pannerNode.html \
|
||||
test_singleSourceDest.html \
|
||||
$(NULL)
|
||||
|
||||
|
68
content/media/webaudio/test/test_pannerNode.html
Normal file
68
content/media/webaudio/test/test_pannerNode.html
Normal file
@ -0,0 +1,68 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test PannerNode</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
function near(a, b, msg) {
|
||||
ok(Math.abs(a - b) < 1e-4, msg);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(function() {
|
||||
SpecialPowers.setBoolPref("media.webaudio.enabled", true);
|
||||
|
||||
var context = new mozAudioContext();
|
||||
var buffer = context.createBuffer(1, 2048, 44100);
|
||||
for (var i = 0; i < 2048; ++i) {
|
||||
buffer.getChannelData(0)[i] = Math.sin(440 * 2 * Math.PI * i / 44100);
|
||||
}
|
||||
|
||||
var destination = context.destination;
|
||||
|
||||
var source = context.createBufferSource();
|
||||
|
||||
var panner = context.createPanner();
|
||||
|
||||
source.buffer = buffer;
|
||||
|
||||
source.connect(panner);
|
||||
panner.connect(destination);
|
||||
|
||||
// Verify default values
|
||||
is(panner.panningModel, 1, "Correct default value for panning model");
|
||||
is(panner.distanceModel, 1, "Correct default value for distance model");
|
||||
near(panner.refDistance, 1, "Correct default value for ref distance");
|
||||
near(panner.maxDistance, 10000, "Correct default value for max distance");
|
||||
near(panner.rolloffFactor, 1, "Correct default value for rolloff factor");
|
||||
near(panner.coneInnerAngle, 360, "Correct default value for cone inner angle");
|
||||
near(panner.coneOuterAngle, 360, "Correct default value for cone outer angle");
|
||||
near(panner.coneOuterGain, 0, "Correct default value for cone outer gain");
|
||||
|
||||
ok("coneGain" in panner, "panner.coneGain exists");
|
||||
ok("distanceGain in panner, "panner.distanceGain exists");
|
||||
|
||||
panner.setPosition(1, 1, 1);
|
||||
panner.setOrientation(1, 1, 1);
|
||||
panner.setVelocity(1, 1, 1);
|
||||
|
||||
source.start(0);
|
||||
SimpleTest.executeSoon(function() {
|
||||
source.stop(0);
|
||||
source.disconnect();
|
||||
panner.disconnect();
|
||||
|
||||
SpecialPowers.clearUserPref("media.webaudio.enabled");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -292,6 +292,11 @@ DOMInterfaces = {
|
||||
'resultNotAddRefed': [ 'item' ]
|
||||
},
|
||||
|
||||
'PannerNode': [
|
||||
{
|
||||
'resultNotAddRefed': [ 'coneGain', 'distanceGain' ],
|
||||
}],
|
||||
|
||||
'Performance': {
|
||||
'nativeType': 'nsPerformance',
|
||||
'resultNotAddRefed': [ 'timing', 'navigation' ]
|
||||
|
@ -30,6 +30,8 @@ interface mozAudioContext {
|
||||
GainNode createGain();
|
||||
[Creator]
|
||||
DelayNode createDelay(optional float maxDelayTime = 1);
|
||||
[Creator]
|
||||
PannerNode createPanner();
|
||||
|
||||
};
|
||||
|
||||
|
52
dom/webidl/PannerNode.webidl
Normal file
52
dom/webidl/PannerNode.webidl
Normal file
@ -0,0 +1,52 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
|
||||
*
|
||||
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[PrefControlled]
|
||||
interface PannerNode : AudioNode {
|
||||
|
||||
// Panning model
|
||||
const unsigned short EQUALPOWER = 0;
|
||||
const unsigned short HRTF = 1;
|
||||
const unsigned short SOUNDFIELD = 2;
|
||||
|
||||
// Distance model
|
||||
const unsigned short LINEAR_DISTANCE = 0;
|
||||
const unsigned short INVERSE_DISTANCE = 1;
|
||||
const unsigned short EXPONENTIAL_DISTANCE = 2;
|
||||
|
||||
// Default for stereo is HRTF
|
||||
[SetterThrows]
|
||||
attribute unsigned short panningModel;
|
||||
|
||||
// Uses a 3D cartesian coordinate system
|
||||
void setPosition(float x, float y, float z);
|
||||
void setOrientation(float x, float y, float z);
|
||||
void setVelocity(float x, float y, float z);
|
||||
|
||||
// Distance model and attributes
|
||||
[SetterThrows]
|
||||
attribute unsigned short distanceModel;
|
||||
attribute float refDistance;
|
||||
attribute float maxDistance;
|
||||
attribute float rolloffFactor;
|
||||
|
||||
// Directional sound cone
|
||||
attribute float coneInnerAngle;
|
||||
attribute float coneOuterAngle;
|
||||
attribute float coneOuterGain;
|
||||
|
||||
// Dynamically calculated gain values
|
||||
readonly attribute AudioParam coneGain;
|
||||
readonly attribute AudioParam distanceGain;
|
||||
|
||||
};
|
||||
|
@ -39,6 +39,7 @@ webidl_files = \
|
||||
ImageData.webidl \
|
||||
NodeList.webidl \
|
||||
PaintRequestList.webidl \
|
||||
PannerNode.webidl \
|
||||
Performance.webidl \
|
||||
PerformanceNavigation.webidl \
|
||||
PerformanceTiming.webidl \
|
||||
|
Loading…
Reference in New Issue
Block a user