185 : QAmbientSoundPrivate{
188 addSpatialSound(engine),
191 withResonanceApi([&](vraudio::ResonanceAudioApi *api) {
192 api->SetSourcePosition(sourceId, pos.x(), pos.y(), pos.z());
193 api->SetSourceRotation(sourceId, rotation.x(), rotation.y(), rotation.z(),
196 api->SetSoundObjectNearFieldEffectGain(sourceId,
nearFieldGain);
235 if (!engine || sourceId < 0)
237 auto *ep = QAudioEnginePrivate::get(engine);
240 if (!ep->currentRoom())
242 auto *rp = QAudioRoomPrivate::get(ep->currentRoom());
246 auto listenerPos = ep->listenerPosition();
250 QVector3D roomDim2 = ep->currentRoom()->dimensions() / 2.;
251 QVector3D roomPos = ep->currentRoom()->position();
252 QQuaternion roomRot = ep->currentRoom()->rotation();
253 QVector3D dist = pos - roomPos;
255 dist = roomRot.rotatedVector(dist);
256 if (qAbs(dist.x()) <= roomDim2.x() &&
257 qAbs(dist.y()) <= roomDim2.y() &&
258 qAbs(dist.z()) <= roomDim2.z()) {
260 ep->resonanceAudio->api->SetSourceRoomEffectsGain(sourceId, 1);
269 auto relativeListenerPos = *listenerPos - roomPos;
270 relativeListenerPos = roomRot.rotatedVector(relativeListenerPos);
272 auto direction = dist.normalized();
278 const float transitionDistance =
size + 0.4;
279 std::array<QAudioRoom::Wall, 3> walls;
280 walls[X] = direction.x() > 0 ? QAudioRoom::RightWall : QAudioRoom::LeftWall;
281 walls[Y] = direction.y() > 0 ? QAudioRoom::FrontWall : QAudioRoom::BackWall;
282 walls[Z] = direction.z() > 0 ? QAudioRoom::Ceiling : QAudioRoom::Floor;
283 std::array<
float, 3> factors = {};
284 bool foundWall =
false;
285 if (direction.x() != 0) {
286 float sign = direction.x() > 0 ? 1.f : -1.f;
287 float dx = sign * roomDim2.x() - relativeListenerPos.x();
288 QVector3D intersection = relativeListenerPos + direction*dx/direction.x();
289 float dy = roomDim2.y() - qAbs(intersection.y());
290 float dz = roomDim2.z() - qAbs(intersection.z());
291 if (dy > 0 && dz > 0) {
294 factors[Y] = qMax(0.f, 1.f/3.f - dy/transitionDistance);
295 factors[Z] = qMax(0.f, 1.f/3.f - dz/transitionDistance);
296 factors[X] = 1.f - factors[Y] - factors[Z];
300 if (!foundWall && direction.y() != 0) {
301 float sign = direction.y() > 0 ? 1.f : -1.f;
302 float dy = sign * roomDim2.y() - relativeListenerPos.y();
303 QVector3D intersection = relativeListenerPos + direction*dy/direction.y();
304 float dx = roomDim2.x() - qAbs(intersection.x());
305 float dz = roomDim2.z() - qAbs(intersection.z());
306 if (dx > 0 && dz > 0) {
309 factors[X] = qMax(0.f, 1.f/3.f - dx/transitionDistance);
310 factors[Z] = qMax(0.f, 1.f/3.f - dz/transitionDistance);
311 factors[Y] = 1.f - factors[X] - factors[Z];
316 Q_ASSERT(direction.z() != 0);
317 float sign = direction.z() > 0 ? 1.f : -1.f;
318 float dz = sign * roomDim2.z() - relativeListenerPos.z();
319 QVector3D intersection = relativeListenerPos + direction*dz/direction.z();
320 float dx = roomDim2.x() - qAbs(intersection.x());
321 float dy = roomDim2.y() - qAbs(intersection.y());
322 if (dx > 0 && dy > 0) {
325 factors[X] = qMax(0.f, 1.f/3.f - dx/transitionDistance);
326 factors[Y] = qMax(0.f, 1.f/3.f - dy/transitionDistance);
327 factors[Z] = 1.f - factors[X] - factors[Y];
333 for (
int i = 0; i < 3; ++i) {
339 ep->resonanceAudio->api->SetSourceRoomEffectsGain(sourceId, 0);
342 ep->resonanceAudio->api->SetSourceVolume(sourceId, volume() *
wallDampening);
489void QSpatialSound::setDirectivity(
float alpha)
492 auto *ep = QAudioEnginePrivate::get(d->engine);
496 alpha = qBound(0., alpha, 1.);
497 if (alpha == d->directivity)
499 d->directivity = alpha;
501 ep->resonanceAudio->api->SetSoundObjectDirectivity(d->sourceId, d->directivity, d->directivityOrder);
503 emit directivityChanged();