summaryrefslogtreecommitdiffstats
path: root/dom/media/webaudio/AudioListener.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/webaudio/AudioListener.cpp')
-rw-r--r--dom/media/webaudio/AudioListener.cpp136
1 files changed, 136 insertions, 0 deletions
diff --git a/dom/media/webaudio/AudioListener.cpp b/dom/media/webaudio/AudioListener.cpp
new file mode 100644
index 0000000000..2e00af9764
--- /dev/null
+++ b/dom/media/webaudio/AudioListener.cpp
@@ -0,0 +1,136 @@
+/* -*- 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/. */
+
+#include "AudioContext.h"
+#include "AudioListener.h"
+#include "MediaTrackGraphImpl.h"
+#include "Tracing.h"
+#include "mozilla/dom/AudioListenerBinding.h"
+
+namespace mozilla::dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(AudioListener, mContext)
+
+AudioListenerEngine::AudioListenerEngine()
+ : mPosition(), mFrontVector(0., 0., -1.), mRightVector(1., 0., 0.) {}
+
+void AudioListenerEngine::RecvListenerEngineEvent(
+ AudioListenerEngine::AudioListenerParameter aParameter,
+ const ThreeDPoint& aValue) {
+ switch (aParameter) {
+ case AudioListenerParameter::POSITION:
+ mPosition = aValue;
+ break;
+ case AudioListenerParameter::FRONT:
+ mFrontVector = aValue;
+ break;
+ case AudioListenerParameter::RIGHT:
+ mRightVector = aValue;
+ break;
+ default:
+ MOZ_CRASH("Not handled");
+ }
+}
+
+const ThreeDPoint& AudioListenerEngine::Position() const { return mPosition; }
+const ThreeDPoint& AudioListenerEngine::FrontVector() const {
+ return mFrontVector;
+}
+const ThreeDPoint& AudioListenerEngine::RightVector() const {
+ return mRightVector;
+}
+
+AudioListener::AudioListener(AudioContext* aContext)
+ : mContext(aContext),
+ mEngine(new AudioListenerEngine()),
+ mPosition(),
+ mFrontVector(0., 0., -1.),
+ mRightVector(1., 0., 0.) {
+ MOZ_ASSERT(aContext);
+}
+
+JSObject* AudioListener::WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) {
+ return AudioListener_Binding::Wrap(aCx, this, aGivenProto);
+}
+
+void AudioListener::SetOrientation(double aX, double aY, double aZ, double aXUp,
+ double aYUp, double aZUp) {
+ ThreeDPoint front(aX, aY, aZ);
+ // The panning effect and the azimuth and elevation calculation in the Web
+ // Audio spec becomes undefined with linearly dependent vectors, so keep
+ // existing state in these situations.
+ if (front.IsZero()) {
+ return;
+ }
+ // Normalize before using CrossProduct() to avoid overflow.
+ front.Normalize();
+ ThreeDPoint up(aXUp, aYUp, aZUp);
+ if (up.IsZero()) {
+ return;
+ }
+ up.Normalize();
+ ThreeDPoint right = front.CrossProduct(up);
+ if (right.IsZero()) {
+ return;
+ }
+ right.Normalize();
+
+ if (!mFrontVector.FuzzyEqual(front)) {
+ mFrontVector = front;
+ SendListenerEngineEvent(AudioListenerEngine::AudioListenerParameter::FRONT,
+ mFrontVector);
+ }
+ if (!mRightVector.FuzzyEqual(right)) {
+ mRightVector = right;
+ SendListenerEngineEvent(AudioListenerEngine::AudioListenerParameter::RIGHT,
+ mRightVector);
+ }
+}
+
+void AudioListener::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;
+ SendListenerEngineEvent(AudioListenerEngine::AudioListenerParameter::POSITION,
+ mPosition);
+}
+
+void AudioListener::SendListenerEngineEvent(
+ AudioListenerEngine::AudioListenerParameter aParameter,
+ const ThreeDPoint& aValue) {
+ class Message final : public ControlMessage {
+ public:
+ Message(AudioListenerEngine* aEngine,
+ AudioListenerEngine::AudioListenerParameter aParameter,
+ const ThreeDPoint& aValue)
+ : ControlMessage(nullptr),
+ mEngine(aEngine),
+ mParameter(aParameter),
+ mValue(aValue) {}
+ void Run() override {
+ TRACE("AudioListener::RecvListenerEngineEvent");
+ mEngine->RecvListenerEngineEvent(mParameter, mValue);
+ }
+ RefPtr<AudioListenerEngine> mEngine;
+ AudioListenerEngine::AudioListenerParameter mParameter;
+ ThreeDPoint mValue;
+ };
+
+ mContext->DestinationTrack()->GraphImpl()->AppendMessage(
+ MakeUnique<Message>(Engine(), aParameter, aValue));
+}
+
+size_t AudioListener::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
+ return aMallocSizeOf(this);
+}
+
+} // namespace mozilla::dom