Skip to content
This documentation describes version 4.0.0, which is not released yet. The current version on PyPI is 3.3.0 and does not carry everything described here.

hearing.hearing_protectors

What a hearing protector leaves at the ear (ISO 4869-2:2018).

A protector is measured on people, not on a coupler: ISO 4869-1 seats it on at least 16 subjects and records the threshold shift it produces in each octave band. What comes out is a distribution, one attenuation per subject per band, and ISO 4869-2 is the standard that turns that distribution into a level someone can act on.

The distribution first (Clause 5). Every method here starts from the assumed protection value, the mean attenuation reduced by a multiple of its own spread (Formula (1)):

The constant is the inverse standard normal cumulative distribution at the protection performance (Table 1), so with is the attenuation 84 % of wearers reach or beat, and with is what all but one in fifty reach. A protector is never quoted at its mean.

Then one of three methods, in decreasing order of what they need to know about the noise:

  • The octave-band method (Clause 6) subtracts the assumed protection value band by band from the A-weighted noise spectrum, Formula (2). It needs the spectrum and is the most faithful.
  • The HML method (Clause 7) collapses the protector to three numbers, its high-, medium- and low-frequency attenuation values, each the predicted noise level reduction for a reference noise of a stated . It needs only the C- and A-weighted levels of the noise.
  • The SNR method (Clause 8) collapses it to one number against a pink noise and subtracts it from the C-weighted level. It needs only that level.

The three answer the same question and rarely agree exactly: on the worked example of Annexes B, C and D the same protector in the same noise gives 81 dB, 82 dB and 82 dB. Clause 1’s own NOTE puts differences of 3 dB or less between comparable protectors below the resolution of the exercise.

The octave-band method starts at 63 Hz when both the noise and the protector have data there and at 125 Hz when either does not (Clause 6). The HML (Clause 7) and SNR (Clause 8) computations start at 125 Hz always, whatever is available at 63 Hz, which is why the reference spectra of Tables 2 and 3 begin there.

Clause, formula and table numbers refer to ISO 4869-2:2018(E).

Auto-generated from the source docstrings by scripts/generate_api_docs.py (make api-docs). Do not edit by hand.

assumed_protection_value(
attenuation: Sequence[Sequence[float]] | np.ndarray,
*,
performance: int = 84,
frequencies: Sequence[float] | np.ndarray | None = None,
) -> AssumedProtectionResult

Assumed protection values of a hearing protector (Formula (1)).

The attenuation of a protector is a distribution over people, and Clause 5 reduces it to the level a stated share of wearers reaches or beats:

with and the mean and standard deviation of the per-subject attenuations of ISO 4869-1 and the inverse standard normal cumulative distribution at the protection performance (Table 1). The standard deviation is the sample one, over N - 1.

Parameters

NameDescription
attenuationA (subjects, bands) grid of sound attenuation values, in dB, one row per subject, measured to ISO 4869-1.
performanceThe protection performance x, in per cent, from Table 1: 50, 75, 80, 84 (the default), 90, 95 or 98.
frequenciesOctave-band mid-frequencies, in hertz, or None for the eight bands of Formula (2) when the grid has eight columns.

Returns: AssumedProtectionResult.

Raises

ExceptionWhen
ValueErrorif the grid is not two-dimensional or holds fewer than two subjects, if any value is not finite, if performance is not one Table 1 tabulates, or if frequencies does not match the grid.
AssumedProtectionResult(
apv: np.ndarray,
mean_attenuation: np.ndarray,
standard_deviation: np.ndarray,
performance: int,
alpha: float,
frequencies: np.ndarray,
subjects: int,
)

Assumed protection values of a hearing protector (Clause 5).

Attributes

