summaryrefslogtreecommitdiffstats
path: root/dom/media/webaudio/AudioListener.h
blob: e3eaf1ca42718457700d62cf989df62f26f50a13 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/* -*- 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 AudioListener_h_
#define AudioListener_h_

#include "nsWrapperCache.h"
#include "nsCycleCollectionParticipant.h"
#include "mozilla/Attributes.h"
#include "ThreeDPoint.h"
#include "AudioContext.h"
#include "PannerNode.h"
#include "WebAudioUtils.h"
#include "js/TypeDecls.h"
#include "mozilla/MemoryReporting.h"

namespace mozilla {

namespace dom {

class AudioListener final : public nsWrapperCache
{
public:
  explicit AudioListener(AudioContext* aContext);

  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AudioListener)
  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(AudioListener)

  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;

  AudioContext* GetParentObject() const
  {
    return mContext;
  }

  JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;

  double DopplerFactor() const
  {
    return mDopplerFactor;
  }
  void SetDopplerFactor(double aDopplerFactor)
  {
    if (WebAudioUtils::FuzzyEqual(mDopplerFactor, aDopplerFactor)) {
      return;
    }
    mDopplerFactor = aDopplerFactor;
    SendDoubleParameterToStream(PannerNode::LISTENER_DOPPLER_FACTOR, mDopplerFactor);
  }

  double SpeedOfSound() const
  {
    return mSpeedOfSound;
  }
  void SetSpeedOfSound(double aSpeedOfSound)
  {
    if (WebAudioUtils::FuzzyEqual(mSpeedOfSound, aSpeedOfSound)) {
      return;
    }
    mSpeedOfSound = aSpeedOfSound;
    SendDoubleParameterToStream(PannerNode::LISTENER_SPEED_OF_SOUND, mSpeedOfSound);
  }

  void SetPosition(double aX, double aY, double aZ)
  {
    if (WebAudioUtils::FuzzyEqual(mPosition.x, aX) &&
        WebAudioUtils::FuzzyEqual(mPosition.y, aY) &&
        WebAudioUtils::FuzzyEqual(mPosition.z, aZ)) {
      return;
    }
    mPosition.x = aX;
    mPosition.y = aY;
    mPosition.z = aZ;
    SendThreeDPointParameterToStream(PannerNode::LISTENER_POSITION, mPosition);
  }

  const ThreeDPoint& Position() const
  {
    return mPosition;
  }

  void SetOrientation(double aX, double aY, double aZ,
                      double aXUp, double aYUp, double aZUp);

  const ThreeDPoint& Velocity() const
  {
    return mVelocity;
  }

  void SetVelocity(double aX, double aY, double aZ)
  {
    if (WebAudioUtils::FuzzyEqual(mVelocity.x, aX) &&
        WebAudioUtils::FuzzyEqual(mVelocity.y, aY) &&
        WebAudioUtils::FuzzyEqual(mVelocity.z, aZ)) {
      return;
    }
    mVelocity.x = aX;
    mVelocity.y = aY;
    mVelocity.z = aZ;
    SendThreeDPointParameterToStream(PannerNode::LISTENER_VELOCITY, mVelocity);
    UpdatePannersVelocity();
  }

  void RegisterPannerNode(PannerNode* aPannerNode);
  void UnregisterPannerNode(PannerNode* aPannerNode);

private:
  ~AudioListener() {}

  void SendDoubleParameterToStream(uint32_t aIndex, double aValue);
  void SendThreeDPointParameterToStream(uint32_t aIndex, const ThreeDPoint& aValue);
  void UpdatePannersVelocity();

private:
  friend class PannerNode;
  RefPtr<AudioContext> mContext;
  ThreeDPoint mPosition;
  ThreeDPoint mFrontVector;
  ThreeDPoint mRightVector;
  ThreeDPoint mVelocity;
  double mDopplerFactor;
  double mSpeedOfSound;
  nsTArray<WeakPtr<PannerNode> > mPanners;
};

} // namespace dom
} // namespace mozilla

#endif