diff options
Diffstat (limited to 'dom/media/webaudio/PannerNode.h')
-rw-r--r-- | dom/media/webaudio/PannerNode.h | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/dom/media/webaudio/PannerNode.h b/dom/media/webaudio/PannerNode.h new file mode 100644 index 000000000..184db4603 --- /dev/null +++ b/dom/media/webaudio/PannerNode.h @@ -0,0 +1,296 @@ +/* -*- 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/dom/PannerNodeBinding.h" +#include "ThreeDPoint.h" +#include "mozilla/WeakPtr.h" +#include <limits> +#include <set> + +namespace mozilla { +namespace dom { + +class AudioContext; +class AudioBufferSourceNode; + +class PannerNode final : public AudioNode, + public SupportsWeakPtr<PannerNode> +{ +public: + MOZ_DECLARE_WEAKREFERENCE_TYPENAME(PannerNode) + explicit PannerNode(AudioContext* aContext); + + JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override; + + void DestroyMediaStream() override; + + void SetChannelCount(uint32_t aChannelCount, ErrorResult& aRv) override + { + if (aChannelCount > 2) { + aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); + return; + } + AudioNode::SetChannelCount(aChannelCount, aRv); + } + void SetChannelCountModeValue(ChannelCountMode aMode, ErrorResult& aRv) override + { + if (aMode == ChannelCountMode::Max) { + aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); + return; + } + AudioNode::SetChannelCountModeValue(aMode, aRv); + } + + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PannerNode, AudioNode) + + PanningModelType PanningModel() const + { + return mPanningModel; + } + void SetPanningModel(PanningModelType aPanningModel); + + DistanceModelType DistanceModel() const + { + return mDistanceModel; + } + void SetDistanceModel(DistanceModelType aDistanceModel) + { + mDistanceModel = aDistanceModel; + SendInt32ParameterToStream(DISTANCE_MODEL, int32_t(mDistanceModel)); + } + + void SetPosition(double aX, double aY, double aZ) + { + if (fabs(aX) > std::numeric_limits<float>::max() || + fabs(aY) > std::numeric_limits<float>::max() || + fabs(aZ) > std::numeric_limits<float>::max()) { + return; + } + mPositionX->SetValue(aX); + mPositionY->SetValue(aY); + mPositionZ->SetValue(aZ); + SendThreeDPointParameterToStream(POSITION, ConvertAudioParamTo3DP(mPositionX, mPositionY, mPositionZ)); + } + + void SetOrientation(double aX, double aY, double aZ) + { + if (fabs(aX) > std::numeric_limits<float>::max() || + fabs(aY) > std::numeric_limits<float>::max() || + fabs(aZ) > std::numeric_limits<float>::max()) { + return; + } + mOrientationX->SetValue(aX); + mOrientationY->SetValue(aY); + mOrientationZ->SetValue(aZ); + SendThreeDPointParameterToStream(ORIENTATION, ConvertAudioParamTo3DP(mOrientationX, mOrientationY, mOrientationZ)); + } + + void SetVelocity(double aX, double aY, double aZ) + { + if (WebAudioUtils::FuzzyEqual(mVelocity.x, aX) && + WebAudioUtils::FuzzyEqual(mVelocity.y, aY) && + WebAudioUtils::FuzzyEqual(mVelocity.z, aZ)) { + return; + } + mVelocity.x = aX; + mVelocity.y = aY; + mVelocity.z = aZ; + SendThreeDPointParameterToStream(VELOCITY, mVelocity); + SendDopplerToSourcesIfNeeded(); + } + + double RefDistance() const + { + return mRefDistance; + } + void SetRefDistance(double aRefDistance) + { + if (WebAudioUtils::FuzzyEqual(mRefDistance, aRefDistance)) { + return; + } + mRefDistance = aRefDistance; + SendDoubleParameterToStream(REF_DISTANCE, mRefDistance); + } + + double MaxDistance() const + { + return mMaxDistance; + } + void SetMaxDistance(double aMaxDistance) + { + if (WebAudioUtils::FuzzyEqual(mMaxDistance, aMaxDistance)) { + return; + } + mMaxDistance = aMaxDistance; + SendDoubleParameterToStream(MAX_DISTANCE, mMaxDistance); + } + + double RolloffFactor() const + { + return mRolloffFactor; + } + void SetRolloffFactor(double aRolloffFactor) + { + if (WebAudioUtils::FuzzyEqual(mRolloffFactor, aRolloffFactor)) { + return; + } + mRolloffFactor = aRolloffFactor; + SendDoubleParameterToStream(ROLLOFF_FACTOR, mRolloffFactor); + } + + double ConeInnerAngle() const + { + return mConeInnerAngle; + } + void SetConeInnerAngle(double aConeInnerAngle) + { + if (WebAudioUtils::FuzzyEqual(mConeInnerAngle, aConeInnerAngle)) { + return; + } + mConeInnerAngle = aConeInnerAngle; + SendDoubleParameterToStream(CONE_INNER_ANGLE, mConeInnerAngle); + } + + double ConeOuterAngle() const + { + return mConeOuterAngle; + } + void SetConeOuterAngle(double aConeOuterAngle) + { + if (WebAudioUtils::FuzzyEqual(mConeOuterAngle, aConeOuterAngle)) { + return; + } + mConeOuterAngle = aConeOuterAngle; + SendDoubleParameterToStream(CONE_OUTER_ANGLE, mConeOuterAngle); + } + + double ConeOuterGain() const + { + return mConeOuterGain; + } + void SetConeOuterGain(double aConeOuterGain) + { + if (WebAudioUtils::FuzzyEqual(mConeOuterGain, aConeOuterGain)) { + return; + } + mConeOuterGain = aConeOuterGain; + SendDoubleParameterToStream(CONE_OUTER_GAIN, mConeOuterGain); + } + + AudioParam* PositionX() + { + return mPositionX; + } + + AudioParam* PositionY() + { + return mPositionY; + } + + AudioParam* PositionZ() + { + return mPositionZ; + } + + AudioParam* OrientationX() + { + return mOrientationX; + } + + AudioParam* OrientationY() + { + return mOrientationY; + } + + AudioParam* OrientationZ() + { + return mOrientationZ; + } + + + float ComputeDopplerShift(); + void SendDopplerToSourcesIfNeeded(); + void FindConnectedSources(); + void FindConnectedSources(AudioNode* aNode, nsTArray<AudioBufferSourceNode*>& aSources, std::set<AudioNode*>& aSeenNodes); + + const char* NodeType() const override + { + return "PannerNode"; + } + + size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override; + size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override; + +protected: + virtual ~PannerNode(); + +private: + friend class AudioListener; + friend class PannerNodeEngine; + enum EngineParameters { + LISTENER_POSITION, + LISTENER_FRONT_VECTOR, // unit length + LISTENER_RIGHT_VECTOR, // unit length, orthogonal to LISTENER_FRONT_VECTOR + LISTENER_VELOCITY, + LISTENER_DOPPLER_FACTOR, + LISTENER_SPEED_OF_SOUND, + PANNING_MODEL, + DISTANCE_MODEL, + POSITION, + POSITIONX, + POSITIONY, + POSITIONZ, + ORIENTATION, // unit length or zero + ORIENTATIONX, + ORIENTATIONY, + ORIENTATIONZ, + VELOCITY, + REF_DISTANCE, + MAX_DISTANCE, + ROLLOFF_FACTOR, + CONE_INNER_ANGLE, + CONE_OUTER_ANGLE, + CONE_OUTER_GAIN + }; + + ThreeDPoint ConvertAudioParamTo3DP(RefPtr <AudioParam> aX, RefPtr <AudioParam> aY, RefPtr <AudioParam> aZ) + { + return ThreeDPoint(aX->GetValue(), aY->GetValue(), aZ->GetValue()); + } + + PanningModelType mPanningModel; + DistanceModelType mDistanceModel; + RefPtr<AudioParam> mPositionX; + RefPtr<AudioParam> mPositionY; + RefPtr<AudioParam> mPositionZ; + RefPtr<AudioParam> mOrientationX; + RefPtr<AudioParam> mOrientationY; + RefPtr<AudioParam> mOrientationZ; + ThreeDPoint mVelocity; + + double mRefDistance; + double mMaxDistance; + double mRolloffFactor; + double mConeInnerAngle; + double mConeOuterAngle; + double mConeOuterGain; + + // An array of all the AudioBufferSourceNode connected directly or indirectly + // to this AudioPannerNode. + nsTArray<AudioBufferSourceNode*> mSources; +}; + +} // namespace dom +} // namespace mozilla + +#endif + |