2 * Copyright (C) 2010, Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "platform/audio/AudioBus.h"
29 #include "platform/audio/Cone.h"
30 #include "platform/audio/Distance.h"
31 #include "platform/audio/HRTFDatabaseLoader.h"
32 #include "platform/audio/Panner.h"
33 #include "modules/webaudio/AudioListener.h"
34 #include "modules/webaudio/AudioNode.h"
35 #include "platform/geometry/FloatPoint3D.h"
36 #include "wtf/HashMap.h"
37 #include "wtf/OwnPtr.h"
41 // PannerNode is an AudioNode with one input and one output.
42 // It positions a sound in 3D space, with the exact effect dependent on the panning model.
43 // It has a position and an orientation in 3D space which is relative to the position and orientation of the context's AudioListener.
44 // A distance effect will attenuate the gain as the position moves away from the listener.
45 // A cone effect will attenuate the gain as the orientation moves away from the listener.
46 // All of these effects follow the OpenAL specification very closely.
48 class PannerNode FINAL : public AudioNode {
50 // These enums are used to distinguish what cached values of panner are dirty.
52 AzimuthElevationDirty = 0x1,
53 DistanceConeGainDirty = 0x2,
54 DopplerRateDirty = 0x4,
57 static PassRefPtrWillBeRawPtr<PannerNode> create(AudioContext* context, float sampleRate)
59 return adoptRefWillBeNoop(new PannerNode(context, sampleRate));
62 virtual ~PannerNode();
65 virtual void process(size_t framesToProcess) OVERRIDE;
66 virtual void pullInputs(size_t framesToProcess) OVERRIDE;
67 virtual void initialize() OVERRIDE;
68 virtual void uninitialize() OVERRIDE;
71 String panningModel() const;
72 void setPanningModel(const String&);
74 // Position, orientation and velocity
75 void setPosition(float x, float y, float z);
76 void setOrientation(float x, float y, float z);
77 void setVelocity(float x, float y, float z);
79 // Distance parameters
80 String distanceModel() const;
81 void setDistanceModel(const String&);
83 double refDistance() { return m_distanceEffect.refDistance(); }
84 void setRefDistance(double);
86 double maxDistance() { return m_distanceEffect.maxDistance(); }
87 void setMaxDistance(double);
89 double rolloffFactor() { return m_distanceEffect.rolloffFactor(); }
90 void setRolloffFactor(double);
92 // Sound cones - angles in degrees
93 double coneInnerAngle() const { return m_coneEffect.innerAngle(); }
94 void setConeInnerAngle(double);
96 double coneOuterAngle() const { return m_coneEffect.outerAngle(); }
97 void setConeOuterAngle(double);
99 double coneOuterGain() const { return m_coneEffect.outerGain(); }
100 void setConeOuterGain(double);
102 void markPannerAsDirty(unsigned);
104 // It must be called on audio thread, currently called only process() in AudioBufferSourceNode.
105 double dopplerRate();
107 virtual double tailTime() const OVERRIDE { return m_panner ? m_panner->tailTime() : 0; }
108 virtual double latencyTime() const OVERRIDE { return m_panner ? m_panner->latencyTime() : 0; }
111 PannerNode(AudioContext*, float sampleRate);
113 // AudioContext's listener
114 AudioListener* listener();
116 bool setPanningModel(unsigned); // Returns true on success.
117 bool setDistanceModel(unsigned); // Returns true on success.
119 void calculateAzimuthElevation(double* outAzimuth, double* outElevation);
120 float calculateDistanceConeGain(); // Returns the combined distance and cone gain attenuation.
121 double calculateDopplerRate();
123 void azimuthElevation(double* outAzimuth, double* outElevation);
124 float distanceConeGain();
126 bool isAzimuthElevationDirty() const { return m_isAzimuthElevationDirty; }
127 bool isDistanceConeGainDirty() const { return m_isDistanceConeGainDirty; }
128 bool isDopplerRateDirty() const { return m_isDopplerRateDirty; }
130 // Notifies any AudioBufferSourceNodes connected to us either directly or indirectly about our existence.
131 // This is in order to handle the pitch change necessary for the doppler shift.
132 void notifyAudioSourcesConnectedToNode(AudioNode*, HashMap<AudioNode*, bool> &visitedNodes);
134 OwnPtr<Panner> m_panner;
135 unsigned m_panningModel;
136 unsigned m_distanceModel;
138 // Current source location information
139 FloatPoint3D m_position;
140 FloatPoint3D m_orientation;
141 FloatPoint3D m_velocity;
143 bool m_isAzimuthElevationDirty;
144 bool m_isDistanceConeGainDirty;
145 bool m_isDopplerRateDirty;
148 DistanceEffect m_distanceEffect;
149 ConeEffect m_coneEffect;
153 double m_cachedAzimuth;
154 double m_cachedElevation;
155 float m_cachedDistanceConeGain;
156 double m_cachedDopplerRate;
158 RefPtr<HRTFDatabaseLoader> m_hrtfDatabaseLoader;
160 // AudioContext's connection count
161 unsigned m_connectionCount;
163 // Synchronize process() with setting of the panning model, source's location information, listener, distance parameters and sound cones.
164 mutable Mutex m_processLock;
167 } // namespace WebCore
169 #endif // PannerNode_h