Bug 849916 - Part 3: Create an engine for PannerNodes and make sure that we deliver the panner and listener parameters to it; r=padenot

This commit is contained in:
Ehsan Akhgari 2013-03-12 14:34:55 -04:00
parent 7a26abd817
commit ffee05887e
4 changed files with 195 additions and 0 deletions

View File

@ -37,6 +37,36 @@ AudioListener::WrapObject(JSContext* aCx, JSObject* aScope)
return AudioListenerBinding::Wrap(aCx, aScope, this);
}
void
AudioListener::RegisterPannerNode(PannerNode* aPannerNode)
{
mPanners.AppendElement(aPannerNode);
// Let the panner node know about our parameters
aPannerNode->SendThreeDPointParameterToStream(PannerNode::LISTENER_POSITION, mPosition);
aPannerNode->SendThreeDPointParameterToStream(PannerNode::LISTENER_ORIENTATION, mOrientation);
aPannerNode->SendThreeDPointParameterToStream(PannerNode::LISTENER_UPVECTOR, mUpVector);
aPannerNode->SendThreeDPointParameterToStream(PannerNode::LISTENER_VELOCITY, mVelocity);
aPannerNode->SendDoubleParameterToStream(PannerNode::LISTENER_DOPPLER_FACTOR, mDopplerFactor);
aPannerNode->SendDoubleParameterToStream(PannerNode::LISTENER_SPEED_OF_SOUND, mSpeedOfSound);
}
void
AudioListener::SendDoubleParameterToStream(uint32_t aIndex, double aValue)
{
for (uint32_t i = 0; i < mPanners.Length(); ++i) {
mPanners[i]->SendDoubleParameterToStream(aIndex, aValue);
}
}
void
AudioListener::SendThreeDPointParameterToStream(uint32_t aIndex, const ThreeDPoint& aValue)
{
for (uint32_t i = 0; i < mPanners.Length(); ++i) {
mPanners[i]->SendThreeDPointParameterToStream(aIndex, aValue);
}
}
}
}

View File

@ -14,6 +14,7 @@
#include "nsAutoPtr.h"
#include "ThreeDPoint.h"
#include "AudioContext.h"
#include "PannerNode.h"
struct JSContext;
@ -46,6 +47,7 @@ public:
void SetDopplerFactor(double aDopplerFactor)
{
mDopplerFactor = aDopplerFactor;
SendDoubleParameterToStream(PannerNode::LISTENER_DOPPLER_FACTOR, mDopplerFactor);
}
double SpeedOfSound() const
@ -55,6 +57,7 @@ public:
void SetSpeedOfSound(double aSpeedOfSound)
{
mSpeedOfSound = aSpeedOfSound;
SendDoubleParameterToStream(PannerNode::LISTENER_SPEED_OF_SOUND, mSpeedOfSound);
}
void SetPosition(double aX, double aY, double aZ)
@ -62,6 +65,7 @@ public:
mPosition.x = aX;
mPosition.y = aY;
mPosition.z = aZ;
SendThreeDPointParameterToStream(PannerNode::LISTENER_POSITION, mPosition);
}
void SetOrientation(double aX, double aY, double aZ,
@ -73,6 +77,8 @@ public:
mUpVector.x = aXUp;
mUpVector.y = aYUp;
mUpVector.z = aZUp;
SendThreeDPointParameterToStream(PannerNode::LISTENER_ORIENTATION, mOrientation);
SendThreeDPointParameterToStream(PannerNode::LISTENER_UPVECTOR, mUpVector);
}
void SetVelocity(double aX, double aY, double aZ)
@ -80,8 +86,19 @@ public:
mVelocity.x = aX;
mVelocity.y = aY;
mVelocity.z = aZ;
SendThreeDPointParameterToStream(PannerNode::LISTENER_VELOCITY, mVelocity);
}
void RegisterPannerNode(PannerNode* aPannerNode);
void UnregisterPannerNode(PannerNode* aPannerNode)
{
mPanners.RemoveElement(aPannerNode);
}
private:
void SendDoubleParameterToStream(uint32_t aIndex, double aValue);
void SendThreeDPointParameterToStream(uint32_t aIndex, const ThreeDPoint& aValue);
private:
nsRefPtr<AudioContext> mContext;
ThreeDPoint mPosition;
@ -90,6 +107,7 @@ private:
ThreeDPoint mVelocity;
double mDopplerFactor;
double mSpeedOfSound;
nsTArray<PannerNode*> mPanners;
};
}

View File

