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#include "qaudiolistener.h"
4#include "qaudioengine_p.h"
5#include "resonance_audio.h"
6#include <qaudiosink.h>
7#include <qurl.h>
8#include <qdebug.h>
9#include <qaudiodecoder.h>
10
11QT_BEGIN_NAMESPACE
12
13class QAudioListenerPrivate
14{
15public:
16 QAudioEngine *engine = nullptr;
17 QVector3D pos;
18 QQuaternion rotation;
19};
20
21/*!
22 \class QAudioListener
23 \inmodule QtSpatialAudio
24 \ingroup spatialaudio
25 \ingroup multimedia_audio
26
27 \brief Defines the position and orientation of the person listening to a sound field
28 defined by QAudioEngine.
29
30 A QAudioEngine can have exactly one listener that defines the position and orientation
31 of the person listening to the sound field.
32 */
33
34/*!
35 Creates a listener for the spatial audio engine for \a engine.
36 */
37QAudioListener::QAudioListener(QAudioEngine *engine)
38 : d(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 delete d;
51}
52
53/*!
54 Sets the listener's position in 3D space to \a pos. Units are in centimeters
55 by default.
56
57 \sa QAudioEngine::distanceScale
58 */
59void QAudioListener::setPosition(QVector3D pos)
60{
61 auto *ep = QAudioEnginePrivate::get(engine: d->engine);
62 if (!ep)
63 return;
64 pos *= ep->distanceScale;
65 if (d->pos == pos)
66 return;
67
68 d->pos = pos;
69 if (ep && ep->resonanceAudio->api) {
70 ep->resonanceAudio->api->SetHeadPosition(x: pos.x(), y: pos.y(), z: pos.z());
71 ep->listenerPositionDirty = true;
72 }
73}
74
75/*!
76 Returns the current position of the listener.
77 */
78QVector3D QAudioListener::position() const
79{
80 auto *ep = QAudioEnginePrivate::get(engine: d->engine);
81 if (!ep)
82 return QVector3D();
83 return d->pos/ep->distanceScale;
84}
85
86/*!
87 Sets the listener's orientation in 3D space to \a q.
88 */
89void QAudioListener::setRotation(const QQuaternion &q)
90{
91 d->rotation = q;
92 auto *ep = QAudioEnginePrivate::get(engine: d->engine);
93 if (ep && ep->resonanceAudio->api)
94 ep->resonanceAudio->api->SetHeadRotation(x: d->rotation.x(), y: d->rotation.y(), z: d->rotation.z(), w: d->rotation.scalar());
95}
96
97/*!
98 Returns the listener's orientation in 3D space.
99 */
100QQuaternion QAudioListener::rotation() const
101{
102 return d->rotation;
103}
104
105/*!
106 \internal
107 */
108void QAudioListener::setEngine(QAudioEngine *engine)
109{
110 if (d->engine) {
111 auto *ed = QAudioEnginePrivate::get(engine: d->engine);
112 ed->listener = nullptr;
113 }
114 d->engine = engine;
115 if (d->engine) {
116 auto *ed = QAudioEnginePrivate::get(engine: d->engine);
117 if (ed->listener) {
118 qWarning() << "Ignoring attempt to add a second listener to the spatial audio engine.";
119 d->engine = nullptr;
120 return;
121 }
122 ed->listener = this;
123 }
124}
125
126/*!
127 Returns the engine associated with this listener.
128 */
129QAudioEngine *QAudioListener::engine() const
130{
131 return d->engine;
132}
133
134QT_END_NAMESPACE
135

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtmultimedia/src/spatialaudio/qaudiolistener.cpp