Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Positional audio isn't correct #4

Closed
icculus opened this issue Aug 14, 2021 · 10 comments
Closed

Positional audio isn't correct #4

icculus opened this issue Aug 14, 2021 · 10 comments
Assignees

Comments

@icculus
Copy link
Owner

icculus commented Aug 14, 2021

As for the transition: yes, this code also has problems. It's already an extremely naive approach, and on top of that, there's clearly some incorrect math somewhere causing that jarring transition. Fixing that is on the TODO list (but I'm going to split this comment into a second bug so there's an actual place we're tracking that change).

Originally posted by @icculus in #2 (comment)

@icculus icculus self-assigned this Aug 14, 2021
@adahlkvist-feral
Copy link

I believe you are overcomplicating your approach to calculating the angle between the "at" and the "position".

I think the correct way is to do the following:

  1. Take the position vector and subtract the listener position, store in a vector called V
  2. Let a = Dot(V, Up)
  3. Remove upwards component of V by doing V = V - a * Up
  4. V will now lie in the plane with your "at" vector
  5. Use the cross product to calculate the angle.

@adahlkvist-feral
Copy link

		ALfloat V[3];
		SDL_memcpy(V, position, sizeof(V));
		ALfloat a = dotproduct(V, up);

		V[0] -= a * up[0];
		V[1] -= a * up[1];
		V[2] -= a * up[2];

		ALfloat mags = magnitude(at) * magnitude(V);
		ALfloat dot = dotproduct(at, V);
		radians = (mags == 0.0f) ? 0.0f : SDL_acosf(dot / mags);

		if (dot < 0.0f)
		{
			radians = -radians;
		}

@adahlkvist-feral
Copy link

Actually the above code might not always work, you need to clamp the thing you put into SDL_acosf from -1 to 1 otherwise you get NaN issues when the float rounding goes ever so slightly above 1 sometimes.

@adahlkvist-feral
Copy link

adahlkvist-feral commented Apr 12, 2023

Upon further reflection, I think the right code would look like this:

	// Get position relative to the listener
	ALfloat V[3];
	SDL_memcpy(V, position, sizeof(V));
	ALfloat a = dotproduct(V, up);

	// Remove upwards component so it lies completely within the horizontal plane.
	V[0] -= a * up[0];
	V[1] -= a * up[1];
	V[2] -= a * up[2];  

	// Calculate angle
	ALfloat mags = magnitude(at) * magnitude(V);
	ALfloat cosAngle = (mags == 0.0f) ? 0.0f : (dotproduct(at, V) / mags);
	cosAngle = fmaxf(fminf(cosAngle, 1.0f), -1.0f);
	radians = SDL_acosf(cosAngle);

	// Get "right" vector
	ALfloat R[3];
	xyzzy(R, at, up);

	// If it's facing right, then it's positive, if it's facing left, then it's negative.
	if (dotproduct(R,V) < 0.0f)
	{
		radians = -radians;
	}
	```

@ericoporto
Copy link
Contributor

A person made a fork with an alternative calculation that appears related to this

Helco@f5db374

@mcb2003
Copy link

mcb2003 commented Aug 12, 2024

A person made a fork with an alternative calculation that appears related to this

Helco@f5db374

I tested this, can confirm it fixed the issues I was having with very jarring transitions. My test application places two stereo sources in front of the listener, then spins the listener around. It works great with this fork. Any chance this patch could be merged?

@icculus
Copy link
Owner Author

icculus commented Aug 12, 2024

The patch in a9e2f30 is based on @Helco's work (thanks!).

The original patch was always converting to source-relative mode and didn't have the SIMD versions implemented, so I tweaked and updated it.

It's possible this math is also wrong (and/or I screwed it up, either in updating it or in the SIMD translation), so PLEASE test the latest and report back!

@icculus
Copy link
Owner Author

icculus commented Aug 12, 2024

The patch in a9e2f30 is based on Helco's work (thanks!).

(Actually, reading back, this was @adahlkvist-feral's work originally.)

@Helco
Copy link

Helco commented Aug 13, 2024

3D positions seem to have rotated 90° in the new commit compared to my fork. But I also introduced a copy-paste error in my fork and already had to fiddle around with orientations.
Maybe just a gotcha for someone unlucky enough to use the fork.

Thanks again, also to adahlkvist-feral whose code I stole for the fork

@icculus icculus reopened this Aug 14, 2024
@Helco
Copy link

Helco commented Aug 17, 2024

I checked that the current sound orientations seem to be same between MojoAL and OpenAL-Soft, so the rotation must have been a bug in my fork.

@icculus icculus closed this as completed Aug 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants