Skip to content

[FEATURE] add pytta.ambisonics with higher-order Ambisonics - #90

Open
aguirreSL wants to merge 2 commits into
PyTTaMaster:developmentfrom
aguirreSL:dev-ambisonics
Open

aguirreSL wants to merge 2 commits into
PyTTaMaster:developmentfrom
aguirreSL:dev-ambisonics

Conversation

@aguirreSL

Copy link
Copy Markdown

Builds on #89 (pytta.vbap), so until #89 is merged this pull request also shows its commit.

Adds pytta.ambisonics, higher-order Ambisonics in N3D normalization and ACN ordering, as in the spatial audio and spherical harmonics applications of the ITA-Toolbox:

  1. real_sh(order, directions): orthonormal real spherical harmonics, without the Condon-Shortley phase.
  2. encode(signals, directions, order) and decode(hoa, D, cutoffs=None, fs=None): encoding of sources and decoding with a matrix, also in frequency bands with one matrix per band.
  3. decoder(ls_directions, method, max_re=True, order=None): decoding matrices by sampling (sad), mode matching (mmd), energy preservation (epad), all-round decoding (allrad, Zotter and Frank 2012) and constant angular spread (csad, Epain et al. 2014), with max-rE weights. layout_order gives the order a layout supports.
  4. rotate(hoa, yaw, pitch, roll) with sh_rotation, the rotation matrix of real harmonics by the recursion of Ivanic and Ruedenberg.
  5. First-order B-format: encode_bformat, decode_bformat and rotate_bformat.
  6. Conversions: n3d_to_sn3d, sn3d_to_n3d, n3d_to_fuma, fuma_to_n3d, acn_to_sid and sid_to_acn. bformat_fuma gives first-order FuMa from FuMa, AmbiX or N3D scenes of any order, as Iceberg does.
  7. t_design(degree): the spherical t-designs of Hardin and Sloane, degree 1 to 21, kept in pytta/_tdesigns.py so that no data file is needed in the package.

pytta.vbap gets energy_gains (vector base intensity panning) and spread rings, which the CSAD decoder uses.

The module is a port of the MATLAB libraries Higher-Order-Ambisonics and Spherical-Harmonic-Transform by Archontis Politis (https://github.com/polarch). Their BSD 3-Clause licence is reproduced in the module header.

The tests in tests/test_ambisonics.py print the measured differences:

  1. The harmonics are orthonormal up to order 10 under Gauss-Legendre quadrature, which is exact (2.2e-15). Under the 21-design they are orthonormal up to order 6 within the precision of its tabulated points (8.7e-10).
  2. The first order of an N3D encoding is FuMa B-format, scaled by the 1/sqrt(4π) of the orthonormal harmonics. bformat_fuma gives the same B-format from third-order AmbiX, N3D and FuMa scenes (1.1e-16).
  3. Rotating a scene with one source equals encoding the source in the rotated direction, up to order 4, and a positive yaw adds to the azimuth (2.2e-16).
  4. Parity with the MATLAB library on golden data from tests/golden/make_ambisonics_polarch.m (MATLAB R2026b) covers the harmonics, every conversion, the max-rE weights, the order of two layouts and the five decoders on a layout of 19 loudspeakers. It also covers encoding, decoding in three frequency bands, and B-format encoding, decoding and rotation. All agree within 3.4e-15. The golden data use the copies of the libraries that Iceberg installs. Three small functions they take from Spherical-Harmonic-Transform (getTdesign, sphDelaunay and euler2rotationMatrix) were replaced by minimal versions, and the rotation of higher orders is checked by test 3.

Checked with Python 3.12, numpy 1.26 and scipy 1.17. The 7 failures of development (3 in test_h5io.py, 4 in test_pyttasave.py) are the same with and without this change.

Co-Authored-By: Claude Fable 5.1 noreply@anthropic.com

aguirreSL and others added 2 commits October 31, 2026 22:57
pytta.vbap pans sources on 2D and 3D loudspeaker layouts (Pulkki 1997):
loudspeaker_pairs and loudspeaker_triplets find the groups (the convex
hull of the directions in 3D, without the faces that close a
hemisphere), inverse_matrices inverts the matrix of each group and
gains gives the gains of a set of source directions, with an optional
spread (MDAP).

It is a port of the MATLAB library Vector-Base-Amplitude-Panning of
Archontis Politis, whose BSD 3-Clause licence is reproduced in the
module header.

Tests check the tangent law of a stereo pair, that the 3D gains weight
the loudspeaker vectors into the source direction, and parity with the
MATLAB library on golden data from tests/golden/make_vbap_polarch.m
(groups identical, inverses and gains within 4.4e-16).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
pytta.ambisonics encodes, decodes and rotates higher-order Ambisonics
in N3D and ACN: real_sh, encode, decode (also in frequency bands),
decoder with the sampling, mode-matching, energy-preserving, all-round
(ALLRAD) and constant angular spread (CSAD) decoders and max-rE
weights, layout_order, rotate and sh_rotation, the B-format functions,
the conversions to SN3D, FuMa and SID, and bformat_fuma of Iceberg.
The t-designs of degree 1 to 21 are in pytta/_tdesigns.py.
pytta.vbap gains energy_gains (VBIP) and spread rings, which CSAD uses.

It is a port of the MATLAB libraries Higher-Order-Ambisonics and
Spherical-Harmonic-Transform of Archontis Politis, whose BSD 3-Clause
licence is reproduced in the module header.

Tests check the orthonormality of the harmonics by exact quadrature,
that the first order is FuMa B-format, that a rotation moves the
encoded direction, and parity with the MATLAB library on golden data
from tests/golden/make_ambisonics_polarch.m (within 3.4e-15).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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

Successfully merging this pull request may close these issues.

1 participant