1a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch/*
228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu * Copyright (C) 2010, Google Inc. All rights reserved.
3a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch *
4a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * Redistribution and use in source and binary forms, with or without
5a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * modification, are permitted provided that the following conditions
6a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * are met:
7a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * 1.  Redistributions of source code must retain the above copyright
828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu *    notice, this list of conditions and the following disclaimer.
9a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * 2.  Redistributions in binary form must reproduce the above copyright
1028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu *    notice, this list of conditions and the following disclaimer in the
1128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu *    documentation and/or other materials provided with the distribution.
12a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch *
1328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
2028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch */
24a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
25a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#ifndef AudioPannerNode_h
26a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#define AudioPannerNode_h
27a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
28a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "AudioBus.h"
29a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "AudioGain.h"
30a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "AudioListener.h"
31a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "AudioNode.h"
32a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "Cone.h"
33a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "Distance.h"
34f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include "FloatPoint3D.h"
35a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "Panner.h"
36a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include <wtf/OwnPtr.h>
37a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
38a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochnamespace WebCore {
39a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
40a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch// AudioPannerNode is an AudioNode with one input and one output.
41a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch// It positions a sound in 3D space, with the exact effect dependent on the panning model.
42a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch// It has a position and an orientation in 3D space which is relative to the position and orientation of the context's AudioListener.
43a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch// A distance effect will attenuate the gain as the position moves away from the listener.
44a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch// A cone effect will attenuate the gain as the orientation moves away from the listener.
45a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch// All of these effects follow the OpenAL specification very closely.
46a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
47a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochclass AudioPannerNode : public AudioNode {
48a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochpublic:
496b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    // These must be defined as in the .idl file and must match those in the Panner class.
50a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    enum {
516b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        EQUALPOWER = 0,
526b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        HRTF = 1,
536b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        SOUNDFIELD = 2,
54a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    };
55a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
56a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    static PassRefPtr<AudioPannerNode> create(AudioContext* context, double sampleRate)
57a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    {
58a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return adoptRef(new AudioPannerNode(context, sampleRate));
59a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
60a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
61a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    virtual ~AudioPannerNode();
62a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
63a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // AudioNode
64a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    virtual void process(size_t framesToProcess);
65a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    virtual void pullInputs(size_t framesToProcess);
66a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    virtual void reset();
67a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    virtual void initialize();
68a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    virtual void uninitialize();
69a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
70a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Listener
71a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    AudioListener* listener();
72a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
73a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Panning model
74a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    unsigned short panningModel() const { return m_panningModel; }
75a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void setPanningModel(unsigned short);
76a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
77a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Position
78f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    FloatPoint3D position() const { return m_position; }
79f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    void setPosition(float x, float y, float z) { m_position = FloatPoint3D(x, y, z); }
80a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
81a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Orientation
82f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    FloatPoint3D orientation() const { return m_position; }
83f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    void setOrientation(float x, float y, float z) { m_orientation = FloatPoint3D(x, y, z); }
84a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
85a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Velocity
86f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    FloatPoint3D velocity() const { return m_velocity; }
87f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    void setVelocity(float x, float y, float z) { m_velocity = FloatPoint3D(x, y, z); }
88a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
89a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Distance parameters
90a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    unsigned short distanceModel() { return m_distanceEffect.model(); }
91a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void setDistanceModel(unsigned short model) { m_distanceEffect.setModel(static_cast<DistanceEffect::ModelType>(model), true); }
92a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
93a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    float refDistance() { return static_cast<float>(m_distanceEffect.refDistance()); }
94a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void setRefDistance(float refDistance) { m_distanceEffect.setRefDistance(refDistance); }
95a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
96a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    float maxDistance() { return static_cast<float>(m_distanceEffect.maxDistance()); }
97a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void setMaxDistance(float maxDistance) { m_distanceEffect.setMaxDistance(maxDistance); }
98a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
99a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    float rolloffFactor() { return static_cast<float>(m_distanceEffect.rolloffFactor()); }
100a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void setRolloffFactor(float rolloffFactor) { m_distanceEffect.setRolloffFactor(rolloffFactor); }
101a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
102a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Sound cones - angles in degrees
103a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    float coneInnerAngle() const { return static_cast<float>(m_coneEffect.innerAngle()); }
104a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void setConeInnerAngle(float angle) { m_coneEffect.setInnerAngle(angle); }
105a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
106a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    float coneOuterAngle() const { return static_cast<float>(m_coneEffect.outerAngle()); }
107a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void setConeOuterAngle(float angle) { m_coneEffect.setOuterAngle(angle); }
108a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
109a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    float coneOuterGain() const { return static_cast<float>(m_coneEffect.outerGain()); }
110a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void setConeOuterGain(float angle) { m_coneEffect.setOuterGain(angle); }
111a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
112a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void getAzimuthElevation(double* outAzimuth, double* outElevation);
113a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    float dopplerRate();
114a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
115a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Accessors for dynamically calculated gain values.
116a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    AudioGain* distanceGain() { return m_distanceGain.get(); }
117a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    AudioGain* coneGain() { return m_coneGain.get(); }
118a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
119a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochprivate:
120a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    AudioPannerNode(AudioContext*, double sampleRate);
121a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
122a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Returns the combined distance and cone gain attenuation.
123a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    float distanceConeGain();
124a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
125a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Notifies any AudioBufferSourceNodes connected to us either directly or indirectly about our existence.
126a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // This is in order to handle the pitch change necessary for the doppler shift.
127a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void notifyAudioSourcesConnectedToNode(AudioNode*);
128a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
129a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    OwnPtr<Panner> m_panner;
130a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    unsigned m_panningModel;
131a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
132f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    FloatPoint3D m_position;
133f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    FloatPoint3D m_orientation;
134f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    FloatPoint3D m_velocity;
135a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
136a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Gain
137a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<AudioGain> m_distanceGain;
138a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<AudioGain> m_coneGain;
139a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    DistanceEffect m_distanceEffect;
140a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ConeEffect m_coneEffect;
141a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    double m_lastGain;
142a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
143a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    unsigned m_connectionCount;
144a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch};
145a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
146a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} // namespace WebCore
147a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
148a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#endif // AudioPannerNode_h
149