@ -5,12 +5,110 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "PannerNode.h"
#include "AudioNodeEngine.h"
#include "AudioNodeStream.h"
#include "AudioListener.h"
namespace mozilla {
namespace dom {
class PannerNodeEngine : public AudioNodeEngine
{
public:
PannerNodeEngine()
// Please keep these default values consistent with PannerNode::PannerNode below.
: mPanningModel(PanningModelTypeValues::HRTF)
, mDistanceModel(DistanceModelTypeValues::Inverse)
, mPosition()
, mOrientation(1., 0., 0.)
, mVelocity()
, mRefDistance(1.)
, mMaxDistance(10000.)
, mRolloffFactor(1.)
, mConeInnerAngle(360.)
, mConeOuterAngle(360.)
, mConeOuterGain(0.)
// These will be initialized when a PannerNode is created, so just initialize them
// to some dummy values here.
, mListenerDopplerFactor(0.)
, mListenerSpeedOfSound(0.)
{
}
virtual void SetInt32Parameter(uint32_t aIndex, int32_t aParam) MOZ_OVERRIDE
{
switch (aIndex) {
case PannerNode::PANNING_MODEL:
mPanningModel = PanningModelType(aParam);
break;
case PannerNode::DISTANCE_MODEL:
mDistanceModel = DistanceModelType(aParam);
break;
default:
NS_ERROR("Bad PannerNodeEngine Int32Parameter");
}
}
virtual void SetThreeDPointParameter(uint32_t aIndex, const ThreeDPoint& aParam) MOZ_OVERRIDE
{
switch (aIndex) {
case PannerNode::LISTENER_POSITION: mListenerPosition = aParam; break;
case PannerNode::LISTENER_ORIENTATION: mListenerOrientation = aParam; break;
case PannerNode::LISTENER_UPVECTOR: mListenerUpVector = aParam; break;
case PannerNode::LISTENER_VELOCITY: mListenerVelocity = aParam; break;
case PannerNode::POSITION: mPosition = aParam; break;
case PannerNode::ORIENTATION: mOrientation = aParam; break;
case PannerNode::VELOCITY: mVelocity = aParam; break;
default:
NS_ERROR("Bad PannerNodeEngine ThreeDPointParameter");
}
}
virtual void SetDoubleParameter(uint32_t aIndex, double aParam) MOZ_OVERRIDE
{
switch (aIndex) {
case PannerNode::LISTENER_DOPPLER_FACTOR: mListenerDopplerFactor = aParam; break;
case PannerNode::LISTENER_SPEED_OF_SOUND: mListenerSpeedOfSound = aParam; break;
case PannerNode::REF_DISTANCE: mRefDistance = aParam; break;
case PannerNode::MAX_DISTANCE: mMaxDistance = aParam; break;
case PannerNode::ROLLOFF_FACTOR: mRolloffFactor = aParam; break;
case PannerNode::CONE_INNER_ANGLE: mConeInnerAngle = aParam; break;
case PannerNode::CONE_OUTER_ANGLE: mConeOuterAngle = aParam; break;
case PannerNode::CONE_OUTER_GAIN: mConeOuterGain = aParam; break;
default:
NS_ERROR("Bad PannerNodeEngine DoubleParameter");
}
}
virtual void ProduceAudioBlock(AudioNodeStream* aStream,
const AudioChunk& aInput,
AudioChunk* aOutput,
bool *aFinished) MOZ_OVERRIDE
{
// TODO: actually do 3D positioning computations here
*aOutput = aInput;
}
PanningModelType mPanningModel;
DistanceModelType mDistanceModel;
ThreeDPoint mPosition;
ThreeDPoint mOrientation;
ThreeDPoint mVelocity;
double mRefDistance;
double mMaxDistance;
double mRolloffFactor;
double mConeInnerAngle;
double mConeOuterAngle;
double mConeOuterGain;
ThreeDPoint mListenerPosition;
ThreeDPoint mListenerOrientation;
ThreeDPoint mListenerUpVector;
ThreeDPoint mListenerVelocity;
double mListenerDopplerFactor;
double mListenerSpeedOfSound;
};
PannerNode::PannerNode(AudioContext* aContext)
: AudioNode(aContext)
// Please keep these default values consistent with PannerNodeEngine::PannerNodeEngine above.
, mPanningModel(PanningModelTypeValues::HRTF)
, mDistanceModel(DistanceModelTypeValues::Inverse)
, mPosition()
@ -23,6 +121,15 @@ PannerNode::PannerNode(AudioContext* aContext)
, mConeOuterAngle(360.)
, mConeOuterGain(0.)
{
mStream = aContext->Graph()->CreateAudioNodeStream(new PannerNodeEngine());
// We should register once we have set up our stream and engine.
Context()->Listener()->RegisterPannerNode(this);
}
PannerNode::~PannerNode()
{
Context()->Listener()->UnregisterPannerNode(this);
DestroyMediaStream();
}
JSObject*

View File

@ -23,9 +23,15 @@ class PannerNode : public AudioNode
{
public:
explicit PannerNode(AudioContext* aContext);
virtual ~PannerNode();
virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope);
virtual bool SupportsMediaStreams() const MOZ_OVERRIDE
{
return true;
}
PanningModelType PanningModel() const
{
return mPanningModel;
@ -33,6 +39,7 @@ public:
void SetPanningModel(PanningModelType aPanningModel)
{
mPanningModel = aPanningModel;
SendInt32ParameterToStream(PANNING_MODEL, int32_t(mPanningModel));
}
DistanceModelType DistanceModel() const
@ -42,6 +49,7 @@ public:
void SetDistanceModel(DistanceModelType aDistanceModel)
{
mDistanceModel = aDistanceModel;
SendInt32ParameterToStream(DISTANCE_MODEL, int32_t(mDistanceModel));
}
void SetPosition(double aX, double aY, double aZ)
@ -49,6 +57,7 @@ public:
mPosition.x = aX;
mPosition.y = aY;
mPosition.z = aZ;
SendThreeDPointParameterToStream(POSITION, mPosition);
}
void SetOrientation(double aX, double aY, double aZ)
@ -56,6 +65,7 @@ public:
mOrientation.x = aX;
mOrientation.y = aY;
mOrientation.z = aZ;
SendThreeDPointParameterToStream(ORIENTATION, mOrientation);
}
void SetVelocity(double aX, double aY, double aZ)
@ -63,6 +73,7 @@ public:
mVelocity.x = aX;
mVelocity.y = aY;
mVelocity.z = aZ;
SendThreeDPointParameterToStream(VELOCITY, mVelocity);
}
double RefDistance() const
@ -72,6 +83,7 @@ public:
void SetRefDistance(double aRefDistance)
{
mRefDistance = aRefDistance;
SendDoubleParameterToStream(REF_DISTANCE, mRefDistance);
}
double MaxDistance() const
@ -81,6 +93,7 @@ public:
void SetMaxDistance(double aMaxDistance)
{
mMaxDistance = aMaxDistance;
SendDoubleParameterToStream(MAX_DISTANCE, mMaxDistance);
}
double RolloffFactor() const
@ -90,6 +103,7 @@ public:
void SetRolloffFactor(double aRolloffFactor)
{
mRolloffFactor = aRolloffFactor;
SendDoubleParameterToStream(ROLLOFF_FACTOR, mRolloffFactor);
}
double ConeInnerAngle() const
@ -99,6 +113,7 @@ public:
void SetConeInnerAngle(double aConeInnerAngle)
{
mConeInnerAngle = aConeInnerAngle;
SendDoubleParameterToStream(CONE_INNER_ANGLE, mConeInnerAngle);
}
double ConeOuterAngle() const
@ -108,6 +123,7 @@ public:
void SetConeOuterAngle(double aConeOuterAngle)
{
mConeOuterAngle = aConeOuterAngle;
SendDoubleParameterToStream(CONE_OUTER_ANGLE, mConeOuterAngle);
}
double ConeOuterGain() const
@ -117,8 +133,32 @@ public:
void SetConeOuterGain(double aConeOuterGain)
{
mConeOuterGain = aConeOuterGain;
SendDoubleParameterToStream(CONE_OUTER_GAIN, mConeOuterGain);
}
private:
friend class AudioListener;
friend class PannerNodeEngine;
enum EngineParameters {
LISTENER_POSITION,
LISTENER_ORIENTATION,
LISTENER_UPVECTOR,
LISTENER_VELOCITY,
LISTENER_DOPPLER_FACTOR,
LISTENER_SPEED_OF_SOUND,
PANNING_MODEL,
DISTANCE_MODEL,
POSITION,
ORIENTATION,
VELOCITY,
REF_DISTANCE,
MAX_DISTANCE,
ROLLOFF_FACTOR,
CONE_INNER_ANGLE,
CONE_OUTER_ANGLE,
CONE_OUTER_GAIN
};
private:
PanningModelType mPanningModel;
DistanceModelType mDistanceModel;