Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qaudiolistener.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-3.0-only
3
5
6#include <QtSpatialAudio/private/qaudioengine_p.h>
7#include <QtMultimedia/qaudiosink.h>
8#include <QtCore/private/qobject_p.h>
9
10#include <resonance_audio.h>
11
12QT_BEGIN_NAMESPACE
13
14class QAudioListenerPrivate : public QObjectPrivate
15{
16public:
17 QAudioEngine *engine = nullptr;
18 QVector3D pos;
19 QQuaternion rotation;
20};
21
22/*!
23 \class QAudioListener
24 \inmodule QtSpatialAudio
25 \ingroup spatialaudio
26 \ingroup multimedia_audio
27
28 \brief Defines the position and orientation of the person listening to a sound field
29 defined by QAudioEngine.
30
31 A QAudioEngine can have exactly one listener that defines the position and orientation
32 of the person listening to the sound field.
33 */
34
35/*!
36 Creates a listener for the spatial audio engine for \a engine.
37 */
38QAudioListener::QAudioListener(QAudioEngine *engine) : QObject(*new QAudioListenerPrivate)
39{
40 setEngine(engine);
41}
42
43/*!
44 Destroys the listener.
45 */
46QAudioListener::~QAudioListener()
47{
48 // Unregister this listener from the engine
49 setEngine(nullptr);
50}
51
52/*!
53 Sets the listener's position in 3D space to \a pos. Units are in centimeters
54 by default.
55
56 \sa QAudioEngine::distanceScale
57 */
58void QAudioListener::setPosition(QVector3D pos)
59{
60 Q_D(QAudioListener);
61
62 auto *ep = QAudioEnginePrivate::get(d->engine);
63 if (!ep)
64 return;
65 pos *= ep->distanceScale;
66 if (d->pos == pos)
67 return;
68
69 d->pos = pos;
70 if (ep && ep->resonanceAudio->api) {
71 ep->resonanceAudio->api->SetHeadPosition(pos.x(), pos.y(), pos.z());
72 ep->listenerPositionDirty = true;
73 }
74}
75
76/*!
77 Returns the current position of the listener.
78 */
79QVector3D QAudioListener::position() const
80{
81 Q_D(const QAudioListener);
82 auto *ep = QAudioEnginePrivate::get(d->engine);
83 if (!ep)
84 return QVector3D();
85
86 return d->pos / ep->distanceScale;
87}
88
89/*!
90 Sets the listener's orientation in 3D space to \a q.
91 */
92void QAudioListener::setRotation(const QQuaternion &q)
93{
94 Q_D(QAudioListener);
95 d->rotation = q;
96 auto *ep = QAudioEnginePrivate::get(d->engine);
97 if (ep && ep->resonanceAudio->api)
98 ep->resonanceAudio->api->SetHeadRotation(d->rotation.x(), d->rotation.y(), d->rotation.z(), d->rotation.scalar());
99}
100
101/*!
102 Returns the listener's orientation in 3D space.
103 */
104QQuaternion QAudioListener::rotation() const
105{
106 Q_D(const QAudioListener);
107 return d->rotation;
108}
109
110/*!
111 \internal
112 */
113void QAudioListener::setEngine(QAudioEngine *engine)
114{
115 Q_D(QAudioListener);
116 if (d->engine) {
117 auto *ed = QAudioEnginePrivate::get(d->engine);
118 ed->listener = nullptr;
119 }
120 d->engine = engine;
121 if (d->engine) {
122 auto *ed = QAudioEnginePrivate::get(d->engine);
123 if (ed->listener) {
124 qWarning() << "Ignoring attempt to add a second listener to the spatial audio engine.";
125 d->engine = nullptr;
126 return;
127 }
128 ed->listener = this;
129 }
130}
131
132/*!
133 Returns the engine associated with this listener.
134 */
135QAudioEngine *QAudioListener::engine() const
136{
137 Q_D(const QAudioListener);
138 return d->engine;
139}
140
141QT_END_NAMESPACE