Line data Source code
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 "mozilla/dom/PannerNodeBinding.h"
13 : #include "ThreeDPoint.h"
14 : #include "mozilla/WeakPtr.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 SupportsWeakPtr<PannerNode>
27 : {
28 : public:
29 : static already_AddRefed<PannerNode>
30 : Create(AudioContext& aAudioContext, const PannerOptions& aOptions,
31 : ErrorResult& aRv);
32 :
33 0 : MOZ_DECLARE_WEAKREFERENCE_TYPENAME(PannerNode)
34 :
35 : static already_AddRefed<PannerNode>
36 0 : Constructor(const GlobalObject& aGlobal, AudioContext& aAudioContext,
37 : const PannerOptions& aOptions, ErrorResult& aRv)
38 : {
39 0 : return Create(aAudioContext, aOptions, aRv);
40 : }
41 :
42 : JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
43 :
44 : void DestroyMediaStream() override;
45 :
46 0 : void SetChannelCount(uint32_t aChannelCount, ErrorResult& aRv) override
47 : {
48 0 : if (aChannelCount > 2) {
49 0 : aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
50 0 : return;
51 : }
52 0 : AudioNode::SetChannelCount(aChannelCount, aRv);
53 : }
54 0 : void SetChannelCountModeValue(ChannelCountMode aMode, ErrorResult& aRv) override
55 : {
56 0 : if (aMode == ChannelCountMode::Max) {
57 0 : aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
58 0 : return;
59 : }
60 0 : AudioNode::SetChannelCountModeValue(aMode, aRv);
61 : }
62 :
63 : NS_DECL_ISUPPORTS_INHERITED
64 0 : NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PannerNode, AudioNode)
65 :
66 0 : PanningModelType PanningModel() const
67 : {
68 0 : return mPanningModel;
69 : }
70 : void SetPanningModel(PanningModelType aPanningModel);
71 :
72 0 : DistanceModelType DistanceModel() const
73 : {
74 0 : return mDistanceModel;
75 : }
76 0 : void SetDistanceModel(DistanceModelType aDistanceModel)
77 : {
78 0 : mDistanceModel = aDistanceModel;
79 0 : SendInt32ParameterToStream(DISTANCE_MODEL, int32_t(mDistanceModel));
80 0 : }
81 :
82 0 : void SetPosition(double aX, double aY, double aZ)
83 : {
84 0 : if (fabs(aX) > std::numeric_limits<float>::max() ||
85 0 : fabs(aY) > std::numeric_limits<float>::max() ||
86 0 : fabs(aZ) > std::numeric_limits<float>::max()) {
87 0 : return;
88 : }
89 0 : mPositionX->SetValue(aX);
90 0 : mPositionY->SetValue(aY);
91 0 : mPositionZ->SetValue(aZ);
92 0 : SendThreeDPointParameterToStream(POSITION, ConvertAudioParamTo3DP(mPositionX, mPositionY, mPositionZ));
93 : }
94 :
95 0 : void SetOrientation(double aX, double aY, double aZ)
96 : {
97 0 : if (fabs(aX) > std::numeric_limits<float>::max() ||
98 0 : fabs(aY) > std::numeric_limits<float>::max() ||
99 0 : fabs(aZ) > std::numeric_limits<float>::max()) {
100 0 : return;
101 : }
102 0 : mOrientationX->SetValue(aX);
103 0 : mOrientationY->SetValue(aY);
104 0 : mOrientationZ->SetValue(aZ);
105 0 : SendThreeDPointParameterToStream(ORIENTATION, ConvertAudioParamTo3DP(mOrientationX, mOrientationY, mOrientationZ));
106 : }
107 :
108 0 : void SetVelocity(double aX, double aY, double aZ)
109 : {
110 0 : if (WebAudioUtils::FuzzyEqual(mVelocity.x, aX) &&
111 0 : WebAudioUtils::FuzzyEqual(mVelocity.y, aY) &&
112 0 : WebAudioUtils::FuzzyEqual(mVelocity.z, aZ)) {
113 0 : return;
114 : }
115 0 : mVelocity.x = aX;
116 0 : mVelocity.y = aY;
117 0 : mVelocity.z = aZ;
118 0 : SendThreeDPointParameterToStream(VELOCITY, mVelocity);
119 0 : SendDopplerToSourcesIfNeeded();
120 : }
121 :
122 0 : double RefDistance() const
123 : {
124 0 : return mRefDistance;
125 : }
126 0 : void SetRefDistance(double aRefDistance)
127 : {
128 0 : if (WebAudioUtils::FuzzyEqual(mRefDistance, aRefDistance)) {
129 0 : return;
130 : }
131 0 : mRefDistance = aRefDistance;
132 0 : SendDoubleParameterToStream(REF_DISTANCE, mRefDistance);
133 : }
134 :
135 0 : double MaxDistance() const
136 : {
137 0 : return mMaxDistance;
138 : }
139 0 : void SetMaxDistance(double aMaxDistance)
140 : {
141 0 : if (WebAudioUtils::FuzzyEqual(mMaxDistance, aMaxDistance)) {
142 0 : return;
143 : }
144 0 : mMaxDistance = aMaxDistance;
145 0 : SendDoubleParameterToStream(MAX_DISTANCE, mMaxDistance);
146 : }
147 :
148 0 : double RolloffFactor() const
149 : {
150 0 : return mRolloffFactor;
151 : }
152 0 : void SetRolloffFactor(double aRolloffFactor)
153 : {
154 0 : if (WebAudioUtils::FuzzyEqual(mRolloffFactor, aRolloffFactor)) {
155 0 : return;
156 : }
157 0 : mRolloffFactor = aRolloffFactor;
158 0 : SendDoubleParameterToStream(ROLLOFF_FACTOR, mRolloffFactor);
159 : }
160 :
161 0 : double ConeInnerAngle() const
162 : {
163 0 : return mConeInnerAngle;
164 : }
165 0 : void SetConeInnerAngle(double aConeInnerAngle)
166 : {
167 0 : if (WebAudioUtils::FuzzyEqual(mConeInnerAngle, aConeInnerAngle)) {
168 0 : return;
169 : }
170 0 : mConeInnerAngle = aConeInnerAngle;
171 0 : SendDoubleParameterToStream(CONE_INNER_ANGLE, mConeInnerAngle);
172 : }
173 :
174 0 : double ConeOuterAngle() const
175 : {
176 0 : return mConeOuterAngle;
177 : }
178 0 : void SetConeOuterAngle(double aConeOuterAngle)
179 : {
180 0 : if (WebAudioUtils::FuzzyEqual(mConeOuterAngle, aConeOuterAngle)) {
181 0 : return;
182 : }
183 0 : mConeOuterAngle = aConeOuterAngle;
184 0 : SendDoubleParameterToStream(CONE_OUTER_ANGLE, mConeOuterAngle);
185 : }
186 :
187 0 : double ConeOuterGain() const
188 : {
189 0 : return mConeOuterGain;
190 : }
191 0 : void SetConeOuterGain(double aConeOuterGain)
192 : {
193 0 : if (WebAudioUtils::FuzzyEqual(mConeOuterGain, aConeOuterGain)) {
194 0 : return;
195 : }
196 0 : mConeOuterGain = aConeOuterGain;
197 0 : SendDoubleParameterToStream(CONE_OUTER_GAIN, mConeOuterGain);
198 : }
199 :
200 0 : AudioParam* PositionX()
201 : {
202 0 : return mPositionX;
203 : }
204 :
205 0 : AudioParam* PositionY()
206 : {
207 0 : return mPositionY;
208 : }
209 :
210 0 : AudioParam* PositionZ()
211 : {
212 0 : return mPositionZ;
213 : }
214 :
215 0 : AudioParam* OrientationX()
216 : {
217 0 : return mOrientationX;
218 : }
219 :
220 0 : AudioParam* OrientationY()
221 : {
222 0 : return mOrientationY;
223 : }
224 :
225 0 : AudioParam* OrientationZ()
226 : {
227 0 : return mOrientationZ;
228 : }
229 :
230 :
231 : float ComputeDopplerShift();
232 : void SendDopplerToSourcesIfNeeded();
233 : void FindConnectedSources();
234 : void FindConnectedSources(AudioNode* aNode, nsTArray<AudioBufferSourceNode*>& aSources, std::set<AudioNode*>& aSeenNodes);
235 :
236 0 : const char* NodeType() const override
237 : {
238 0 : return "PannerNode";
239 : }
240 :
241 : size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
242 : size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
243 :
244 : private:
245 : explicit PannerNode(AudioContext* aContext);
246 : ~PannerNode();
247 :
248 : friend class AudioListener;
249 : friend class PannerNodeEngine;
250 : enum EngineParameters {
251 : LISTENER_POSITION,
252 : LISTENER_FRONT_VECTOR, // unit length
253 : LISTENER_RIGHT_VECTOR, // unit length, orthogonal to LISTENER_FRONT_VECTOR
254 : LISTENER_VELOCITY,
255 : LISTENER_DOPPLER_FACTOR,
256 : LISTENER_SPEED_OF_SOUND,
257 : PANNING_MODEL,
258 : DISTANCE_MODEL,
259 : POSITION,
260 : POSITIONX,
261 : POSITIONY,
262 : POSITIONZ,
263 : ORIENTATION, // unit length or zero
264 : ORIENTATIONX,
265 : ORIENTATIONY,
266 : ORIENTATIONZ,
267 : VELOCITY,
268 : REF_DISTANCE,
269 : MAX_DISTANCE,
270 : ROLLOFF_FACTOR,
271 : CONE_INNER_ANGLE,
272 : CONE_OUTER_ANGLE,
273 : CONE_OUTER_GAIN
274 : };
275 :
276 0 : ThreeDPoint ConvertAudioParamTo3DP(RefPtr <AudioParam> aX, RefPtr <AudioParam> aY, RefPtr <AudioParam> aZ)
277 : {
278 0 : return ThreeDPoint(aX->GetValue(), aY->GetValue(), aZ->GetValue());
279 : }
280 :
281 : PanningModelType mPanningModel;
282 : DistanceModelType mDistanceModel;
283 : RefPtr<AudioParam> mPositionX;
284 : RefPtr<AudioParam> mPositionY;
285 : RefPtr<AudioParam> mPositionZ;
286 : RefPtr<AudioParam> mOrientationX;
287 : RefPtr<AudioParam> mOrientationY;
288 : RefPtr<AudioParam> mOrientationZ;
289 : ThreeDPoint mVelocity;
290 :
291 : double mRefDistance;
292 : double mMaxDistance;
293 : double mRolloffFactor;
294 : double mConeInnerAngle;
295 : double mConeOuterAngle;
296 : double mConeOuterGain;
297 :
298 : // An array of all the AudioBufferSourceNode connected directly or indirectly
299 : // to this AudioPannerNode.
300 : nsTArray<AudioBufferSourceNode*> mSources;
301 : };
302 :
303 : } // namespace dom
304 : } // namespace mozilla
305 :
306 : #endif
|