Home | History | Annotate | Download | only in webaudio
      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  * 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.
     12  *
     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.
     23  */
     24 
     25 #ifndef AudioPannerNode_h
     26 #define AudioPannerNode_h
     27 
     28 #include "AudioBus.h"
     29 #include "AudioGain.h"
     30 #include "AudioListener.h"
     31 #include "AudioNode.h"
     32 #include "Cone.h"
     33 #include "Distance.h"
     34 #include "FloatPoint3D.h"
     35 #include "Panner.h"
     36 #include <wtf/OwnPtr.h>
     37 
     38 namespace WebCore {
     39 
     40 // AudioPannerNode is an AudioNode with one input and one output.
     41 // It positions a sound in 3D space, with the exact effect dependent on the panning model.
     42 // It has a position and an orientation in 3D space which is relative to the position and orientation of the context's AudioListener.
     43 // A distance effect will attenuate the gain as the position moves away from the listener.
     44 // A cone effect will attenuate the gain as the orientation moves away from the listener.
     45 // All of these effects follow the OpenAL specification very closely.
     46 
     47 class AudioPannerNode : public AudioNode {
     48 public:
     49     // These must be defined as in the .idl file and must match those in the Panner class.
     50     enum {
     51         EQUALPOWER = 0,
     52         HRTF = 1,
     53         SOUNDFIELD = 2,
     54     };
     55 
     56     static PassRefPtr<AudioPannerNode> create(AudioContext* context, double sampleRate)
     57     {
     58         return adoptRef(new AudioPannerNode(context, sampleRate));
     59     }
     60 
     61     virtual ~AudioPannerNode();
     62 
     63     // AudioNode
     64     virtual void process(size_t framesToProcess);
     65     virtual void pullInputs(size_t framesToProcess);
     66     virtual void reset();
     67     virtual void initialize();
     68     virtual void uninitialize();
     69 
     70     // Listener
     71     AudioListener* listener();
     72 
     73     // Panning model
     74     unsigned short panningModel() const { return m_panningModel; }
     75     void setPanningModel(unsigned short);
     76 
     77     // Position
     78     FloatPoint3D position() const { return m_position; }
     79     void setPosition(float x, float y, float z) { m_position = FloatPoint3D(x, y, z); }
     80 
     81     // Orientation
     82     FloatPoint3D orientation() const { return m_position; }
     83     void setOrientation(float x, float y, float z) { m_orientation = FloatPoint3D(x, y, z); }
     84 
     85     // Velocity
     86     FloatPoint3D velocity() const { return m_velocity; }
     87     void setVelocity(float x, float y, float z) { m_velocity = FloatPoint3D(x, y, z); }
     88 
     89     // Distance parameters
     90     unsigned short distanceModel() { return m_distanceEffect.model(); }
     91     void setDistanceModel(unsigned short model) { m_distanceEffect.setModel(static_cast<DistanceEffect::ModelType>(model), true); }
     92 
     93     float refDistance() { return static_cast<float>(m_distanceEffect.refDistance()); }
     94     void setRefDistance(float refDistance) { m_distanceEffect.setRefDistance(refDistance); }
     95 
     96     float maxDistance() { return static_cast<float>(m_distanceEffect.maxDistance()); }
     97     void setMaxDistance(float maxDistance) { m_distanceEffect.setMaxDistance(maxDistance); }
     98 
     99     float rolloffFactor() { return static_cast<float>(m_distanceEffect.rolloffFactor()); }
    100     void setRolloffFactor(float rolloffFactor) { m_distanceEffect.setRolloffFactor(rolloffFactor); }
    101 
    102     // Sound cones - angles in degrees
    103     float coneInnerAngle() const { return static_cast<float>(m_coneEffect.innerAngle()); }
    104     void setConeInnerAngle(float angle) { m_coneEffect.setInnerAngle(angle); }
    105 
    106     float coneOuterAngle() const { return static_cast<float>(m_coneEffect.outerAngle()); }
    107     void setConeOuterAngle(float angle) { m_coneEffect.setOuterAngle(angle); }
    108 
    109     float coneOuterGain() const { return static_cast<float>(m_coneEffect.outerGain()); }
    110     void setConeOuterGain(float angle) { m_coneEffect.setOuterGain(angle); }
    111 
    112     void getAzimuthElevation(double* outAzimuth, double* outElevation);
    113     float dopplerRate();
    114 
    115     // Accessors for dynamically calculated gain values.
    116     AudioGain* distanceGain() { return m_distanceGain.get(); }
    117     AudioGain* coneGain() { return m_coneGain.get(); }
    118 
    119 private:
    120     AudioPannerNode(AudioContext*, double sampleRate);
    121 
    122     // Returns the combined distance and cone gain attenuation.
    123     float distanceConeGain();
    124 
    125     // Notifies any AudioBufferSourceNodes connected to us either directly or indirectly about our existence.
    126     // This is in order to handle the pitch change necessary for the doppler shift.
    127     void notifyAudioSourcesConnectedToNode(AudioNode*);
    128 
    129     OwnPtr<Panner> m_panner;
    130     unsigned m_panningModel;
    131 
    132     FloatPoint3D m_position;
    133     FloatPoint3D m_orientation;
    134     FloatPoint3D m_velocity;
    135 
    136     // Gain
    137     RefPtr<AudioGain> m_distanceGain;
    138     RefPtr<AudioGain> m_coneGain;
    139     DistanceEffect m_distanceEffect;
    140     ConeEffect m_coneEffect;
    141     double m_lastGain;
    142 
    143     unsigned m_connectionCount;
    144 };
    145 
    146 } // namespace WebCore
    147 
    148 #endif // AudioPannerNode_h
    149