NameDescription
apv per octave band, in dB.
mean_attenuationThe mean attenuation per band, in dB.
standard_deviationThe standard deviation per band, in dB, over the test subjects.
performanceThe protection performance x, in per cent.
alphaThe Table 1 constant that performance selected.
frequenciesOctave-band mid-frequencies, in hertz.
subjectsNumber of test subjects the distribution came from.
AssumedProtectionResult.plot(
ax: Axes | None = None,
language: str = 'en',
**kwargs: Any,
) -> Axes

Draw the mean attenuation, its spread and the assumed protection.

Parameters

NameDescription
axExisting axes, or None to create a figure.
languageLabel language, "en" (default) or "es".
kwargsForwarded to the APV curve.

Returns: The axes.

hml_protected_level(
l_p_a: float,
l_p_c: float,
rating: HMLRatingResult,
) -> ProtectedLevelResult

Effective A-weighted level by the HML method (Formulas (16) to (18)).

Two straight segments through the three anchors, in :

Both branches pass through at dB, which is where the medium-frequency value is defined (Clause 3.6). The three values that enter them are the rounded ones: Clause 7.2 rounds , and to the nearest integer, so that is what a protector is published with and what this consumes, whatever the unrounded fit behind them was. Clause 7.3 allows the unweighted level in place of the C-weighted one, which for very low-frequency noise returns a higher, safer .

Parameters

NameDescription
l_p_aA-weighted sound pressure level of the noise, in dB.
l_p_cC-weighted sound pressure level of the noise, in dB.
ratingThe protector’s HMLRatingResult.

Returns: ProtectedLevelResult.

Raises

ExceptionWhen
ValueErrorif either level is not finite.
hml_rating(
attenuation: Sequence[Sequence[float]] | np.ndarray,
*,
performance: int = 84,
) -> HMLRatingResult

The H, M and L values of a protector (Formulas (3) to (15)).

Clause 7.2 fits the protector against the eight reference noises of Table 2. For each subject and each noise it forms the predicted noise level reduction

and collapses the eight into three, weighted by the empirical constants of Table 2:

The four quiet-spectrum noises carry H and the four loud-spectrum ones carry M and L, which is the split the formulas print. Each index is then reduced by its own spread across subjects exactly as Formula (1) reduces the attenuation (Formulas (3) to (11)).

Parameters

NameDescription
attenuationA (subjects, bands) grid of sound attenuation values, in dB. Formula (15) reads 125 Hz to 8000 Hz, so a grid of eight bands is taken to start at 63 Hz and its first column is dropped; a grid of seven is taken to start at 125 Hz.
performanceThe protection performance x, in per cent, from Table 1.

Returns: HMLRatingResult.

Raises

ExceptionWhen
ValueErrorif the grid is not two-dimensional, holds fewer than two subjects, carries neither seven nor eight bands, or if performance is not one Table 1 tabulates.

Constant (tuple).

HML_REFERENCE_C_MINUS_A = (-1.2, -0.5, 0.1, 1.6, 2.3, 4.3, 6.1, 8.4)

Constant (tuple).

HML_REFERENCE_D = (-1.2, -0.49, 0.14, 1.56, -2.98, -1.01, 0.85, 3.14)

Constant (tuple).

HML_REFERENCE_NOISES = ((62.6, 70.8, 81.0, 90.4, 96.2, 94.7, 92.3), (68.9, 78.3, 84.3, 92.8, 96.3, 94.0, 90.0), (71.1, 80.8, 88.0, 95.0, 94.4, 94.1, 89.0), (77.2, 84.5, 89.8, 95.5, 94.3, 92.5, 88.8), (77.4, 86.5, 92.5, 96.4, 93.0, 90.4, 83.7), (82.0, 89.3, 93.3, 95.6, 93.0, 90.1, 83.0), (84.2, 90.1, 93.6, 96.2, 91.3, 87.9, 81.9), (88.0, 93.4, 93.8, 94.2, 91.4, 87.9, 79.9))
HMLRatingResult(
high: float,
medium: float,
low: float,
subject_h: np.ndarray,
subject_m: np.ndarray,
subject_l: np.ndarray,
predicted_reduction: np.ndarray,
performance: int,
alpha: float,
)

