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