1 /*
2  * Copyright (C) 2010 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_AUDIO_LISTENER_H_
30 #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_AUDIO_LISTENER_H_
31 
32 #include "third_party/blink/renderer/modules/webaudio/audio_param.h"
33 #include "third_party/blink/renderer/modules/webaudio/inspector_helper_mixin.h"
34 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
35 #include "third_party/blink/renderer/platform/geometry/float_point_3d.h"
36 #include "third_party/blink/renderer/platform/heap/handle.h"
37 
38 namespace blink {
39 
40 class HRTFDatabaseLoader;
41 class PannerHandler;
42 
43 // AudioListener maintains the state of the listener in the audio scene as
44 // defined in the OpenAL specification.
45 
46 class AudioListener : public ScriptWrappable, public InspectorHelperMixin {
47   DEFINE_WRAPPERTYPEINFO();
48 
49  public:
50   explicit AudioListener(BaseAudioContext&);
51   ~AudioListener() override;
52 
53   // Location of the listener
positionX()54   AudioParam* positionX() const { return position_x_; }
positionY()55   AudioParam* positionY() const { return position_y_; }
positionZ()56   AudioParam* positionZ() const { return position_z_; }
57 
58   // Forward direction vector of the listener
forwardX()59   AudioParam* forwardX() const { return forward_x_; }
forwardY()60   AudioParam* forwardY() const { return forward_y_; }
forwardZ()61   AudioParam* forwardZ() const { return forward_z_; }
62 
63   // Up direction vector for the listener
upX()64   AudioParam* upX() const { return up_x_; }
upY()65   AudioParam* upY() const { return up_y_; }
upZ()66   AudioParam* upZ() const { return up_z_; }
67 
68   // True if any of AudioParams have automations.
69   bool HasSampleAccurateValues() const;
70 
71   // True if any of the AudioParams are set for a-rate automations
72   // (the default).
73   bool IsAudioRate() const;
74 
75   // Update the internal state of the listener, including updating the dirty
76   // state of all PannerNodes if necessary.
77   void UpdateState();
78 
IsListenerDirty()79   bool IsListenerDirty() const { return is_listener_dirty_; }
80 
GetPosition()81   const FloatPoint3D GetPosition() const {
82     return FloatPoint3D(position_x_->value(), position_y_->value(),
83                         position_z_->value());
84   }
Orientation()85   const FloatPoint3D Orientation() const {
86     return FloatPoint3D(forward_x_->value(), forward_y_->value(),
87                         forward_z_->value());
88   }
UpVector()89   const FloatPoint3D UpVector() const {
90     return FloatPoint3D(up_x_->value(), up_y_->value(), up_z_->value());
91   }
92 
93   const float* GetPositionXValues(uint32_t frames_to_process);
94   const float* GetPositionYValues(uint32_t frames_to_process);
95   const float* GetPositionZValues(uint32_t frames_to_process);
96 
97   const float* GetForwardXValues(uint32_t frames_to_process);
98   const float* GetForwardYValues(uint32_t frames_to_process);
99   const float* GetForwardZValues(uint32_t frames_to_process);
100 
101   const float* GetUpXValues(uint32_t frames_to_process);
102   const float* GetUpYValues(uint32_t frames_to_process);
103   const float* GetUpZValues(uint32_t frames_to_process);
104 
105   // Position
setPosition(float x,float y,float z,ExceptionState & exceptionState)106   void setPosition(float x, float y, float z, ExceptionState& exceptionState) {
107     setPosition(FloatPoint3D(x, y, z), exceptionState);
108   }
109 
110   // Orientation and Up-vector
setOrientation(float x,float y,float z,float up_x,float up_y,float up_z,ExceptionState & exceptionState)111   void setOrientation(float x,
112                       float y,
113                       float z,
114                       float up_x,
115                       float up_y,
116                       float up_z,
117                       ExceptionState& exceptionState) {
118     setOrientation(FloatPoint3D(x, y, z), exceptionState);
119     SetUpVector(FloatPoint3D(up_x, up_y, up_z), exceptionState);
120   }
121 
ListenerLock()122   Mutex& ListenerLock() { return listener_lock_; }
123   void AddPanner(PannerHandler&);
124   void RemovePanner(PannerHandler&);
125 
126   // HRTF DB loader
HrtfDatabaseLoader()127   HRTFDatabaseLoader* HrtfDatabaseLoader() {
128     return hrtf_database_loader_.get();
129   }
130   void CreateAndLoadHRTFDatabaseLoader(float);
131   bool IsHRTFDatabaseLoaded();
132   void WaitForHRTFDatabaseLoaderThreadCompletion();
133 
134   // InspectorHelperMixin: Note that this object belongs to a BaseAudioContext,
135   // so these methods get called by the parent context.
136   void ReportDidCreate() final;
137   void ReportWillBeDestroyed() final;
138 
139   void Trace(Visitor*) const override;
140 
141  private:
142   void setPosition(const FloatPoint3D&, ExceptionState&);
143   void setOrientation(const FloatPoint3D&, ExceptionState&);
144   void SetUpVector(const FloatPoint3D&, ExceptionState&);
145 
146   void MarkPannersAsDirty(unsigned);
147 
148   // Location of the listener
149   Member<AudioParam> position_x_;
150   Member<AudioParam> position_y_;
151   Member<AudioParam> position_z_;
152 
153   // Forward direction vector of the listener
154   Member<AudioParam> forward_x_;
155   Member<AudioParam> forward_y_;
156   Member<AudioParam> forward_z_;
157 
158   // Up direction vector for the listener
159   Member<AudioParam> up_x_;
160   Member<AudioParam> up_y_;
161   Member<AudioParam> up_z_;
162 
163   // The position, forward, and up vectors from the last rendering quantum.
164   FloatPoint3D last_position_;
165   FloatPoint3D last_forward_;
166   FloatPoint3D last_up_;
167 
168   // Last time that the automations were updated.
169   double last_update_time_;
170 
171   // Set every rendering quantum if the listener has moved in any way
172   // (position, forward, or up).  This should only be read or written to from
173   // the audio thread.
174   bool is_listener_dirty_;
175 
176   void UpdateValuesIfNeeded(uint32_t frames_to_process);
177 
178   AudioFloatArray position_x_values_;
179   AudioFloatArray position_y_values_;
180   AudioFloatArray position_z_values_;
181 
182   AudioFloatArray forward_x_values_;
183   AudioFloatArray forward_y_values_;
184   AudioFloatArray forward_z_values_;
185 
186   AudioFloatArray up_x_values_;
187   AudioFloatArray up_y_values_;
188   AudioFloatArray up_z_values_;
189 
190   // Synchronize a panner's process() with setting of the state of the listener.
191   mutable Mutex listener_lock_;
192   // List for pannerNodes in context. This is updated only in the main thread,
193   // and can be referred in audio thread.
194   // These raw pointers are safe because PannerHandler::uninitialize()
195   // unregisters it from m_panners.
196   HashSet<PannerHandler*> panners_;
197   // HRTF DB loader for panner node.
198   scoped_refptr<HRTFDatabaseLoader> hrtf_database_loader_;
199 };
200 
201 }  // namespace blink
202 
203 #endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBAUDIO_AUDIO_LISTENER_H_
204