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 PannerNode_h
     26 #define PannerNode_h
     27 
     28 #include "core/platform/audio/AudioBus.h"
     29 #include "core/platform/audio/Cone.h"
     30 #include "core/platform/audio/Distance.h"
     31 #include "core/platform/audio/Panner.h"
     32 #include "core/platform/graphics/FloatPoint3D.h"
     33 #include "modules/webaudio/AudioListener.h"
     34 #include "modules/webaudio/AudioNode.h"
     35 #include "modules/webaudio/AudioParam.h"
     36 #include "wtf/OwnPtr.h"
     37 
     38 namespace WebCore {
     39 
     40 // PannerNode 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 PannerNode : 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     // These must be defined as in the .idl file and must match those
     57     // in the DistanceEffect class.
     58     enum {
     59         LINEAR_DISTANCE = 0,
     60         INVERSE_DISTANCE = 1,
     61         EXPONENTIAL_DISTANCE = 2,
     62     };
     63 
     64     static PassRefPtr<PannerNode> create(AudioContext* context, float sampleRate)
     65     {
     66         return adoptRef(new PannerNode(context, sampleRate));
     67     }
     68 
     69     virtual ~PannerNode();
     70 
     71     // AudioNode
     72     virtual void process(size_t framesToProcess);
     73     virtual void pullInputs(size_t framesToProcess);
     74     virtual void reset();
     75     virtual void initialize();
     76     virtual void uninitialize();
     77 
     78     // Listener
     79     AudioListener* listener();
     80 
     81     // Panning model
     82     String panningModel() const;
     83     bool setPanningModel(unsigned); // Returns true on success.
     84     void setPanningModel(const String&);
     85 
     86     // Position
     87     FloatPoint3D position() const { return m_position; }
     88     void setPosition(float x, float y, float z) { m_position = FloatPoint3D(x, y, z); }
     89 
     90     // Orientation
     91     FloatPoint3D orientation() const { return m_position; }
     92     void setOrientation(float x, float y, float z) { m_orientation = FloatPoint3D(x, y, z); }
     93 
     94     // Velocity
     95     FloatPoint3D velocity() const { return m_velocity; }
     96     void setVelocity(float x, float y, float z) { m_velocity = FloatPoint3D(x, y, z); }
     97 
     98     // Distance parameters
     99     String distanceModel() const;
    100     bool setDistanceModel(unsigned); // Returns true on success.
    101     void setDistanceModel(const String&);
    102 
    103     double refDistance() { return m_distanceEffect.refDistance(); }
    104     void setRefDistance(double refDistance) { m_distanceEffect.setRefDistance(refDistance); }
    105 
    106     double maxDistance() { return m_distanceEffect.maxDistance(); }
    107     void setMaxDistance(double maxDistance) { m_distanceEffect.setMaxDistance(maxDistance); }
    108 
    109     double rolloffFactor() { return m_distanceEffect.rolloffFactor(); }
    110     void setRolloffFactor(double rolloffFactor) { m_distanceEffect.setRolloffFactor(rolloffFactor); }
    111 
    112     // Sound cones - angles in degrees
    113     double coneInnerAngle() const { return m_coneEffect.innerAngle(); }
    114     void setConeInnerAngle(double angle) { m_coneEffect.setInnerAngle(angle); }
    115 
    116     double coneOuterAngle() const { return m_coneEffect.outerAngle(); }
    117     void setConeOuterAngle(double angle) { m_coneEffect.setOuterAngle(angle); }
    118 
    119     double coneOuterGain() const { return m_coneEffect.outerGain(); }
    120     void setConeOuterGain(double angle) { m_coneEffect.setOuterGain(angle); }
    121 
    122     void getAzimuthElevation(double* outAzimuth, double* outElevation);
    123     float dopplerRate();
    124 
    125     // Accessors for dynamically calculated gain values.
    126     AudioParam* distanceGain() { return m_distanceGain.get(); }
    127     AudioParam* coneGain() { return m_coneGain.get(); }
    128 
    129     virtual double tailTime() const OVERRIDE { return m_panner ? m_panner->tailTime() : 0; }
    130     virtual double latencyTime() const OVERRIDE { return m_panner ? m_panner->latencyTime() : 0; }
    131 
    132 private:
    133     PannerNode(AudioContext*, float sampleRate);
    134 
    135     // Returns the combined distance and cone gain attenuation.
    136     float distanceConeGain();
    137 
    138     // Notifies any AudioBufferSourceNodes connected to us either directly or indirectly about our existence.
    139     // This is in order to handle the pitch change necessary for the doppler shift.
    140     void notifyAudioSourcesConnectedToNode(AudioNode*);
    141 
    142     OwnPtr<Panner> m_panner;
    143     unsigned m_panningModel;
    144 
    145     FloatPoint3D m_position;
    146     FloatPoint3D m_orientation;
    147     FloatPoint3D m_velocity;
    148 
    149     // Gain
    150     RefPtr<AudioParam> m_distanceGain;
    151     RefPtr<AudioParam> m_coneGain;
    152     DistanceEffect m_distanceEffect;
    153     ConeEffect m_coneEffect;
    154     float m_lastGain;
    155 
    156     unsigned m_connectionCount;
    157 
    158     // Synchronize process() and setPanningModel() which can change the panner.
    159     mutable Mutex m_pannerLock;
    160 };
    161 
    162 } // namespace WebCore
    163 
    164 #endif // PannerNode_h
    165