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.

psychoacoustics.quality.fluctuation_strength_ecma

Psychoacoustic fluctuation strength per ECMA-418-2:2025 (4th ed., Clause 9).

Clean-room implementation of the fluctuation-strength signal chain of ECMA-418-2:2025 (Clause 9, Sottek Hearing Model). The shared auditory front-end (Clause 5: outer/middle-ear filter, 53-band auditory filter bank, compressive nonlinearity of Formulae 23-25) is reused from phonometry.psychoacoustics.loudness.ecma; this module adds the fluctuation-strength chain, which mirrors the roughness chain of Clause 7 but replaces the DFT-based envelope analysis with High-resolution Spectral Analysis (HSA):

  • fluctuation-strength zero-padding (Clause 5.1.2.2) and segmentation (Clause 5.1.5.2) with the fixed block/hop / (Clause 9.1.1);
  • the Hilbert envelope of each critical-band block and a factor-32 downsampling to 1500 Hz (Clause 9.1.2, Formula 119);
  • the envelope-dependent analysis windows with quieter-period detection (Clause 9.1.3, Formula 120);
  • the HSA of the windowed envelopes — a least-squares fit of window-kernel spectral line pairs to the k = 0..48 DFT bins (Clause 9.1.4, Formulae 121-142);
  • the identification of prominent spectral line pairs from the local maxima of the power spectrum and the local minima of the HSA error over a logarithmic modulation-rate grid (Clause 9.1.5, Formulae 143-146);
  • the band-pass modulation-rate weighting (Clause 9.1.6, Formulae 147-148), the damped-Newton fine tuning of the dominant modulation rate (Clause 9.1.7, Formulae 149-152), the harmonic analysis (Clause 9.1.8, Formulae 153-156) and the centre-of-gravity weighting (Clause 9.1.9, Formulae 157-158);
  • the scaling with the HSA-based specific loudness (Clause 9.1.10, Formulae 159-161); and
  • the interpolation to 50 Hz, the distribution-dependent nonlinear transform with the calibration constant c_F, the first-order smoothing (Clause 9.1.11, Formulae 162-168) and the aggregation into the average specific fluctuation strength F’(z) (Clause 9.1.12), the time-dependent fluctuation strength F(l50) (Clause 9.1.13, Formula 169) and the representative 90th-percentile single value F (Clause 9.1.14).

The API is monaural: the quadratic-mean binaural combination of Formula (170) (Clause 9.1.15) is not implemented — analyse each channel separately.

The calibration constant c_F of Formula (163) is the standard’s tabulated value (not reverse-fit), and the chain reproduces the Clause 9 reference point: a 1 kHz carrier 100 %-amplitude-modulated at 4 Hz with an overall sound pressure level of 60 dB SPL converges to 0.9958 vacil_HMS against the defined 1 vacil_HMS as the 90th percentile settles (0.9931 for a 5 s signal, 0.9957 at 8 s, 0.9958 by 12 s). Footnote 47 allows a +/-0.25 % adjustment of c_F, which is not used. The level convention follows Clause 7/9 as established for the roughness metric: the stated 60 dB is the overall RMS level of the modulated signal, not the carrier level.

