Skip to content

[FEATURE] add pytta.iso3382 with lateral energy fractions and IACC - #66

Open
aguirreSL wants to merge 1 commit into
PyTTaMaster:developmentfrom
aguirreSL:dev-iso3382_spatial
Open

aguirreSL wants to merge 1 commit into
PyTTaMaster:developmentfrom
aguirreSL:dev-iso3382_spatial

Conversation

@aguirreSL

@aguirreSL aguirreSL commented Oct 31, 2026 •

Copy link
Copy Markdown

Adds the module pytta.iso3382 with two spatial measures of ISO 3382-1:2009 that RoomAnalysis does not have:

  1. lateral_fraction(omni, eight, nthOct=1, minFreq=125, maxFreq=4000) gives the early lateral energy fractions JLF (A.14) and JLFC (A.15) from the impulse responses of an omnidirectional and a figure-of-eight microphone at the same point. JLF sums pL² and JLFC sums pL·p from 5 ms to 80 ms, both over the sum of p² from 0 to 80 ms.
  2. iacc(binaural, t1=0, t2=None, nthOct=1, minFreq=125, maxFreq=4000) gives the interaural cross correlation coefficient (B.1, B.2): the largest magnitude of the normalized cross correlation of the left and right ear responses over t1 to t2, for lags shorter than 1 ms. t1=0, t2=0.08 gives the early IACC and t1=0.08 the late one.

Both work by octave or fractional octave band through OctFilter, or broadband with nthOct=None. The time origin is the start of the impulse response, the first sample whose squared value is within 20 dB of the maximum, found on the broadband responses and kept for every band. The late lateral sound level LJ (A.16) is not included, since it needs the response of the source at 10 m in a free field.

The tests in tests/test_iso3382_spatial.py build responses from single reflections, so the expected values are exact:

  1. With lateral reflections at 3 ms, 20 ms, 40 ms (60° off the lateral axis) and 100 ms, JLF and JLFC match A.14 and A.15. This pins the 5 ms and 80 ms limits and the cosine against the squared cosine.
  2. Silence before the direct sound does not change the fractions.
  3. IACC is 1 for identical ears, for inverted ears and for ears 0.5 ms apart, and 0 for ears 2 ms apart.
  4. Identical early parts with late parts 3 ms apart give an early IACC of 1 and a late IACC of 0.
  5. Band analysis returns one value per octave from 125 Hz to 4 kHz.

Checked with Python 3.12, numpy 1.26 and scipy 1.17. The existing tests behave as on development: the 7 failures there (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

pytta.iso3382.lateral_fraction gives the early lateral energy fractions
JLF and JLFC of ISO 3382-1:2009 (A.14, A.15) from the impulse responses
of an omnidirectional and a figure-of-eight microphone, and
pytta.iso3382.iacc the interaural cross correlation coefficient (B.1,
B.2) of a binaural response over any time window. Both work by octave or
fractional octave band, or broadband. The time origin is the start of
the response, the first sample within 20 dB of the maximum.

Tests use responses made of single reflections, so JLF, JLFC and IACC
are exact, and pin the 5 ms and 80 ms limits, the lags below 1 ms, the
early and late windows and the band output.

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