7#include <QtMultimedia/private/qmultimedia_ranges_p.h>
8#include <QtSpatialAudio/private/qaudioengine_threaded_p.h>
9#include <QtSpatialAudio/private/qaudioroom_p.h>
10#include <QtCore/qspan.h>
14#include <resonance_audio.h>
18QAudioEnginePrivate::QAudioEnginePrivate(
int sampleRate)
19 : m_sampleRate(sampleRate),
21 std::make_unique<vraudio::ResonanceAudio>(2, framesPerBuffer, sampleRate),
24 resonanceAudio->api->SetStereoSpeakerMode(outputMode() != QAudioEngine::Headphone);
25 resonanceAudio->api->SetMasterVolume(masterVolume());
32 if (scale == m_distanceScale)
34 m_distanceScale = scale;
36 emit q->distanceScaleChanged();
41 return m_distanceScale;
49 resonanceAudio->api->SetMasterVolume(volume);
51 emit q->masterVolumeChanged();
61 if (pos == m_position)
71 resonanceAudio->api->SetHeadRotation(rotation.x(), rotation.y(), rotation.z(),
77 if (resonanceAudio->roomEffectsEnabled == enabled)
79 resonanceAudio->roomEffectsEnabled = enabled;
84 return resonanceAudio->roomEffectsEnabled;
89 if (m_outputMode == mode)
92 resonanceAudio->api->SetStereoSpeakerMode(mode != QAudioEngine::Headphone);
95 emit q->outputModeChanged();
105 Q_ASSERT(!QtMultimediaPrivate::ranges::contains(rooms, room));
106 rooms.push_back(room);
111 Q_ASSERT(QtMultimediaPrivate::ranges::contains(rooms, room));
112 q20::erase(rooms, room);
117 return m_currentRoom;
125 bool roomDirty =
false;
126 for (
const auto &room : rooms) {
127 auto *rd = QAudioRoomPrivate::get(room);
134 auto inferredRoom = findSmallestRoomForListener(rooms);
135 if (inferredRoom.room != m_currentRoom)
137 const bool previousRoom = m_currentRoom;
138 m_currentRoom = inferredRoom.room;
144 if (!m_currentRoom) {
145 resonanceAudio->api->EnableRoomEffects(
false);
149 resonanceAudio->api->EnableRoomEffects(
true);
151 QAudioRoomPrivate *rp = QAudioRoomPrivate::get(m_currentRoom);
152 resonanceAudio->api->SetReflectionProperties(rp->reflections);
153 resonanceAudio->api->SetReverbProperties(rp->reverb);
162 const std::optional<QVector3D> listenerPos = listenerPosition();
170 std::optional<
float> roomVolume;
171 QAudioRoom *room =
nullptr;
173 for (QAudioRoom *r : std::as_const(rooms)) {
174 QVector3D dim2 = r->dimensions() / 2.;
175 float vol = dim2.x() * dim2.y() * dim2.z();
176 if (roomVolume && vol > roomVolume)
178 QVector3D dist = r->position() - *listenerPos;
180 dist = r->rotation().rotatedVector(dist);
181 if (qAbs(dist.x()) <= dim2.x() && qAbs(dist.y()) <= dim2.y()
182 && qAbs(dist.z()) <= dim2.z()) {
190 roomVolume.value_or(0.f),
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254QAudioEngine::QAudioEngine(
int sampleRate, QObject *parent)
255 : QObject(*
new QAudioEngineThreaded(sampleRate), parent)
260
261
262QAudioEngine::~QAudioEngine()
268
269
270
271
272
273
274
275
276
279
280
281
282
283
284
285void QAudioEngine::setOutputMode(OutputMode mode)
288 d->setOutputMode(mode);
291QAudioEngine::OutputMode QAudioEngine::outputMode()
const
293 Q_D(
const QAudioEngine);
294 return d->outputMode();
298
299
300int QAudioEngine::sampleRate()
const
302 Q_D(
const QAudioEngine);
303 return d->sampleRate();
307
308
309
310
311void QAudioEngine::setOutputDevice(
const QAudioDevice &device)
314 d->setOutputDevice(device);
317QAudioDevice QAudioEngine::outputDevice()
const
319 Q_D(
const QAudioEngine);
320 return d->outputDevice();
324
325
326
327
328void QAudioEngine::setMasterVolume(
float volume)
331 return d->setMasterVolume(volume);
334float QAudioEngine::masterVolume()
const
336 Q_D(
const QAudioEngine);
337 return d->masterVolume();
341
342
343void QAudioEngine::start()
350
351
352void QAudioEngine::stop()
359
360
361
362
363void QAudioEngine::setPaused(
bool paused)
366 d->setPaused(paused);
369bool QAudioEngine::paused()
const
371 Q_D(
const QAudioEngine);
372 return d->isPaused();
376
377
378
379
380
381
382
383void QAudioEngine::setRoomEffectsEnabled(
bool enabled)
386 d->setRoomEffectsEnabled(enabled);
390
391
392bool QAudioEngine::roomEffectsEnabled()
const
394 Q_D(
const QAudioEngine);
395 return d->roomEffectsEnabled();
399
400
401
402
403
404
405
406
407void QAudioEngine::setDistanceScale(
float scale)
413 qWarning() <<
"QAudioEngine: Invalid distance scale.";
416 d->setDistanceScale(scale);
419float QAudioEngine::distanceScale()
const
421 Q_D(
const QAudioEngine);
422 return d->distanceScale() * 100.f;
426
427
428
429
431
432
433
434
436
437
438
440
441
442
446#include "moc_qaudioengine.cpp"
void removeRoom(QAudioRoom *)
void setMasterVolume(float)
virtual void updateRoomEffects()=0
void addRoom(QAudioRoom *)
bool roomEffectsEnabled() const
float distanceScale() const
QAudioRoom * currentRoom() const
void setOutputMode(QAudioEngine::OutputMode)
SmallestRoomForListenerResult findSmallestRoomForListener(QSpan< QAudioRoom * > rooms) const
void setListenerPosition(std::optional< QVector3D >)
float masterVolume() const
void setDistanceScale(float scale)
void setListenerRotation(const QQuaternion &)
~QAudioEnginePrivate() override
void setRoomEffectsEnabled(bool)