Skip to content

[FEATURE] add pytta.din45681 with the tonal audibility of DIN 45681 - #88

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

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

Conversation

@aguirreSL

Copy link
Copy Markdown

Adds pytta.din45681 with the tonal audibility of DIN 45681:2002, as ita_tonality in the ITA-Toolbox (applications/Psychoacoustics).

tonal_audibility(signal) takes one channel of sound pressure in Pa and returns the largest audibility DeltaL in dB, the frequency of that tone and a list with each tone found: its frequency, critical bandwidth, LS, LT, LG, av, DeltaL and DeltaL of its critical band. The method follows ita_tonality step by step:

  1. The A-weighted power spectrum is averaged over Hann windowed blocks with lines of 2 Hz.
  2. For each line from 100 Hz to 8192 Hz, the masking level LS of its critical band, dfc = 25 + 75 (1 + 1.4 (f/1 kHz)^2)^0.69 Hz, is the energy mean of the lines not more than 6 dB above LS, iterated until it settles.
  3. A region of lines 6 dB or more above LS is a tone candidate at its highest line. Its level LT adds the neighbour lines within 10 dB of the peak.
  4. DeltaL = LT - LG - av, with LG = LS + 10 lg(dfc/df) and av = -2 - lg(1 + (f/502)^2.5). A candidate wider than 18 (1 + 0.001 f) Hz, or with a flank less steep than 24, is no tone.
  5. Tones in one critical band are summed.

The code is a port, so the licence of the ITA-Toolbox (BSD, four clauses) is reproduced in the module header, with the acknowledgment its third clause asks for. Three points differ from the MATLAB code, and the docstring states them:

  1. ita_tonality labels FFT line k with the frequency (k + 1) df, so every frequency it reports is 2 Hz high. This module uses k df.
  2. Its levels are 6 dB low, for tones and noise alike, so DeltaL is the same. This module gives absolute levels.
  3. Its search for a tone region uses LS = 0 below 100 Hz and would read past the end of LS above 8192 Hz. This module stops the search at both ends.

The tone adjustment K_T of the standard is not computed, as in ita_tonality.

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

  1. A 1 kHz tone in white noise gives the DeltaL of the formula within 0.19 dB. The masking level of a noise estimated from 19 blocks scatters by up to 0.34 dB over noise seeds, so the tolerance is 0.5 dB.
  2. Parity with ita_tonality on golden data from tests/golden/make_din45681_ita.m (MATLAB R2026b, same samples): tones at 400 Hz, 1 kHz and 3 kHz in noise and two tones in one critical band give the DeltaL of ITA within 0.005 dB, the same number of tones, and frequencies 2 Hz below those of ITA.
  3. Noise alone has no tone.
  4. Invalid input is rejected.

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

tonal_audibility(signal) finds the tonal components of a noise and their
audibility DeltaL = LT - LG - av, DIN 45681:2002: A-weighted spectrum
averaged over Hann blocks with lines of 2 Hz, masking level of the
critical band by iteration, tone level from the lines within 10 dB of
the peak, distinctness by width and flank steepness, and the sum of the
tones in one critical band.

It is a port of ita_tonality of the ITA-Toolbox, whose BSD licence is
reproduced in the module header. Three points differ from the MATLAB
code and are documented: the frequency of each FFT line (ita_tonality
reads each one 2 Hz high), the absolute scale of the levels (6 dB low
there for tones and noise alike, so DeltaL is the same), and the ends of
the search for a tone region, which stop at 100 Hz and 8192 Hz.

Tests check a tone in white noise against the formula, parity with
ita_tonality on golden data from tests/golden/make_din45681_ita.m
(DeltaL within 0.005 dB, frequencies 2 Hz below ITA), that noise alone
has no tone, and the rejection of invalid input.

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