1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef PannerNode_h_ 8 #define PannerNode_h_ 9 10 #include "AudioNode.h" 11 #include "AudioParam.h" 12 #include "nsPrintfCString.h" 13 #include "mozilla/dom/PannerNodeBinding.h" 14 #include "ThreeDPoint.h" 15 #include <limits> 16 #include <set> 17 18 namespace mozilla { 19 namespace dom { 20 21 class AudioContext; 22 class AudioBufferSourceNode; 23 struct PannerOptions; 24 25 class PannerNode final : public AudioNode { 26 public: 27 static already_AddRefed<PannerNode> Create(AudioContext& aAudioContext, 28 const PannerOptions& aOptions, 29 ErrorResult& aRv); 30 Constructor(const GlobalObject & aGlobal,AudioContext & aAudioContext,const PannerOptions & aOptions,ErrorResult & aRv)31 static already_AddRefed<PannerNode> Constructor(const GlobalObject& aGlobal, 32 AudioContext& aAudioContext, 33 const PannerOptions& aOptions, 34 ErrorResult& aRv) { 35 return Create(aAudioContext, aOptions, aRv); 36 } 37 38 JSObject* WrapObject(JSContext* aCx, 39 JS::Handle<JSObject*> aGivenProto) override; 40 SetChannelCount(uint32_t aChannelCount,ErrorResult & aRv)41 void SetChannelCount(uint32_t aChannelCount, ErrorResult& aRv) override { 42 if (aChannelCount > 2) { 43 aRv.ThrowNotSupportedError( 44 nsPrintfCString("%u is greater than 2", aChannelCount)); 45 return; 46 } 47 AudioNode::SetChannelCount(aChannelCount, aRv); 48 } SetChannelCountModeValue(ChannelCountMode aMode,ErrorResult & aRv)49 void SetChannelCountModeValue(ChannelCountMode aMode, 50 ErrorResult& aRv) override { 51 if (aMode == ChannelCountMode::Max) { 52 aRv.ThrowNotSupportedError("Cannot set channel count mode to \"max\""); 53 return; 54 } 55 AudioNode::SetChannelCountModeValue(aMode, aRv); 56 } 57 58 NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PannerNode,AudioNode)59 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PannerNode, AudioNode) 60 61 PanningModelType PanningModel() const { return mPanningModel; } 62 void SetPanningModel(PanningModelType aPanningModel); 63 DistanceModel()64 DistanceModelType DistanceModel() const { return mDistanceModel; } SetDistanceModel(DistanceModelType aDistanceModel)65 void SetDistanceModel(DistanceModelType aDistanceModel) { 66 mDistanceModel = aDistanceModel; 67 SendInt32ParameterToTrack(DISTANCE_MODEL, int32_t(mDistanceModel)); 68 } 69 70 void SetPosition(double aX, double aY, double aZ, ErrorResult& aRv); 71 void SetOrientation(double aX, double aY, double aZ, ErrorResult& aRv); 72 RefDistance()73 double RefDistance() const { return mRefDistance; } SetRefDistance(double aRefDistance,ErrorResult & aRv)74 void SetRefDistance(double aRefDistance, ErrorResult& aRv) { 75 if (WebAudioUtils::FuzzyEqual(mRefDistance, aRefDistance)) { 76 return; 77 } 78 79 if (aRefDistance < 0) { 80 aRv.ThrowRangeError( 81 "The refDistance value passed to PannerNode must not be negative."); 82 return; 83 } 84 85 mRefDistance = aRefDistance; 86 SendDoubleParameterToTrack(REF_DISTANCE, mRefDistance); 87 } 88 MaxDistance()89 double MaxDistance() const { return mMaxDistance; } SetMaxDistance(double aMaxDistance,ErrorResult & aRv)90 void SetMaxDistance(double aMaxDistance, ErrorResult& aRv) { 91 if (WebAudioUtils::FuzzyEqual(mMaxDistance, aMaxDistance)) { 92 return; 93 } 94 95 if (aMaxDistance <= 0) { 96 aRv.ThrowRangeError( 97 "The maxDistance value passed to PannerNode must be positive."); 98 return; 99 } 100 101 mMaxDistance = aMaxDistance; 102 SendDoubleParameterToTrack(MAX_DISTANCE, mMaxDistance); 103 } 104 RolloffFactor()105 double RolloffFactor() const { return mRolloffFactor; } SetRolloffFactor(double aRolloffFactor,ErrorResult & aRv)106 void SetRolloffFactor(double aRolloffFactor, ErrorResult& aRv) { 107 if (WebAudioUtils::FuzzyEqual(mRolloffFactor, aRolloffFactor)) { 108 return; 109 } 110 111 if (aRolloffFactor < 0) { 112 aRv.ThrowRangeError( 113 "The rolloffFactor value passed to PannerNode must not be negative."); 114 return; 115 } 116 117 mRolloffFactor = aRolloffFactor; 118 SendDoubleParameterToTrack(ROLLOFF_FACTOR, mRolloffFactor); 119 } 120 ConeInnerAngle()121 double ConeInnerAngle() const { return mConeInnerAngle; } SetConeInnerAngle(double aConeInnerAngle)122 void SetConeInnerAngle(double aConeInnerAngle) { 123 if (WebAudioUtils::FuzzyEqual(mConeInnerAngle, aConeInnerAngle)) { 124 return; 125 } 126 mConeInnerAngle = aConeInnerAngle; 127 SendDoubleParameterToTrack(CONE_INNER_ANGLE, mConeInnerAngle); 128 } 129 ConeOuterAngle()130 double ConeOuterAngle() const { return mConeOuterAngle; } SetConeOuterAngle(double aConeOuterAngle)131 void SetConeOuterAngle(double aConeOuterAngle) { 132 if (WebAudioUtils::FuzzyEqual(mConeOuterAngle, aConeOuterAngle)) { 133 return; 134 } 135 mConeOuterAngle = aConeOuterAngle; 136 SendDoubleParameterToTrack(CONE_OUTER_ANGLE, mConeOuterAngle); 137 } 138 ConeOuterGain()139 double ConeOuterGain() const { return mConeOuterGain; } SetConeOuterGain(double aConeOuterGain,ErrorResult & aRv)140 void SetConeOuterGain(double aConeOuterGain, ErrorResult& aRv) { 141 if (WebAudioUtils::FuzzyEqual(mConeOuterGain, aConeOuterGain)) { 142 return; 143 } 144 145 if (aConeOuterGain < 0 || aConeOuterGain > 1) { 146 aRv.ThrowInvalidStateError( 147 nsPrintfCString("%g is not in the range [0, 1]", aConeOuterGain)); 148 return; 149 } 150 151 mConeOuterGain = aConeOuterGain; 152 SendDoubleParameterToTrack(CONE_OUTER_GAIN, mConeOuterGain); 153 } 154 PositionX()155 AudioParam* PositionX() { return mPositionX; } 156 PositionY()157 AudioParam* PositionY() { return mPositionY; } 158 PositionZ()159 AudioParam* PositionZ() { return mPositionZ; } 160 OrientationX()161 AudioParam* OrientationX() { return mOrientationX; } 162 OrientationY()163 AudioParam* OrientationY() { return mOrientationY; } 164 OrientationZ()165 AudioParam* OrientationZ() { return mOrientationZ; } 166 NodeType()167 const char* NodeType() const override { return "PannerNode"; } 168 169 size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override; 170 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override; 171 172 private: 173 explicit PannerNode(AudioContext* aContext); 174 ~PannerNode() = default; 175 176 friend class AudioListener; 177 friend class PannerNodeEngine; 178 enum EngineParameters { 179 PANNING_MODEL, 180 DISTANCE_MODEL, 181 POSITION, 182 POSITIONX, 183 POSITIONY, 184 POSITIONZ, 185 ORIENTATION, // unit length or zero 186 ORIENTATIONX, 187 ORIENTATIONY, 188 ORIENTATIONZ, 189 REF_DISTANCE, 190 MAX_DISTANCE, 191 ROLLOFF_FACTOR, 192 CONE_INNER_ANGLE, 193 CONE_OUTER_ANGLE, 194 CONE_OUTER_GAIN 195 }; 196 ConvertAudioParamTo3DP(RefPtr<AudioParam> aX,RefPtr<AudioParam> aY,RefPtr<AudioParam> aZ)197 ThreeDPoint ConvertAudioParamTo3DP(RefPtr<AudioParam> aX, 198 RefPtr<AudioParam> aY, 199 RefPtr<AudioParam> aZ) { 200 return ThreeDPoint(aX->GetValue(), aY->GetValue(), aZ->GetValue()); 201 } 202 203 PanningModelType mPanningModel; 204 DistanceModelType mDistanceModel; 205 RefPtr<AudioParam> mPositionX; 206 RefPtr<AudioParam> mPositionY; 207 RefPtr<AudioParam> mPositionZ; 208 RefPtr<AudioParam> mOrientationX; 209 RefPtr<AudioParam> mOrientationY; 210 RefPtr<AudioParam> mOrientationZ; 211 212 double mRefDistance; 213 double mMaxDistance; 214 double mRolloffFactor; 215 double mConeInnerAngle; 216 double mConeOuterAngle; 217 double mConeOuterGain; 218 }; 219 220 } // namespace dom 221 } // namespace mozilla 222 223 #endif 224