The three HML attenuation values of a protector (Clause 7.2).

Attributes

NameDescription
high, the high-frequency value, in dB, unrounded.
medium, the medium-frequency value, in dB, unrounded.
low, the low-frequency value, in dB, unrounded.
subject_h per test subject, in dB (Formula (12)).
subject_m per test subject, in dB (Formula (13)).
subject_l per test subject, in dB (Formula (14)).
predicted_reduction per subject and reference noise, in dB, a (subjects, 8) grid (Formula (15)).
performanceThe protection performance x, in per cent.
alphaThe Table 1 constant that performance selected.
HMLRatingResult.plot(
ax: Axes | None = None,
language: str = 'en',
**kwargs: Any,
) -> Axes

Draw the predicted noise level reduction against LpC - LpA.

Parameters

NameDescription
axExisting axes, or None to create a figure.
languageLabel language, "en" (default) or "es".
kwargsForwarded to the PNR curve.

Returns: The axes.

property

(H, M, L) rounded the way Clause 7.2 reports them.

Returns: The three values as integers, halves away from zero.

octave_band_protected_level(
noise_levels: Sequence[float] | np.ndarray,
apv: Sequence[float] | np.ndarray | AssumedProtectionResult,
*,
frequencies: Sequence[float] | np.ndarray | None = None,
a_weighting: Sequence[float] | np.ndarray | None = None,
) -> ProtectedLevelResult

Effective A-weighted level by the octave-band method (Formula (2)).

The most faithful of the three methods, and the only one that sees the shape of the noise:

The summation runs over the eight octaves from 63 Hz, or over seven from 125 Hz when 63 Hz data is missing for either the noise or the protector (Clause 6). Pass seven values to both arguments for that case.

Parameters

NameDescription
noise_levelsOctave-band sound pressure levels of the noise, , in dB. Unweighted: the A weighting is added here.
apvAssumed protection values, in dB, or the AssumedProtectionResult that carries them.
frequenciesOctave-band mid-frequencies, in hertz, or None for the eight bands of Formula (2), or those seven without 63 Hz.
a_weightingFrequency weighting A at those bands, in dB, or None for PROTECTOR_A_WEIGHTING, which is IEC 61672-1:2013 Table 3.

Returns: ProtectedLevelResult.

Raises

ExceptionWhen
ValueErrorif the band counts disagree, if any value is not finite, or if the bands are neither the eight of Formula (2) nor those seven without 63 Hz and frequencies was not given.

Constant (tuple).

PINK_NOISE_A_WEIGHTED = (75.9, 83.4, 88.8, 92.0, 93.2, 93.0, 90.9)
ProtectedLevelResult(
effective_level: float,
noise_reduction: float | None,
performance: int | None,
method: str,
band_levels: np.ndarray | None = None,
frequencies: np.ndarray | None = None,
)

The A-weighted level left at the ear behind a protector.

Attributes

NameDescription
effective_level, in dB, unrounded. Clauses 6, 7.3 and 8.3 all report it to the nearest integer, which reported_level does.
noise_reduction, in dB, or None where it cannot be formed. The SNR method given only a C-weighted level never learns , and the difference between the C-weighted level and the answer is the rating itself rather than a noise reduction.
performanceThe protection performance x, in per cent, or None when the rating that produced it did not carry one.
method"octave-band", "HML" or "SNR".
band_levelsThe A-weighted band levels behind the protector, in dB, for the octave-band method, and None for the other two, which never see a spectrum.
frequenciesOctave-band mid-frequencies, in hertz, or None.
ProtectedLevelResult.plot(
ax: Axes | None = None,
language: str = 'en',
**kwargs: Any,
) -> Axes

Draw the band levels the protector leaves, where there are any.

Parameters

