65 : QSpatialAudioSoundPrivate{
68 addSpatialSound(engine),
71 withResonanceApi([&](vraudio::ResonanceAudioApi *api) {
72 api->SetSourcePosition(sourceId, pos.x(), pos.y(), pos.z());
73 api->SetSourceRotation(sourceId, rotation.x(), rotation.y(), rotation.z(),
76 api->SetSoundObjectNearFieldEffectGain(sourceId,
nearFieldGain);
115 if (!engine || sourceId < 0)
117 auto *ep = QAudioEnginePrivate::get(engine);
120 if (!ep->currentRoom())
122 auto *rp = QAudioRoomPrivate::get(ep->currentRoom());
126 auto listenerPos = ep->listenerPosition();
130 QVector3D roomDim2 = ep->currentRoom()->dimensions() / 2.;
131 QVector3D roomPos = ep->currentRoom()->position();
132 QQuaternion roomRot = ep->currentRoom()->rotation();
133 QVector3D dist = pos - roomPos;
135 dist = roomRot.rotatedVector(dist);
136 if (qAbs(dist.x()) <= roomDim2.x() &&
137 qAbs(dist.y()) <= roomDim2.y() &&
138 qAbs(dist.z()) <= roomDim2.z()) {
140 ep->resonanceAudio->api->SetSourceRoomEffectsGain(sourceId, 1);
149 auto relativeListenerPos = *listenerPos - roomPos;
150 relativeListenerPos = roomRot.rotatedVector(relativeListenerPos);
152 auto direction = dist.normalized();
158 const float transitionDistance =
size + 0.4;
159 std::array<QAudioRoom::Wall, 3> walls;
160 walls[X] = direction.x() > 0 ? QAudioRoom::RightWall : QAudioRoom::LeftWall;
161 walls[Y] = direction.y() > 0 ? QAudioRoom::FrontWall : QAudioRoom::BackWall;
162 walls[Z] = direction.z() > 0 ? QAudioRoom::Ceiling : QAudioRoom::Floor;
163 std::array<
float, 3> factors = {};
164 bool foundWall =
false;
165 if (direction.x() != 0) {
166 float sign = direction.x() > 0 ? 1.f : -1.f;
167 float dx = sign * roomDim2.x() - relativeListenerPos.x();
168 QVector3D intersection = relativeListenerPos + direction*dx/direction.x();
169 float dy = roomDim2.y() - qAbs(intersection.y());
170 float dz = roomDim2.z() - qAbs(intersection.z());
171 if (dy > 0 && dz > 0) {
174 factors[Y] = qMax(0.f, 1.f/3.f - dy/transitionDistance);
175 factors[Z] = qMax(0.f, 1.f/3.f - dz/transitionDistance);
176 factors[X] = 1.f - factors[Y] - factors[Z];
180 if (!foundWall && direction.y() != 0) {
181 float sign = direction.y() > 0 ? 1.f : -1.f;
182 float dy = sign * roomDim2.y() - relativeListenerPos.y();
183 QVector3D intersection = relativeListenerPos + direction*dy/direction.y();
184 float dx = roomDim2.x() - qAbs(intersection.x());
185 float dz = roomDim2.z() - qAbs(intersection.z());
186 if (dx > 0 && dz > 0) {
189 factors[X] = qMax(0.f, 1.f/3.f - dx/transitionDistance);
190 factors[Z] = qMax(0.f, 1.f/3.f - dz/transitionDistance);
191 factors[Y] = 1.f - factors[X] - factors[Z];
196 Q_ASSERT(direction.z() != 0);
197 float sign = direction.z() > 0 ? 1.f : -1.f;
198 float dz = sign * roomDim2.z() - relativeListenerPos.z();
199 QVector3D intersection = relativeListenerPos + direction*dz/direction.z();
200 float dx = roomDim2.x() - qAbs(intersection.x());
201 float dy = roomDim2.y() - qAbs(intersection.y());
202 if (dx > 0 && dy > 0) {
205 factors[X] = qMax(0.f, 1.f/3.f - dx/transitionDistance);
206 factors[Y] = qMax(0.f, 1.f/3.f - dy/transitionDistance);
207 factors[Z] = 1.f - factors[X] - factors[Y];
213 for (
int i = 0; i < 3; ++i) {
219 ep->resonanceAudio->api->SetSourceRoomEffectsGain(sourceId, 0);
222 ep->resonanceAudio->api->SetSourceVolume(sourceId, volume() *
wallDampening);
524void QSpatialSound::setDirectivity(
float alpha)
527 auto *ep = QAudioEnginePrivate::get(d->engine);
531 alpha = qBound(0., alpha, 1.);
532 if (alpha == d->directivity)
534 d->directivity = alpha;
536 ep->resonanceAudio->api->SetSoundObjectDirectivity(d->sourceId, d->directivity, d->directivityOrder);
538 emit directivityChanged();