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

SN3D normalized spherical harmonics #20

Open
abhayap opened this issue Feb 2, 2021 · 10 comments
Open

SN3D normalized spherical harmonics #20

abhayap opened this issue Feb 2, 2021 · 10 comments

Comments

@abhayap
Copy link

abhayap commented Feb 2, 2021

Is it possible to add support for SN3D normalized spherical harmonics? SN3D is used as a standard in many systems now.

@HaHeho
Copy link
Member

HaHeho commented Feb 2, 2021

We recently added the option to decompose and render real spherical harmonics, see Exp4.

I am not super familiar with the different conventions, so I would have to check whether the one we deployed already is SN3D.

Y = scy.sph_harm(m, n, az, co)
if kind == "complex":
return Y
else: # kind == 'real'
mg0 = m > 0
ml0 = m < 0
Y[mg0] = _np.float_power(-1.0, m)[mg0] * _np.sqrt(2) * _np.real(Y[mg0])
Y[ml0] = _np.sqrt(2) * _np.imag(Y[ml0])
return _np.real(Y)

If not, it should be fairly straight forward to incorporate a different convention. Would you be able to assist with that?

@HaHeho
Copy link
Member

HaHeho commented Feb 2, 2021

We recently added the option to decompose and render real spherical harmonics, see Exp4.

This version is not yet released as the PyPI package, in case that was the source for installing the package. We will update it in the upcoming days. Otherwise, you can install the local code from the repository.

I am not super familiar with the different conventions, so I would have to check whether the one we deployed already is SN3D.

After checking, what we are currently using is ACN ordering and the N3D normalization?

Also our coefficients include the Condon-Shortley phase (according to the scipy). I'm guessing SN3D might use factor 1 instead of (-1)^m?

@JensAhrens could you verify?

If not, it should be fairly straight forward to incorporate a different convention. Would you be able to assist with that?

@abhayap
Copy link
Author

abhayap commented Feb 2, 2021

Thanks for the quick reply! You can find a definition of the SN3D normalization here:
http://www.matthiaskronlachner.com/wp-content/uploads/2013/01/ICSA2014_KronlachnerZotter_AmbisonicTransformations.pdf

It shouldn't be too hard to add support for that. There's also a way to transform the N3D to SN3D. I don't remember the exact formula.

@abhayap
Copy link
Author

abhayap commented Feb 2, 2021

You can find more information and a way to convert from N3D to SN3D here: https://en.wikipedia.org/wiki/Ambisonic_data_exchange_formats

@HaHeho
Copy link
Member

HaHeho commented Feb 2, 2021

You can find more information and a way to convert from N3D to SN3D here: https://en.wikipedia.org/wiki/Ambisonic_data_exchange_formats

Yes, that is what I looked at as well.

One remark: to our method. We usually use
time domain -> frequency domain -> SH domain -> complex multiplication -> summation -> time domain ,
while Ambisonics considers the exchange of time domain signals, so
time domain -> SH domain -> convolution -> summation (whereby the convolution is probably also implemented as a fast convolution in frequency domain).

There shouldn't be a reason to not be able to do
time domain -> SH domain -> frequency domain -> complex multiplication -> summation -> time domain
with the tools implemented here, but we have not tested this AFAIK. However, this should not be difficult to verify.

The actually used convention only matters when exchanging coefficients with other pipelines for rendering. If I may ask, what use case or way of rendering where you considering?

@abhayap
Copy link
Author

abhayap commented Feb 2, 2021

One remark: to our method. We usually use
time domain -> frequency domain -> SH domain -> complex multiplication -> summation -> time domain ,

The final time domain HOA signal needs to have been produced by SN3D normalized spherical harmonics to be properly decoded in various software that accept HOA inputs like: https://facebookincubator.github.io/facebook-360-spatial-workstation/KB/CreatingVideosSpatialAudioFacebook360.html?highlight=sn3d

@chris-hld
Copy link

Converting from N3D to SN3D is just an order weighting:
https://github.com/chris-hld/spaudiopy/blob/ae71d0cfec1cfd587e71eb085c501bcb4c86bf49/spaudiopy/sph.py#L246

Feel free to copy if needed!

@chris-hld
Copy link

chris-hld commented Feb 5, 2021

I am not super familiar with the different conventions, so I would have to check whether the one we deployed already is SN3D.

Y = scy.sph_harm(m, n, az, co)
if kind == "complex":
return Y
else: # kind == 'real'
mg0 = m > 0
ml0 = m < 0
Y[mg0] = _np.float_power(-1.0, m)[mg0] * _np.sqrt(2) * _np.real(Y[mg0])
Y[ml0] = _np.sqrt(2) * _np.imag(Y[ml0])
return _np.real(Y)

That should be N3D.

With _np.float_power(-1.0, m) you are removing the Condon-Shortley phase, however, it looks like only for half of them?
I assume you should check that it is removed in both, m greater and less than 0.
Here is a better reference, with corrections, as the SH plot in the paper above has a flipped sign:

https://www.researchgate.net/profile/Franz_Zotter/publication/266602800_AMBIX_-A_SUGGESTED_AMBISONICS_FORMAT/links/58160c0208aeb720f68800fb/AMBIX-A-SUGGESTED-AMBISONICS-FORMAT.pdf

@HaHeho
Copy link
Member

HaHeho commented Feb 5, 2021

Thanks Chris for these references. 👍

I also noticed that our versions leads to a slightly different result compared to your implementation. However, I did not have the time investigate this closer. Will do so at some point.
https://github.com/chris-hld/spaudiopy/blob/ae71d0cfec1cfd587e71eb085c501bcb4c86bf49/spaudiopy/sph.py#L98-L117

@chris-hld
Copy link

Might be the phase. If there is something else happening than a flip around the z axis, please let me know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants