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