NameDescription
axExisting axes, or None to create a figure.
languageLabel language, "en" (default) or "es".
kwargsForwarded to the protected-level bars.

Returns: The axes.

Raises

ExceptionWhen
ValueErrorfor an HML or SNR result, which carries no spectrum to draw.

property

effective_level rounded the way the standard reports it.

Returns: The nearest integer, halves away from zero.

Constant (dict).

PROTECTION_PERFORMANCES = {50: 0.0, 75: 0.67, 80: 0.84, 84: 1.0, 90: 1.28, 95: 1.64, 98: 2.0}

Constant (tuple).

PROTECTOR_A_WEIGHTING = (-26.2, -16.1, -8.6, -3.2, 0.0, 1.2, 1.0, -1.1)

Constant (tuple).

PROTECTOR_OCTAVE_BANDS = (63.0, 125.0, 250.0, 500.0, 1000.0, 2000.0, 4000.0, 8000.0)
snr_protected_level(
rating: SNRRatingResult,
*,
l_p_c: float | None = None,
l_p_a: float | None = None,
c_minus_a: float | None = None,
) -> ProtectedLevelResult

Effective A-weighted level by the SNR method (Formulas (23) and (24)).

Formula (24) is Formula (23) with the C-weighted level reassembled from an A-weighted measurement and an estimate of the difference, for the common case where only the A-weighted level was recorded. Pass l_p_c, or pass l_p_a together with c_minus_a. Clause 8.3 allows the unweighted level in place of the C-weighted one, which for very low-frequency noise returns a higher, safer .

The rating is used as Clause 8.2 reports it, rounded to the nearest integer.

Parameters

NameDescription
ratingThe protector’s SNRRatingResult.
l_p_cC-weighted sound pressure level of the noise, in dB, for Formula (23).
l_p_aA-weighted sound pressure level of the noise, in dB, for Formula (24).
c_minus_aThe difference , in dB, for Formula (24).

Returns: ProtectedLevelResult.

Raises

ExceptionWhen
ValueErrorif neither pairing is complete, if both are given, or if any level is not finite.
snr_rating(
attenuation: Sequence[Sequence[float]] | np.ndarray,
*,
performance: int = 84,
) -> SNRRatingResult

The single number rating of a protector (Formulas (19) to (22)).

One reference noise instead of eight, and one number instead of three:

where is the pink noise of Table 3, whose C-weighted level is 100 dB. Because the reference noise is fixed, the rating says nothing about the shape of the noise it will meet, which is what the HML method’s three values recover.

Parameters

NameDescription
attenuationA (subjects, bands) grid of sound attenuation values, in dB, over the eight octaves from 63 Hz or the seven from 125 Hz.
performanceThe protection performance x, in per cent, from Table 1.

Returns: SNRRatingResult.

Raises

ExceptionWhen
ValueErrorif the grid is not two-dimensional, holds fewer than two subjects, carries neither seven nor eight bands, or if performance is not one Table 1 tabulates.
SNRRatingResult(
snr: float,
subject_snr: np.ndarray,
mean: float,
standard_deviation: float,
performance: int,
alpha: float,
)

The single number rating of a protector (Clause 8.2).

Attributes

NameDescription
snr, in dB, unrounded.
subject_snr per test subject, in dB (Formula (22)).
mean, in dB (Formula (20)).
standard_deviation, in dB (Formula (21)).
performanceThe protection performance x, in per cent.
alphaThe Table 1 constant that performance selected.
SNRRatingResult.plot(
ax: Axes | None = None,
language: str = 'en',
**kwargs: Any,
) -> Axes

Draw the per-subject ratings the single number was reduced from.

Parameters

NameDescription
axExisting axes, or None to create a figure.
languageLabel language, "en" (default) or "es".
kwargsForwarded to the per-subject bars.

Returns: The axes.

property

snr rounded the way Clause 8.2 reports it.

Returns: The nearest integer, halves away from zero.