summaryrefslogtreecommitdiffstats
path: root/src/spatialaudioquick3d/qquick3dspatialsound.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/spatialaudioquick3d/qquick3dspatialsound.cpp')
-rw-r--r--src/spatialaudioquick3d/qquick3dspatialsound.cpp323
1 files changed, 323 insertions, 0 deletions
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