summaryrefslogtreecommitdiffstats
path: root/dom/media/webaudio/PannerNode.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dom/media/webaudio/PannerNode.h221
1 files changed, 221 insertions, 0 deletions
diff --git a/dom/media/webaudio/PannerNode.h b/dom/media/webaudio/PannerNode.h
new file mode 100644
index 0000000000..94876c371c
--- /dev/null
+++ b/dom/media/webaudio/PannerNode.h
@@ -0,0 +1,221 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef PannerNode_h_
+#define PannerNode_h_
+
+#include "AudioNode.h"
+#include "AudioParam.h"
+#include "nsPrintfCString.h"
+#include "mozilla/dom/PannerNodeBinding.h"
+#include "ThreeDPoint.h"
+#include <limits>
+#include <set>
+
+namespace mozilla::dom {
+
+class AudioContext;
+class AudioBufferSourceNode;
+struct PannerOptions;
+
+class PannerNode final : public AudioNode {
+ public:
+ static already_AddRefed<PannerNode> Create(AudioContext& aAudioContext,
+ const PannerOptions& aOptions,
+ ErrorResult& aRv);
+
+ static already_AddRefed<PannerNode> Constructor(const GlobalObject& aGlobal,
+ AudioContext& aAudioContext,
+ const PannerOptions& aOptions,
+ ErrorResult& aRv) {
+ return Create(aAudioContext, aOptions, aRv);
+ }
+
+ JSObject* WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) override;
+
+ void SetChannelCount(uint32_t aChannelCount, ErrorResult& aRv) override {
+ if (aChannelCount > 2) {
+ aRv.ThrowNotSupportedError(
+ nsPrintfCString("%u is greater than 2", aChannelCount));
+ return;
+ }
+ AudioNode::SetChannelCount(aChannelCount, aRv);
+ }
+ void SetChannelCountModeValue(ChannelCountMode aMode,
+ ErrorResult& aRv) override {
+ if (aMode == ChannelCountMode::Max) {
+ aRv.ThrowNotSupportedError("Cannot set channel count mode to \"max\"");
+ return;
+ }
+ AudioNode::SetChannelCountModeValue(aMode, aRv);
+ }
+
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PannerNode, AudioNode)
+
+ PanningModelType PanningModel() const { return mPanningModel; }
+ void SetPanningModel(PanningModelType aPanningModel);
+
+ DistanceModelType DistanceModel() const { return mDistanceModel; }
+ void SetDistanceModel(DistanceModelType aDistanceModel) {
+ mDistanceModel = aDistanceModel;
+ SendInt32ParameterToTrack(DISTANCE_MODEL, int32_t(mDistanceModel));
+ }
+
+ void SetPosition(double aX, double aY, double aZ, ErrorResult& aRv);
+ void SetOrientation(double aX, double aY, double aZ, ErrorResult& aRv);
+
+ double RefDistance() const { return mRefDistance; }
+ void SetRefDistance(double aRefDistance, ErrorResult& aRv) {
+ if (WebAudioUtils::FuzzyEqual(mRefDistance, aRefDistance)) {
+ return;
+ }
+
+ if (aRefDistance < 0) {
+ aRv.ThrowRangeError(
+ "The refDistance value passed to PannerNode must not be negative.");
+ return;
+ }
+
+ mRefDistance = aRefDistance;
+ SendDoubleParameterToTrack(REF_DISTANCE, mRefDistance);
+ }
+
+ double MaxDistance() const { return mMaxDistance; }
+ void SetMaxDistance(double aMaxDistance, ErrorResult& aRv) {
+ if (WebAudioUtils::FuzzyEqual(mMaxDistance, aMaxDistance)) {
+ return;
+ }
+
+ if (aMaxDistance <= 0) {
+ aRv.ThrowRangeError(
+ "The maxDistance value passed to PannerNode must be positive.");
+ return;
+ }
+
+ mMaxDistance = aMaxDistance;
+ SendDoubleParameterToTrack(MAX_DISTANCE, mMaxDistance);
+ }
+
+ double RolloffFactor() const { return mRolloffFactor; }
+ void SetRolloffFactor(double aRolloffFactor, ErrorResult& aRv) {
+ if (WebAudioUtils::FuzzyEqual(mRolloffFactor, aRolloffFactor)) {
+ return;
+ }
+
+ if (aRolloffFactor < 0) {
+ aRv.ThrowRangeError(
+ "The rolloffFactor value passed to PannerNode must not be negative.");
+ return;
+ }
+
+ mRolloffFactor = aRolloffFactor;
+ SendDoubleParameterToTrack(ROLLOFF_FACTOR, mRolloffFactor);
+ }
+
+ double ConeInnerAngle() const { return mConeInnerAngle; }
+ void SetConeInnerAngle(double aConeInnerAngle) {
+ if (WebAudioUtils::FuzzyEqual(mConeInnerAngle, aConeInnerAngle)) {
+ return;
+ }
+ mConeInnerAngle = aConeInnerAngle;
+ SendDoubleParameterToTrack(CONE_INNER_ANGLE, mConeInnerAngle);
+ }
+
+ double ConeOuterAngle() const { return mConeOuterAngle; }
+ void SetConeOuterAngle(double aConeOuterAngle) {
+ if (WebAudioUtils::FuzzyEqual(mConeOuterAngle, aConeOuterAngle)) {
+ return;
+ }
+ mConeOuterAngle = aConeOuterAngle;
+ SendDoubleParameterToTrack(CONE_OUTER_ANGLE, mConeOuterAngle);
+ }
+
+ double ConeOuterGain() const { return mConeOuterGain; }
+ void SetConeOuterGain(double aConeOuterGain, ErrorResult& aRv) {
+ if (WebAudioUtils::FuzzyEqual(mConeOuterGain, aConeOuterGain)) {
+ return;
+ }
+
+ if (aConeOuterGain < 0 || aConeOuterGain > 1) {
+ aRv.ThrowInvalidStateError(
+ nsPrintfCString("%g is not in the range [0, 1]", aConeOuterGain));
+ return;
+ }
+
+ mConeOuterGain = aConeOuterGain;
+ SendDoubleParameterToTrack(CONE_OUTER_GAIN, mConeOuterGain);
+ }
+
+ AudioParam* PositionX() { return mPositionX; }
+
+ AudioParam* PositionY() { return mPositionY; }
+
+ AudioParam* PositionZ() { return mPositionZ; }
+
+ AudioParam* OrientationX() { return mOrientationX; }
+
+ AudioParam* OrientationY() { return mOrientationY; }
+
+ AudioParam* OrientationZ() { return mOrientationZ; }
+
+ const char* NodeType() const override { return "PannerNode"; }
+
+ size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
+ size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
+
+ private:
+ explicit PannerNode(AudioContext* aContext);
+ ~PannerNode() = default;
+
+ friend class AudioListener;
+ friend class PannerNodeEngine;
+ enum EngineParameters {
+ PANNING_MODEL,
+ DISTANCE_MODEL,
+ POSITION,
+ POSITIONX,
+ POSITIONY,
+ POSITIONZ,
+ ORIENTATION, // unit length or zero
+ ORIENTATIONX,
+ ORIENTATIONY,
+ ORIENTATIONZ,
+ REF_DISTANCE,
+ MAX_DISTANCE,
+ ROLLOFF_FACTOR,
+ CONE_INNER_ANGLE,
+ CONE_OUTER_ANGLE,
+ CONE_OUTER_GAIN
+ };
+
+ ThreeDPoint ConvertAudioParamTo3DP(RefPtr<AudioParam> aX,
+ RefPtr<AudioParam> aY,
+ RefPtr<AudioParam> aZ) {
+ return ThreeDPoint(aX->GetValue(), aY->GetValue(), aZ->GetValue());
+ }
+
+ PanningModelType mPanningModel;
+ DistanceModelType mDistanceModel;
+ RefPtr<AudioParam> mPositionX;
+ RefPtr<AudioParam> mPositionY;
+ RefPtr<AudioParam> mPositionZ;
+ RefPtr<AudioParam> mOrientationX;
+ RefPtr<AudioParam> mOrientationY;
+ RefPtr<AudioParam> mOrientationZ;
+
+ double mRefDistance;
+ double mMaxDistance;
+ double mRolloffFactor;
+ double mConeInnerAngle;
+ double mConeOuterAngle;
+ double mConeOuterGain;
+};
+
+} // namespace mozilla::dom
+
+#endif