summaryrefslogtreecommitdiffstats
path: root/src/spatialaudioquick3d
diff options
context:
space:
mode:
Diffstat (limited to 'src/spatialaudioquick3d')
-rw-r--r--src/spatialaudioquick3d/CMakeLists.txt32
-rw-r--r--src/spatialaudioquick3d/qquick3dambientsound.cpp146
-rw-r--r--src/spatialaudioquick3d/qquick3dambientsound_p.h74
-rw-r--r--src/spatialaudioquick3d/qquick3daudio-qml-types.qdoc32
-rw-r--r--src/spatialaudioquick3d/qquick3daudioengine.cpp128
-rw-r--r--src/spatialaudioquick3d/qquick3daudioengine_p.h64
-rw-r--r--src/spatialaudioquick3d/qquick3daudiolistener.cpp49
-rw-r--r--src/spatialaudioquick3d/qquick3daudiolistener_p.h47
-rw-r--r--src/spatialaudioquick3d/qquick3daudioroom.cpp270
-rw-r--r--src/spatialaudioquick3d/qquick3daudioroom_p.h129
-rw-r--r--src/spatialaudioquick3d/qquick3dspatialaudio_plugin.cpp35
-rw-r--r--src/spatialaudioquick3d/qquick3dspatialsound.cpp323
-rw-r--r--src/spatialaudioquick3d/qquick3dspatialsound_p.h127
-rw-r--r--src/spatialaudioquick3d/qtquick3daudioglobal_p.h28
-rw-r--r--src/spatialaudioquick3d/qtquick3daudiotypes_p.h27
15 files changed, 1511 insertions, 0 deletions
diff --git a/src/spatialaudioquick3d/CMakeLists.txt b/src/spatialaudioquick3d/CMakeLists.txt
new file mode 100644
index 000000000..f781ef766
--- /dev/null
+++ b/src/spatialaudioquick3d/CMakeLists.txt
@@ -0,0 +1,32 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## Quick3D.Sound Module:
+#####################################################################
+
+qt_internal_add_qml_module(Quick3DSpatialAudioPrivate
+ URI "QtQuick3D.SpatialAudio"
+ VERSION "${PROJECT_VERSION}"
+ CLASS_NAME QQuick3DAudioModule
+ PLUGIN_TARGET quick3dspatialaudio
+ NO_GENERATE_PLUGIN_SOURCE
+ NO_PLUGIN_OPTIONAL
+ DEPENDENCIES QtQuick QtQuick3DPrivate QtMultimedia
+ CONFIG_MODULE_NAME quick3dspatialaudio
+ INTERNAL_MODULE
+ SOURCES
+ qquick3daudiolistener.cpp qquick3daudiolistener_p.h
+ qquick3daudioroom.cpp qquick3daudioroom_p.h
+ qquick3dspatialsound.cpp qquick3dspatialsound_p.h
+ qquick3dambientsound.cpp qquick3dambientsound_p.h
+ qquick3daudioengine.cpp qquick3daudioengine_p.h
+ qtquick3daudioglobal_p.h
+ qtquick3daudiotypes_p.h
+ QML_FILES
+ PUBLIC_LIBRARIES
+ Qt::Quick3DPrivate
+ Qt::SpatialAudio
+)
+
+target_sources(quick3dspatialaudio PRIVATE qquick3dspatialaudio_plugin.cpp)
diff --git a/src/spatialaudioquick3d/qquick3dambientsound.cpp b/src/spatialaudioquick3d/qquick3dambientsound.cpp
new file mode 100644
index 000000000..3b8ca4918
--- /dev/null
+++ b/src/spatialaudioquick3d/qquick3dambientsound.cpp
@@ -0,0 +1,146 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-3.0-only
+#include "qquick3dambientsound_p.h"
+#include "qquick3daudioengine_p.h"
+#include "qambientsound.h"
+#include <QAudioFormat>
+#include <qdir.h>
+#include <QQmlContext>
+#include <QQmlFile>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype AmbientSound
+ \inqmlmodule QtQuick3D.SpatialAudio
+ \ingroup quick3d_spatialaudio
+ \ingroup multimedia_audio_qml
+
+ \brief A stereo overlay sound.
+
+ A AmbientSound represents a position and orientation independent sound.
+ It's commonly used for background sounds (e.g. music) that is supposed to be independent
+ of the listeners position and orientation.
+ */
+
+QQuick3DAmbientSound::QQuick3DAmbientSound()
+{
+ m_sound = new QAmbientSound(QQuick3DAudioEngine::getEngine());
+
+ connect(m_sound, &QAmbientSound::sourceChanged, this, &QQuick3DAmbientSound::sourceChanged);
+ connect(m_sound, &QAmbientSound::volumeChanged, this, &QQuick3DAmbientSound::volumeChanged);
+ connect(m_sound, &QAmbientSound::loopsChanged, this, &QQuick3DAmbientSound::loopsChanged);
+ connect(m_sound, &QAmbientSound::autoPlayChanged, this, &QQuick3DAmbientSound::autoPlayChanged);
+}
+
+QQuick3DAmbientSound::~QQuick3DAmbientSound()
+{
+ delete m_sound;
+}
+
+/*!
+ \qmlproperty url AmbientSound::source
+
+ The source file for the sound to be played.
+ */
+QUrl QQuick3DAmbientSound::source() const
+{
+ return m_sound->source();
+}
+
+void QQuick3DAmbientSound::setSource(QUrl source)
+{
+ const QQmlContext *context = qmlContext(this);
+ QUrl url;
+ if (context) {
+ url = context->resolvedUrl(source);
+ } else {
+ url = QUrl::fromLocalFile(QDir::currentPath() + u"/");
+ url = url.resolved(source);
+ }
+ m_sound->setSource(url);
+}
+
+/*!
+ \qmlproperty float AmbientSound::volume
+
+ Defines an overall volume for this sound source.
+ */
+void QQuick3DAmbientSound::setVolume(float volume)
+{
+ m_sound->setVolume(volume);
+}
+
+float QQuick3DAmbientSound::volume() const
+{
+ return m_sound->volume();
+}
+
+/*!
+ \qmlproperty int AmbientSound::loops
+
+ Determines how often the sound is played before the player stops.
+ Set to QAmbienSound::Infinite to loop the current sound forever.
+
+ The default value is \c 1.
+ */
+int QQuick3DAmbientSound::loops() const
+{
+ return m_sound->loops();
+}
+
+void QQuick3DAmbientSound::setLoops(int loops)
+{
+ m_sound->setLoops(loops);
+}
+
+/*!
+ \qmlproperty bool AmbientSound::autoPlay
+
+ Determines whether the sound should automatically start playing when a source
+ gets specified.
+
+ The default value is \c true.
+ */
+bool QQuick3DAmbientSound::autoPlay() const
+{
+ return m_sound->autoPlay();
+}
+
+void QQuick3DAmbientSound::setAutoPlay(bool autoPlay)
+{
+ m_sound->setAutoPlay(autoPlay);
+}
+
+/*!
+ \qmlmethod AmbientSound::play()
+
+ Starts playing back the sound. Does nothing if the sound is already playing.
+ */
+void QQuick3DAmbientSound::play()
+{
+ m_sound->play();
+}
+
+/*!
+ \qmlmethod AmbientSound::pause()
+
+ Pauses sound playback at the current position. Calling play() will continue playback.
+ */
+void QQuick3DAmbientSound::pause()
+{
+ m_sound->pause();
+}
+
+/*!
+ \qmlmethod AmbientSound::stop()
+
+ Stops sound playback and resets the current position and loop count to 0. Calling play() will
+ begin playback at the beginning of the sound file.
+ */
+void QQuick3DAmbientSound::stop()
+{
+ m_sound->stop();
+}
+
+QT_END_NAMESPACE
diff --git a/src/spatialaudioquick3d/qquick3dambientsound_p.h b/src/spatialaudioquick3d/qquick3dambientsound_p.h
new file mode 100644
index 000000000..6185179ce
--- /dev/null
+++ b/src/spatialaudioquick3d/qquick3dambientsound_p.h
@@ -0,0 +1,74 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-3.0-only
+#ifndef QQUICK3DAMBIENTSOUND_H
+#define QQUICK3DAMBIENTSOUND_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qquick3dnode_p.h>
+#include <QUrl>
+#include <qvector3d.h>
+
+QT_BEGIN_NAMESPACE
+
+class QAmbientSound;
+
+class QQuick3DAmbientSound : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
+ Q_PROPERTY(float volume READ volume WRITE setVolume NOTIFY volumeChanged)
+ Q_PROPERTY(int loops READ loops WRITE setLoops NOTIFY loopsChanged)
+ Q_PROPERTY(bool autoPlay READ autoPlay WRITE setAutoPlay NOTIFY autoPlayChanged)
+ QML_NAMED_ELEMENT(AmbientSound)
+
+public:
+ QQuick3DAmbientSound();
+ ~QQuick3DAmbientSound();
+
+ void setSource(QUrl source);
+ QUrl source() const;
+
+ void setVolume(float volume);
+ float volume() const;
+
+ enum Loops
+ {
+ Infinite = -1,
+ Once = 1
+ };
+ Q_ENUM(Loops)
+
+ int loops() const;
+ void setLoops(int loops);
+
+ bool autoPlay() const;
+ void setAutoPlay(bool autoPlay);
+
+public Q_SLOTS:
+ void play();
+ void pause();
+ void stop();
+
+Q_SIGNALS:
+ void sourceChanged();
+ void volumeChanged();
+ void loopsChanged();
+ void autoPlayChanged();
+
+private:
+ QAmbientSound *m_sound = nullptr;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/spatialaudioquick3d/qquick3daudio-qml-types.qdoc b/src/spatialaudioquick3d/qquick3daudio-qml-types.qdoc
new file mode 100644
index 000000000..0ccb69bb9
--- /dev/null
+++ b/src/spatialaudioquick3d/qquick3daudio-qml-types.qdoc
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+\qmlmodule QtQuick3D.Audio
+\title QtQuick3D.SpatialAudio QML Types
+\ingroup qmlmodules
+\brief Provides QML types for spatial audio in Qt Quick 3D.
+
+The QML types Spatial Audio support the basic use cases such as:
+\list
+ \li have a person listening to sounds in 3D space,
+ \li place sound sources in 3D space,
+ \li support room acoustics with direct reflections and reverb,
+ \li support stereo overlay sources (e.g. for sound tracks).
+ \li support output to Headphones using binaural (virtual 3D) rendering of the sound field
+ \li support output to stereo or surround speaker configurations
+\endlist
+
+\section1 QML Types
+
+Qt Quick3D Spatial Audio QML types can be imported into your application using the
+following import statement in your .qml file:
+
+\qml \QtMinorVersion
+import QtQuick3D.Audio
+\endqml
+
+\generatelist qmltypesbymodule QtQuick3D.Audio
+
+\noautolist
+*/
diff --git a/src/spatialaudioquick3d/qquick3daudioengine.cpp b/src/spatialaudioquick3d/qquick3daudioengine.cpp
new file mode 100644
index 000000000..1288effb3
--- /dev/null
+++ b/src/spatialaudioquick3d/qquick3daudioengine.cpp
@@ -0,0 +1,128 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-3.0-only
+#include <qquick3daudioengine_p.h>
+#include <qaudiodevice.h>
+
+QT_BEGIN_NAMESPACE
+
+static QAudioEngine *globalEngine = nullptr;
+
+/*!
+ \qmltype AudioEngine
+ \inqmlmodule QtQuick3D.SpatialAudio
+ \ingroup quick3d_spatialaudio
+ \ingroup multimedia_audio_qml
+
+ \brief AudioEngine manages sound objects inside a 3D scene.
+
+ AudioEngine manages sound objects inside a 3D scene. You can add
+ SpatialSound objects to the scene to define sounds that happen
+ at a specified location in 3D space. AmbientSound allows you to add
+ a stereo overlay (for example voice over or a sound track).
+
+ You can use AudioListener to define the position of the person listening
+ to the sound field relative to the sound sources. Sound sources will be less audible
+ if the listener is further away from source. They will also get mapped to the corresponding
+ loudspeakers depending on the direction between listener and source. In many cases, the
+ AudioListener object can simply be instantiated as a child object of the QtQuick3D.Camera
+ object.
+
+ Create AudioRoom objcects to simulate the sound (reflections and reverb) of a room with
+ certain dimensions and different types of walls.
+
+ AudioEngine does offer a mode where Qt is using simulating the effects of the ear
+ using head related impulse reponse functions (see also https://en.wikipedia.org/wiki/Sound_localization)
+ to localize the sound in 3D space when using headphones and create a spatial audio effect through
+ headphones.
+
+ As the rest of Qt Quick 3D, the audio engine uses a coordinate system that is in centimeters by default.
+ The axes are defined so that positive x points to the right, positive y points up and positive z points
+ backwards.
+*/
+
+
+QQuick3DAudioEngine::QQuick3DAudioEngine()
+{
+ auto *e = getEngine();
+ connect(e, &QAudioEngine::outputModeChanged, this, &QQuick3DAudioEngine::outputModeChanged);
+ connect(e, &QAudioEngine::outputDeviceChanged, this, &QQuick3DAudioEngine::outputDeviceChanged);
+ connect(e, &QAudioEngine::masterVolumeChanged, this, &QQuick3DAudioEngine::masterVolumeChanged);
+}
+
+QQuick3DAudioEngine::~QQuick3DAudioEngine()
+{
+}
+
+/*!
+ \qmlproperty enumeration AudioEngine::outputMode
+
+ Sets or retrieves the current output mode of the engine.
+
+ \table
+ \header \li Property value
+ \li Description
+ \row \li Surround
+ \li Map the sounds to the loudspeaker configuration of the output device.
+ This is normally a stereo or surround speaker setup.
+ \row \li Stereo
+ \li Map the sounds to the stereo loudspeaker configuration of the output device.
+ This will ignore any additional speakers and only use the left and right channels
+ to create a stero rendering of the sound field.
+ \row \li Headphone
+ \li Use Headphone spatialization to create a 3D audio effect when listening
+ to the sound field through headphones.
+ \endtable
+ */
+
+void QQuick3DAudioEngine::setOutputMode(OutputMode mode)
+{
+ globalEngine->setOutputMode(QAudioEngine::OutputMode(mode));
+}
+
+QQuick3DAudioEngine::OutputMode QQuick3DAudioEngine::outputMode() const
+{
+ return OutputMode(globalEngine->outputMode());
+}
+
+/*!
+ \qmlproperty QtMultimedia.AudioDevice AudioEngine::outputDevice
+
+ Sets or returns the device that is being used for outputting the sound field.
+ */
+void QQuick3DAudioEngine::setOutputDevice(const QAudioDevice &device)
+{
+ globalEngine->setOutputDevice(device);
+}
+
+QAudioDevice QQuick3DAudioEngine::outputDevice() const
+{
+ return globalEngine->outputDevice();
+}
+
+/*!
+ \qmlproperty float AudioEngine::masterVolume
+
+ Sets or returns overall volume being used to render the sound field.
+ */
+void QQuick3DAudioEngine::setMasterVolume(float volume)
+{
+ globalEngine->setMasterVolume(volume);
+}
+
+float QQuick3DAudioEngine::masterVolume() const
+{
+ return globalEngine->masterVolume();
+}
+
+QAudioEngine *QQuick3DAudioEngine::getEngine()
+{
+ if (!globalEngine) {
+ globalEngine = new QAudioEngine;
+ globalEngine->start();
+ }
+ return globalEngine;
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qquick3daudioengine_p.cpp"
diff --git a/src/spatialaudioquick3d/qquick3daudioengine_p.h b/src/spatialaudioquick3d/qquick3daudioengine_p.h
new file mode 100644
index 000000000..9cde33e97
--- /dev/null
+++ b/src/spatialaudioquick3d/qquick3daudioengine_p.h
@@ -0,0 +1,64 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-3.0-only
+#ifndef QQUICK3DAUDIOENGINE_H
+#define QQUICK3DAUDIOENGINE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qquick3dnode_p.h>
+#include <QtGui/qvector3d.h>
+#include <qaudioengine.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuick3DSpatialSound;
+
+class QQuick3DAudioEngine : public QObject
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(AudioEngine)
+ Q_PROPERTY(OutputMode outputMode READ outputMode WRITE setOutputMode NOTIFY outputModeChanged)
+ Q_PROPERTY(QAudioDevice outputDevice READ outputDevice WRITE setOutputDevice NOTIFY outputDeviceChanged)
+ Q_PROPERTY(float masterVolume READ masterVolume WRITE setMasterVolume NOTIFY masterVolumeChanged)
+
+public:
+ // Keep in sync with QAudioEngine::OutputMode
+ enum OutputMode {
+ Surround,
+ Stereo,
+ Headphone
+ };
+ Q_ENUM(OutputMode)
+
+ QQuick3DAudioEngine();
+ ~QQuick3DAudioEngine();
+
+ void setOutputMode(OutputMode mode);
+ OutputMode outputMode() const;
+
+ void setOutputDevice(const QAudioDevice &device);
+ QAudioDevice outputDevice() const;
+
+ void setMasterVolume(float volume);
+ float masterVolume() const;
+
+ static QAudioEngine *getEngine();
+
+Q_SIGNALS:
+ void outputModeChanged();
+ void outputDeviceChanged();
+ void masterVolumeChanged();
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/spatialaudioquick3d/qquick3daudiolistener.cpp b/src/spatialaudioquick3d/qquick3daudiolistener.cpp
new file mode 100644
index 000000000..b8445a799
--- /dev/null
+++ b/src/spatialaudioquick3d/qquick3daudiolistener.cpp
@@ -0,0 +1,49 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-3.0-only
+#include <qquick3daudiolistener_p.h>
+#include <qquick3dspatialsound_p.h>
+#include <qquick3daudioengine_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype AudioListener
+ \inqmlmodule QtQuick3D.SpatialAudio
+ \ingroup quick3d_spatialaudio
+ \ingroup multimedia_audio_qml
+
+ \brief defines the position and orientation of the person listening to a sound field
+ defined by a AudioEngine.
+
+ A AudioEngine can have exactly one listener, that defines the position and orientation
+ of the person listening to the sounds defined by the objects placed within the audio engine.
+
+ In most cases, the AudioListener should simply be a child of the Camera element in QtQuick3D.
+ This will ensure that the sound experience is aligned with the visual rendering of the scene.
+ */
+
+QQuick3DAudioListener::QQuick3DAudioListener()
+{
+ m_listener = new QAudioListener(QQuick3DAudioEngine::getEngine());
+ connect(this, &QQuick3DNode::scenePositionChanged, this, &QQuick3DAudioListener::updatePosition);
+ connect(this, &QQuick3DNode::sceneRotationChanged, this, &QQuick3DAudioListener::updateRotation);
+ updatePosition();
+ updateRotation();
+}
+
+QQuick3DAudioListener::~QQuick3DAudioListener()
+{
+ delete m_listener;
+}
+
+void QQuick3DAudioListener::updatePosition()
+{
+ m_listener->setPosition(scenePosition());
+}
+
+void QQuick3DAudioListener::updateRotation()
+{
+ m_listener->setRotation(sceneRotation());
+}
+
+QT_END_NAMESPACE
diff --git a/src/spatialaudioquick3d/qquick3daudiolistener_p.h b/src/spatialaudioquick3d/qquick3daudiolistener_p.h
new file mode 100644
index 000000000..1a24d8f0d
--- /dev/null
+++ b/src/spatialaudioquick3d/qquick3daudiolistener_p.h
@@ -0,0 +1,47 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-3.0-only
+#ifndef QQUICK3DLISTENER_H
+#define QQUICK3DLISTENER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qquick3dnode_p.h>
+#include <QtGui/qvector3d.h>
+
+#include <qaudiolistener.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuick3DAudioListener : public QQuick3DNode
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(AudioListener)
+
+public:
+ QQuick3DAudioListener();
+ ~QQuick3DAudioListener();
+
+ QAudioListener *listener() { return m_listener; }
+protected:
+ QSSGRenderGraphObject *updateSpatialNode(QSSGRenderGraphObject *) override { return nullptr; }
+
+protected Q_SLOTS:
+ void updatePosition();
+ void updateRotation();
+
+private:
+ QAudioListener *m_listener;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/spatialaudioquick3d/qquick3daudioroom.cpp b/src/spatialaudioquick3d/qquick3daudioroom.cpp
new file mode 100644
index 000000000..b79a6f609
--- /dev/null
+++ b/src/spatialaudioquick3d/qquick3daudioroom.cpp
@@ -0,0 +1,270 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-3.0-only
+#include <qquick3daudioroom_p.h>
+#include <qquick3daudioengine_p.h>
+#include <qaudioroom.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype AudioRoom
+ \inqmlmodule QtQuick3D.SpatialAudio
+ \ingroup quick3d_spatialaudio
+ \ingroup multimedia_audio_qml
+
+ Defines a room for the spatial audio engine.
+
+ If the listener is inside a room, first order sound reflections and reverb
+ matching the rooms properties will get applied to the sound field.
+
+ A room is always square and defined by its center position, its orientation and dimensions.
+ Each of the 6 walls of the room can be made of different materials that will contribute
+ to the computed reflections and reverb that the listener will experience while being inside
+ the room.
+
+ If multiple rooms cover the same position, the engine will use the room with the smallest
+ volume.
+ */
+
+QQuick3DAudioRoom::QQuick3DAudioRoom()
+{
+ m_room = new QAudioRoom(QQuick3DAudioEngine::getEngine());
+
+ connect(this, &QQuick3DNode::scenePositionChanged, this, &QQuick3DAudioRoom::updatePosition);
+ connect(this, &QQuick3DNode::sceneRotationChanged, this, &QQuick3DAudioRoom::updateRotation);
+ connect(m_room, &QAudioRoom::dimensionsChanged, this, &QQuick3DAudioRoom::dimensionsChanged);
+ connect(m_room, &QAudioRoom::rotationChanged, this, &QQuick3DAudioRoom::rotationChanged);
+ connect(m_room, &QAudioRoom::wallsChanged, this, &QQuick3DAudioRoom::wallsChanged);
+ connect(m_room, &QAudioRoom::reflectionGainChanged, this, &QQuick3DAudioRoom::reflectionGainChanged);
+ connect(m_room, &QAudioRoom::reverbGainChanged, this, &QQuick3DAudioRoom::reverbGainChanged);
+ connect(m_room, &QAudioRoom::reverbTimeChanged, this, &QQuick3DAudioRoom::reverbTimeChanged);
+ connect(m_room, &QAudioRoom::reverbBrightnessChanged, this, &QQuick3DAudioRoom::reverbBrightnessChanged);
+}
+
+QQuick3DAudioRoom::~QQuick3DAudioRoom()
+{
+ delete m_room;
+}
+
+/*!
+ \qmlproperty vector3D AudioRoom::dimensions
+
+ Defines the dimensions of the room in 3D space. Units are in centimeters
+ by default.
+
+ \sa QtQuick3D::Node::position
+ */
+void QQuick3DAudioRoom::setDimensions(QVector3D dim)
+{
+ m_room->setDimensions(dim);
+}
+
+QVector3D QQuick3DAudioRoom::dimensions() const
+{
+ return m_room->dimensions();
+}
+
+/*!
+ \qmlproperty AudioRoom::Material AudioRoom::leftMaterial
+ \qmlproperty AudioRoom::Material AudioRoom::rightMaterial
+ \qmlproperty AudioRoom::Material AudioRoom::frontMaterial
+ \qmlproperty AudioRoom::Material AudioRoom::backMaterial
+ \qmlproperty AudioRoom::Material AudioRoom::floorMaterial
+ \qmlproperty AudioRoom::Material AudioRoom::ceilingMaterial
+
+ Sets the material to use for the different sides of the room. Properties correlate to
+ coordinates as follows:
+
+ \table
+ \header
+ \li Property
+ \li Coordinate
+ \row \li left \li Negative x
+ \row \li right \li Positive x
+ \row \li back \li Negative z
+ \row \li front \li Positive z
+ \row \li floor \li Negative y
+ \row \li ceiling \li Positive y
+ \endtable
+
+ Valid values for the material are:
+
+ \table
+ \header
+ \li Property value
+ \li Description
+ \row \li Transparent \li The side of the room is open and won't contribute to reflections or reverb.
+ \row \li AcousticCeilingTiles \li Acoustic tiles that suppress most reflections and reverb.
+ \row \li BrickBare \li A bare brick wall.
+ \row \li BrickPainted \li A painted brick wall.
+ \row \li ConcreteBlockCoarse \li A raw concrete wall
+ \row \li ConcreteBlockPainted \li A painted concrete wall
+ \row \li CurtainHeavy \li A heavy curtain. Will mostly reflect low frequencies
+ \row \li FiberGlassInsulation \li Fiber glass insulation. Only reflects very low frequencies
+ \row \li GlassThin \li A thin glass wall
+ \row \li GlassThick \li A thick glass wall
+ \row \li Grass \li Grass
+ \row \li LinoleumOnConcrete \li A Linoleum floor
+ \row \li Marble \li A marble floor
+ \row \li Metal \li Metal
+ \row \li ParquetOnConcrete \li Parquet wooden floor on concrete
+ \row \li PlasterRough \li Rough plaster
+ \row \li PlasterSmooth \li Smooth plaster
+ \row \li PlywoodPanel \li Plywodden panel
+ \row \li PolishedConcreteOrTile \li Polished concrete or tiles
+ \row \li Sheetrock \li Rock
+ \row \li WaterOrIceSurface \li Water or ice
+ \row \li WoodCeiling \li A wooden ceiling
+ \row \li WoodPanel \li Wooden panel
+ \row \li Uniform \li Artificial material giving uniform reflections on all frequencies
+ \endtable
+ */
+void QQuick3DAudioRoom::setLeftMaterial(Material material)
+{
+ m_room->setWallMaterial(QAudioRoom::LeftWall, QAudioRoom::Material(material));
+}
+
+QQuick3DAudioRoom::Material QQuick3DAudioRoom::leftMaterial() const
+{
+ return Material(m_room->wallMaterial(QAudioRoom::LeftWall));
+}
+
+void QQuick3DAudioRoom::setRightMaterial(Material material)
+{
+ m_room->setWallMaterial(QAudioRoom::RightWall, QAudioRoom::Material(material));
+}
+
+QQuick3DAudioRoom::Material QQuick3DAudioRoom::rightMaterial() const
+{
+ return Material(m_room->wallMaterial(QAudioRoom::RightWall));
+}
+
+void QQuick3DAudioRoom::setFrontMaterial(Material material)
+{
+ m_room->setWallMaterial(QAudioRoom::FrontWall, QAudioRoom::Material(material));
+}
+
+QQuick3DAudioRoom::Material QQuick3DAudioRoom::frontMaterial() const
+{
+ return Material(m_room->wallMaterial(QAudioRoom::FrontWall));
+}
+
+void QQuick3DAudioRoom::setBackMaterial(Material material)
+{
+ m_room->setWallMaterial(QAudioRoom::BackWall, QAudioRoom::Material(material));
+}
+
+QQuick3DAudioRoom::Material QQuick3DAudioRoom::backMaterial() const
+{
+ return Material(m_room->wallMaterial(QAudioRoom::BackWall));
+}
+
+void QQuick3DAudioRoom::setFloorMaterial(Material material)
+{
+ m_room->setWallMaterial(QAudioRoom::Floor, QAudioRoom::Material(material));
+}
+
+QQuick3DAudioRoom::Material QQuick3DAudioRoom::floorMaterial() const
+{
+ return Material(m_room->wallMaterial(QAudioRoom::Floor));
+}
+
+void QQuick3DAudioRoom::setCeilingMaterial(Material material)
+{
+ m_room->setWallMaterial(QAudioRoom::Ceiling, QAudioRoom::Material(material));
+}
+
+QQuick3DAudioRoom::Material QQuick3DAudioRoom::ceilingMaterial() const
+{
+ return Material(m_room->wallMaterial(QAudioRoom::Ceiling));
+}
+
+/*!
+ \qmlproperty float AudioRoom::reflectionGain
+
+ A gain factor for reflections generated in this room. A value
+ from 0 to 1 will dampen reflections, while a value larger than 1
+ will apply a gain to reflections, making them louder.
+
+ The default is 1, a factor of 0 disables reflections. Negative
+ values are mapped to 0.
+ */
+void QQuick3DAudioRoom::setReflectionGain(float factor)
+{
+ m_room->setReflectionGain(factor);
+}
+
+float QQuick3DAudioRoom::reflectionGain() const
+{
+ return m_room->reflectionGain();
+}
+
+/*!
+ \qmlproperty float AudioRoom::reverbGain
+
+ A gain factor for reverb generated in this room. A value
+ from 0 to 1 will dampen reverb, while a value larger than 1
+ will apply a gain to the reverb, making it louder.
+
+ The default is 1, a factor of 0 disables reverb. Negative
+ values are mapped to 0.
+ */
+void QQuick3DAudioRoom::setReverbGain(float factor)
+{
+ m_room->setReverbGain(factor);
+}
+
+float QQuick3DAudioRoom::reverbGain() const
+{
+ return m_room->reverbGain();
+}
+
+/*!
+ \qmlproperty float AudioRoom::reverbTime
+
+ A factor to be applies to all reverb timings generated for this room.
+ Larger values will lead to longer reverb timings, making the room sound
+ larger.
+
+ The default is 1. Negative values are mapped to 0.
+ */
+void QQuick3DAudioRoom::setReverbTime(float factor)
+{
+ m_room->setReverbTime(factor);
+}
+
+float QQuick3DAudioRoom::reverbTime() const
+{
+ return m_room->reverbTime();
+}
+
+/*!
+ \qmlproperty float AudioRoom::reverbBrightness
+
+ A brightness factor to be applied to the generated reverb.
+ A positive value will increase reverb for higher frequencies and
+ dampen lower frequencies, a negative value does the reverse.
+
+ The default is 0.
+ */
+void QQuick3DAudioRoom::setReverbBrightness(float factor)
+{
+ m_room->setReverbBrightness(factor);
+}
+
+float QQuick3DAudioRoom::reverbBrightness() const
+{
+ return m_room->reverbBrightness();
+}
+
+void QQuick3DAudioRoom::updatePosition()
+{
+ m_room->setPosition(scenePosition());
+}
+
+void QQuick3DAudioRoom::updateRotation()
+{
+ m_room->setRotation(sceneRotation());
+}
+
+QT_END_NAMESPACE
diff --git a/src/spatialaudioquick3d/qquick3daudioroom_p.h b/src/spatialaudioquick3d/qquick3daudioroom_p.h
new file mode 100644
index 000000000..8198b9307
--- /dev/null
+++ b/src/spatialaudioquick3d/qquick3daudioroom_p.h
@@ -0,0 +1,129 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-3.0-only
+
+#ifndef QQUICK3DAUDIOROOM_H
+#define QQUICK3DAUDIOROOM_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qquick3dnode_p.h>
+#include <QtGui/qvector3d.h>
+#include <qaudioroom.h>
+
+QT_BEGIN_NAMESPACE
+
+class QAudioEngine;
+class QAudioRoomPrivate;
+
+class QQuick3DAudioRoom : public QQuick3DNode
+{
+ Q_OBJECT
+ Q_PROPERTY(QVector3D position READ position WRITE setPosition NOTIFY positionChanged)
+ Q_PROPERTY(QVector3D dimensions READ dimensions WRITE setDimensions NOTIFY dimensionsChanged)
+ Q_PROPERTY(QQuaternion rotation READ rotation WRITE setRotation NOTIFY rotationChanged)
+ Q_PROPERTY(Material leftMaterial READ leftMaterial WRITE setLeftMaterial NOTIFY wallsChanged)
+ Q_PROPERTY(Material rightMaterial READ rightMaterial WRITE setRightMaterial NOTIFY wallsChanged)
+ Q_PROPERTY(Material frontMaterial READ frontMaterial WRITE setFrontMaterial NOTIFY wallsChanged)
+ Q_PROPERTY(Material backMaterial READ backMaterial WRITE setBackMaterial NOTIFY wallsChanged)
+ Q_PROPERTY(Material floorMaterial READ floorMaterial WRITE setFloorMaterial NOTIFY wallsChanged)
+ Q_PROPERTY(Material ceilingMaterial READ ceilingMaterial WRITE setCeilingMaterial NOTIFY wallsChanged)
+ Q_PROPERTY(float reflectionGain READ reflectionGain WRITE setReflectionGain NOTIFY reflectionGainChanged)
+ Q_PROPERTY(float reverbGain READ reverbGain WRITE setReverbGain NOTIFY reverbGainChanged)
+ Q_PROPERTY(float reverbTime READ reverbTime WRITE setReverbTime NOTIFY reverbTimeChanged)
+ Q_PROPERTY(float reverbBrightness READ reverbBrightness WRITE setReverbBrightness NOTIFY reverbBrightnessChanged)
+ QML_NAMED_ELEMENT(AudioRoom)
+public:
+ QQuick3DAudioRoom();
+ ~QQuick3DAudioRoom();
+
+ enum Material {
+ Transparent,
+ AcousticCeilingTiles,
+ BrickBare,
+ BrickPainted,
+ ConcreteBlockCoarse,
+ ConcreteBlockPainted,
+ CurtainHeavy,
+ FiberGlassInsulation,
+ GlassThin,
+ GlassThick,
+ Grass,
+ LinoleumOnConcrete,
+ Marble,
+ Metal,
+ ParquetOnConcrete,
+ PlasterRough,
+ PlasterSmooth,
+ PlywoodPanel,
+ PolishedConcreteOrTile,
+ Sheetrock,
+ WaterOrIceSurface,
+ WoodCeiling,
+ WoodPanel,
+ Uniform,
+ };
+ Q_ENUM(Material)
+
+ void setDimensions(QVector3D pos);
+ QVector3D dimensions() const;
+
+ void setLeftMaterial(Material material);
+ Material leftMaterial() const;
+
+ void setRightMaterial(Material material);
+ Material rightMaterial() const;
+
+ void setFrontMaterial(Material material);
+ Material frontMaterial() const;
+
+ void setBackMaterial(Material material);
+ Material backMaterial() const;
+
+ void setFloorMaterial(Material material);
+ Material floorMaterial() const;
+
+ void setCeilingMaterial(Material material);
+ Material ceilingMaterial() const;
+
+ void setReflectionGain(float factor);
+ float reflectionGain() const;
+
+ void setReverbGain(float factor);
+ float reverbGain() const;
+
+ void setReverbTime(float factor);
+ float reverbTime() const;
+
+ void setReverbBrightness(float factor);
+ float reverbBrightness() const;
+
+Q_SIGNALS:
+ void positionChanged();
+ void dimensionsChanged();
+ void rotationChanged();
+ void wallsChanged();
+ void reflectionGainChanged();
+ void reverbGainChanged();
+ void reverbTimeChanged();
+ void reverbBrightnessChanged();
+
+protected Q_SLOTS:
+ void updatePosition();
+ void updateRotation();
+
+private:
+ QAudioRoom *m_room;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/spatialaudioquick3d/qquick3dspatialaudio_plugin.cpp b/src/spatialaudioquick3d/qquick3dspatialaudio_plugin.cpp
new file mode 100644
index 000000000..399a215ad
--- /dev/null
+++ b/src/spatialaudioquick3d/qquick3dspatialaudio_plugin.cpp
@@ -0,0 +1,35 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-3.0-only
+
+#include <QtQml/qqmlextensionplugin.h>
+#include <QtQml/qqml.h>
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlcomponent.h>
+#include "qtquick3daudioglobal_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuick3DAudioModule : public QQmlEngineExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
+
+public:
+ QQuick3DAudioModule(QObject *parent = nullptr)
+ : QQmlEngineExtensionPlugin(parent)
+ {
+ volatile auto registration = qml_register_types_QtQuick3D_SpatialAudio;
+ Q_UNUSED(registration);
+ }
+
+ void initializeEngine(QQmlEngine *engine, const char *uri) override
+ {
+ Q_UNUSED(engine);
+ Q_UNUSED(uri);
+ }
+};
+
+QT_END_NAMESPACE
+
+#include "qquick3dspatialaudio_plugin.moc"
+
diff --git a/src/spatialaudioquick3d/qquick3dspatialsound.cpp b/src/spatialaudioquick3d/qquick3dspatialsound.cpp
new file mode 100644
index 000000000..04c935c56
--- /dev/null
+++ b/src/spatialaudioquick3d/qquick3dspatialsound.cpp
@@ -0,0 +1,323 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-3.0-only
+#include "qquick3dspatialsound_p.h"
+#include "qquick3daudioengine_p.h"
+#include "qspatialsound.h"
+#include <QAudioFormat>
+#include <qdir.h>
+#include <QQmlContext>
+#include <QQmlFile>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype SpatialSound
+ \inqmlmodule QtQuick3D.SpatialAudio
+ \ingroup quick3d_spatialaudio
+ \ingroup multimedia_audio_qml
+
+ \brief A sound object in 3D space.
+
+ A SpatialSound represents an audible object in 3D space. You can define
+ it's position and orientation in space, set the sound it is playing and define a
+ volume for the object.
+
+ The object can have different attenuation behavior, emit sound mainly in one direction
+ or spherically, and behave as if occluded by some other object.
+ */
+
+QQuick3DSpatialSound::QQuick3DSpatialSound()
+{
+ m_sound = new QSpatialSound(QQuick3DAudioEngine::getEngine());
+
+ connect(this, &QQuick3DNode::scenePositionChanged, this, &QQuick3DSpatialSound::updatePosition);
+ connect(this, &QQuick3DNode::sceneRotationChanged, this, &QQuick3DSpatialSound::updateRotation);
+ connect(m_sound, &QSpatialSound::sourceChanged, this, &QQuick3DSpatialSound::sourceChanged);
+ connect(m_sound, &QSpatialSound::volumeChanged, this, &QQuick3DSpatialSound::volumeChanged);
+ connect(m_sound, &QSpatialSound::distanceModelChanged, this, &QQuick3DSpatialSound::distanceModelChanged);
+ connect(m_sound, &QSpatialSound::sizeChanged, this, &QQuick3DSpatialSound::sizeChanged);
+ connect(m_sound, &QSpatialSound::distanceCutoffChanged, this, &QQuick3DSpatialSound::distanceCutoffChanged);
+ connect(m_sound, &QSpatialSound::manualAttenuationChanged, this, &QQuick3DSpatialSound::manualAttenuationChanged);
+ connect(m_sound, &QSpatialSound::occlusionIntensityChanged, this, &QQuick3DSpatialSound::occlusionIntensityChanged);
+ connect(m_sound, &QSpatialSound::directivityChanged, this, &QQuick3DSpatialSound::directivityChanged);
+ connect(m_sound, &QSpatialSound::directivityOrderChanged, this, &QQuick3DSpatialSound::directivityOrderChanged);
+ connect(m_sound, &QSpatialSound::nearFieldGainChanged, this, &QQuick3DSpatialSound::nearFieldGainChanged);
+ connect(m_sound, &QSpatialSound::loopsChanged, this, &QQuick3DSpatialSound::loopsChanged);
+ connect(m_sound, &QSpatialSound::autoPlayChanged, this, &QQuick3DSpatialSound::autoPlayChanged);
+}
+
+QQuick3DSpatialSound::~QQuick3DSpatialSound()
+{
+ delete m_sound;
+}
+
+/*!
+ \qmlproperty url SpatialSound::source
+
+ The source file for the sound to be played.
+ */
+QUrl QQuick3DSpatialSound::source() const
+{
+ return m_sound->source();
+}
+
+void QQuick3DSpatialSound::setSource(QUrl source)
+{
+ const QQmlContext *context = qmlContext(this);
+ QUrl url;
+ if (context) {
+ url = context->resolvedUrl(source);
+ } else {
+ url = QUrl::fromLocalFile(QDir::currentPath() + u"/");
+ url = url.resolved(source);
+ }
+ m_sound->setSource(url);
+}
+
+/*!
+ \qmlproperty float SpatialSound::volume
+
+ Defines an overall volume for this sound source.
+
+ Values between 0 and 1 will attenuate the sound, while values above 1
+ provide an additional gain boost.
+ */
+void QQuick3DSpatialSound::setVolume(float volume)
+{
+ m_sound->setVolume(volume);
+}
+
+float QQuick3DSpatialSound::volume() const
+{
+ return m_sound->volume();
+}
+
+/*!
+ \qmlproperty enumeration SpatialSound::distanceModel
+
+ Defines how the volume of the sound scales with distance to the listener.
+ The volume starts scaling down
+ from \l size to \l distanceCutoff. The volume is constant for distances smaller
+ than size and zero for distances larger than the cutoff distance.
+
+ \table
+ \header \li Property value
+ \li Description
+ \row \li Logarithmic
+ \li Volume decreases logarithmically with distance.
+ \row \li Linear
+ \li Volume decreases linearly with distance.
+ \row \li ManualAttenuation
+ \li Attenuation is defined manually using the \l manualAttenuation property.
+ \endtable
+ */
+void QQuick3DSpatialSound::setDistanceModel(DistanceModel model)
+{
+ m_sound->setDistanceModel(QSpatialSound::DistanceModel(model));
+}
+
+QQuick3DSpatialSound::DistanceModel QQuick3DSpatialSound::distanceModel() const
+{
+ return DistanceModel(m_sound->distanceModel());
+}
+
+/*!
+ \qmlproperty float SpatialSound::size
+
+ Defines the size of the sound source. If the listener is closer to the sound
+ object than the size, volume will stay constant. The size is also used to for
+ occlusion calculations, where large sources can be partially occluded by a wall.
+ */
+void QQuick3DSpatialSound::setSize(float min)
+{
+ m_sound->setSize(min);
+}
+
+float QQuick3DSpatialSound::size() const
+{
+ return m_sound->size();
+}
+
+/*!
+ \qmlproperty float SpatialSound::distanceCutoff
+
+ Defines a distance beyond which sound coming from the source will cutoff.
+ If the listener is further away from the sound object than the cutoff
+ distance it won't be audible anymore.
+ */
+void QQuick3DSpatialSound::setDistanceCutoff(float max)
+{
+ m_sound->setDistanceCutoff(max);
+}
+
+float QQuick3DSpatialSound::distanceCutoff() const
+{
+ return m_sound->distanceCutoff();
+}
+
+/*!
+ \qmlproperty float SpatialSound::manualAttenuation
+
+ Defines a manual attenuation factor if \l distanceModel is set to
+ SpatialSound.ManualAttenuation.
+ */
+void QQuick3DSpatialSound::setManualAttenuation(float attenuation)
+{
+ m_sound->setManualAttenuation(attenuation);
+}
+
+float QQuick3DSpatialSound::manualAttenuation() const
+{
+ return m_sound->manualAttenuation();
+}
+
+/*!
+ \qmlproperty float SpatialSound::occlusionIntensity
+
+ Defines how much the object is occluded. 0 implies the object is
+ not occluded at all, while a large number implies a large occlusion.
+
+ The default is 0.
+ */
+void QQuick3DSpatialSound::setOcclusionIntensity(float occlusion)
+{
+ m_sound->setOcclusionIntensity(occlusion);
+}
+
+float QQuick3DSpatialSound::occlusionIntensity() const
+{
+ return m_sound->occlusionIntensity();
+}
+
+/*!
+ \qmlproperty float SpatialSound::directivity
+
+ Defines the directivity of the sound source. A value of 0 implies that the sound is
+ emitted equally in all directions, while a value of 1 implies that the source mainly
+ emits sound in the forward direction.
+
+ Valid values are between 0 and 1, the default is 0.
+ */
+void QQuick3DSpatialSound::setDirectivity(float alpha)
+{
+ m_sound->setDirectivity(alpha);
+}
+
+float QQuick3DSpatialSound::directivity() const
+{
+ return m_sound->directivity();
+}
+
+/*!
+ \qmlproperty float SpatialSound::directivityOrder
+
+ Defines the order of the directivity of the sound source. A higher order
+ implies a sharper localization of the sound cone.
+
+ The minimum value and default for this property is 1.
+ */
+void QQuick3DSpatialSound::setDirectivityOrder(float alpha)
+{
+ m_sound->setDirectivityOrder(alpha);
+}
+
+float QQuick3DSpatialSound::directivityOrder() const
+{
+ return m_sound->directivityOrder();
+}
+
+/*!
+ \qmlproperty float SpatialSound::nearFieldGain
+
+ Defines the near field gain for the sound source. Valid values are between 0 and 1.
+ A near field gain of 1 will raise the volume of the sound signal by approx 20 dB for
+ distances very close to the listener.
+ */
+void QQuick3DSpatialSound::setNearFieldGain(float gain)
+{
+ m_sound->setNearFieldGain(gain);
+}
+
+float QQuick3DSpatialSound::nearFieldGain() const
+{
+ return m_sound->nearFieldGain();
+}
+
+void QQuick3DSpatialSound::updatePosition()
+{
+ m_sound->setPosition(scenePosition());
+}
+
+void QQuick3DSpatialSound::updateRotation()
+{
+ m_sound->setRotation(sceneRotation());
+}
+
+/*!
+ \qmlproperty int SpatialSound::loops
+
+ Determines how often the sound is played before the player stops.
+ Set to SpatialSound::Infinite to loop the current sound forever.
+
+ The default value is \c 1.
+ */
+int QQuick3DSpatialSound::loops() const
+{
+ return m_sound->loops();
+}
+
+void QQuick3DSpatialSound::setLoops(int loops)
+{
+ m_sound->setLoops(loops);
+}
+
+/*!
+ \qmlproperty bool SpatialSound::autoPlay
+
+ Determines whether the sound should automatically start playing when a source
+ gets specified.
+
+ The default value is \c true.
+ */
+bool QQuick3DSpatialSound::autoPlay() const
+{
+ return m_sound->autoPlay();
+}
+
+void QQuick3DSpatialSound::setAutoPlay(bool autoPlay)
+{
+ m_sound->setAutoPlay(autoPlay);
+}
+
+/*!
+ \qmlmethod SpatialSound::play()
+
+ Starts playing back the sound. Does nothing if the sound is already playing.
+ */
+void QQuick3DSpatialSound::play()
+{
+ m_sound->play();
+}
+
+/*!
+ \qmlmethod SpatialSound::pause()
+
+ Pauses sound playback at the current position. Calling play() will continue playback.
+ */
+void QQuick3DSpatialSound::pause()
+{
+ m_sound->pause();
+}
+
+/*!
+ \qmlmethod SpatialSound::stop()
+
+ Stops sound playback and resets the current position and loop count to 0. Calling play() will
+ begin playback at the beginning of the sound file.
+ */
+void QQuick3DSpatialSound::stop()
+{
+ m_sound->stop();
+}
+
+QT_END_NAMESPACE
diff --git a/src/spatialaudioquick3d/qquick3dspatialsound_p.h b/src/spatialaudioquick3d/qquick3dspatialsound_p.h
new file mode 100644
index 000000000..d24a63056
--- /dev/null
+++ b/src/spatialaudioquick3d/qquick3dspatialsound_p.h
@@ -0,0 +1,127 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-3.0-only
+#ifndef QQUICK3DSPATIALSOUND_H
+#define QQUICK3DSPATIALSOUND_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qquick3dnode_p.h>
+#include <QUrl>
+#include <qvector3d.h>
+#include <qspatialsound.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuick3DSpatialSound : public QQuick3DNode
+{
+ Q_OBJECT
+ Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
+ Q_PROPERTY(float volume READ volume WRITE setVolume NOTIFY volumeChanged)
+ Q_PROPERTY(DistanceModel distanceModel READ distanceModel WRITE setDistanceModel NOTIFY distanceModelChanged)
+ Q_PROPERTY(float size READ size WRITE setSize NOTIFY sizeChanged)
+ Q_PROPERTY(float distanceCutoff READ distanceCutoff WRITE setDistanceCutoff NOTIFY distanceCutoffChanged)
+ Q_PROPERTY(float manualAttenuation READ manualAttenuation WRITE setManualAttenuation NOTIFY manualAttenuationChanged)
+ Q_PROPERTY(float occlusionIntensity READ occlusionIntensity WRITE setOcclusionIntensity NOTIFY occlusionIntensityChanged)
+ Q_PROPERTY(float directivity READ directivity WRITE setDirectivity NOTIFY directivityChanged)
+ Q_PROPERTY(float directivityOrder READ directivityOrder WRITE setDirectivityOrder NOTIFY directivityOrderChanged)
+ Q_PROPERTY(float nearFieldGain READ nearFieldGain WRITE setNearFieldGain NOTIFY nearFieldGainChanged)
+ Q_PROPERTY(int loops READ loops WRITE setLoops NOTIFY loopsChanged)
+ Q_PROPERTY(bool autoPlay READ autoPlay WRITE setAutoPlay NOTIFY autoPlayChanged)
+ QML_NAMED_ELEMENT(SpatialSound)
+
+public:
+ QQuick3DSpatialSound();
+ ~QQuick3DSpatialSound();
+
+ void setSource(QUrl source);
+ QUrl source() const;
+
+ void setVolume(float volume);
+ float volume() const;
+
+ enum DistanceModel {
+ Logarithmic,
+ Linear,
+ ManualAttenuation
+ };
+ Q_ENUM(DistanceModel);
+
+ void setDistanceModel(DistanceModel model);
+ DistanceModel distanceModel() const;
+
+ void setSize(float min);
+ float size() const;
+
+ void setDistanceCutoff(float max);
+ float distanceCutoff() const;
+
+ void setManualAttenuation(float attenuation);
+ float manualAttenuation() const;
+
+ void setOcclusionIntensity(float occlusion);
+ float occlusionIntensity() const;
+
+ void setDirectivity(float alpha);
+ float directivity() const;
+
+ void setDirectivityOrder(float alpha);
+ float directivityOrder() const;
+
+ void setNearFieldGain(float gain);
+ float nearFieldGain() const;
+
+ enum Loops
+ {
+ Infinite = -1,
+ Once = 1
+ };
+ Q_ENUM(Loops)
+
+ int loops() const;
+ void setLoops(int loops);
+
+ bool autoPlay() const;
+ void setAutoPlay(bool autoPlay);
+
+public Q_SLOTS:
+ void play();
+ void pause();
+ void stop();
+
+Q_SIGNALS:
+ void sourceChanged();
+ void volumeChanged();
+ void distanceModelChanged();
+ void sizeChanged();
+ void distanceCutoffChanged();
+ void manualAttenuationChanged();
+ void occlusionIntensityChanged();
+ void directivityChanged();
+ void directivityOrderChanged();
+ void nearFieldGainChanged();
+ void loopsChanged();
+ void autoPlayChanged();
+
+private Q_SLOTS:
+ void updatePosition();
+ void updateRotation();
+
+protected:
+ QSSGRenderGraphObject *updateSpatialNode(QSSGRenderGraphObject *) override { return nullptr; }
+
+private:
+ QSpatialSound *m_sound = nullptr;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/spatialaudioquick3d/qtquick3daudioglobal_p.h b/src/spatialaudioquick3d/qtquick3daudioglobal_p.h
new file mode 100644
index 000000000..9fbad2173
--- /dev/null
+++ b/src/spatialaudioquick3d/qtquick3daudioglobal_p.h
@@ -0,0 +1,28 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-3.0-only
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QQUICK3DAUDIOGLOBAL_P_H
+#define QQUICK3DAUDIOGLOBAL_P_H
+
+#include <QtCore/qglobal.h>
+#include <QtMultimediaQuick/qtmultimediaquickexports.h>
+
+QT_BEGIN_NAMESPACE
+
+void Q_MULTIMEDIAQUICK_EXPORT qml_register_types_QtQuick3D_SpatialAudio();
+
+QT_END_NAMESPACE
+
+#endif // QMULTIMEDIAQUICKDEFS_P_H
+
diff --git a/src/spatialaudioquick3d/qtquick3daudiotypes_p.h b/src/spatialaudioquick3d/qtquick3daudiotypes_p.h
new file mode 100644
index 000000000..814cb4077
--- /dev/null
+++ b/src/spatialaudioquick3d/qtquick3daudiotypes_p.h
@@ -0,0 +1,27 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-3.0-only
+
+#ifndef QQUICK3DAUDIOTYPES_H
+#define QQUICK3DAUDIOTYPES_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtQml/qqml.h>
+#include <private/qtquick3daudioglobal_p.h>
+
+QT_BEGIN_NAMESPACE
+
+// Nothing for now
+
+QT_END_NAMESPACE
+
+#endif