content/media/webaudio/PannerNode.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/content/media/webaudio/PannerNode.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,301 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* vim:set ts=2 sw=2 sts=2 et cindent: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#ifndef PannerNode_h_
    1.11 +#define PannerNode_h_
    1.12 +
    1.13 +#include "AudioNode.h"
    1.14 +#include "mozilla/dom/PannerNodeBinding.h"
    1.15 +#include "ThreeDPoint.h"
    1.16 +#include "mozilla/WeakPtr.h"
    1.17 +#include "mozilla/Preferences.h"
    1.18 +#include "WebAudioUtils.h"
    1.19 +#include <set>
    1.20 +
    1.21 +namespace mozilla {
    1.22 +namespace dom {
    1.23 +
    1.24 +class AudioContext;
    1.25 +class AudioBufferSourceNode;
    1.26 +
    1.27 +class PannerNode : public AudioNode,
    1.28 +                   public SupportsWeakPtr<PannerNode>
    1.29 +{
    1.30 +public:
    1.31 +  MOZ_DECLARE_REFCOUNTED_TYPENAME(PannerNode)
    1.32 +  explicit PannerNode(AudioContext* aContext);
    1.33 +  virtual ~PannerNode();
    1.34 +
    1.35 +
    1.36 +  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
    1.37 +
    1.38 +  virtual void DestroyMediaStream() MOZ_OVERRIDE;
    1.39 +
    1.40 +  virtual void SetChannelCount(uint32_t aChannelCount, ErrorResult& aRv) MOZ_OVERRIDE
    1.41 +  {
    1.42 +    if (aChannelCount > 2) {
    1.43 +      aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
    1.44 +      return;
    1.45 +    }
    1.46 +    AudioNode::SetChannelCount(aChannelCount, aRv);
    1.47 +  }
    1.48 +  virtual void SetChannelCountModeValue(ChannelCountMode aMode, ErrorResult& aRv) MOZ_OVERRIDE
    1.49 +  {
    1.50 +    if (aMode == ChannelCountMode::Max) {
    1.51 +      aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
    1.52 +      return;
    1.53 +    }
    1.54 +    AudioNode::SetChannelCountModeValue(aMode, aRv);
    1.55 +  }
    1.56 +
    1.57 +  NS_DECL_ISUPPORTS_INHERITED
    1.58 +  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PannerNode, AudioNode)
    1.59 +
    1.60 +  PanningModelType PanningModel() const
    1.61 +  {
    1.62 +    return mPanningModel;
    1.63 +  }
    1.64 +  void SetPanningModel(PanningModelType aPanningModel)
    1.65 +  {
    1.66 +    if (!Preferences::GetBool("media.webaudio.legacy.PannerNode")) {
    1.67 +      // Do not accept the alternate enum values unless the legacy pref
    1.68 +      // has been turned on.
    1.69 +      switch (aPanningModel) {
    1.70 +      case PanningModelType::_0:
    1.71 +      case PanningModelType::_1:
    1.72 +        // Do nothing in order to emulate setting an invalid enum value.
    1.73 +        return;
    1.74 +      default:
    1.75 +        // Shut up the compiler warning
    1.76 +        break;
    1.77 +      }
    1.78 +    }
    1.79 +
    1.80 +    // Handle the alternate enum values
    1.81 +    switch (aPanningModel) {
    1.82 +    case PanningModelType::_0: aPanningModel = PanningModelType::Equalpower; break;
    1.83 +    case PanningModelType::_1: aPanningModel = PanningModelType::HRTF; break;
    1.84 +    default:
    1.85 +      // Shut up the compiler warning
    1.86 +      break;
    1.87 +    }
    1.88 +
    1.89 +    mPanningModel = aPanningModel;
    1.90 +    SendInt32ParameterToStream(PANNING_MODEL, int32_t(mPanningModel));
    1.91 +  }
    1.92 +
    1.93 +  DistanceModelType DistanceModel() const
    1.94 +  {
    1.95 +    return mDistanceModel;
    1.96 +  }
    1.97 +  void SetDistanceModel(DistanceModelType aDistanceModel)
    1.98 +  {
    1.99 +    if (!Preferences::GetBool("media.webaudio.legacy.PannerNode")) {
   1.100 +      // Do not accept the alternate enum values unless the legacy pref
   1.101 +      // has been turned on.
   1.102 +      switch (aDistanceModel) {
   1.103 +      case DistanceModelType::_0:
   1.104 +      case DistanceModelType::_1:
   1.105 +      case DistanceModelType::_2:
   1.106 +        // Do nothing in order to emulate setting an invalid enum value.
   1.107 +        return;
   1.108 +      default:
   1.109 +        // Shut up the compiler warning
   1.110 +        break;
   1.111 +      }
   1.112 +    }
   1.113 +
   1.114 +    // Handle the alternate enum values
   1.115 +    switch (aDistanceModel) {
   1.116 +    case DistanceModelType::_0: aDistanceModel = DistanceModelType::Linear; break;
   1.117 +    case DistanceModelType::_1: aDistanceModel = DistanceModelType::Inverse; break;
   1.118 +    case DistanceModelType::_2: aDistanceModel = DistanceModelType::Exponential; break;
   1.119 +    default:
   1.120 +      // Shut up the compiler warning
   1.121 +      break;
   1.122 +    }
   1.123 +
   1.124 +    mDistanceModel = aDistanceModel;
   1.125 +    SendInt32ParameterToStream(DISTANCE_MODEL, int32_t(mDistanceModel));
   1.126 +  }
   1.127 +
   1.128 +  void SetPosition(double aX, double aY, double aZ)
   1.129 +  {
   1.130 +    if (WebAudioUtils::FuzzyEqual(mPosition.x, aX) &&
   1.131 +        WebAudioUtils::FuzzyEqual(mPosition.y, aY) &&
   1.132 +        WebAudioUtils::FuzzyEqual(mPosition.z, aZ)) {
   1.133 +      return;
   1.134 +    }
   1.135 +    mPosition.x = aX;
   1.136 +    mPosition.y = aY;
   1.137 +    mPosition.z = aZ;
   1.138 +    SendThreeDPointParameterToStream(POSITION, mPosition);
   1.139 +  }
   1.140 +
   1.141 +  void SetOrientation(double aX, double aY, double aZ)
   1.142 +  {
   1.143 +    ThreeDPoint orientation(aX, aY, aZ);
   1.144 +    if (!orientation.IsZero()) {
   1.145 +      orientation.Normalize();
   1.146 +    }
   1.147 +    if (mOrientation.FuzzyEqual(orientation)) {
   1.148 +      return;
   1.149 +    }
   1.150 +    mOrientation = orientation;
   1.151 +    SendThreeDPointParameterToStream(ORIENTATION, mOrientation);
   1.152 +  }
   1.153 +
   1.154 +  void SetVelocity(double aX, double aY, double aZ)
   1.155 +  {
   1.156 +    if (WebAudioUtils::FuzzyEqual(mVelocity.x, aX) &&
   1.157 +        WebAudioUtils::FuzzyEqual(mVelocity.y, aY) &&
   1.158 +        WebAudioUtils::FuzzyEqual(mVelocity.z, aZ)) {
   1.159 +      return;
   1.160 +    }
   1.161 +    mVelocity.x = aX;
   1.162 +    mVelocity.y = aY;
   1.163 +    mVelocity.z = aZ;
   1.164 +    SendThreeDPointParameterToStream(VELOCITY, mVelocity);
   1.165 +    SendDopplerToSourcesIfNeeded();
   1.166 +  }
   1.167 +
   1.168 +  double RefDistance() const
   1.169 +  {
   1.170 +    return mRefDistance;
   1.171 +  }
   1.172 +  void SetRefDistance(double aRefDistance)
   1.173 +  {
   1.174 +    if (WebAudioUtils::FuzzyEqual(mRefDistance, aRefDistance)) {
   1.175 +      return;
   1.176 +    }
   1.177 +    mRefDistance = aRefDistance;
   1.178 +    SendDoubleParameterToStream(REF_DISTANCE, mRefDistance);
   1.179 +  }
   1.180 +
   1.181 +  double MaxDistance() const
   1.182 +  {
   1.183 +    return mMaxDistance;
   1.184 +  }
   1.185 +  void SetMaxDistance(double aMaxDistance)
   1.186 +  {
   1.187 +    if (WebAudioUtils::FuzzyEqual(mMaxDistance, aMaxDistance)) {
   1.188 +      return;
   1.189 +    }
   1.190 +    mMaxDistance = aMaxDistance;
   1.191 +    SendDoubleParameterToStream(MAX_DISTANCE, mMaxDistance);
   1.192 +  }
   1.193 +
   1.194 +  double RolloffFactor() const
   1.195 +  {
   1.196 +    return mRolloffFactor;
   1.197 +  }
   1.198 +  void SetRolloffFactor(double aRolloffFactor)
   1.199 +  {
   1.200 +    if (WebAudioUtils::FuzzyEqual(mRolloffFactor, aRolloffFactor)) {
   1.201 +      return;
   1.202 +    }
   1.203 +    mRolloffFactor = aRolloffFactor;
   1.204 +    SendDoubleParameterToStream(ROLLOFF_FACTOR, mRolloffFactor);
   1.205 +  }
   1.206 +
   1.207 +  double ConeInnerAngle() const
   1.208 +  {
   1.209 +    return mConeInnerAngle;
   1.210 +  }
   1.211 +  void SetConeInnerAngle(double aConeInnerAngle)
   1.212 +  {
   1.213 +    if (WebAudioUtils::FuzzyEqual(mConeInnerAngle, aConeInnerAngle)) {
   1.214 +      return;
   1.215 +    }
   1.216 +    mConeInnerAngle = aConeInnerAngle;
   1.217 +    SendDoubleParameterToStream(CONE_INNER_ANGLE, mConeInnerAngle);
   1.218 +  }
   1.219 +
   1.220 +  double ConeOuterAngle() const
   1.221 +  {
   1.222 +    return mConeOuterAngle;
   1.223 +  }
   1.224 +  void SetConeOuterAngle(double aConeOuterAngle)
   1.225 +  {
   1.226 +    if (WebAudioUtils::FuzzyEqual(mConeOuterAngle, aConeOuterAngle)) {
   1.227 +      return;
   1.228 +    }
   1.229 +    mConeOuterAngle = aConeOuterAngle;
   1.230 +    SendDoubleParameterToStream(CONE_OUTER_ANGLE, mConeOuterAngle);
   1.231 +  }
   1.232 +
   1.233 +  double ConeOuterGain() const
   1.234 +  {
   1.235 +    return mConeOuterGain;
   1.236 +  }
   1.237 +  void SetConeOuterGain(double aConeOuterGain)
   1.238 +  {
   1.239 +    if (WebAudioUtils::FuzzyEqual(mConeOuterGain, aConeOuterGain)) {
   1.240 +      return;
   1.241 +    }
   1.242 +    mConeOuterGain = aConeOuterGain;
   1.243 +    SendDoubleParameterToStream(CONE_OUTER_GAIN, mConeOuterGain);
   1.244 +  }
   1.245 +
   1.246 +  float ComputeDopplerShift();
   1.247 +  void SendDopplerToSourcesIfNeeded();
   1.248 +  void FindConnectedSources();
   1.249 +  void FindConnectedSources(AudioNode* aNode, nsTArray<AudioBufferSourceNode*>& aSources, std::set<AudioNode*>& aSeenNodes);
   1.250 +
   1.251 +  virtual const char* NodeType() const
   1.252 +  {
   1.253 +    return "PannerNode";
   1.254 +  }
   1.255 +
   1.256 +  virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
   1.257 +  virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
   1.258 +
   1.259 +private:
   1.260 +  friend class AudioListener;
   1.261 +  friend class PannerNodeEngine;
   1.262 +  enum EngineParameters {
   1.263 +    LISTENER_POSITION,
   1.264 +    LISTENER_FRONT_VECTOR, // unit length
   1.265 +    LISTENER_RIGHT_VECTOR, // unit length, orthogonal to LISTENER_FRONT_VECTOR
   1.266 +    LISTENER_VELOCITY,
   1.267 +    LISTENER_DOPPLER_FACTOR,
   1.268 +    LISTENER_SPEED_OF_SOUND,
   1.269 +    PANNING_MODEL,
   1.270 +    DISTANCE_MODEL,
   1.271 +    POSITION,
   1.272 +    ORIENTATION, // unit length or zero
   1.273 +    VELOCITY,
   1.274 +    REF_DISTANCE,
   1.275 +    MAX_DISTANCE,
   1.276 +    ROLLOFF_FACTOR,
   1.277 +    CONE_INNER_ANGLE,
   1.278 +    CONE_OUTER_ANGLE,
   1.279 +    CONE_OUTER_GAIN
   1.280 +  };
   1.281 +
   1.282 +private:
   1.283 +  PanningModelType mPanningModel;
   1.284 +  DistanceModelType mDistanceModel;
   1.285 +  ThreeDPoint mPosition;
   1.286 +  ThreeDPoint mOrientation;
   1.287 +  ThreeDPoint mVelocity;
   1.288 +  double mRefDistance;
   1.289 +  double mMaxDistance;
   1.290 +  double mRolloffFactor;
   1.291 +  double mConeInnerAngle;
   1.292 +  double mConeOuterAngle;
   1.293 +  double mConeOuterGain;
   1.294 +
   1.295 +  // An array of all the AudioBufferSourceNode connected directly or indirectly
   1.296 +  // to this AudioPannerNode.
   1.297 +  nsTArray<AudioBufferSourceNode*> mSources;
   1.298 +};
   1.299 +
   1.300 +}
   1.301 +}
   1.302 +
   1.303 +#endif
   1.304 +

mercurial