1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #ifndef QAUDIOENGINE_OPENAL_P_H
41 #define QAUDIOENGINE_OPENAL_P_H
42 
43 //
44 //  W A R N I N G
45 //  -------------
46 //
47 // This file is not part of the Qt API.  It exists purely as an
48 // implementation detail.  This header file may change from version to
49 // version without notice, or even be removed.
50 //
51 // We mean it.
52 //
53 
54 #include <QObject>
55 #include <QList>
56 #include <QMap>
57 #include <QTimer>
58 #include <QUrl>
59 
60 #if defined(HEADER_OPENAL_PREFIX)
61 #include <OpenAL/al.h>
62 #include <OpenAL/alc.h>
63 #else
64 #include <AL/al.h>
65 #include <AL/alc.h>
66 #endif
67 
68 #include "qsoundsource_p.h"
69 #include "qsoundbuffer_p.h"
70 
71 QT_BEGIN_NAMESPACE
72 
73 class QSample;
74 class QSampleCache;
75 
76 class QSoundBufferPrivateAL : public QSoundBuffer
77 {
78     Q_OBJECT
79 public:
80     QSoundBufferPrivateAL(QObject* parent);
81     virtual void bindToSource(ALuint alSource) = 0;
82     virtual void unbindFromSource(ALuint alSource) = 0;
83 };
84 
85 
86 class StaticSoundBufferAL : public QSoundBufferPrivateAL
87 {
88     Q_OBJECT
89 
90 public:
91     StaticSoundBufferAL(QObject *parent, const QUrl &url, QSampleCache *sampleLoader);
92     ~StaticSoundBufferAL();
93 
94     State state() const override;
95 
96     void load() override;
97 
98     void bindToSource(ALuint alSource) override;
99     void unbindFromSource(ALuint alSource) override;
100 
addRef()101     inline long addRef() { return ++m_ref; }
release()102     inline long release() { return --m_ref; }
refCount()103     inline long refCount() const { return m_ref; }
104 
105 public Q_SLOTS:
106     void sampleReady();
107     void decoderError();
108 
109 private:
110     long m_ref;
111     QUrl m_url;
112     ALuint m_alBuffer;
113     State m_state;
114     QSample *m_sample;
115     QSampleCache *m_sampleLoader;
116 };
117 
118 
119 class QSoundSourcePrivate : public QSoundSource
120 {
121     Q_OBJECT
122 public:
123     QSoundSourcePrivate(QObject *parent);
124     ~QSoundSourcePrivate();
125 
126     void play() override;
127     void pause() override;
128     void stop() override;
129 
130     QSoundSource::State state() const override;
131 
132     bool isLooping() const;
133     void setLooping(bool looping) override;
134     void setPosition(const QVector3D& position) override;
135     void setDirection(const QVector3D& direction) override;
136     void setVelocity(const QVector3D& velocity) override;
137 
138     QVector3D velocity() const override;
139     QVector3D position() const override;
140     QVector3D direction() const override;
141 
142     void setGain(qreal gain) override;
143     void setPitch(qreal pitch) override;
144     void setCone(qreal innerAngle, qreal outerAngle, qreal outerGain) override;
145 
146     void bindBuffer(QSoundBuffer*) override;
147     void unbindBuffer() override;
148 
149     void checkState();
150 
151     void release();
152 
153 Q_SIGNALS:
154     void activate(QObject*);
155 
156 private:
157     void sourcePlay();
158     void sourcePause();
159 
160     ALuint  m_alSource;
161     QSoundBufferPrivateAL *m_bindBuffer;
162     bool                 m_isReady; //true if the sound source is already bound to some sound buffer
163     QSoundSource::State  m_state;
164     qreal   m_gain;
165     qreal   m_pitch;
166     qreal   m_coneInnerAngle;
167     qreal   m_coneOuterAngle;
168     qreal   m_coneOuterGain;
169 };
170 
171 
172 class QAudioEnginePrivate : public QObject
173 {
174     Q_OBJECT
175 public:
176     QAudioEnginePrivate(QObject *parent);
177     ~QAudioEnginePrivate();
178 
179     bool isLoading() const;
180 
181     QSoundSource* createSoundSource();
182     void releaseSoundSource(QSoundSource *soundInstance);
183     QSoundBuffer* getStaticSoundBuffer(const QUrl& url);
184     void releaseSoundBuffer(QSoundBuffer *buffer);
185 
186     QVector3D listenerPosition() const;
187     QVector3D listenerVelocity() const;
188     qreal listenerGain() const;
189     void setListenerPosition(const QVector3D& position);
190     void setListenerVelocity(const QVector3D& velocity);
191     void setListenerOrientation(const QVector3D& direction, const QVector3D& up);
192     void setListenerGain(qreal gain);
193     void setDopplerFactor(qreal dopplerFactor);
194     void setSpeedOfSound(qreal speedOfSound);
195 
196     static bool checkNoError(const char *msg);
197 
198 Q_SIGNALS:
199     void isLoadingChanged();
200 
201 private Q_SLOTS:
202     void updateSoundSources();
203     void soundSourceActivate(QObject *soundSource);
204 
205 private:
206     QList<QSoundSourcePrivate*> m_activeInstances;
207     QList<QSoundSourcePrivate*> m_instancePool;
208     QMap<QUrl, QSoundBufferPrivateAL*> m_staticBufferPool;
209 
210     QSampleCache *m_sampleLoader;
211     QTimer m_updateTimer;
212 };
213 
214 QT_END_NAMESPACE
215 
216 #endif
217