Clause 9 interpretation notes (all resolved by internal consistency and pinned by the calibration signal; the confirmed defects are recorded in docs/ERRATA.md):

  • Formula (127) prints the phase factor ; the DFT of the rectangular analysis window requires in place of (with the HSA cannot reproduce the very spectra it fits, breaking the exact-recovery property claimed for it).
  • Formula (144) subtracts 1 from the three-bin centroid before scaling by delta_f; with the 0-based bin convention stated below Formula (122) (bin k maps to ) that offset shifts every modulation rate one bin low, so the centroid is used without the offset.
  • Clause 9.1.7 states the Newton constants (differential step 1e-5, damped step cap 2e-4, stop tolerance 1e-7) without units; read in Hz they cap the total displacement at 2e-3 Hz, which makes the fine tuning inert and the failure check against 1.25 * delta_f (0.92 Hz) unreachable. They are self-consistent as normalized frequencies (f / r_s), which is how this module applies them.
  • The amplitude of a spectral line pair (Formulae 146-147, 155, 157-160) is taken as the squared magnitude of the half-line solution components of Formula (123), : with that reading Formula (160) is exactly the RMS of the modelled band signal (the loudness chain of Formulae 22-23 applied to the harmonic complex) and the tabulated c_F reproduces the calibration signal.
  • The < 0.125 Hz discard of Clause 9.1.7 names f_c,1,opt; it is applied here to the rate that survives the failure check (the original f~_c,imax when the fine tuning was cancelled), since discarding a block on a diverged optimizer output would drop healthy modulation.
  • For signals shorter than the ~0.74 s transient (fewer than 37 frames at 50 Hz), the Clause 9.1.12/9.1.14 discard of l50 = 0..35 would leave no frames; the aggregation then falls back to all frames instead of reporting an empty (zero) result.

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

EcmaFluctuationStrength(
fluctuation_strength: float,
specific_fluctuation_strength: np.ndarray,
bark: np.ndarray,
centre_frequencies: np.ndarray,
time: np.ndarray,
fluctuation_strength_vs_time: np.ndarray,
specific_fluctuation_strength_vs_time: np.ndarray,
field: str,
)

Result of an ECMA-418-2:2025 (Sottek) fluctuation-strength calculation.

fluctuation_strength is the single representative fluctuation strength F in vacil_HMS (the 90th percentile of F(l50), Clause 9.1.14). specific_fluctuation_strength is the average specific fluctuation strength F’(z) in vacil_HMS/Bark_HMS over the 53 auditory bands (Clause 9.1.12), with bark the critical-band-rate scale z (0.5..26.5 Bark_HMS) and centre_frequencies the band centre frequencies F(z). time and fluctuation_strength_vs_time hold the time-dependent fluctuation strength F(l50) at 50 Hz (Formula 169); specific_fluctuation_strength_vs_time is the time-dependent specific fluctuation strength F’(l50, z) (Formula 168) of shape (n_times, 53). field records the assumed sound field.

EcmaFluctuationStrength.plot(
ax: Axes | None = None,
*,
language: str = 'en',
**kwargs: Any,
) -> Axes | np.ndarray

Plot the fluctuation-strength result (see phonometry._plot.psychoacoustics).

Draws the time-dependent fluctuation strength F(l50) and a specific-fluctuation-strength heatmap. Requires matplotlib (pip install phonometry[plot]).

fluctuation_strength_ecma(
signal_in: Signal | np.ndarray,
fs: float | None = None,
field: Literal['free', 'diffuse'] = 'free',
) -> EcmaFluctuationStrength

Psychoacoustic fluctuation strength per ECMA-418-2:2025 (Clause 9).

Parameters

NameDescription
signal_inCalibrated sound pressure signal in pascals. Accepts a phonometry.io.Signal, which is where “calibrated” comes from without arithmetic: this model reads absolute levels, so an uncalibrated record is taken as if one digital unit were one pascal and the answer is wrong by however far that is from true.
fsSampling rate in Hz. Signals not at 48 kHz are resampled (Clause 5.1.1). Required for a bare array; a Signal brings its own, and an explicit value that disagrees with it raises instead of silently winning.
field"free" (default) or "diffuse" sound field, selecting the outer/middle-ear filter of Clause 5.1.3.

Returns: An EcmaFluctuationStrength with the single value F (Clause 9.1.14), the average specific fluctuation strength F’(z) (Clause 9.1.12) and the time-dependent fluctuation strength F(l50) (Formula 169).

Raises

ExceptionWhen
ValueErrorfor an empty, multichannel or non-finite signal, a non-finite or non-positive fs, or an unknown field.

A 1 kHz carrier 100 %-amplitude-modulated at 4 Hz with an overall level of 60 dB SPL yields 1 vacil_HMS (Clause 9 calibration; reproduced to 0.9958 vacil_HMS with the tabulated c_F of Formula (163) once the 90th percentile settles, by a 12 s signal).