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 : #include "AudioListener.h"
8 : #include "AudioContext.h"
9 : #include "mozilla/dom/AudioListenerBinding.h"
10 :
11 : namespace mozilla {
12 : namespace dom {
13 :
14 0 : NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(AudioListener, mContext)
15 :
16 0 : NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AudioListener, AddRef)
17 0 : NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AudioListener, Release)
18 :
19 0 : AudioListener::AudioListener(AudioContext* aContext)
20 : : mContext(aContext)
21 : , mPosition()
22 : , mFrontVector(0., 0., -1.)
23 : , mRightVector(1., 0., 0.)
24 : , mVelocity()
25 : , mDopplerFactor(1.)
26 0 : , mSpeedOfSound(343.3) // meters/second
27 : {
28 0 : MOZ_ASSERT(aContext);
29 0 : }
30 :
31 : JSObject*
32 0 : AudioListener::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
33 : {
34 0 : return AudioListenerBinding::Wrap(aCx, this, aGivenProto);
35 : }
36 :
37 : void
38 0 : AudioListener::SetOrientation(double aX, double aY, double aZ,
39 : double aXUp, double aYUp, double aZUp)
40 : {
41 0 : ThreeDPoint front(aX, aY, aZ);
42 : // The panning effect and the azimuth and elevation calculation in the Web
43 : // Audio spec becomes undefined with linearly dependent vectors, so keep
44 : // existing state in these situations.
45 0 : if (front.IsZero()) {
46 0 : return;
47 : }
48 : // Normalize before using CrossProduct() to avoid overflow.
49 0 : front.Normalize();
50 0 : ThreeDPoint up(aXUp, aYUp, aZUp);
51 0 : if (up.IsZero()) {
52 0 : return;
53 : }
54 0 : up.Normalize();
55 0 : ThreeDPoint right = front.CrossProduct(up);
56 0 : if (right.IsZero()) {
57 0 : return;
58 : }
59 0 : right.Normalize();
60 :
61 0 : if (!mFrontVector.FuzzyEqual(front)) {
62 0 : mFrontVector = front;
63 0 : SendThreeDPointParameterToStream(PannerNode::LISTENER_FRONT_VECTOR, front);
64 : }
65 0 : if (!mRightVector.FuzzyEqual(right)) {
66 0 : mRightVector = right;
67 0 : SendThreeDPointParameterToStream(PannerNode::LISTENER_RIGHT_VECTOR, right);
68 : }
69 : }
70 :
71 : void
72 0 : AudioListener::RegisterPannerNode(PannerNode* aPannerNode)
73 : {
74 0 : mPanners.AppendElement(aPannerNode);
75 :
76 : // Let the panner node know about our parameters
77 0 : aPannerNode->SendThreeDPointParameterToStream(PannerNode::LISTENER_POSITION, mPosition);
78 0 : aPannerNode->SendThreeDPointParameterToStream(PannerNode::LISTENER_FRONT_VECTOR, mFrontVector);
79 0 : aPannerNode->SendThreeDPointParameterToStream(PannerNode::LISTENER_RIGHT_VECTOR, mRightVector);
80 0 : aPannerNode->SendThreeDPointParameterToStream(PannerNode::LISTENER_VELOCITY, mVelocity);
81 0 : aPannerNode->SendDoubleParameterToStream(PannerNode::LISTENER_DOPPLER_FACTOR, mDopplerFactor);
82 0 : aPannerNode->SendDoubleParameterToStream(PannerNode::LISTENER_SPEED_OF_SOUND, mSpeedOfSound);
83 0 : UpdatePannersVelocity();
84 0 : }
85 :
86 0 : void AudioListener::UnregisterPannerNode(PannerNode* aPannerNode)
87 : {
88 0 : mPanners.RemoveElement(aPannerNode);
89 0 : }
90 :
91 : void
92 0 : AudioListener::SendDoubleParameterToStream(uint32_t aIndex, double aValue)
93 : {
94 0 : for (uint32_t i = 0; i < mPanners.Length(); ++i) {
95 0 : if (mPanners[i]) {
96 0 : mPanners[i]->SendDoubleParameterToStream(aIndex, aValue);
97 : }
98 : }
99 0 : }
100 :
101 : void
102 0 : AudioListener::SendThreeDPointParameterToStream(uint32_t aIndex, const ThreeDPoint& aValue)
103 : {
104 0 : for (uint32_t i = 0; i < mPanners.Length(); ++i) {
105 0 : if (mPanners[i]) {
106 0 : mPanners[i]->SendThreeDPointParameterToStream(aIndex, aValue);
107 : }
108 : }
109 0 : }
110 :
111 0 : void AudioListener::UpdatePannersVelocity()
112 : {
113 0 : for (uint32_t i = 0; i < mPanners.Length(); ++i) {
114 0 : if (mPanners[i]) {
115 0 : mPanners[i]->SendDopplerToSourcesIfNeeded();
116 : }
117 : }
118 0 : }
119 :
120 : size_t
121 0 : AudioListener::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
122 : {
123 0 : size_t amount = aMallocSizeOf(this);
124 : // AudioNodes are tracked separately
125 0 : amount += mPanners.ShallowSizeOfExcludingThis(aMallocSizeOf);
126 0 : return amount;
127 : }
128 :
129 : } // namespace dom
130 : } // namespace mozilla
131 :
|