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/Panner.h"
32 #include "modules/webaudio/AudioListener.h"
33 #include "modules/webaudio/AudioNode.h"
34 #include "platform/geometry/FloatPoint3D.h"
35 #include "wtf/HashMap.h"
39 // PannerNode is an AudioNode with one input and one output.
40 // It positions a sound in 3D space, with the exact effect dependent on the panning model.
41 // It has a position and an orientation in 3D space which is relative to the position and orientation of the context's AudioListener.
42 // A distance effect will attenuate the gain as the position moves away from the listener.
43 // A cone effect will attenuate the gain as the orientation moves away from the listener.
44 // All of these effects follow the OpenAL specification very closely.
46 class PannerNode final : public AudioNode {
47 DEFINE_WRAPPERTYPEINFO();
49 // These enums are used to distinguish what cached values of panner are dirty.
51 AzimuthElevationDirty = 0x1,
52 DistanceConeGainDirty = 0x2,
53 DopplerRateDirty = 0x4,
56 static PannerNode* create(AudioContext* context, float sampleRate)
58 return new PannerNode(context, sampleRate);
61 virtual ~PannerNode();
64 virtual void dispose() override;
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; }
110 virtual void setChannelCount(unsigned long, ExceptionState&) final;
111 virtual void setChannelCountMode(const String&, ExceptionState&) final;
113 virtual void trace(Visitor*) override;
116 PannerNode(AudioContext*, float sampleRate);
118 // AudioContext's listener
119 AudioListener* listener();
121 bool setPanningModel(unsigned); // Returns true on success.
122 bool setDistanceModel(unsigned); // Returns true on success.
124 void calculateAzimuthElevation(double* outAzimuth, double* outElevation);
125 float calculateDistanceConeGain(); // Returns the combined distance and cone gain attenuation.
126 double calculateDopplerRate();
128 void azimuthElevation(double* outAzimuth, double* outElevation);
129 float distanceConeGain();
131 bool isAzimuthElevationDirty() const { return m_isAzimuthElevationDirty; }
132 bool isDistanceConeGainDirty() const { return m_isDistanceConeGainDirty; }
133 bool isDopplerRateDirty() const { return m_isDopplerRateDirty; }
135 // Notifies any AudioBufferSourceNodes connected to us either directly or indirectly about our existence.
136 // This is in order to handle the pitch change necessary for the doppler shift.
137 void notifyAudioSourcesConnectedToNode(AudioNode*, HashMap<AudioNode*, bool> &visitedNodes);
139 Member<Panner> m_panner;
140 unsigned m_panningModel;
141 unsigned m_distanceModel;
143 // Current source location information
144 FloatPoint3D m_position;
145 FloatPoint3D m_orientation;
146 FloatPoint3D m_velocity;
148 bool m_isAzimuthElevationDirty;
149 bool m_isDistanceConeGainDirty;
150 bool m_isDopplerRateDirty;
153 DistanceEffect m_distanceEffect;
154 ConeEffect m_coneEffect;
158 double m_cachedAzimuth;
159 double m_cachedElevation;
160 float m_cachedDistanceConeGain;
161 double m_cachedDopplerRate;
163 // AudioContext's connection count
164 unsigned m_connectionCount;
166 // Synchronize process() with setting of the panning model, source's location information, listener, distance parameters and sound cones.
167 mutable Mutex m_processLock;
172 #endif // PannerNode_h