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

Check if Zwicker method can be applied and raise ValueError if it can't #18

Merged

Conversation

hakostra
Copy link
Contributor

@hakostra hakostra commented Sep 2, 2021

Ref. ISO 532-1:2017 paragraph A.3

The table A.3 giving the weights of the 1/3 band levels for
center freq. below 300 Hz is only specified for levels up to 120 dB
If one of the first 11 bands (from 25 to 250 Hz) exceed 120 dB the
Zwicker method cannot be applied.

The following small Python program demonstrate the problem:

from mosqito.functions.loudness_zwicker.comp_loudness import \
    comp_loudness_from_3spec
import numpy as np

spec_third = np.array([
    -60.,
    72.81982796,
    75.02877195,
    76.77521407,
    75.74044304,
    76.28867638,
    81.1369093,
    78.10383462,
    77.11103446,
    88.17833045,
    122.08840462,  # <- Problem with this band (250 Hz)
    120.56022017,
    82.57685237,
    81.70341169,
    73.70823606,
    75.76547571,
    76.15397857,
    71.07174789,
    74.87522753,
    67.70714846,
    67.65688453,
    62.96996558,
    62.53792231,
    58.02535465,
    58.01203941,
    54.55116421,
    52.31250338,
    51.15658175])

loudness = comp_loudness_from_3spec(True, spec_third)
Ln = sone_to_phon(loudness["values"])

print(f"Loudness: {Ln}")

Giving the following error:

  File "loudness_error.py", line 36, in <module>
    loudness = comp_loudness_from_3spec(True, spec_third)
  File "/home/hakostra/.local/lib/python3.8/site-packages/mosqito/functions/loudness_zwicker/comp_loudness.py", line 96, in comp_loudness_from_3spec
    N, N_specific = loudness_zwicker_stationary(third_spec, third_axis, field_type)
  File "/home/hakostra/.local/lib/python3.8/site-packages/mosqito/functions/loudness_zwicker/loudness_zwicker_stationary.py", line 106, in loudness_zwicker_stationary
    Nm = calc_main_loudness(spec_third, field_type)
  File "/home/hakostra/.local/lib/python3.8/site-packages/mosqito/functions/loudness_zwicker/loudness_zwicker_shared.py", line 123, in calc_main_loudness
    while spec_third[i] > rap[j] - dll[j, i] and j < dll.shape[0]:
IndexError: index 8 is out of bounds for axis 0 with size 8

The spectrum is actually from a very loud but real data source. I do of course acknowledge that the loudness can't be computed for this data, but instead of throwing a random out-of-bounds error (indicating a programming error) it should give a ValueError that can be understood and handled by the user.

I was in doubt as of where the check should be performed, but since the calc_main_loudness is the first common routine for both stationary and non-stationary signals I thought that was the best place.

Ref. ISO 532-1:2017 paragraph A.3

The table A.3 giving the weights of the 1/3 band levels for
center freq. below 300 Hz is only specified for levels up to 120 dB
If one of the first 11 bands (from 25 to 250 Hz) exceed 120 dB the
Zwicker method cannot be applied.
@mglesser
Copy link
Collaborator

mglesser commented Sep 2, 2021

This PR will definitely enhance the quality of the code. Thanks for posting. I agree that calc_main_loudness is the appropriate place for the test.

@mglesser mglesser merged commit 8556971 into Eomys:master Sep 2, 2021
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.

2 participants