← [Documentation index](README.md)

# API Reference

All core functionality lives in fifteen domain subpackages; every public name
is also re-exported by the top-level `phonometry` package.

> **Note.** This page is the curated quick table for the GitHub/PyPI audience:
> one row per public name, kept complete by a CI gate
> (`scripts/check_api_reference.py`). The full generated reference, with every
> signature, parameter table and cross-link, lives on the site:
> [phonometry API reference](https://jmrplens.github.io/phonometry/reference/api/).

## Namespaces

The library is organized into fifteen domain subpackages, and importing the
domain namespace is the primary form used throughout the documentation:

```python
from phonometry import aircraft

contour = aircraft.noise_contour(path, powers, distances, sel, lmax, x=gx, y=gy)
```

| Subpackage | Scope |
| :--- | :--- |
| `phonometry.metrology` | Filter banks, weighting and time weighting, levels, calibration, IEC verifiers, GUM uncertainty |
| `phonometry.psychoacoustics` | Loudness (Zwicker, ECMA, Moore-Glasberg), sharpness, tonality, roughness, fluctuation strength, annoyance, tonal audibility |
| `phonometry.hearing` | Hearing threshold, NIHL, occupational exposure, SII, STI |
| `phonometry.emission` | Sound power (ISO 3740 family), sound intensity, vibration-based power |
| `phonometry.room` | Room acoustics (ISO 3382), impulse responses, open-plan, room-noise criteria, reverberation prediction, EN 12354-6 |
| `phonometry.materials` | Absorption (ISO 354/11654), impedance tube, airflow resistance, scattering/diffusion, road absorption, dynamic stiffness |
| `phonometry.building` | Sound insulation measurement and prediction (EN 12354, ISO 717/16283/10140/15186/10052/10848), structure-borne sound |
| `phonometry.vibration` | Human vibration (ISO 2631/5349/8041), multiple shocks, mobility (ISO 7626), transfer stiffness (ISO 10846) |
| `phonometry.environmental` | Rating levels, ISO 1996-2 measurement, outdoor propagation (ISO 9613), atmospheric refraction (ray tracing and the parabolic equation), wind-turbine noise, impulsive prominence |
| `phonometry.aircraft` | EPNL (ICAO Annex 16), SAE ARP 5534 absorption, airport contours (ECAC Doc 29), rotorcraft (ECAC Doc 32) |
| `phonometry.underwater` | ISO 18405/17208/18406 levels, propagation, sound speed, sonar equation, seabed, ambient and ship-traffic noise, numerical solvers |
| `phonometry.electroacoustics` | Distortion (IEC 60268-3 / AES17), transfer function and coherence, radiating piston |
| `phonometry.noise_control` | Reactive silencers (four-pole method), HVAC duct attenuation, machine-enclosure insertion loss |
| `phonometry.broadcast` | Programme loudness and true peak (ITU-R BS.1770-5, EBU R 128 with Tech 3341/3342) |
| `phonometry.simulation` | 2D acoustic FDTD wave simulation (staggered grid, sources, probes, impedance boundaries, obstacles) |

Every name in the table below is also re-exported at the top level, so
`from phonometry import <name>` works for every row. The pre-3.2 flat module
paths (for example `phonometry.insulation`) keep importing for one deprecation
cycle and warn on use; they are removed in 4.0.

| Name | Type | Description (Inputs) | Usage Snippet (Outputs) |
| :--- | :--- | :--- | :--- |
| `octave_filter` | `function` | **High-level analysis.**<br>• `x`: Signal array<br>• `fs`: Sample rate [Hz]<br>• `fraction`: 1, 3, etc. (Default: 1)<br>• `order`: Filter order (Default: 6)<br>• `limits`: [f_min, f_max] (Default: [12, 20000])<br>• `filter_type`: 'butter', 'cheby1', 'cheby2', 'ellip', 'bessel' (Default: 'butter')<br>• `sigbands`: Return time signals (Default: False)<br>• `detrend`: Remove DC offset (Default: True)<br>• `calibration_factor`: Sensitivity multiplier (Default: 1.0)<br>• `dbfs`: Output in dBFS instead of dB SPL (Default: False)<br>• `mode`: 'rms' or 'peak' (Default: 'rms')<br>• `nominal`: IEC 61260-1 nominal labels (Default: False)<br>• `show`: Plot response (Default: False)<br>• `plot_file`: Path to save plot (Default: None)<br>• `ripple`: Passband ripple [dB] (for cheby1/ellip)<br>• `attenuation`: Stopband atten. [dB] (Default: 72; for cheby2/ellip; cheby2 needs >= 70 dB for class 1) | `spl, freq = octave_filter(x, fs, ...)`<br>• `spl`: levels [dB]<br>• `freq`: frequencies [Hz]<br><br>**With `sigbands=True`:**<br>`spl, freq, xb = octave_filter(x, fs, sigbands=True)`<br>• `xb`: List of filtered signals (one per band)<br><br>**Calibrated usage:**<br>`spl, f = octave_filter(x, fs, calibration_factor=0.05)` |
| `OctaveFilterBank` | `class` | **Efficient bank implementation.**<br>• `fs`: Sample rate [Hz]<br>• `fraction`: 1, 3, etc.<br>• `order`: Filter order<br>• `limits`: [f_min, f_max] (Default: [12, 20000])<br>• `filter_type`: Architecture name<br>• `show`: Plot response (Default: False)<br>• `plot_file`: Path to save the plot (Default: None)<br>• `calibration_factor`: Sensitivity multiplier<br>• `dbfs`: Use dBFS (Default: False)<br>• `stateful`: Carry filter state between calls (Default: False)<br>• `steady_ic`: Steady-state initial conditions (Default: False)<br>• `resample`: Multirate decimation (Default: True)<br>• `ripple`: Passband ripple [dB]<br>• `attenuation`: Stopband attenuation [dB] (Default: 72; cheby2 needs >= 70 dB for class 1) | `bank = OctaveFilterBank(fs=48000, fraction=3, order=6, filter_type='butter')`<br>`spl, f = bank.filter(x, sigbands=False, mode='rms', detrend=True, zero_phase=False)`<br><br>• `bank`: Instance of the filter bank<br>• `bank.freq` / `bank.freq_d` / `bank.freq_u` / `bank.sos`: computed properties |
| `OctaveFilterBank.spectrogram` | `method` | **Band levels over time.**<br>• `x`: Signal array (1D or 2D)<br>• `window_time`: Window length [s] (Default: 0.125)<br>• `overlap`: Fraction in [0, 1) (Default: 0.5)<br>• `mode`: 'rms' or 'peak'<br>• `zero_phase`: Group-delay-free frames (Default: False) | `levels, freq, times = bank.spectrogram(x)`<br><br>• `levels`: (bands, frames) or (channels, bands, frames)<br>• `times`: window centers [s] |
| `weighting_filter` | `function` | **Acoustic weighting.**<br>• `x`: Signal array<br>• `fs`: Sample rate [Hz]<br>• `curve`: 'A', 'C' (IEC 61672-1), 'B' (ANSI S1.4-1983, historical), 'D' (withdrawn IEC 537, aircraft), 'G' (ISO 7196 infrasound), 'AU' (IEC 61012) or 'Z' (Default: 'A')<br>• `high_accuracy`: IEC class 1 HF accuracy via internal oversampling (Default: True) | `y = weighting_filter(x, fs, curve='A')`<br><br>• `y`: weighted signal |
| `WeightingFilter` | `class` | **Reusable weighting filter.**<br>• `fs`: Sample rate [Hz]<br>• `curve`: 'A', 'B', 'C', 'D', 'G', 'AU' or 'Z'<br>• `stateful`: Block processing (Default: False)<br>• `steady_ic`: Steady-state initial conditions (Default: False)<br>• `high_accuracy`: Defaults to True except stateful | `wf = WeightingFilter(fs, 'A')`<br>`y = wf.filter(x)` |
| `time_weighting` | `function` | **Energy capture.**<br>• `x`: Raw signal array (squared internally; time is the last axis)<br>• `fs`: Sample rate [Hz]<br>• `mode`: 'fast', 'slow', or 'impulse'<br>• `initial_state`: None, 'zero', 'first', scalar, or array (Default: None) | `env = time_weighting(x, fs, mode='fast')`<br><br>• `env`: energy envelope (Mean Square), same shape as `x` |
| `TimeWeighting` | `class` | **Stateful time weighting.**<br>• `fs`: Sample rate [Hz]<br>• `mode`: 'fast', 'slow', 'impulse' (Default: 'fast') | `tw = TimeWeighting(fs, mode='fast')`<br>`env = tw.process(block)` per block<br>`tw.reset()` to start over |
| `leq` | `function` | **Equivalent level (Leq).**<br>• `x`: Signal array (1D or 2D)<br>• `calibration_factor`: Sensitivity multiplier (Default: 1.0)<br>• `dbfs`: Output in dBFS (Default: False) | `level = leq(x, calibration_factor=s)`<br><br>• `level`: Scalar (1D) or per-channel array (2D) |
| `laeq` | `function` | **A-weighted Leq (LAeq).**<br>• `x`: Signal array (1D or 2D)<br>• `fs`: Sample rate [Hz]<br>• `calibration_factor` / `dbfs`: as `leq` | `level = laeq(x, fs, calibration_factor=s)`<br><br>• `level`: Scalar (1D) or per-channel array (2D) |
| `ln_levels` | `function` | **Statistical levels (LN).**<br>• `x`: Signal array (1D or 2D)<br>• `fs`: Sample rate [Hz]<br>• `n`: Exceedance percentiles (Default: (10, 50, 90))<br>• `mode`: 'fast', 'slow', 'impulse' (Default: 'fast')<br>• `weighting`: 'A', 'C', 'G', 'Z' or None (Default: None)<br>• `calibration_factor` / `dbfs`: as `leq` | `stats = ln_levels(x, fs, n=(10, 50, 90), weighting='A')`<br><br>• `stats`: Dict `{10: L10, 50: L50, 90: L90}` |
| `lc_peak` | `function` | **C-weighted peak (LCpeak).**<br>• `x`: Signal array (1D or 2D)<br>• `fs`: Sample rate [Hz]<br>• `calibration_factor`: as `leq`<br>• `dbfs`: 0 dBFS = full-scale *peak* (amplitude 1.0), unlike the RMS reference of `leq`<br>• `oversample`: HF inter-sample peak recovery (Default: 8; 1 = on-grid, under-reads up to ~1.15 dB at 48 kHz) | `peak = lc_peak(x, fs)`<br><br>• IEC 61672-1 §5.13; verified against Table 5 |
| `sel` | `function` | **Sound exposure level (SEL/LAE).**<br>• `x`: Whole-event signal (1D or 2D)<br>• `fs`: Sample rate [Hz]<br>• `weighting`: 'A', 'C', 'G', 'Z' or None (Default: None)<br>• `calibration_factor` / `dbfs`: as `leq` | `lae = sel(x, fs, weighting='A')`<br><br>• Event level normalized to 1 s |
| `sound_exposure` | `function` | **A-weighted exposure E (IEC 61252).**<br>• `x`: Signal (1D or 2D)<br>• `fs`: Sample rate [Hz]<br>• `duration_hours`: exposure period represented (Default: recording length)<br>• `calibration_factor` | `E = sound_exposure(x, fs, duration_hours=8)`<br><br>• `E`: Pa²·h |
| `lex_8h` | `function` | **Daily exposure LEX,8h / LEP,d.**<br>• Same params as `sound_exposure` | `lex = lex_8h(x, fs, duration_hours=4)`<br><br>• Normalized 8 h level [dB] |
| `loudness_zwicker` | `function` | **Zwicker loudness (ISO 532-1:2017).**<br>• `x`: Calibrated signal in Pa (1D)<br>• `fs`: Sample rate [Hz]<br>• `field`: 'free' or 'diffuse' (Default: 'free')<br>• `stationary`: Clause 5 stationary method (Default: False)<br>• `time_skip`: seconds excluded from the stationary mean square (Annex B.1 uses 0.2 s; Default: 0.0)<br>• `calibration_factor`: Digital units to Pa (Default: 1.0) | `res = loudness_zwicker(x, fs)`<br><br>• `ZwickerLoudness`; time-varying runs add N5/N10 and the 500 Hz N(t) trace |
| `loudness_zwicker_from_spectrum` | `function` | **Stationary loudness from band levels.**<br>• `levels`: 28 one-third-octave levels, 25 Hz-12.5 kHz [dB SPL]<br>• `field`: 'free' or 'diffuse' (Default: 'free') | `res = loudness_zwicker_from_spectrum(levels)`<br><br>• `res.loudness` [sone], `res.loudness_level` [phon] |
| `ZwickerLoudness` | `dataclass` | **Loudness result.**<br>• `loudness`: N [sone]<br>• `loudness_level`: LN [phon]<br>• `specific`: N′(z), 240 bins of 0.1 Bark<br>• `n5` / `n10`: percentile loudness (time-varying only)<br>• `time` / `loudness_vs_time`: 500 Hz trace<br>• `field`: sound field assumed ('free'/'diffuse') | `res.loudness, res.n5`<br><br>• Time-varying fields are `None` for stationary results |
| `sharpness_din` | `function` | **Sharpness in acum (DIN 45692).**<br>• `x`: Signal (1D)<br>• `fs`: Sample rate [Hz]<br>• `field`: 'free' or 'diffuse' (Default: 'free')<br>• `method`: 'din', 'aures' or 'bismarck' (Default: 'din')<br>• `calibration_factor`: Digital units to Pa (Default: 1.0) | `s = sharpness_din(x, fs)`<br><br>• `s`: sharpness [acum] |
| `sharpness_din_from_specific` | `function` | **Sharpness from a specific-loudness pattern.**<br>• `specific`: N′(z), 240 values at 0.1 Bark (e.g. `ZwickerLoudness.specific`)<br>• `method`: 'din', 'aures' or 'bismarck' (Default: 'din') | `s = sharpness_din_from_specific(res.specific)`<br><br>• `s`: sharpness [acum] |
| `loudness_moore_glasberg` | `function` | **Moore-Glasberg loudness (ISO 532-2:2017).**<br>• `x`: Calibrated signal in Pa (1D)<br>• `fs`: Sample rate [Hz]<br>• `field`: 'free', 'diffuse' or 'eardrum' (Default: 'free')<br>• `presentation`: 'binaural'/'diotic' or 'monaural' (Default: 'binaural') | `res = loudness_moore_glasberg(x, fs)`<br><br>• `MooreGlasbergLoudness` (roex excitation pattern) |
| `loudness_moore_glasberg_from_spectrum` | `function` | **Exact loudness from sinusoidal components (ISO 532-2 §5.2/5.4).**<br>• `components`: sequence of (frequency [Hz], level [dB SPL]) pairs<br>• `field`: 'free'/'diffuse'/'eardrum' (Default: 'free')<br>• `presentation`: (Default: 'binaural') | `res = loudness_moore_glasberg_from_spectrum([(1000.0, 40.0)])`<br><br>• 1 kHz/40 dB → 1.000 sone |
| `loudness_moore_glasberg_from_third_octave` | `function` | **Loudness from 29 one-third-octave band levels (ISO 532-2 §5.5).**<br>• `band_levels`: 29 levels, 25 Hz–16 kHz [dB SPL]<br>• `field` / `presentation`: as above | `res = loudness_moore_glasberg_from_third_octave(levels)`<br><br>• `MooreGlasbergLoudness` |
| `MooreGlasbergLoudness` | `dataclass` | **Moore-Glasberg loudness result.**<br>• `loudness`: N [sone]<br>• `loudness_level`: LN [phon]<br>• `specific`: N′(i), 372 bins of 0.1 Cam<br>• `erb_number` / `centre_frequencies`: Cam / Hz axes<br>• `field` / `presentation`<br>• `.plot()`: specific loudness N′(i) over Cam | `res.loudness, res.loudness_level` |
| `loudness_moore_glasberg_time` | `function` | **Time-varying loudness (ISO 532-3:2023).**<br>• `signal`: Calibrated Pa; 1D (diotic) or (n, 2) ears<br>• `fs`: Sample rate [Hz]<br>• `field`: 'free'/'diffuse'/'eardrum' (Default: 'free')<br>• `presentation`: (Default: 'binaural')<br>• `percentiles`: exceedance % (Default: (1,5,10,50,90,95)) | `res = loudness_moore_glasberg_time(x, fs)`<br><br>• `MooreGlasbergTimeVaryingLoudness` |
| `MooreGlasbergTimeVaryingLoudness` | `dataclass` | **Time-varying loudness result.**<br>• `time`: 1 ms grid [s]<br>• `short_term_loudness` / `long_term_loudness`: S′(t)/S″(t) [sone]<br>• `short_term_loudness_level` / `long_term_loudness_level` [phon]<br>• `n_max` / `loudness_level_max`: peak long-term loudness<br>• `percentiles`: dict {percent: sone}<br>• `.plot()`: STL and LTL vs time | `res.n_max, res.percentiles[5.0]` |
| `loudness_ecma` | `function` | **Sottek Hearing Model loudness (ECMA-418-2:2025).**<br>• `signal_in`: Calibrated signal in Pa (1D)<br>• `fs`: Sample rate [Hz] (resampled to 48 kHz)<br>• `field`: 'free' or 'diffuse' (Default: 'free') | `res = loudness_ecma(x, fs)`<br><br>• `EcmaLoudness`; 1 kHz/40 dB ≈ 1 sone_HMS |
| `EcmaLoudness` | `dataclass` | **Sottek loudness result.**<br>• `loudness`: N [sone_HMS]<br>• `specific_loudness`: N′(z), 53 Bark_HMS bands<br>• `bark` / `centre_frequencies`: z / Hz axes<br>• `time` / `loudness_vs_time`: N(l) at 187.5 Hz<br>• `field`<br>• `.plot()`: N′(z) + N(l) | `res.loudness, res.specific_loudness` |
| `tonality_ecma` | `function` | **Sottek tonality (ECMA-418-2:2025).**<br>• `signal_in`: Calibrated signal in Pa (1D)<br>• `fs`: Sample rate [Hz] (resampled to 48 kHz)<br>• `field`: 'free' or 'diffuse' (Default: 'free')<br>• `f_low` / `f_high`: optional user band [Hz] (Default: None) | `res = tonality_ecma(x, fs)`<br><br>• `EcmaTonality`; 1 kHz/40 dB ≈ 1 tu_HMS |
| `EcmaTonality` | `dataclass` | **Sottek tonality result.**<br>• `tonality`: T [tu_HMS]<br>• `specific_tonality`: T′(z), 53 bands<br>• `tonal_frequencies`: f_ton,z per band [Hz]<br>• `bark` / `centre_frequencies`<br>• `time` / `tonality_vs_time` / `tonal_frequency_vs_time`: T(l), f_ton(l)<br>• `field`<br>• `.plot()`: T′(z) + T(l) | `res.tonality, res.tonal_frequencies` |
| `roughness_ecma` | `function` | **Sottek roughness (ECMA-418-2:2025), new capability.**<br>• `signal_in`: Calibrated signal in Pa (1D)<br>• `fs`: Sample rate [Hz] (resampled to 48 kHz)<br>• `field`: 'free' or 'diffuse' (Default: 'free') | `res = roughness_ecma(x, fs)`<br><br>• `EcmaRoughness`; 1 kHz/70 Hz/100 %-AM/60 dB ≈ 1 asper |
| `EcmaRoughness` | `dataclass` | **Sottek roughness result.**<br>• `roughness`: R [asper] (90th percentile of R(l50))<br>• `specific_roughness`: R′(z), 53 bands<br>• `bark` / `centre_frequencies`<br>• `time` / `roughness_vs_time`: R(l50) at 50 Hz<br>• `specific_roughness_vs_time`: (n_times, 53)<br>• `field`<br>• `.plot()`: R(l50) + specific-roughness heatmap | `res.roughness, res.specific_roughness` |
| `fluctuation_strength_ecma` | `function` | **Sottek fluctuation strength (ECMA-418-2:2025 Clause 9), new capability.**<br>• `signal_in`: Calibrated signal in Pa (1D)<br>• `fs`: Sample rate [Hz] (resampled to 48 kHz)<br>• `field`: 'free' or 'diffuse' (Default: 'free') | `res = fluctuation_strength_ecma(x, fs)`<br><br>• `EcmaFluctuationStrength`; 1 kHz/4 Hz/100 %-AM/60 dB ≈ 1 vacil_HMS |
| `EcmaFluctuationStrength` | `dataclass` | **Sottek fluctuation-strength result.**<br>• `fluctuation_strength`: F [vacil_HMS] (90th percentile of F(l50))<br>• `specific_fluctuation_strength`: F′(z), 53 bands<br>• `bark` / `centre_frequencies`<br>• `time` / `fluctuation_strength_vs_time`: F(l50) at 50 Hz<br>• `specific_fluctuation_strength_vs_time`: (n_times, 53)<br>• `field`<br>• `.plot()`: F(l50) + specific-fluctuation-strength heatmap | `res.fluctuation_strength, res.specific_fluctuation_strength` |
| `psychoacoustic_annoyance` | `function` | **Psychoacoustic annoyance PA (Fastl & Zwicker Eqs 16.2–16.4), exact model.**<br>• `n5`: percentile loudness N5 [sone]<br>• `sharpness` S [acum]<br>• `fluctuation_strength` F [vacil]<br>• `roughness` R [asper] | `res = psychoacoustic_annoyance(30, 2.0, 0.5, 0.3)`<br><br>• `PsychoacousticAnnoyanceResult`; `res.annoyance == 37.0478` |
| `psychoacoustic_annoyance_from_signal` | `function` | **PA from a calibrated signal (convenience, engineering estimate).**<br>• `x`: Calibrated signal in Pa (1D)<br>• `fs`: Sample rate [Hz]<br>• `field`: 'free' or 'diffuse' (Default: 'free')<br>• `calibration_factor` (Default: 1.0)<br>Mixes Zwicker N5/S + Sottek R + Osses F. | `res = psychoacoustic_annoyance_from_signal(x, fs)`<br><br>• `PsychoacousticAnnoyanceResult` |
| `PsychoacousticAnnoyanceResult` | `dataclass` | **Psychoacoustic annoyance result.**<br>• `annoyance`: PA<br>• `n5` [sone] / `sharpness` [acum] / `fluctuation_strength` [vacil] / `roughness` [asper]: the four inputs<br>• `w_s`: sharpness weighting wS<br>• `w_fr`: roughness/fluctuation weighting wFR<br>• `.plot()`: term-contribution bar | `res.annoyance, res.w_s, res.w_fr` |
| `fluctuation_strength_am_noise` | `function` | **Fluctuation strength of AM broadband noise (Fastl & Zwicker Eq. 10.2), exact closed form.**<br>• `level_db` L [dB]<br>• `modulation_factor` m (0–1)<br>• `mod_frequency` fmod [Hz] | `fluctuation_strength_am_noise(60, 1.0, 4.0)  # 3.6943 vacil` |
| `fluctuation_strength` | `function` | **Fluctuation strength F (Osses 2016 signal model), no numeric standard, free-field.**<br>• `signal_in`: Calibrated signal in Pa (1D)<br>• `fs`: Sample rate [Hz] | `res = fluctuation_strength(x, fs)`<br><br>• `FluctuationStrengthResult`; 1 kHz/60 dB/m=1/4 Hz AM ≈ 1 vacil |
| `FluctuationStrengthResult` | `dataclass` | **Fluctuation strength result.**<br>• `fluctuation_strength`: F [vacil]<br>• `specific`: F′(z), 47 values<br>• `bark_axis`: z [Bark], 47 values<br>• `time_dependent`: F(t) per frame<br>• `.plot()`: specific F′(z) over the Bark axis | `res.fluctuation_strength, res.specific` |
| `equal_loudness_contour` | `function` | **ISO 226:2023 equal-loudness contour.**<br>• `phon`: Loudness level, 20-90 phon | `freqs, spl = equal_loudness_contour(40.0)`<br><br>• SPL at the 29 preferred frequencies |
| `equal_loudness_contours` | `function` | **ISO 226:2023 equal-loudness contour family (plottable).**<br>• `phons`: Loudness levels [phon] (Default: 20-90 in 10-phon steps)<br>• `frequencies`: Grid [Hz] (Default: the 29 preferred) | `res = equal_loudness_contours()`<br><br>• `EqualLoudnessContours`; `res.plot()` |
| `EqualLoudnessContours` | `dataclass` | **Equal-loudness contour family result.**<br>• `frequencies`: grid [Hz]<br>• `phons`: contour levels [phon]<br>• `contours`: SPL, `(len(phons), len(frequencies))` [dB] (`nan` where undefined)<br>• `threshold`: hearing threshold $T_f$ [dB]<br>• `.plot()`: the iconic ISO 226 chart | `res.contours, res.threshold` |
| `loudness_level` | `function` | **Loudness level of a pure tone (phon).**<br>• `spl`: Tone SPL [dB]<br>• `frequency`: One of the 29 Table 1 frequencies [Hz] | `phon = loudness_level(73.0, 63.0)` |
| `hearing_threshold` | `function` | **Threshold of hearing (ISO 226 Table 1).**<br>• (no parameters) | `freqs, tf = hearing_threshold()` |
| `tone_to_noise_ratio` | `function` | **Tone-to-noise ratio (ECMA-418-1 §11).**<br>• `x`: Signal (1D)<br>• `fs`: Sample rate [Hz]<br>• `tone_freq`: Tone to assess [Hz] (Default: highest peak)<br>• `resolution_hz`: FFT bin spacing (Default: 1.0) | `r = tone_to_noise_ratio(x, fs)`<br><br>• `ToneAssessment(frequency, ratio_db, criterion_db, prominent)` |
| `prominence_ratio` | `function` | **Prominence ratio (ECMA-418-1 §12).**<br>• Same params as `tone_to_noise_ratio` | `r = prominence_ratio(x, fs, tone_freq=1000)`<br><br>• `ToneAssessment(...)` |
| `ToneAssessment` | `dataclass` | **Tone prominence verdict.**<br>• `frequency`: Assessed tone [Hz]<br>• `ratio_db`: TNR or PR [dB]<br>• `criterion_db`: Prominence limit at that frequency [dB]<br>• `prominent`: bool | `r = tone_to_noise_ratio(x, fs)`<br>`if r.prominent: ...` |
| `tone_audibility` | `function` | **Tone audibility ΔL = LT−LG−av (ISO/PAS 20065 Formulae 12–14).**<br>• `tone_level` LT, `mean_narrowband_level` LS [dB]<br>• `tone_frequency` fT [Hz], `line_spacing` Δf [Hz] | `tone_audibility(67.96, 49.22, 137.3, 2.7)  # 5.01 dB` |
| `assess_tones` | `function` | **Audibility of a spectrum's tones (ISO/PAS 20065).**<br>• `tone_frequencies` [Hz], `tone_levels` LT, `mean_narrowband_levels` LS [dB]<br>• `line_spacing` Δf [Hz]<br>• `extended_uncertainties`: attach the Clause 5.4 U per tone (Default: True) | `res = assess_tones(fT, LT, LS, 2.7)`<br><br>• `ToneAudibilityResult` |
| `critical_bandwidth_engineering` | `function` | **Critical bandwidth Δfc about a tone (Formula 2).**<br>• `tone_frequency` fT [Hz] | `critical_bandwidth_engineering(137.3)  # 101.36 Hz` |
| `critical_band_corners` | `function` | **Corner frequencies (f₁, f₂) of the critical band (Formulae 3–5).**<br>• `tone_frequency` fT [Hz] | `f1, f2 = critical_band_corners(137.3)` |
| `critical_band_level` | `function` | **Masking-noise level LG = LS+10lg(Δfc/Δf) (Formula 12).**<br>• `mean_narrowband_level` LS [dB], `tone_frequency` fT, `line_spacing` Δf [Hz] | `critical_band_level(49.22, 137.3, 2.7)  # 64.97 dB` |
| `masking_index` | `function` | **Masking index av = −2−lg[1+(f/502)²·⁵] (Formula 13).**<br>• `frequency` f [Hz] | `masking_index(137.3)  # -2.02 dB` |
| `audibility_from_levels` | `function` | **ΔL = LT − LG − av (Formula 14).**<br>• `tone_level` LT, `critical_band_level` LG, `masking_index` av [dB] | `audibility_from_levels(67.96, 64.98, -2.02)  # 5.0 dB` |
| `energy_sum_level` | `function` | **Energy sum of lines with window correction (Formulae 7/8).**<br>• `line_levels` Li [dB]; a single line (K = 1) takes its level unchanged (Formula 7, no correction)<br>• `effective_bandwidth_factor` Δfe/Δf (Default: 1.5, Hanning; K > 1 only) | `energy_sum_level([80, 80])  # 81.25 dB` |
| `mean_narrowband_level` | `function` | **Masking-noise level LS from a critical-band spectrum (Formula 6, iterative Annex D).**<br>• `levels` Li [dB], `frequencies` [Hz]<br>• `tone_frequency` fT [Hz]<br>• `effective_bandwidth_factor` (Default: 1.5) | `mean_narrowband_level(levels, freqs, 137.3)  # 49.22 dB` |
| `tone_level` | `function` | **Tone level LT from the tonal lines about a peak (Formulae (7)/(8): single lines take (7), without the Hanning bandwidth correction).**<br>• `levels` Li [dB], `frequencies` [Hz]<br>• `tone_frequency` fT [Hz], `mean_narrowband_level` LS [dB]<br>• `effective_bandwidth_factor` (Default: 1.5) | `tone_level(levels, freqs, 137.3, ls)  # 67.96 dB` |
| `audibility_uncertainty` / `mean_audibility_uncertainty` | `function` | **Extended uncertainty U of the audibility (ISO/PAS 20065 Clause 5.4/6, 90 % bilateral).**<br>• per tone: `audibility_uncertainty(tone_line_levels, noise_line_levels, tone_frequency, line_spacing)`<br>• mean: U of the energy-averaged audibility over the per-spectrum (ΔL, U) pairs<br>Mandatory when fewer than 12 spectra are averaged (Clause 6) | `u = audibility_uncertainty(lt_lines, ls_lines, 137.3, 2.7)`<br><br>• U [dB] |
| `analyze_spectrum` | `function` | **Detect & rate the audible tones of a spectrum (Clause 5.3.8 + distinctness 5.3.4), incl. Step 3 same-band FG combination (Formula 17).**<br>• `levels` Li [dB], `frequencies` [Hz]<br>• `line_spacing` Δf [Hz]<br>• `effective_bandwidth_factor` (Default: 1.5) | `res = analyze_spectrum(levels, freqs, 2.7)`<br><br>• `ToneAudibilityResult` of detected tones + FG entries (`group_sizes`) |
| `combined_tone_level` | `function` | **Multi-tone FG combined level (Formula 17).**<br>• `levels` Li [dB], `frequencies` [Hz]<br>• `tone_frequencies` [Hz], `mean_narrowband_levels` LS [dB]<br>• `effective_bandwidth_factor` (Default: 1.5) | `combined_tone_level(lv, f, [118.4,137.3,158.8], ls)  # 72.15 dB` |
| `two_tone_separation_frequency` | `function` | **Two-tone separation threshold fD = 21·10^(1.2·\|lg(fT/212)\|^1.8) Hz (Formula 19).**<br>• `tone_frequency` fT [Hz] (more prominent tone) | `two_tone_separation_frequency(212.0)  # 21.0 Hz` |
| `resolve_tones_separately` | `function` | **Rate two tones <1000 Hz separately vs combined (Formulae 18/19).**<br>• `tone1_frequency`, `tone2_frequency` [Hz]<br>• `audibility1`, `audibility2` ΔL [dB] | `resolve_tones_separately(200., 260., 3., 2.)  # True` |
| `mean_audibility` | `function` | **Energy-mean mean audibility over spectra (Formula 20).**<br>• `decisive_audibilities` ΔLj [dB]; no-tone spectra use −10 dB | `mean_audibility([9.18, 6.04, 7.46])  # dB` |
| `ToneAudibilityResult` | `dataclass` | **Tonal audibility of a spectrum's tones (ISO/PAS 20065).**<br>• `audibilities` ΔL, `critical_band_levels` LG, `masking_indices` av [dB]<br>• `critical_bandwidths` Δfc, `lower_corners`/`upper_corners` [Hz]<br>• `audible`: ΔL > 0 mask<br>• `extended_uncertainties`: Clause 5.4 U per tone [dB]<br>• `group_sizes`: 1 = single tone, N ≥ 2 = Step 3 FG entry (None from `assess_tones`)<br>• `decisive_audibility` / `decisive_frequency`<br>• `.plot()`: per-tone ΔL vs frequency | `res.decisive_audibility, res.audible` |
| `HANNING_BANDWIDTH_FACTOR` | `float` | **Hanning effective-bandwidth factor Δfe/Δf (ISO/PAS 20065 Annex A).**<br>1.5 | `HANNING_BANDWIDTH_FACTOR  # 1.5` |
| `NO_TONE_AUDIBILITY` | `float` | **Audibility reported when no tone is found [dB] (ISO/PAS 20065 Formula 21).**<br>-10.0 | `NO_TONE_AUDIBILITY  # -10.0` |
| `sti_from_impulse_response` | `function` | **Full STI, indirect method (IEC 60268-16 Ed. 5).**<br>• `ir`: Impulse response (1D)<br>• `fs`: Sample rate [Hz] (>= 22500)<br>• `snr`: SNR [dB], scalar or 7 bands (Default: None)<br>• `level`: 7 speech band levels [dB SPL]; enables masking + reception threshold (Default: None)<br>• `ambient`: 7 noise band levels [dB SPL]; requires `level` | `res = sti_from_impulse_response(ir, fs, snr=25.0)`<br><br>• `STIResult` with `mtf` (7×14) |
| `stipa` | `function` | **STIPA direct method (Annex B).**<br>• `x`: Recorded STIPA signal (1D), 15-25 s<br>• `fs`: Sample rate [Hz] (>= 22500)<br>• `reference`: Measured source signal instead of the nominal m = 0.55 (Default: None)<br>• `level` / `ambient`: as `sti_from_impulse_response`<br>• warns (`UserWarning`) if the recording is < 15 s (STI biased low) | `res = stipa(recording, fs)`<br><br>• `STIResult` with `mtf` (7×2) |
| `stipa_signal` | `function` | **STIPA test-signal generator (A.4/A.6.1).**<br>• `fs`: Sample rate [Hz] (>= 22500)<br>• `seconds`: Duration [s] (Default: 18.0)<br>• `level_db`: RMS level [dB SPL] (Default: None → RMS 0.1)<br>• `seed`: Pink-noise seed (Default: None) | `sig = stipa_signal(48000, seconds=18.0)`<br><br>• 1D test signal, Ed. 5 male spectrum |
| `STIResult` | `dataclass` | **STI result.**<br>• `sti`: 0 to 1<br>• `mti`: band indices (7,)<br>• `mtf`: corrected m values (7×14 or 7×2)<br>• `band_levels`: levels used or None<br>• `rating`: Annex F letter 'A+'…'U' | `res = stipa(x, fs)`<br>`print(res.sti, res.rating)` |
| `sound_intensity` | `function` | **p-p sound intensity (IEC 61043).**<br>• `p1`, `p2`: Microphone signals [Pa], equal length<br>• `fs`: Sample rate [Hz]<br>• `spacing`: Microphone separation Δr [m]<br>• `rho`: Air density (Default: 1.204)<br>• `c`: Speed of sound (Default: 343.0)<br>• `fraction`: None, 1 or 3 (Default: None)<br>• `limits`: [f_min, f_max] (Default: [12, 20000])<br>• `bias_correct`: undo finite-difference under-read of band/broadband totals near `max_valid_frequency` (Default: False) | `res = sound_intensity(p1, p2, fs, spacing=0.012, fraction=3)`<br><br>• `IntensityResult` |
| `IntensityResult` | `dataclass` | **Intensity result.**<br>• Per band (with `fraction`): `frequency`, `intensity` [W/m²], `intensity_level`, `pressure_level`, `pressure_intensity_index`, `direction` (±1), `bias_correction`<br>• Broadband: `total_*` counterparts<br>• `max_valid_frequency`: 0.1·c/Δr | `res.total_intensity_level`<br>`res.total_direction` |
| `field_indicators` | `function` | **ISO 9614-1 Annex A field indicators.**<br>• `pressure_levels`: Lpi per position [dB]<br>• `normal_intensity`: Signed Ini per position [W/m²] | `fi = field_indicators(lp, i_n)`<br><br>• `FieldIndicators(f2, f3, f4)` |
| `FieldIndicators` | `dataclass` | **ISO 9614-1 Annex A indicators.**<br>• `f2`: surface pressure-intensity indicator (Eq. A.3)<br>• `f3`: negative partial power indicator (Eq. A.6)<br>• `f4`: field non-uniformity indicator (Eq. A.8)<br>• f3 − f2 > 0 reveals negative partial power | `fi.f2, fi.f3, fi.f4`<br><br>• Criteria: Ld > F2, N > C·F4² |
| `dynamic_capability_index` | `function` | **Dynamic capability Ld (ISO 9614-1 §3.12).**<br>• `pressure_residual_intensity_index`: δpI0 [dB]<br>• `bias_error_factor`: K [dB] (Default: 10.0) | `ld = dynamic_capability_index(18.0)`<br><br>• Adequate when `Ld > F2` (criterion 1) |
| `CalibrationWarning` | `warning class` | **Unreliable calibration recording.**<br>Emitted by `sensitivity` (with `fs` given and `validate=True`) when the tone is unstable (IEC 60942 limit) or too short | `warnings.simplefilter("error", CalibrationWarning)` |
| `lden` | `function` | **Day-evening-night level (ISO 1996-1 §3.6.4).**<br>• `lday`/`levening`/`lnight`: LAeq per period [dB]<br>• `hours`: Period durations (Default: (12, 4, 8)) | `l = lden(63.2, 58.1, 51.4)` |
| `ldn` | `function` | **Day-night level (ISO 1996-1 §3.6.5).**<br>• `lday`/`lnight`: LAeq per period [dB]<br>• `hours`: Default (15, 9) | `l = ldn(63.2, 51.4)` |
| `composite_rating_level` | `function` | **Whole-day composite rating (ISO 1996-1 §6.5).**<br>• `periods`: list of (level_db, hours, adjustment_db) summing 24 h | `r = composite_rating_level([(63, 12, 0), (58, 4, 5), (51, 8, 10)])` |
| `assess_tonal_audibility` | `function` | **Tonal audibility & adjustment (ISO 1996-2 Annex C).**<br>• `tone_level` Lpt, `masking_noise_level` Lpn [dB]<br>• `centre_frequency` fc [Hz] | `res = assess_tonal_audibility(54.1, 45.2, 430.0)`<br><br>• `TonalAssessmentResult` (`.audibility`, `.adjustment`, `.plot()`) |
| `tonal_audibility` | `function` | **ΔLta = Lpt−Lpn+2+lg[1+(fc/502)²·⁵] (Formula C.3).**<br>• `tone_level`, `masking_noise_level` [dB], `centre_frequency` [Hz] | `d = tonal_audibility(54.1, 45.2, 430.0)  # 11.1 dB` |
| `tonal_adjustment` | `function` | **Kt(ΔLta) piecewise (Formulae C.4-C.6).**<br>• `audibility` ΔLta [dB] | `tonal_adjustment(7.0)  # 3.0 dB` |
| `tonal_adjustment_from_mean_audibility` | `function` | **Kt from mean audibility ΔL (ISO 1996-2 Table J.1).**<br>• `mean_audibility` [dB], `coarse` (Default: False) | `tonal_adjustment_from_mean_audibility(5.0)  # 3` |
| `critical_bandwidth` | `function` | **Critical bandwidth (ISO 1996-2 Table C.1).**<br>• `centre_frequency` [Hz] (100 Hz ≤ 500 Hz, else 20 %·fc) | `critical_bandwidth(4000.0)  # 800 Hz` |
| `tonal_seeking_survey` | `function` | **One-third-octave tonal screen (ISO 1996-2 Annex K).**<br>• `levels` [dB], `frequencies` [Hz] (15/8/5 dB neighbour rule) | `flags = tonal_seeking_survey(levels, freqs)` |
| `residual_sound_correction` | `function` | **Residual-noise correction L = 10 lg(10^(L'/10)−10^(Lres/10)) (Formula 16).**<br>• `measured_level` L', `residual_level` Lres [dB] | `res = residual_sound_correction(58.0, 50.0)`<br><br>• `ResidualCorrectionResult` (`.corrected_level`, `.reportable_upper_bound`, `.reliable`) |
| `gaussian_residual_level` | `function` | **Residual Leq from percentiles (ISO 1996-2 Annex I).**<br>• `l50` [dB]; exactly one of `l90` / `l95` (must not exceed `l50`) | `gaussian_residual_level(50.0, l90=40.0)` |
| `combined_standard_uncertainty` | `function` | **u = √(Σ(cj·uj)²) (ISO 1996-2 Formula 2).**<br>• `contributions`: cj·uj products or (uj, cj) pairs | `u = combined_standard_uncertainty([0.59, 0.3, 2.0, 0.40, 0.38])  # 2.18` |
| `environmental_expanded_uncertainty` | `function` | **U = k·u (ISO 1996-2 §4).**<br>• `standard_uncertainty` [dB], `confidence` 0.95 (k=2) / 0.80 (k=1.3) | `environmental_expanded_uncertainty(2.18)  # 4.36` |
| `residual_correction_uncertainty` | `function` | **Uncertainty of the residual-corrected level (Formulae F.7-F.9).**<br>• `measured_level`, `residual_level`, `measured_uncertainty`, `residual_uncertainty` [dB] | `residual_correction_uncertainty(58, 50, 0.5, 2.0)` |
| `uncertainty_from_repeated_measurements` | `function` | **Energy mean & uncertainty from repeats: primary Formulae (17)+(19) route, Formula (20) approximation alongside.**<br>• `levels` [dB] (≥ 2); warns when they spread > 3 dB | `res = uncertainty_from_repeated_measurements(levels)`<br><br>• `RepeatedMeasurementResult` |
| `TonalAssessmentResult` | `dataclass` | **Tonal assessment (ISO 1996-2).**<br>• `audibility` ΔLta, `adjustment` Kt [dB]<br>• `centre_frequency`, `critical_bandwidth`; `.plot()` | `res.audibility, res.adjustment` |
| `ResidualCorrectionResult` | `dataclass` | **Residual-corrected level (ISO 1996-2).**<br>• `corrected_level` [dB], `reportable_upper_bound` = measured L' [dB], `margin` [dB], `reliable` (> 3 dB; when False report the upper bound, not the correction) | `res.corrected_level, res.reliable` |
| `RepeatedMeasurementResult` | `dataclass` | **Repeat-measurement mean & uncertainty (ISO 1996-2).**<br>• `mean_level`, `standard_uncertainty` (Formulae (17)+(19)), `approximate_uncertainty` (Formula (20)) [dB], `n` | `res.mean_level, res.standard_uncertainty` |
| `linkwitz_riley` | `function` | **Audio crossover.**<br>• `x`: Signal array<br>• `fs`: Sample rate [Hz]<br>• `freq`: Crossover frequency [Hz]<br>• `order`: Any even number (Default: 4) | `lo, hi = linkwitz_riley(x, fs, freq=1000, order=4)`<br><br>• `lo`: Low-pass filtered signal<br>• `hi`: High-pass filtered signal |
| `parametric_eq` | `function` | **Parametric EQ, one shot (RBJ Audio EQ Cookbook).**<br>• `x`: Signal array (1D or 2D `[channels, samples]`)<br>• `fs`: Sample rate [Hz]<br>• `sections`: an `EQSection` or a sequence of them | `y = parametric_eq(x, fs, EQSection("peaking", 1000, gain_db=6.0))` |
| `ParametricEQ` | `class` | **Reusable parametric-EQ cascade (RBJ Audio EQ Cookbook).**<br>• `fs`: Sample rate [Hz]<br>• `sections`: `EQSection` or sequence of them (cascade order)<br>• `stateful`: Block processing (Default: False)<br>• `steady_ic`: Steady-state initial conditions (Default: False)<br>• `.sos`: the designed cascade, `.filter(x)`, `.response()` | `eq = ParametricEQ(fs, sections)`<br>`y = eq.filter(x)`<br>`res = eq.response()` |
| `EQSection` | `dataclass` | **One cookbook biquad specification.**<br>• `filter_type`: 'peaking', 'lowshelf', 'highshelf', 'lowpass', 'highpass', 'bandpass', 'bandpass_skirt', 'notch', 'allpass'<br>• `f0`: Centre/corner frequency [Hz]<br>• `gain_db`: Gain (peaking/shelves) [dB]<br>• One of `q` (Default: 1/√2), `bw` [octaves] or `slope` (shelves) | `EQSection("peaking", 1000.0, gain_db=-6.0, bw=1.0)` |
| `EQResponseResult` | `dataclass` | **Parametric-EQ cascade response.**<br>• `frequencies` [Hz], `magnitude_db` [dB], `phase_rad` [rad]<br>• `section_magnitude_db`: per-section magnitudes [dB]<br>• `sos`: the cascade, `fs`, `sections`; `.plot()` magnitude + phase | `res = eq.response()`<br>`res.plot()` |
| `sensitivity` | `function`| **SPL Calibration.**<br>• `ref_signal`: Calibration signal<br>• `target_spl`: Level of calibrator (Default: 94.0)<br>• `ref_pressure`: Reference pressure (Default: 20e-6)<br>• `narrowband`: coherent Goertzel tone estimate that rejects broadband hum/noise (needs `fs`; Default: False) | `s = sensitivity(ref_signal, target_spl=94.0)`<br><br>• `s`: Float (multiplier for pressure) |
| `verify_filter_class` | `function` | **IEC 61260 class check.**<br>• `bank`: an `OctaveFilterBank`<br>• `num_points`: frequency grid points per band (Default: 32768)<br>• `edition`: `'2014'` (classes 1/2, default) or `'1995'` (IEC 61260:1995 / ANSI S1.11-2004, adds class 0) | `result = verify_filter_class(bank, edition="1995")`<br><br>• `result["overall_class"]`: 1/2 or None (`'2014'`); 0/1/2 or None (`'1995'`)<br>• `result["bands"]`: per-band class and `margin_class<c>_db` [dB] |
| `filter_class_compliance` | `function` | **IEC 61260 class check as a report result.**<br>Same verification as `verify_filter_class`, returned as a `FilterComplianceResult` with `.plot()` and `.report()`.<br>• `bank`: an `OctaveFilterBank`<br>• `num_points`: frequency grid points per band (Default: 32768)<br>• `edition`: `'2014'` (default) or `'1995'` (adds class 0) | `result = filter_class_compliance(bank, edition="1995")`<br>`result.report("iec61260.pdf", metadata=ReportMetadata(required_class=0))` |
| `FilterComplianceResult` | `dataclass` | **IEC 61260 filter class-compliance result.**<br>• `overall_class`: strictest class every band meets: 1/2 (`'2014'`), 0/1/2 (`'1995'`), or `None`<br>• `bands`: per-band verdict dictionaries<br>• `range_limited`: stop-band mask beyond the processing Nyquist not exercised<br>• `.available_classes()` / `.reference_class()`: the edition's classes and the fiche's reference class<br>• `.plot()`: measured relative attenuation over the class corridor<br>• `.report(path, *, metadata=None, required_class via metadata)`: one-page PDF fiche | `filter_class_compliance(bank).report("iec61260.pdf")` |
| `class_limits` | `function` | **IEC 61260 Table 1 acceptance limits.**<br>• `fraction`: bandwidth designator denominator b (1, 3, ...)<br>• `filter_class`: 1 or 2 (`'2014'`); 0, 1 or 2 (`'1995'`)<br>• `omega`: normalized frequencies f/fm<br>• `edition`: `'2014'` (default) or `'1995'` | `lo, hi = class_limits(3, 0, omega, edition="1995")`<br><br>• `lo` / `hi`: min/max relative attenuation [dB] (`hi` is `inf` outside the pass-band) |
| `verify_weighting_class` | `function` | **Weighting tolerance check** against IEC 61672-1:2013 Table 3 (A/C/Z), ANSI S1.4-1983 Tables IV/V (B, Types as classes) or IEC 61012:1990 Table 1 (AU), at the exact base-10 frequencies, plus the 5.5.7 between-nominals sweep.<br>• `wf`: a `WeightingFilter` (A, B, C, AU or Z)<br>• `sweep_points` (Default: 4096) | `result = verify_weighting_class(wf)`<br><br>• `result["overall_class"]`: 1, 2 or None<br>• `result["range_limited"]`: finite-lower-limit rows beyond Nyquist<br>• `result["bands"]`: per-frequency class, deviation and margins [dB]<br>• `result["between_nominals"]`: 5.5.7 sweep margins |
| `weighting_class_limits` | `function` | **IEC 61672-1:2013 Table 3 acceptance limits.**<br>• `weighting_class`: 1 or 2 | `f, lo, hi = weighting_class_limits(1)`<br><br>• `f`: 34 nominal frequencies [Hz]<br>• `lo` / `hi`: lower/upper deviation limits [dB] (`lo` is `-inf` where one-sided) |
| `nominal_frequencies` | `function` | **ANSI Frequency generator.**<br>• `fraction`: 1, 3, etc. (Required)<br>• `limits`: [f_min, f_max] (Default: [12, 20000]) | `f_cen, f_low, f_high, labels = nominal_frequencies(fraction=3)`<br><br>• `f_cen`: List of center frequencies [Hz]<br>• `f_low`: List of lower edges [Hz]<br>• `f_high`: List of upper edges [Hz]<br>• `labels`: IEC nominal frequency labels |
| `normalized_frequencies` | `function` | **Standard IEC Frequencies.**<br>• `fraction`: 1 or 3 | `freqs = normalized_frequencies(fraction=3)`<br><br>• `freqs`: List of standard center frequencies [Hz] |
| `sweep_signal` | `function` | **ESS excitation (ISO 18233 Annex B).**<br>• `fs`: Sample rate [Hz]<br>• `f1`: Start frequency [Hz]<br>• `f2`: Stop frequency [Hz] (≤ fs/2)<br>• `seconds`: Duration [s]<br>• `amplitude`: Peak (Default: 1.0)<br>• `fade`: Half-Hann fraction (Default: 0.01) | `s = sweep_signal(48000, 20, 20000, 3.0)`<br><br>• 1D exponential sine sweep |
| `inverse_filter` | `function` | **Farina inverse filter for an ESS.**<br>• Same parameters as `sweep_signal` | `inv = inverse_filter(48000, 20, 20000, 3.0)`<br><br>• Time-reversed, +6 dB/oct compensated sweep |
| `impulse_response` | `function` | **Sweep deconvolution (ISO 18233 B.5).**<br>• `recorded`: Recorded response (1D)<br>• `reference`: Emitted sweep (1D)<br>• `fs`: Sample rate [Hz]<br>• `method`: 'spectral' (Default) or 'farina'<br>• `f_range`: (f1, f2) for 'farina'<br>• `regularization`: Tikhonov term (Default: 1e-6)<br>• `length`: causal samples (Default: len(recorded))<br>• `return_full`: keep distortion tail (Default: False) | `ir = impulse_response(rec, sweep, fs)`<br><br>• `ImpulseResponseResult` (array-like; `.plot()`) |
| `mls_signal` | `function` | **Maximum-length sequence (ISO 18233 Annex A).**<br>• `order`: Register length N, 2-20 | `mls = mls_signal(16)`<br><br>• Bipolar sequence, length 2**N − 1 |
| `mls_impulse_response` | `function` | **IR from a periodic MLS.**<br>• `recorded`: Response spanning whole MLS periods (1D)<br>• `mls`: Excitation sequence<br>• `length`: IR samples (Default: 2**N − 1)<br>• `fs`: optional sample rate for the plot time axis | `ir = mls_impulse_response(rec, mls)`<br><br>• `ImpulseResponseResult` (array-like; `.plot()`) |
| `ImpulseResponseResult` | `dataclass` | **Recovered impulse response with metadata.**<br>• `ir`: IR samples<br>• `fs` [Hz] or None (e.g. an MLS recovery without one)<br>• `method`: 'spectral'/'farina'/'mls'/'golay'<br>• array-like: `np.asarray(res)`, indexing, `len()` and `shape`/`dtype` forward to `ir`<br>• `.plot()` | `ir = impulse_response(rec, sweep, fs)`<br>`room_parameters(ir, fs)  # drop-in array` |
| `golay_pair` | `function` | **Complementary Golay pair (Havelock Pt. I Ch. 6).**<br>• `order`: recursion steps n, 1-22; each code has 2**n samples<br>Periodic autocorrelations sum to an exact 2L·delta | `a, b = golay_pair(14)`<br><br>• Two bipolar codes, length 2**n |
| `golay_impulse_response` | `function` | **IR from a periodic Golay-pair excitation.**<br>• `recorded_a` / `recorded_b`: steady-state responses to each code (whole periods)<br>• `pair`: the `(a, b)` codes<br>• `length`: IR samples (Default: 2**n)<br>• `fs`: optional sample rate for the plot time axis<br>Noiseless LTI recovery is exact (machine precision) | `ir = golay_impulse_response(rec_a, rec_b, pair)`<br><br>• `ImpulseResponseResult` (array-like; `.plot()`) |
| `shaped_sweep_signal` | `function` | **Sweep with an arbitrary target spectrum (Mueller & Massarani Secs. 4.2-4.3).**<br>• `fs`, `f1`, `f2`, `seconds`<br>• `target`: 'pink' (Default), 'white' or `(frequencies_hz, magnitude_db)`<br>• `amplitude` (Default: 1.0), `start_delay` (Default: 0.05·seconds), `fade` (Default: 0.01)<br>Group delay grows with the target power: near-constant envelope | `sweep = shaped_sweep_signal(fs, 50, 5000, 2, target="pink")`<br><br>• `ShapedSweepResult` (array-like; `.plot()`) |
| `ShapedSweepResult` | `dataclass` | **Synthesized shaped sweep.**<br>• `signal`, `fs`, `frequencies`, `magnitude` (imposed, peak 1), `group_delay` [s], `f_range`, `crest_factor_db`<br>• array-like: usable directly as the deconvolution reference<br>• `.plot()`: waveform + Welch spectrum vs target | `ir = impulse_response(rec, np.asarray(sweep), fs)` |
| `ImpulseResponseWarning` | `warning class` | **Suspect recovered impulse response.**<br>Emitted e.g. for MLS aliasing in the recovery | `warnings.simplefilter('error', ImpulseResponseWarning)` |
| `plot_excitation` | `function` | **Plot an excitation signal.**<br>• `signal`: sweep or MLS samples (1D)<br>• `fs`: Sample rate [Hz]<br>• `kind`: `'sweep'` (default) or `'mls'` | `plot_excitation(sweep, fs, kind="sweep")`<br><br>• waveform + spectrogram / spectrum axes |
| `decay_curve` | `function` | **Schroeder decay curve (ISO 3382-1 5.3.3).**<br>• `ir`: Impulse response (1D)<br>• `fs`: Sample rate [Hz]<br>• `band`: Band centre [Hz] (Default: None → broadband)<br>• `fraction`: 1 or 3 (Default: 1)<br>• `zero_phase`: forward-backward band filtering, halves the 125 Hz short-T bias (Default: False) | `dc = decay_curve(ir, fs)` → `DecayCurve`<br>`time, level = dc` still unpacks (`time` [s], `level` [dB], 0 dB at t=0)<br>`dc.plot()` draws the decay + EDT/T20/T30 fits |
| `DecayCurve` | `dataclass` | **Schroeder decay curve (ISO 3382-1 5.3.3).**<br>• `time`: from the direct sound [s]<br>• `level`: decay [dB], 0 dB at t = 0, up to the noise truncation point<br>• `band`: centre [Hz] or None (broadband)<br>• iterable: unpacks as `time, level`<br>• `.plot()`: decay + EDT/T20/T30 fits | `dc = decay_curve(ir, fs)`<br>`dc.time, dc.level, dc.band` |
| `room_parameters` | `function` | **Room acoustics (ISO 3382-1/2).**<br>• `ir`: Impulse response (1D)<br>• `fs`: Sample rate [Hz]<br>• `limits`: (f_min, f_max) or None (Default: (125, 4000))<br>• `fraction`: 1 or 3 (Default: 1)<br>• `zero_phase`: forward-backward octave filtering, halves the 125 Hz short-T T30 bias (Default: False) | `res = room_parameters(ir, fs)`<br><br>• `RoomAcousticsResult` per band |
| `RoomAcousticsResult` | `dataclass` | **Per-band room parameters.**<br>• `frequency` [Hz]<br>• `edt`, `t20`, `t30` [s]<br>• `c50`, `c80` [dB], `d50`, `ts` [s]<br>• `dynamic_range` [dB]<br>• `edt_valid`/`t20_valid`/`t30_valid`<br>• `curvature` [%] | `res.t30, res.c80, res.t30_valid`<br><br>• Arrays with one entry per band |
| `open_plan_metrics` | `function` | **Open-plan office metrics (ISO 3382-3).**<br>• `positions_m`: Source distances [m] (≥ 4)<br>• `spl_a_speech`: A-weighted speech level per position [dB]<br>• `sti_values`: STI per position | `m = open_plan_metrics(r, lp, sti)`<br><br>• `OpenPlanResult` |
| `OpenPlanResult` | `dataclass` | **Open-plan single numbers.**<br>• `d2s`: Spatial decay rate [dB/doubling]<br>• `lp_as_4m`: Speech level at 4 m [dB]<br>• `rd`: Distraction distance [m]<br>• `rp`: Privacy distance [m] | `m.d2s, m.rd, m.rp`<br><br>• `nan` when undefined |
| `image_source_rir` | `function` | **Image-source room impulse response (Kuttruff 4.1 / Vorländer 11).**<br>• `dimensions`: `(Lx, Ly, Lz)` [m]<br>• `source`/`receiver`: `(x, y, z)` [m]<br>• `absorption`: scalar / (6,) per-wall / per-band / (6, n) [0, 1]<br>• `fs` [Hz], `max_order` (Default: 20)<br>• `air_attenuation`: intensity `m` [1/m]<br>• `frequencies` [Hz] for a per-band RIR | `res = image_source_rir((7,5,3), (2,1.6,1.5), (5.2,3.4,1.7), 0.12, fs=48000)`<br><br>• `ImageSourceResult` |
| `ImageSourceResult` | `dataclass` | **Synthetic RIR by image sources.**<br>• `ir`: sampled RIR (1D or per-band)<br>• exact reflection table `times`/`distances`/`orders`/`amplitudes`/`image_positions`<br>• `direct_time` [s]<br>• `.plot()`: reflectogram | `res.ir, res.times, res.orders`<br>`res.plot()` |
| `audible_image_count` / `reflection_density` | `function` | **Shoebox image count (Kuttruff Eq. 9.23) and reflection density (Eq. 4.6).**<br>• `audible_image_count(order)`: `(2/3)(2i³+3i²+4i)`<br>• `reflection_density(t, volume, c=343)`: `4πc³t²/V` | `audible_image_count(10)  # 1560`<br>`reflection_density(0.1, 120.0)` |
| `steady_state_field` | `function` | **Steady-state room field (Bies 6.4).**<br>• `sound_power_level` `Lw` [dB]<br>• `surface_area` `S` [m²], `mean_absorption` `ᾱ` (0, 1)<br>• `distances` [m] (Default: 0.1–10 rc)<br>• `directivity` `Q` (Default: 1)<br>• `characteristic_impedance` [Pa·s/m] for the ρc term | `f = steady_state_field(90.0, 100.0, 0.2)`<br><br>• `SteadyFieldResult` |
| `SteadyFieldResult` | `dataclass` | **SPL vs distance, direct/reverberant/total.**<br>• `distances` [m]<br>• `direct`/`reverberant`/`total` [dB]<br>• `critical_distance` [m], `room_constant` [m²]<br>• `.plot()` | `f.total, f.critical_distance`<br>`f.plot()` |
| `room_constant` / `critical_distance` / `schroeder_frequency` / `steady_state_spl` | `function` | **Steady-field building blocks (Bies 6.43/6.44, Kuttruff 3.44/5.44).**<br>• `room_constant(S, ᾱ)` = `Sᾱ/(1-ᾱ)` [m²]<br>• `critical_distance(R, directivity=1)` = `√(QR/16π)` [m]<br>• `schroeder_frequency(T, V)` = `2000√(T/V)` [Hz]<br>• `steady_state_spl(Lw, r, R, directivity=1)` [dB] | `R = room_constant(100, 0.2)`<br>`critical_distance(R)`<br>`schroeder_frequency(1.0, 200.0)` |
| `airborne_insulation` | `function` | **Field airborne insulation (ISO 16283-1).**<br>• `l1`/`l2`: Source/receiving levels [dB], 1D or (positions, bands)<br>• `t2`: Receiving-room T per band [s]<br>• `area`: Partition S [m²] (for R')<br>• `volume`: Receiving V [m³] (for R')<br>• `t0`: Reference T0 [s] (Default: 0.5) | `ins = airborne_insulation(l1, l2, t2, area=10, volume=50)`<br><br>• `AirborneInsulationResult` |
| `weighted_rating` | `function` | **Single-number rating + C/Ctr (ISO 717-1).**<br>• `values_by_band`: 16 thirds or 5 octaves [dB]<br>• `bands`: 'third-octave', 'octave' or None | `w = weighted_rating(R)`<br><br>• `WeightedRatingResult` (Rw, C, Ctr) |
| `weighted_rating_extended` | `function` | **Rating + enlarged-range terms (ISO 717-1 Annex B).**<br>• `values_by_band` [dB] with `frequencies` [Hz] (None = the 16 core bands)<br>• `one_decimal`: 0.1 dB shift + one-decimal reductions for uncertainty statements (Default: False) | `ext = weighted_rating_extended(r, freqs)`<br><br>• `ExtendedWeightedRatingResult` (rating, c, ctr, c_50_3150 … ctr_100_5000) |
| `ExtendedWeightedRatingResult` | `dataclass` | **Weighted rating with the enlarged-range adaptation terms (ISO 717-1 Annex B).**<br>• `rating` + `c`, `ctr`<br>• `c_50_3150`, `c_50_5000`, `c_100_5000` and the `ctr_` twins<br>• `core`: the base `WeightedRatingResult` | `res = weighted_rating_extended(freqs, r)` |
| `energy_average_level` | `function` | **Energy-average level (ISO 16283-1 (9)).**<br>• `levels`: Levels [dB] to average<br>• `axis`: Averaging axis (Default: -1) | `L = energy_average_level([60, 66])`<br><br>• `10 lg( mean(10^(Li/10)) )` |
| `AirborneInsulationResult` | `dataclass` | **Field insulation per band.**<br>• `d`: Level difference D [dB]<br>• `dnt`: Standardized DnT [dB]<br>• `r_prime`: Apparent R' [dB] or None<br>• `l1`, `l2`, `t2`, `t0`: retained measurement chain (or None)<br>• `.report(path, quantity='dnt'/'r_prime', ...)`: ISO 16283-1 field test report (Annex B form) with the ISO 717-1 rating → PDF | `res.report("DnTw.pdf", metadata=ReportMetadata(requirement=50.0))` |
| `WeightedRatingResult` | `dataclass` | **Weighted rating result.**<br>• `rating`: Rw/DnT,w … [dB], int<br>• `c`: Spectrum term C, int<br>• `ctr`: Spectrum term Ctr, int<br>• `unfavourable_sum`: [dB]<br>• `band_centers`: Measured-curve centres [Hz] or None<br>• `measured`: Measured band values [dB] or None<br>• `shifted_reference`: Shifted Table 3 reference [dB] or None | `w.rating, w.c, w.ctr` |
| `impact_insulation` | `function` | **Field impact insulation (ISO 16283-2).**<br>• `li`: Impact SPL [dB], 1D or (positions, bands)<br>• `t2`: Receiving-room T per band [s]<br>• `volume`: Receiving V [m³] (for L'n)<br>• `t0`: Reference T0 [s] (Default: 0.5) | `imp = impact_insulation(li, t2, volume=50)`<br><br>• `ImpactInsulationResult` (`l_n_t`, `l_n`) |
| `weighted_impact_rating` | `function` | **Single-number impact rating + CI (ISO 717-2).**<br>• `values_by_band`: 16 thirds (100-3150 Hz) or 5 octaves (125-2000 Hz) [dB]<br>• `bands`: 'third-octave', 'octave' or None | `r = weighted_impact_rating(imp.l_n_t)`<br><br>• `ImpactRatingResult` (Ln,w, CI); octave rating carries the -5 dB rule |
| `weighted_impact_rating_extended` | `function` | **Impact rating + CI,50-2500 (ISO 717-2:2020 A.2.1 NOTE).**<br>• `values_by_band` [dB] with `frequencies` [Hz] (None = the 16 core bands)<br>• `one_decimal`: 0.1 dB shift (reproduces Ln,r,0,w = 77.6, CI,r,0 = -10.3 of A.2.2) (Default: False) | `ext = weighted_impact_rating_extended(ln, freqs)`<br><br>• `ExtendedImpactRatingResult` (rating, ci, ci_50_2500) |
| `ExtendedImpactRatingResult` | `dataclass` | **Weighted impact rating with CI,50-2500 (ISO 717-2:2020 A.2.1).**<br>• `rating`, `ci`, `ci_50_2500`<br>• `core`: the base `ImpactRatingResult` | `res = weighted_impact_rating_extended(freqs, ln)` |
| `weighted_impact_improvement` | `function` | **Weighted improvement ΔLw (ISO 717-2 §5).**<br>• `delta_l`: 16 one-third-octave ΔL (100-3150 Hz) [dB]<br>Applies the Table 4 reference floor: ΔLw = 78 − Ln,r,w | `weighted_impact_improvement(delta_l)`<br><br>• ΔLw [dB] (e.g. 19) |
| `impact_improvement_adaptation_term` | `function` | **Spectrum adaptation term CI,Δ (ISO 717-2:2020 Formula (A.4)).**<br>• `delta_l`: 16 one-third-octave ΔL (100-3150 Hz) [dB]<br>CI,Δ = CI,r,0 − CI,r (CI,r,0 = −11 dB); ISO 16251-1 clause 8 e) | `impact_improvement_adaptation_term(delta_l)`<br><br>• CI,Δ [dB], int |
| `impact_improvement` | `function` | **Floor-covering improvement ΔL (ISO 16251-1).**<br>• `bare`, `with_covering`: acceleration levels L0/L1 per band [dB]<br>• `frequencies` [Hz] (a clause 6.3 spectrum is rated on its 100-3150 Hz sub-range)<br>• `background`: optional Lb per band [dB] (Formula 2) | `res = impact_improvement(l0, l1, f)`<br><br>• `FloorCoveringImprovementResult` |
| `acceleration_level` | `function` | **Vibratory acceleration level La (ISO 16251-1 Formula 1).**<br>• `acceleration`: RMS a per band [m/s²]<br>• `reference`: a0 (Default: 1e-6) | `acceleration_level(1e-3)  # 60 dB` |
| `background_corrected_level` | `function` | **Background correction (ISO 16251-1 Formula 2).**<br>• `signal_and_background`, `background` [dB] | `L, limited = background_corrected_level(lp, lb)`<br><br>• (corrected [dB], limit-of-measurement mask) |
| `improvement_octave_bands` | `function` | **Thirds → octaves for ΔL (ISO 16251-1 Formula 5).**<br>• `improvement`, `frequencies` (whole octave triplets) | `f_oct, dl_oct = improvement_octave_bands(dl, f)` |
| `FloorCoveringImprovementResult` | `dataclass` | **Floor-covering improvement (ISO 16251-1).**<br>• `improvement` ΔL [dB], `delta_lw`, `ci_delta` (or None)<br>• `limited`: > ΔL mask; `.octave_bands()`, `.plot()` | `res.delta_lw, res.ci_delta` |
| `ImpactInsulationResult` | `dataclass` | **Impact insulation per band.**<br>• `l_n_t`: Standardized L'nT [dB]<br>• `l_n`: Normalized L'n [dB] or None<br>• `li`, `t2`, `t0`: retained measurement chain (or None)<br>• `.report(path, quantity='l_n_t'/'l_n', ...)`: ISO 16283-2 field test report (Annex C form) with the ISO 717-2 rating → PDF | `imp.report("LnTw.pdf", metadata=ReportMetadata(requirement=58.0))` |
| `ImpactRatingResult` | `dataclass` | **Weighted impact rating.**<br>• `rating`: Ln,w/L'n,w/L'nT,w [dB], int<br>• `ci`: Spectrum term CI, int<br>• `unfavourable_sum`: [dB]<br>• `band_centers`: Measured-curve centres [Hz] or None<br>• `measured`: Measured impact levels [dB] or None<br>• `shifted_reference`: Shifted impact reference [dB] or None | `r.rating, r.ci` |
| `ReportMetadata` | `dataclass` | **Metadata for the accredited ISO 717 `.report()` PDF fiche.**<br>• All fields optional; only the supplied ones render<br>• `specimen`, `client`, `manufacturer`, `test_room`, `instrumentation`, `calibration`, `mounting`, `measurement_standard`, `test_date`<br>• numeric (finite, positive): `area`, `mass_per_area`, `source_volume`, `receiving_volume`, `temperature`, `relative_humidity`, `pressure`, `requirement`<br>• `laboratory`, `operator`, `report_id`, `notes` | `w.report("f.pdf", metadata=ReportMetadata(area=10.0, requirement=52.0))` |
| `facade_insulation` | `function` | **Field façade insulation (ISO 16283-3).**<br>• `l1_2m`/`l2`: Level 2 m in front / receiving levels [dB], 1D or (positions, bands)<br>• `t2`: Receiving-room T per band [s]<br>• `area`: Element S [m²], `volume`: Receiving V [m³], `surface_level`: L1,s [dB] (all three for R')<br>• `method`: 'loudspeaker' (−1.5 dB) / 'road_traffic' (−3 dB)<br>• `t0`: Reference T0 [s] (Default: 0.5)<br>• `frequencies` [Hz] | `fac = facade_insulation(l1_2m, l2, t2, volume=50, area=11.5, surface_level=ls)`<br><br>• `FacadeInsulationResult` |
| `FacadeInsulationResult` | `dataclass` | **Façade insulation per band.**<br>• `d_2m`: Level difference D2m [dB]<br>• `d_2m_nt`: Standardized D2m,nT [dB]<br>• `d_2m_n`: Normalized D2m,n [dB] or None<br>• `r_prime`: Apparent R'45°/R'tr,s [dB] or None<br>• `frequencies` [Hz] or None<br>• `.plot()` | `fac.d_2m_nt, fac.r_prime` |
| `lab_airborne_insulation` | `function` | **Laboratory airborne insulation (ISO 10140-2).**<br>• `l1`/`l2`: Source/receiving levels [dB], 1D or (positions, bands)<br>• `t2`: Receiving-room T per band [s]<br>• `area`: Free test-opening S [m²]<br>• `volume`: Receiving V [m³] | `lab = lab_airborne_insulation(l1, l2, t2, area=10, volume=50)`<br><br>• `LabAirborneInsulationResult` |
| `lab_impact_insulation` | `function` | **Laboratory impact insulation (ISO 10140-3).**<br>• `li`: Tapping-machine impact SPL [dB], 1D or (positions, bands)<br>• `t2`: Receiving-room T per band [s]<br>• `volume`: Receiving V [m³] | `imp = lab_impact_insulation(li, t2, volume=50)`<br><br>• `LabImpactInsulationResult` |
| `intensity_sound_reduction` | `function` | **Intensity sound reduction index RI (ISO 15186-1 Formula (7)).**<br>• `lp1`: Source-room level [dB], 1D or (positions, bands)<br>• `l_in`: Normal intensity level over the surface [dB]<br>• `measurement_area`: Surface Sm [m²], `area`: Specimen S [m²]<br>• `kc`: Adaptation term per band [dB] for RI,M (Default: None) | `res = intensity_sound_reduction(lp1, l_in, measurement_area=12, area=10)`<br><br>• `IntensityReductionResult` (`r_i`, `r_i_modified`, `rating`, `rating_modified`) |
| `adaptation_term_kc` | `function` | **Adaptation term Kc (ISO 15186-1 Annex B).**<br>• `freq`: Midband frequencies [Hz]<br>• `boundary_area`/`volume`: Room Sb2/V2 for Formula (B.1); omit both for the 10 lg(1+61,4/f) approximation (B.2) | `kc = adaptation_term_kc(freqs)`<br><br>• Kc per band [dB] |
| `intensity_element_normalized_difference` | `function` | **Intensity element normalized level difference DI,n,e (ISO 15186-1 Formula (8)).**<br>• `lp1`/`l_in`: Source level / surface intensity level [dB]<br>• `measurement_area`: Surface Sm [m²]<br>• `n`: Element units N (Default: 1) | `d = intensity_element_normalized_difference(lp1, l_in, measurement_area=10)`<br><br>• `IntensityElementNormalizedResult` (`d_i_n_e`, `rating`) |
| `surface_pressure_intensity_indicator` / `combine_subareas` | `function` | **Surface indicator FpI and subarea combination (ISO 15186-1 Formulas (10)-(12)).**<br>• `lp`/`l_in`: Surface pressure / intensity levels [dB]<br>• `combine_subareas(l_in, measurement_area)`: `(subareas, bands)` levels + per-subarea areas (negative area = reverse-flow subarea, Clause 6.4.6) | `fpi = surface_pressure_intensity_indicator(lp, l_in)`<br><br>• `FpI` array; `(LIn, Sm = Σ abs(Smi))` |
| `IntensityReductionResult` / `IntensityElementNormalizedResult` | `dataclass` | **ISO 15186-1 intensity insulation results.**<br>• `r_i` / `r_i_modified` per band with `rating` / `rating_modified`<br>• `d_i_n_e` per band with `rating` | `res = intensity_sound_reduction(...)` |
| `reverberation_index` / `estimate_reverberation_index` | `function` | **Survey reverberation index k (ISO 10052:2021 Clause 3.3 / Table 4).**<br>• `reverberation_index(t)`: k = 10 lg(T/0.5) per band<br>• `estimate_reverberation_index(volume, room)`: k from Table 4 (`room`: `kitchen`/`bathroom`/`furnished`/`a`-`h`/`a+e`...); `weighted=True` for the A/C column | `k = reverberation_index(t)`<br><br>• k per band [dB] |
| `survey_airborne_insulation` | `function` | **Survey airborne insulation (ISO 10052:2021 Clauses 3.2-3.6).**<br>• `l1`/`l2`: source/receiving levels [dB]<br>• `reverberation_index`: k per band [dB]<br>• `volume` (for Dn/R'), `area` (R', V/7.5 rule) | `res = survey_airborne_insulation(l1, l2, k, volume=50, area=12)`<br><br>• `SurveyAirborneResult` (`d`, `d_nt`, `d_n`, `r_prime`, `rating`, `r_prime_rating`) |
| `survey_impact_insulation` / `survey_facade_insulation` | `function` | **Survey impact & façade insulation (ISO 10052:2021 Clauses 3.7-3.9 / 3.13-3.15).**<br>• `li` (impact) or `l1_2m`/`l2` (façade), `reverberation_index`, `volume` | `imp = survey_impact_insulation(li, k, volume=50)`<br><br>• `SurveyImpactResult` / `SurveyFacadeResult` |
| `survey_service_equipment_level` | `function` | **Service-equipment noise LXY (ISO 10052:2021 Clauses 3.16-3.18).**<br>• `measurements`: three A/C-weighted positions [dB]<br>• `reverberation_index`: k (scalar or per band)<br>• `volume` (for LXY,n) | `se = survey_service_equipment_level([35, 30, 32], 3.0, volume=50)`<br><br>• `SurveyServiceEquipmentResult` (`l_xy`, `l_xy_nt`, `l_xy_n`) |
| `SurveyAirborneResult` / `SurveyImpactResult` / `SurveyFacadeResult` / `SurveyServiceEquipmentResult` | `dataclass` | **ISO 10052 survey-method results.**<br>• per-band quantities (`d`, `d_nt`, `d_n`, `r_prime`; `l_i`, `l_nt`, `l_n`; `d_2m`...; `l_xy`...)<br>• weighted `rating` where the method defines one | `res = survey_airborne_insulation(...)` |
| `background_correction` | `function` | **Background-noise correction (ISO 10140-4 §4.3).**<br>• `signal_and_background`: Combined Lsb per band [dB]<br>• `background`: Lb per band [dB]<br>• 6–15 dB margin corrected, ≤6 dB capped at 1.3 dB, ≥15 dB unchanged | `L = background_correction(lsb, lb)`<br><br>• Corrected levels [dB] (`LabInsulationWarning` at the limit of measurement) |
| `LabAirborneInsulationResult` | `dataclass` | **Laboratory airborne result.**<br>• `r`: Sound reduction index R [dB]<br>• `absorption`: A = 0.16 V/T [m²]<br>• `rating`: `WeightedRatingResult` or None<br>• `.plot()` (needs the rating)<br>• `.report(path, ...)`: ISO 10140-2 laboratory test report with the ISO 717-1 rating → PDF (also needs the rating; 16 one-third-octave or 5 octave bands) | `lab.r, lab.rating.rating` |
| `LabImpactInsulationResult` | `dataclass` | **Laboratory impact result.**<br>• `l_n`: Normalized impact level Ln [dB]<br>• `absorption`: A [m²]<br>• `rating`: `ImpactRatingResult` or None<br>• `.plot()` (needs the rating)<br>• `.report(path, ...)`: ISO 10140-3 laboratory test report with the ISO 717-2 rating → PDF (also needs the rating; 16 one-third-octave or 5 octave bands) | `imp.l_n, imp.rating.rating` |
| `LabInsulationWarning` | `warning class` | **Limit-of-measurement condition (ISO 10140-4).**<br>Emitted by `background_correction` when a band's signal-to-background margin is ≤ 6 dB (fixed 1.3 dB cap applied) | `warnings.simplefilter('error', LabInsulationWarning)` |
| `predicted_airborne_insulation` | `function` | **Predicted apparent airborne R'w (EN 12354-1 Formula 26).**<br>• `r_direct`: Separating-element Rs,w [dB]<br>• `flanking_paths`: sequence of `FlankingPath` (Default: ())<br>• `delta_r_direct`: Lining ΔRDd,w [dB] (Default: 0) | `res = predicted_airborne_insulation(r_direct=57, flanking_paths=paths)`<br><br>• `AirbornePredictionResult` |
| `predicted_impact_insulation` | `function` | **Predicted apparent impact L'n,w (EN 12354-2 Formula 21).**<br>• `ln_w_eq`: Bare-floor equivalent Ln,w,eq [dB]<br>• `delta_l_w`: Covering improvement ΔLw [dB] (Default: 0)<br>• `k_correction`: Flanking K [dB] (Default: 0) | `imp = predicted_impact_insulation(ln_w_eq=76.2, delta_l_w=33, k_correction=2)`<br><br>• `ImpactPredictionResult` |
| `junction_vibration_reduction` | `function` | **Vibration reduction index Kij (EN 12354-1 Annex E.3-E.9).**<br>• `junction_type`: 'rigid_cross'/'rigid_t'/'flexible_t'/'lightweight_facade'/'lightweight_double_homogeneous'/'lightweight_double_coupled'/'corner'/'thickness_change'<br>• `path`: 'through' (K13) / 'corner' (K12=K23) / 'double_leaf' (K24)<br>• `mass_ratio`: m'⊥,i/m'i<br>• `frequency` [Hz] (Default: 500), `f1` [Hz] (Default: 125) | `k = junction_vibration_reduction('rigid_cross', 'through', 1.61)`<br><br>• Kij [dB] |
| `junction_min_vibration_reduction` | `function` | **Minimum Kij,min (EN 12354-1 Formula 29).**<br>• `coupling_length`: lf [m]<br>• `s_i`, `s_j`: Element areas [m²] | `kmin = junction_min_vibration_reduction(4.5, 11.5, 11.5)`<br><br>• Kij,min [dB] |
| `flanking_path` | `function` | **One flanking path Rij,w (EN 12354-1 Formula 28a).**<br>• `label`, `kind`: 'Ff'/'Df'/'Fd'<br>• `r_source`/`r_receive`: element indices [dB]<br>• `k_ij` [dB], `separating_area` Ss [m²], `coupling_length` lf [m]<br>• `delta_r` [dB] (Default: 0), `kij_min` [dB] clamp (Default: None) | `p = flanking_path(label='f', kind='Ff', r_source=49, r_receive=49, k_ij=12.4, separating_area=11.5, coupling_length=4.5)`<br><br>• `FlankingPath` |
| `flanking_element` | `function` | **The three paths (Ff, Df, Fd) of one flanking element.**<br>• `label`, `r_flanking`, `r_separating` [dB]<br>• `k_ff`/`k_fd`/`k_df` [dB]<br>• `separating_area` Ss [m²], `coupling_length` lf [m]<br>• `delta_r_ff`/`delta_r_fd`/`delta_r_df` [dB] (Default: 0)<br>• `flanking_area` SF [m²] (Default: None): enables the automatic Kij,min clamp (Clause 4.4.2 / Formula 29) | `ff, df, fd = flanking_element(label='floor', r_flanking=49, r_separating=57, k_ff=12.4, k_fd=8.9, k_df=8.9, separating_area=11.5, coupling_length=4.5)` |
| `combine_linings` | `function` | **Combine two lining improvements (EN 12354-1 Formulas 30/31).**<br>• `delta_a`, `delta_b` [dB] (pass 0 for a single lining) | `dr = combine_linings(14.0, 14.0)`<br><br>• max(a,b) + min(a,b)/2 = 21.0 [dB] |
| `equivalent_impact_level` | `function` | **Bare-floor equivalent Ln,w,eq (EN 12354-2 Annex B).**<br>• `mass_per_area`: m' [kg/m²] | `lneq = equivalent_impact_level(322.0)`<br><br>• 164 − 35 lg(m') = 76.2 [dB] |
| `impact_flanking_correction` | `function` | **Flanking correction K (EN 12354-2 Table 1).**<br>• `separating_mass`, `flanking_mass` [kg/m²] (nearest tabulated) | `k = impact_flanking_correction(322.0, 145.0)`<br><br>• K = 2 [dB], int |
| `standardized_impact_level` | `function` | **Standardized L'nT,w (EN 12354-2 Formula 3, exact 0.032·V form).**<br>• `l_prime_n_w`: L'n,w [dB]<br>• `volume`: Receiving V [m³] (Annex E.3's V/30 is the standard's own rounding) | `lnt = standardized_impact_level(45.2, 50.0)`<br><br>• L'nT,w = 43.2 [dB] |
| `standardized_level_difference` | `function` | **DnT,w from R'w (EN 12354-1 Formula 5b, exact 0.32·V/Ss form).**<br>• `r_prime_w`: R'w [dB]<br>• `volume` V [m³], `separating_area` Ss [m²] | `dnt = standardized_level_difference(52.2, 50.0, 11.5)`<br><br>• DnT,w = 53.6 → 54 [dB] |
| `facade_sound_reduction` | `function` | **Predicted façade insulation D2m,nT (EN 12354-3 Formula 10/13).**<br>• `elements`: sequence of `FacadeElement`<br>• `area`: Façade S [m²], `volume`: Receiving V [m³]<br>• `delta_l_fs`: ΔLfs [dB] (Default: 0), `bands`<br>• `frequencies`: band centres [Hz] (Default: None; length must equal the band count), carried on the result for plotting | `fac = facade_sound_reduction(elements, area=11.3, volume=50.0, bands="octave")`<br><br>• `FacadePredictionResult` |
| `FacadePredictionResult` | `dataclass` | **Predicted façade airborne insulation (EN 12354-3:2000).**<br>• `r_prime`, `r_45`, `r_tr_s`, `d_2m_nt` per band<br>• `r_tr_s_w`, `d_2m_nt_w`, `c_tr` single numbers | `res = facade_sound_reduction(...)` |
| `radiated_sound_power` | `function` | **Radiated sound power LW (EN 12354-4 Formula 2/3).**<br>• `elements`, `lp_in`: Inside Lp,in [dB]<br>• `area`: Segment S [m²]<br>• `c_d`: Cd [dB] (Default: -6), `r_prime_cap`: optional R' cap [dB] (Default: None; the Annex G example footnote uses 40), `octave_bands` | `seg = radiated_sound_power(elements, lp_in=lp, area=200.0, c_d=-5.0)`<br><br>• `RadiatedPowerResult` |
| `RadiatedPowerResult` | `dataclass` | **Sound power radiated outside by a façade segment (EN 12354-4).**<br>• `l_w`, `r_prime` per band<br>• `l_w_dba`: A-weighted total | `res = radiated_sound_power(...)` |
| `outdoor_attenuation` | `function` | **Finite radiating-side attenuation A'tot (EN 12354-4 Annex E).**<br>• `width`, `height`: Side dimensions [m]<br>• `distance`: Perpendicular d [m] | `a = outdoor_attenuation(60.0, 10.0, 5.0)`<br><br>• A'tot = 26.3 [dB] |
| `outdoor_level` | `function` | **Exterior level Lp (EN 12354-4 Formula E.1).**<br>• `l_w`: Radiated LW [dB], scalar or per-side<br>• `attenuation`: A'tot [dB], scalar or per-side | `lp = outdoor_level(62.9, 26.3)`<br><br>• Lp = 36.6 [dB] |
| `facade_shape_level_difference` | `function` | **Façade-shape term ΔLfs (EN 12354-3 Annex C, Figure C.2).**<br>• `shape`: 'plane_facade'/'gallery_2'…'gallery_5'/'balcony_6'…'balcony_8'/'terrace_open'/'terrace_closed'<br>• `line_of_sight` h [m] (Default: 0), `absorption` αw (Default: 0.3, interpolated) | `dlfs = facade_shape_level_difference('balcony_6', line_of_sight=2.0, absorption=0.6)`<br><br>• ΔLfs = 1 [dB] |
| `FacadeElement` | `dataclass` | **One façade transmission path (EN 12354-3/-4).**<br>• give exactly one of `r`: area element [dB] / `dn_e`: small element [dB] / `insertion_loss`: opening [dB]<br>• `area`: Sᵢ [m²] (for `r` / `insertion_loss`) | `FacadeElement("window", area=4.5, r=[23, 22, 30, 36, 37])` |
| `AirbornePredictionResult` | `dataclass` | **Predicted airborne insulation.**<br>• `r_prime_w`: Apparent R'w [dB]<br>• `r_direct_w`: Direct RDd,w [dB]<br>• `paths`: tuple of `PathContribution`<br>• `dominant`: highest-energy path | `res.r_prime_w, res.dominant.label` |
| `ImpactPredictionResult` | `dataclass` | **Predicted impact insulation.**<br>• `l_prime_n_w`: Apparent L'n,w [dB]<br>• `ln_w_eq`, `delta_l_w`, `k_correction` [dB] | `imp.l_prime_n_w` |
| `FlankingPath` | `dataclass` | **One flanking transmission path.**<br>• `label`, `kind`: 'Ff'/'Df'/'Fd'<br>• `r_ij_w`: Flanking index Rij,w [dB] | `p.r_ij_w` |
| `PathContribution` | `dataclass` | **A path with its energy share.**<br>• `label`, `kind`: 'Dd'/'Ff'/'Df'/'Fd'<br>• `r_w`: Path index [dB]<br>• `fraction`: share of transmitted energy (0–1) | `c.r_w, c.fraction` |
| `vibration_reduction_index` | `function` | **Measured vibration reduction index Kij (ISO 10848 Formula 13/14).**<br>• `velocity_level_difference`: direction-averaged D̄v,ij [dB]<br>• `junction_length` lij [m], `area_i`/`area_j` [m²]<br>• `frequency` [Hz], `structural_reverberation_time_i`/`_j` [s] (both → Formula 13; else simplified 14)<br>• `speed_of_sound` (Default: 343)<br>• `modal_overlap`: per-band M; M < 0.25 bands bracketed and excluded from K̄ij (ISO 10848-4 Clause 9) | `res = vibration_reduction_index(dbar, 4.0, 12.0, 10.0, frequency=f, structural_reverberation_time_i=0.35, structural_reverberation_time_j=0.40)`<br><br>• `VibrationReductionResult` |
| `direction_averaged_level_difference` | `function` | **Direction average D̄v,ij = ½(Dv,ij+Dv,ji) (ISO 10848 Formula 11).**<br>• `dv_ij`, `dv_ji` [dB] | `dbar = direction_averaged_level_difference(dv_ij, dv_ji)` |
| `velocity_level_difference` | `function` | **Velocity level difference Dv,ij = Lv,i−Lv,j (ISO 10848 Formula 8).**<br>• `source_level`, `receive_level` [dB] | `dv = velocity_level_difference(lv_i, lv_j)` |
| `equivalent_absorption_length` | `function` | **Equivalent absorption length aj (ISO 10848 Formula 12).**<br>• `area` Sj [m²], `structural_reverberation_time` Ts [s], `frequency` [Hz]<br>• `speed_of_sound` (Default: 343) | `a = equivalent_absorption_length(10.0, 0.5, f)` |
| `total_loss_factor` | `function` | **Total loss factor η = 2.2/(f·Ts) (ISO 10848 Clause 7.3.1).**<br>• `frequency` [Hz], `structural_reverberation_time` [s] | `eta = total_loss_factor(f, ts)` |
| `normalized_flanking_level_difference` | `function` | **Airborne Dn,f = L1−L2−10 lg(A/A0) (ISO 10848 Formula 4).**<br>• `source_level` L1, `receive_level` L2 [dB]<br>• `absorption_area` A [m²]<br>• `reference_area` A0 (Default: 10) | `res = normalized_flanking_level_difference(l1, l2, a)`<br><br>• `FlankingLevelDifferenceResult` |
| `normalized_flanking_impact_level` | `function` | **Impact Ln,f = L2+10 lg(A/A0) (ISO 10848 Formula 5).**<br>• `receive_level` L2 [dB], `absorption_area` A [m²]<br>• `reference_area` A0 (Default: 10) | `res = normalized_flanking_impact_level(l2, a)`<br><br>• `FlankingImpactLevelResult` |
| `vibration_reduction_index_from_flanking` | `function` | **Indirect Kij from Dn,f (ISO 10848 Clause 4.3.1).**<br>• `normalized_flanking_level_difference` Dn,f, `reduction_index_i`/`_j` Ri/Rj [dB]<br>• `junction_length`, `area_i`/`area_j`, `absorption_length_i`/`_j` | `k = vibration_reduction_index_from_flanking(dnf, ri, rj, 2.0, 10.0, 12.0, ai, aj)`<br><br>• Kij [dB] |
| `critical_frequency` | `function` | **Thin-plate critical frequency fc = c0²/(1.8·cL·h·π) (ISO 10848 Formula 20).**<br>• `longitudinal_wave_speed` cL [m/s], `thickness` h [m]<br>• `speed_of_sound` (Default: 343) | `fc = critical_frequency(5500.0, 0.2)` |
| `strong_coupling_satisfied` | `function` | **Strong-coupling validity check (ISO 10848 Formula 15).**<br>• `velocity_level_difference` D̄v,ij [dB]<br>• `mass_i`/`mass_j` [kg/m²], `critical_frequency_i`/`_j` [Hz] | `ok = strong_coupling_satisfied(dbar, 20, 20, 100, 100)`<br><br>• bool per band |
| `modal_density` | `function` | **Modal density n = π·S·fc/c0² (ISO 10848-4 Formula 5).**<br>• `area` S [m²], `critical_frequency` fc [Hz]<br>• `speed_of_sound` (Default: 343) | `n = modal_density(10.0, 200.0)` |
| `modal_overlap_factor` | `function` | **Modal overlap M = 2.2·n/Ts (ISO 10848-4 Formula 6).**<br>• `area`, `critical_frequency`, `structural_reverberation_time` [s] | `m = modal_overlap_factor(10.0, 200.0, ts)  # feed vibration_reduction_index(modal_overlap=m)` |
| `band_mode_count` | `function` | **In-band mode count N = 0.23·f·n (ISO 10848-4 Formula 4).**<br>• `frequency` [Hz], `area`, `critical_frequency` | `n5 = band_mode_count(f, 10.0, 200.0)  # N≥5 OK` |
| `VibrationReductionResult` | `dataclass` | **Measured Kij (ISO 10848).**<br>• `frequencies` [Hz] (or None), `k_ij` [dB]<br>• `single_number`: mean K̄ij 200–1250 Hz (thirds) / 125–1000 Hz (octaves), or None<br>• `bracketed`: M < 0.25 flags (or None)<br>• `.octave_bands()`, `.plot()` | `res.k_ij, res.single_number` |
| `FlankingLevelDifferenceResult` | `dataclass` | **Normalized flanking level difference Dn,f (ISO 10848).**<br>• `d_n_f` [dB], `rating`: Dn,f,w (or None)<br>• `.plot()` | `res.d_n_f, res.rating` |
| `FlankingImpactLevelResult` | `dataclass` | **Normalized flanking impact level Ln,f (ISO 10848).**<br>• `l_n_f` [dB], `rating`: Ln,f,w (or None)<br>• `.plot()` | `res.l_n_f, res.rating` |
| `mass_law_transmission_loss` / `field_incidence_correction` | `function` | **Panel mass law TL (Bies Eq. 7.40/7.42).**<br>• `frequency` [Hz], `mass_per_area` m'' [kg/m²]<br>• `incidence`: 'normal'/'field', `band`: 'third' (−5.5 dB) / 'octave' (−4.0 dB)<br>• +6 dB/octave and +6 dB/mass doubling | `tl = mass_law_transmission_loss(500, 20)` |
| `single_panel_transmission_loss` | `function` | **Single-panel R, Sharp's method (Bies 7.2.4.1).**<br>• `frequency` [Hz], `mass_per_area` [kg/m²]<br>• `critical_frequency` fc [Hz] or `bending_stiffness` B' [N·m]<br>• `loss_factor` η, `band` | `r = single_panel_transmission_loss(f, 15, critical_frequency=2100)`<br><br>• `SoundReductionResult` |
| `double_wall_transmission_loss` / `mass_spring_mass_resonance` | `function` | **Double-wall R (Bies 7.2.6, Eq. 7.62-7.64).**<br>• `mass1`/`mass2` [kg/m²], `gap` d [m]<br>• `cavity_medium`: porous fill (`PorousMediumResult`) lowers f0<br>• below f0 = total-mass law; f0 = mass-air-mass resonance | `r = double_wall_transmission_loss(f, 12, 12, 0.1)`<br><br>• `SoundReductionResult` |
| `SoundReductionResult` | `dataclass` | **Predicted R(f) of a construction (Bies 7.2).**<br>• `transmission_loss` R [dB], `transmission_coefficient` τ<br>• `critical_frequency` / `resonance_frequency`<br>• `.rating()` → Rw (ISO 717-1), `.plot()` | `res.transmission_loss, res.rating().rating` |
| `slit_transmission_coefficient` / `slit_resonance_frequencies` | `function` | **Straight slit τ (Hopkins Eq. 4.99, Gomperts).**<br>• `frequency` [Hz], `width` w [m], `depth` d [m]<br>• `field`: 'diffuse'/'normal', `position`: 'mid'/'edge'<br>• maxima at d+2e = zλ/2 | `res = slit_transmission_coefficient(f, 0.002, 0.1)`<br><br>• `ApertureTransmissionResult` |
| `circular_aperture_transmission_coefficient` | `function` | **Circular hole τ (Hopkins Eq. 4.102, Wilson-Soroka).**<br>• `frequency` [Hz], `radius` a [m], `depth` d [m]<br>• τ → 1 for a large hole | `res = circular_aperture_transmission_coefficient(f, 0.01, 0.002)`<br><br>• `ApertureTransmissionResult` |
| `composite_transmission_loss` / `transmission_loss_from_coefficient` | `function` | **Composite R of parallel elements (Hopkins Eq. 4.92).**<br>• `areas` Sₙ [m²], `reduction_indices` Rₙ [dB] (1-D or (N, bands))<br>• a bare opening (Sₐ/S) caps R at 10 lg(S/Sₐ) | `r = composite_transmission_loss([0.99, 0.01], [55, 0])` |
| `ApertureTransmissionResult` | `dataclass` | **Slit / hole transmission (Hopkins 4.3.10).**<br>• `transmission_coefficient` τ, `transmission_loss` R = −10 lg(τ)<br>• `kind`: 'slit'/'circular', `.plot()` | `res.transmission_loss` |
| `band_uncertainty` | `function` | **One-third-octave standard uncertainty u (ISO 12999-1 Tables 2/4/6).**<br>• `measurand`: 'airborne'/'impact'/'impact_reduction'<br>• `situation`: 'A'/'B'/'C'<br>• `upper_limit`: σR95 (airborne A, Annex D) (Default: False) | `u = band_uncertainty('airborne', 'B')`<br><br>• `BandUncertainty` |
| `single_number_uncertainty` | `function` | **Single-number standard uncertainty u (ISO 12999-1 Tables 3/5/7).**<br>• `quantity`: 'r_w'/'ln_w'/'delta_lw' (+ aliases, +c/+ctr variants)<br>• `situation`: 'A'/'B'/'C'<br>• `upper_limit` (Default: False) | `u = single_number_uncertainty('r_w', 'B')`<br><br>• u [dB] (0.9) |
| `single_number_uncertainty_uncorrelated` | `function` | **Uncorrelated single-number u from bands (ISO 12999-1 Formula B.2).**<br>• `band_uncertainties`: per-band u_i [dB]<br>• `reference_differences`: L_i − R_i [dB] | `u = single_number_uncertainty_uncorrelated(u_i, d_i)`<br><br>• Energy-weighted quadrature u [dB] |
| `maximum_repeatability_standard_deviation` | `function` | **Max repeatability σx per band (ISO 12999-1 Table 1).**<br>• (no parameters) | `b = maximum_repeatability_standard_deviation()`<br><br>• `BandUncertainty` (lab self-verification) |
| `insulation_coverage_factor` | `function` | **Coverage factor k (ISO 12999-1 Table 8).**<br>• `confidence`: fraction (Default: 0.95)<br>• `one_sided` (Default: False) | `k = insulation_coverage_factor(0.95)`<br><br>• 1.96 (two-sided) / 1.65 (one-sided) |
| `insulation_expanded_uncertainty` | `function` | **Expanded uncertainty U = k·u (ISO 12999-1 Formula 2).**<br>• `u` [dB]<br>• `coverage`: fraction (Default: 0.95)<br>• `one_sided` (Default: False); enforces k ≥ 1 | `U = insulation_expanded_uncertainty(0.9)`<br><br>• 1.764 [dB] |
| `uncertain_value` | `function` | **Attach U to a rating (ISO 12999-1 Clause 8).**<br>• `value` [dB], `quantity`, `situation`<br>• `coverage` (Default: 0.95), `one_sided` (Default: False), `upper_limit` (Default: False) | `uv = uncertain_value(52.0, 'rprime_w', 'B')`<br><br>• `UncertainValue` (value ± U) |
| `combine_uncertainties` | `function` | **Quadrature combination (ISO 12999-1 Formula C.2).**<br>• `*components`: non-negative u_i [dB] | `uc = combine_uncertainties(1.0, 0.6)`<br><br>• sqrt(Σ u_i²) = 1.166 [dB] |
| `prediction_input_uncertainty` | `function` | **Prediction input uncertainty (ISO 12999-1 Formula A.1).**<br>• `sigma_reproducibility`, `sigma_product` [dB]<br>• `n`: measurements (≥ 1) | `u = prediction_input_uncertainty(1.8, 1.0, 3)`<br><br>• sqrt((σR²+σp²)/n + σp²) [dB] |
| `reduce_by_independent_measurements` | `function` | **Reduce u by m measurements (ISO 12999-1 Formula A.7).**<br>• `u` [dB]<br>• `m`: independent measurements (≥ 1) | `ur = reduce_by_independent_measurements(1.0, 4)`<br><br>• u/√m = 0.5 [dB] |
| `satisfies_lower_requirement` | `function` | **Conformity to a minimum (ISO 12999-1 Formula 5).**<br>• `value`, `expanded_uncertainty_value`, `requirement` [dB] | `ok = satisfies_lower_requirement(52.0, 1.485, 50.0)`<br><br>• True when value − U > requirement |
| `satisfies_upper_requirement` | `function` | **Conformity to a maximum (ISO 12999-1 Formula 4).**<br>• `value`, `expanded_uncertainty_value`, `requirement` [dB] | `ok = satisfies_upper_requirement(45.0, 1.5, 50.0)`<br><br>• True when value + U < requirement |
| `BandUncertainty` | `dataclass` | **Per-band standard uncertainty (ISO 12999-1).**<br>• `measurand`, `situation`<br>• `frequencies` [Hz], `uncertainties` [dB]<br>• `upper_limit`: σR95 flag<br>• `.to_arrays()` | `b.frequencies, b.uncertainties` |
| `UncertainValue` | `dataclass` | **A value with its expanded uncertainty.**<br>• `value`, `standard_uncertainty`, `expanded_uncertainty` [dB]<br>• `coverage_factor`, `confidence`, `one_sided`<br>• `.lower` = y − U, `.upper` = y + U | `uv.lower, uv.upper` |
| `COVERAGE_FACTORS` | `mapping` | **Table 8 coverage factors (read-only).**<br>Keyed by `(confidence, one_sided)` → k | `COVERAGE_FACTORS[(0.95, False)]  # 1.96` |
| `sound_absorption_coefficient_uncertainty` | `function` | **Absorption-coefficient uncertainty αs (ISO 12999-2 Table 1, Formula 1).**<br>• `alpha`, `frequencies` [Hz] (1/3-oct 63–5000)<br>• `condition`: 'reproducibility'/'repeatability'<br>• `confidence` (Default: 0.95) | `r = sound_absorption_coefficient_uncertainty(a_s, f)`<br><br>• `AbsorptionUncertaintyResult` |
| `equivalent_area_uncertainty` | `function` | **Equivalent-area uncertainty AT (ISO 12999-2 Formula 2, S = 10 m²).**<br>• `area`, `frequencies` [Hz]<br>• `condition`, `confidence` (Default: 0.95) | `r = equivalent_area_uncertainty(a_t, f)`<br><br>• `AbsorptionUncertaintyResult` |
| `practical_coefficient_uncertainty` | `function` | **Practical-coefficient uncertainty αp (ISO 12999-2 Table 2, Formula 4).**<br>• `alpha_p`, `frequencies` [Hz] (octave 250–4000)<br>• `condition`, `confidence` (Default: 0.95) | `r = practical_coefficient_uncertainty(a_p, f)`<br><br>• `AbsorptionUncertaintyResult` |
| `weighted_coefficient_uncertainty` | `function` | **Weighted-coefficient uncertainty αw (ISO 12999-2 Formulae 6/7).**<br>• `alpha_w` (carried for the interval)<br>• `condition`, `confidence` | `weighted_coefficient_uncertainty(0.70)`<br><br>• σR = 0.035 / σr = 0.020 |
| `single_number_rating_uncertainty` | `function` | **DLα,NRD uncertainty (ISO 12999-2 Formulae 8/9, EN 1793-1).**<br>• `dl_alpha` [dB] (≥ 0)<br>• `condition`, `confidence` | `single_number_rating_uncertainty(8.1)`<br><br>• σR = 0.10·DLα / σr = 0.02·DLα |
| `absorption_coverage_factor` | `function` | **Coverage factor k (ISO 12999-2 Table 3, rounded).**<br>• `confidence`: 0.68/0.80/0.90/0.95/0.99/0.999 | `absorption_coverage_factor(0.95)  # 2.0` |
| `AbsorptionUncertaintyResult` | `dataclass` | **Absorption uncertainty (ISO 12999-2).**<br>• `standard_uncertainty` u, `expanded_uncertainty` U = k·u<br>• `reported_expanded_uncertainty` (Clause 8 rounding)<br>• `.lower`, `.upper`, `.plot()` | `r.reported_expanded_uncertainty` |
| `sound_power_pressure` | `function` | **Sound power from surface pressure (ISO 3744/3746).**<br>• `levels_positions`: (NM, NB) SPL [dB]<br>• `surface`: 'hemisphere' / 'box'<br>• `radius` [m] or `dimensions`+`distance` [m]<br>• `reflecting_planes`: 1/2/3 (Default: 1)<br>• `background_levels`: for K1<br>• `frequencies` [Hz]: for LWA<br>• `reverberation_time`+`volume` / `absorption_area` / `mean_absorption_coefficient`+`room_surface`: for K2<br>• `grade`: 'engineering' (Default) / 'survey'<br>• `omc_uncertainty` [dB] (Default: 0) | `res = sound_power_pressure(levels, 'hemisphere', radius=1.5, frequencies=f)`<br><br>• `SoundPowerResult` |
| `measurement_positions` | `function` | **Hemisphere mic coordinates (ISO 3744 Annex B).**<br>• `surface`: 'hemisphere'<br>• `radius` [m]<br>• `reflecting_planes`: 1/2/3<br>• `tones`: Table B.1 vs B.2 (Default: True)<br>• `grade`: 'engineering'/'survey' | `xyz = measurement_positions('hemisphere', radius=1.5)`<br><br>• (N, 3) coordinates [m] |
| `background_noise_correction` | `function` | **Background correction K1 (ISO 3744 Eq. 16).**<br>• `source_levels` [dB]<br>• `background_levels` [dB]<br>• `grade`: 'engineering'/'survey' | `k1 = background_noise_correction(src, bg)`<br><br>• K1 per band [dB] |
| `environmental_correction` | `function` | **Environmental correction K2 (ISO 3744 Eq. A.2).**<br>• `surface_area` S [m²]<br>• `absorption_area` A, or `reverberation_time`+`volume`, or `mean_absorption_coefficient`+`room_surface` | `k2 = environmental_correction(14.1, reverberation_time=0.6, volume=300)`<br><br>• K2 [dB] |
| `SoundPowerResult` | `dataclass` | **Surface-pressure sound power.**<br>• `sound_power_level` [dB]<br>• `surface_pressure_level`, `mean_pressure_level` [dB]<br>• `background_correction`, `environmental_correction` [dB]<br>• `directivity_index` [dB] `(NM, NB)`<br>• `surface_area` [m²]<br>• `sound_power_level_a` [dB]<br>• `uncertainty` [dB]<br>• `grade`<br>• `declare(...)` → `NoiseEmissionDeclaration` | `res.sound_power_level, res.sound_power_level_a` |
| `OperatingModeDeclaration` | `dataclass` | **ISO 4871 dual-number values for one operating mode.**<br>• `mode`: column label<br>• `sound_power_level` L_WA [dB re 1 pW]<br>• `sound_power_uncertainty` K_WA [dB]<br>• `emission_pressure_level` L_pA, `emission_pressure_uncertainty` K_pA [dB] (optional)<br>• `verification_level` L_1 [dB] (optional)<br>• `declared_sound_power_level`: L_WAd = L_WA + K_WA (3.15)<br>• `verified`: L_1 ≤ L_WAd (6.2, combined form)<br>• `verified_dual`: L_1 ≤ round(L_WA) + round(K_WA) (6.2, dual-number form) | `OperatingModeDeclaration('Mode 1', 88.0, 2.0)` |
| `NoiseEmissionDeclaration` | `dataclass` | **ISO 4871:1996 noise emission declaration (machinery).**<br>• `modes`: `OperatingModeDeclaration` per mode<br>• `machine`, `operating_conditions` (clause 5)<br>• `noise_test_code`, `basic_standards` (clause 5 b)<br>• `form`: 'dual-number' (Default) / 'single-number'<br>• `.report(path, ...)`: ISO 4871 fiche → PDF | `NoiseEmissionDeclaration((m1, m2), machine='...').report('iso4871.pdf')` |
| `sound_power_reverberation` | `function` | **Reverberation-room LW, direct (ISO 3741).**<br>• `levels`: mean room SPL [dB] (1D or (NM, NB))<br>• `t60` [s]<br>• `volume` V [m³]<br>• `surface_area` S [m²]<br>• `frequencies` [Hz] (required)<br>• `background_levels`: for K1<br>• `temperature` [°C] (Default: 23)<br>• `static_pressure` [kPa] (Default: 101.325) | `rev = sound_power_reverberation(lp, t60, 200, 220, f)`<br><br>• `ReverberationSoundPowerResult` |
| `sound_power_comparison` | `function` | **Reverberation-room LW, comparison (ISO 3741).**<br>• `levels`, `levels_ref`: room SPL [dB]<br>• `lw_ref`: reference-source LW [dB]<br>• `frequencies` [Hz]<br>• `background_levels`, `background_levels_ref`<br>• `temperature`, `static_pressure` | `cmp = sound_power_comparison(lp, lp_ref, lw_ref)`<br><br>• `ReverberationSoundPowerResult` (method='comparison') |
| `ReverberationSoundPowerResult` | `dataclass` | **Reverberation-room sound power.**<br>• `frequencies` [Hz] (or `None`)<br>• `sound_power_level` [dB]<br>• `mean_pressure_level` [dB]<br>• `absorption_area` [m²]<br>• `waterhouse_correction` [dB]<br>• `background_correction`, `c1`, `c2` [dB]<br>• `speed_of_sound` [m/s]<br>• `sound_power_level_a` [dB]<br>• `method` | `rev.sound_power_level, rev.waterhouse_correction` |
| `sound_power_intensity` | `function` | **Sound power by intensity scanning (ISO 9614-2).**<br>• `normal_intensity`: (N_seg, N_bands) [W/m²]<br>• `areas`: segment Si [m²]<br>• `normal_intensity_2`: 2nd sweep (criterion 3)<br>• `pressure_levels`: for FpI<br>• `pressure_residual_index`: δpI0 [dB]<br>• `frequencies` [Hz]<br>• `band_type`: 'third' (Default)/'octave'<br>• `grade`: 'engineering'/'survey'<br>• `repeatability_limit`: override s | `ir = sound_power_intensity(scan1, areas, frequencies=f, band_type='octave')`<br><br>• `SoundPowerIntensityResult` |
| `SoundPowerIntensityResult` | `dataclass` | **Scanning sound power.**<br>• `partial_power`, `partial_power_level`<br>• `sound_power`, `sound_power_level` [dB] (NaN where `negative_band`)<br>• `negative_band`: per-band bool (True where P ≤ 0)<br>• `surface_pressure_intensity_index` (FpI)<br>• `negative_partial_power_index` (F+/-)<br>• `repeatability`, `dynamic_capability_index` (Ld)<br>• `achieved_grade`<br>• `surface_area`, `sound_power_level_a`, `grade` | `ir.sound_power_level, ir.achieved_grade` |
| `absorption_area` | `function` | **Equivalent absorption area (ISO 354 Eq. 5/7).**<br>• `t60`: T [s]<br>• `volume` V [m³]<br>• `temperature` [°C] (Default: 20)<br>• `speed_of_sound` [m/s] (overrides temperature)<br>• `m`: air attenuation [1/m] (Default: 0) | `A = absorption_area(t60, volume=200)`<br><br>• A [m²] |
| `absorption_coefficient` | `function` | **Sound absorption coefficient (ISO 354 Eq. 9).**<br>• `t1`, `t2`: empty / with-specimen T [s]<br>• `volume` V [m³]<br>• `sample_area` S [m²]<br>• `temperature1`/`temperature2` [°C]<br>• `speed_of_sound1`/`2`, `m1`/`m2` | `a = absorption_coefficient(t1, t2, 200, 10.8)`<br><br>• α_s (unclamped, may exceed 1) |
| `attenuation_from_alpha` | `function` | **ISO 9613-1 α → m (ISO 354 8.1.2.1).**<br>• `alpha`: attenuation [dB/m] | `m = attenuation_from_alpha(0.01)`<br><br>• m = α/(10 lg e) [1/m] |
| `measure_sound_absorption` | `function` | **Reverberation-room absorption measurement (ISO 354 Eq. 5/7/8/9).**<br>• `frequencies` [Hz], `t_empty` T1 [s], `t_specimen` T2 [s]<br>• `volume` V [m³], `area` S [m²]<br>• `temperature` [°C] (Default: 20), `humidity` [%]<br>• `speed_of_sound` [m/s], `m` [1/m] (Default: 0) | `r = measure_sound_absorption(f, t1, t2, volume=200, area=10.8)`<br><br>• `SoundAbsorptionMeasurement` |
| `SoundAbsorptionMeasurement` | `dataclass` | **Reverberation-room sound absorption (ISO 354).**<br>• `frequencies` [Hz], `t_empty`/`t_specimen` [s]<br>• `volume`, `area`, `temperature`, `humidity`, `speed_of_sound`<br>• `air_attenuation` m [1/m]<br>• `absorption_area_empty` A1, `absorption_area_with_specimen` A2 [m²]<br>• `alpha_s` (unclamped)<br>• `.equivalent_absorption_area` AT = A2−A1<br>• `.plot()` / `.report()` | `r.alpha_s, r.equivalent_absorption_area` |
| `air_attenuation` | `function` | **Atmospheric attenuation coefficient α (ISO 9613-1 Eq. 5).**<br>• `frequencies` [Hz]<br>• `temperature` [°C] (Default: 20)<br>• `relative_humidity` [%] (Default: 50)<br>• `pressure` [kPa] (Default: 101.325)<br>• `exact_midband`: snap to Table 1 midbands (Default: False) | `a = air_attenuation([1000, 4000], 20, 50)`<br><br>• α [dB/m] (×1000 = dB/km); out-of-range warns |
| `air_attenuation_m` | `function` | **ISO 354 power attenuation m from conditions (ISO 9613-1 + ISO 354).**<br>• Same parameters as `air_attenuation` | `m = air_attenuation_m([1000, 4000], 20, 50)`<br><br>• m = α/(10 lg e) [1/m] |
| `AtmosphericAbsorptionWarning` | `warning class` | **ISO 9613-1 out-of-range advisory.**<br>Emitted by `air_attenuation` when temperature/humidity/frequency leave the tabulated ranges or pressure exceeds 200 kPa; the result still returns | `warnings.simplefilter('error', AtmosphericAbsorptionWarning)` |
| `atmospheric_attenuation` | `function` | **Plottable ISO 9613-1 attenuation-coefficient curve.**<br>• Same parameters as `air_attenuation`<br>• `distance` d [m] (optional; enables total attenuation) | `res = atmospheric_attenuation([1000, 4000], 20, 50)`<br><br>• `AtmosphericAttenuation`; `res.plot()` |
| `AtmosphericAttenuation` | `dataclass` | **Atmospheric attenuation result (ISO 9613-1).**<br>• `frequencies` [Hz]<br>• `attenuation_coefficient` α [dB/m]<br>• `temperature`, `relative_humidity`, `pressure`<br>• `distance` [m] or `None`<br>• `.total_attenuation` A = α·d [dB] (ISO 9613-2 Aatm) or `None`<br>• `.plot()`: α (dB/km) vs frequency | `res.attenuation_coefficient, res.total_attenuation` |
| `geometric_divergence` | `function` | **Geometrical divergence Adiv (ISO 9613-2 Eq. 7).**<br>• `distance` d [m] | `a = geometric_divergence(100.0)`<br><br>• 20 lg(d/d₀) + 11 = 51 dB at 100 m |
| `atmospheric_absorption` | `function` | **Atmospheric absorption term Aatm (ISO 9613-2 Eq. 8)**, α at the exact base-10 midbands (the Table 2 convention).<br>• `distance` d [m]<br>• `frequencies` [Hz] (snapped to exact midbands)<br>• `temperature`/`humidity`/`pressure` | `aatm = atmospheric_absorption(200, bands)`<br><br>• α·d per band [dB] |
| `ground_attenuation` | `function` | **Ground effect Agr, general method (ISO 9613-2 7.3.1, Eq. 9).**<br>• `distance` d, `source_height` hs, `receiver_height` hr [m]<br>• `frequencies` [Hz]<br>• `ground_source`/`ground_middle`/`ground_receiver` G ∈ [0,1]<br>• `projected_distance` dp [m] | `agr = ground_attenuation(200, 2, 2, bands, 1, 1, 1)`<br><br>• As+Ar+Am per band [dB] (negative = gain) |
| `ground_attenuation_alternative` | `function` | **Ground effect Agr, A-weighted method (ISO 9613-2 7.3.2, Eq. 10).**<br>• `distance` d [m]<br>• `mean_height` hm [m] | `agr = ground_attenuation_alternative(200, 2)`<br><br>• 4.8 − (2hm/d)·(17+300/d) ≥ 0 [dB] |
| `directivity_omega` | `function` | **Solid-angle directivity index DΩ (ISO 9613-2 Eq. 11).**<br>• `source_height` hs, `receiver_height` hr, `projected_distance` dp [m] | `dw = directivity_omega(1.5, 1.5, 200)`<br><br>• 0…~3 dB (add to Dc for the 7.3.2 method) |
| `Barrier` | `dataclass` | **Barrier diffraction geometry (ISO 9613-2 7.4).**<br>• `source_to_edge` dss, `edge_to_receiver` dsr [m]<br>• `parallel_distance` a [m] (Default: 0)<br>• `edge_separation` e [m] (Default: None → single diffraction)<br>• `ground_reflections_by_image` (Default: False → C₂=20)<br>• `lateral` (Default: False → top-edge)<br>• `line_of_sight_clear` (Default: False; True gives z the negative sign of Eq. 16 when the sight line passes above the edge) | `b = Barrier(source_to_edge=101, edge_to_receiver=101)`<br><br>• `.is_double` when e is given |
| `barrier_attenuation` | `function` | **Barrier diffraction Dz (ISO 9613-2 Eq. 14).**<br>• `barrier`: `Barrier`<br>• `distance` d [m]<br>• `frequencies` [Hz] | `dz = barrier_attenuation(b, 200, bands)`<br><br>• 10 lg[3+(C₂/λ)C₃ z Kmet], capped 20/25 dB; 10 lg 3 at grazing (z = 0), decaying to ≥ 0 for negative z |
| `meteorological_correction` | `function` | **Meteorological correction Cmet (ISO 9613-2 Eq. 21/22).**<br>• `projected_distance` dp, `source_height` hs, `receiver_height` hr [m]<br>• `c0`: factor C₀ [dB] | `c = meteorological_correction(200, 1.5, 1.5, 2.0)`<br><br>• C₀[1 − 10(hs+hr)/dp] ≥ 0 [dB] |
| `outdoor_propagation_attenuation` | `function` | **Total octave-band attenuation A (ISO 9613-2 Eq. 4).**<br>• `distance` d, `source_height` hs, `receiver_height` hr [m]<br>• `frequencies` [Hz]<br>• `ground_source`/`ground_middle`/`ground_receiver` G<br>• `barrier`: `Barrier` or None<br>• `temperature`/`humidity`/`pressure` (Default: 20 °C/70 %/101.325 kPa, a Table 2 reference atmosphere)<br>• `projected_distance` dp [m] | `att = outdoor_propagation_attenuation(200, 2, 2, bands, 1, 1, 1)`<br><br>• `OutdoorAttenuation` term breakdown |
| `predicted_receiver_level` | `function` | **Predicted octave-band receiver level (ISO 9613-2 Eq. 3/6).**<br>• `sound_power_level` Lw [dB]<br>• same geometry/ground/barrier/atmosphere params as `outdoor_propagation_attenuation`<br>• `directivity_index` Di, `d_omega` DΩ [dB]<br>• `c0`: subtract Cmet (Default: None) | `lp = predicted_receiver_level(lw, 200, 2, 2, bands)`<br><br>• LfT(DW) = Lw + Dc − A per band [dB] |
| `OutdoorAttenuation` | `dataclass` | **Per-band ISO 9613-2 attenuation breakdown.**<br>• `frequencies` [Hz]<br>• `a_div`, `a_atm`, `a_gr`, `a_bar` [dB]<br>• `a_total` = Adiv+Aatm+Agr+Abar [dB]<br>• `d_omega` [dB]<br>• `.report()` one-page ISO 9613-2 prediction fiche (pass a `SourceEmission` for the A-weighted receiver level) | `att.a_div, att.a_bar, att.a_total` |
| `SourceEmission` | `dataclass` | **Source emission for the receiver-level fiche (ISO 9613-2 Eq. 3), report-time only.**<br>• `sound_power_level` Lw [dB]<br>• `directivity_index` Di [dB] (Default: 0)<br>• `d_omega` DΩ [dB] (Default: 0)<br>• `cmet` Cmet [dB] (Default: None) | `att.report("f.pdf", source_emission=SourceEmission(lw))` |
| `DEFAULT_FREQUENCIES` | `tuple` | **ISO 9613-2 nominal octave bands.**<br>(no parameters) | `DEFAULT_FREQUENCIES  # (63, …, 8000)` |
| `ground_effect` | `function` | **Spherical-wave ground effect ΔL (Weyl-Van der Pol; Attenborough 2e Eq. 2.40, Salomons Eq. 3.4).**<br>• `frequencies` [Hz], `source_height` hs, `receiver_height` hr, `distance` [m]<br>• `impedance` (normalized) or `flow_resistivity` σ [Pa·s/m²]<br>• `model` 'delany_bazley'/'miki' | `r = ground_effect(bands, 1, 1.5, 50, flow_resistivity=2e5)`<br><br>• `SphericalGroundResult` (ΔL, Q, Rp, F) |
| `spherical_reflection_coefficient` | `function` | **Spherical-wave reflection coefficient Q = Rp + (1−Rp)F(w) (Attenborough Eq. 2.40c; Salomons Eq. D.58).**<br>• `frequencies`, `normalized_impedance`, `source_height`, `receiver_height`, `distance` | `q = spherical_reflection_coefficient(bands, 12-6j, 1, 1.5, 50)` |
| `SphericalGroundResult` | `dataclass` | **Spherical-wave ground-effect result.**<br>• `excess_attenuation` ΔL [dB re free field]<br>• `reflection_coefficient` Q, `plane_reflection_coefficient` Rp, `boundary_loss` F<br>• `r_direct`, `r_reflected` [m]<br>• `.plot()` | `r.excess_attenuation, r.reflection_coefficient` |
| `fresnel_number` | `function` | **Barrier Fresnel number N = (2/λ)(A+B−d) (Bies 5e Eq. 5.134).**<br>• `source_to_edge` A, `edge_to_receiver` B, `direct_distance` d [m]<br>• `frequencies` [Hz] | `n = fresnel_number(101, 101, 200, bands)` |
| `kurze_anderson_attenuation` | `function` | **Kurze-Anderson barrier attenuation (Bies Eq. 5.138).**<br>• `fresnel_number` N | `kurze_anderson_attenuation(0.0)  # 5 dB` |
| `barrier_insertion_loss` | `function` | **Barrier insertion loss: Kurze-Anderson / exact half-plane / coherent ground four-path (Attenborough Ch. 9, Bies 5.3.5-5.3.7).**<br>• `frequencies`, `source_height`, `barrier_distance`, `barrier_height`, `receiver_distance`, `receiver_height`<br>• `method` 'exact'/'kurze_anderson'<br>• `thickness` e [m] (thick barrier)<br>• `ground_impedance` or `ground_flow_resistivity` | `il = barrier_insertion_loss(bands, 1, 50, 4, 100, 1.5, ground_flow_resistivity=2e5)`<br><br>• `BarrierInsertionLoss` |
| `BarrierInsertionLoss` | `dataclass` | **Per-band barrier insertion loss.**<br>• `insertion_loss` [dB], `fresnel_number`, `method`, `ground`<br>• `.plot()` (IL vs frequency) | `il.insertion_loss` |
| `linear_sound_speed_profile` | `function` | **Linear effective sound-speed profile c_eff(z) = c0 + g·z (Salomons Sec. 4.2).**<br>• `gradient` g [s⁻¹]<br>• `ground_speed` c0 [m/s], `max_height` [m] | `p = linear_sound_speed_profile(0.1)`<br><br>• `EffectiveSoundSpeedProfile` |
| `log_linear_sound_speed_profile` | `function` | **Logarithmic surface-layer profile c_eff(z) = c0 + b·ln(1+z/z0) (Salomons Eq. 4.5).**<br>• `b` [m/s] (downward > 0)<br>• `ground_speed` c0, `roughness_length` z0, `max_height` [m], `n_points` | `p = log_linear_sound_speed_profile(1.0)`<br><br>• `EffectiveSoundSpeedProfile` |
| `EffectiveSoundSpeedProfile` | `dataclass` | **Effective sound-speed profile c_eff(z).**<br>• `heights` z [m], `sound_speeds` [m/s], `description`<br>• `.speed_at(z)`, `.plot()` | `p.speed_at(10.0)` |
| `ray_curvature_radius` | `function` | **Radius of curvature of a ray in a linear gradient Rc = c0/(&#124;g&#124; cos θ0) (Salomons Sec. 4.4).**<br>• `gradient` g [s⁻¹]<br>• `ground_speed` c0 [m/s], `launch_angle_deg` θ0 | `ray_curvature_radius(0.1)  # 3430 m` |
| `shadow_zone_distance` | `function` | **Shadow-boundary distance in upward refraction √(2Rc)(√hs+√hr) (Salomons Sec. 4.4).**<br>• `gradient` g < 0 [s⁻¹]<br>• `source_height` hs, `receiver_height` hr [m]<br>• `ground_speed` c0 | `shadow_zone_distance(-0.1, 2, 2)` |
| `atmospheric_ray_paths` | `function` | **Ray tracing through a refracting atmosphere (Snell's law, Salomons Eq. 4.3).**<br>• `profile`: `EffectiveSoundSpeedProfile`<br>• `source_height` [m], `launch_angles_deg`<br>• `max_range` [m], `n_steps` | `r = atmospheric_ray_paths(p, source_height=2, launch_angles_deg=[-2,0,2])`<br><br>• `AtmosphericRayResult` |
| `AtmosphericRayResult` | `dataclass` | **Ray-tracing solution.**<br>• `ranges`, `heights`, `travel_times` [s]<br>• `turning_points`, `ground_reflections`<br>• `.plot()` (ray paths) | `r.heights, r.turning_points` |
| `atmospheric_parabolic_equation` | `function` | **Relative-level field from the Green's Function PE (Salomons App. H).**<br>• `frequency_hz`, `profile`, `source_height` [m]<br>• `impedance` or `flow_resistivity` σ, `model`<br>• `max_range`/`max_height`/`range_step`/`height_step` [m] | `pe = atmospheric_parabolic_equation(500, p, source_height=2, flow_resistivity=2e5)`<br><br>• `AtmosphericPEResult` |
| `AtmosphericPEResult` | `dataclass` | **GFPE relative-level field (dB re free field).**<br>• `ranges`, `heights`, `relative_level` (z×r)<br>• `normalized_impedance`<br>• `.level_at_height(z)`, `.plot()` | `pe.level_at_height(2.0)` |
| `task_based_exposure` | `function` | **Task-based daily exposure LEX,8h + U (ISO 9612 Clause 9).**<br>• `tasks`: sequence of `Task`<br>• `instrument`: 'class1'/'class2'/'personal_exposimeter' (Default)<br>• `u3` [dB] (Default: 1.0)<br>• `include_duration_uncertainty` (Default: True)<br>• `warn` (Default: True) | `res = task_based_exposure(tasks)`<br><br>• `ExposureResult` with per-task breakdown |
| `job_based_exposure` | `function` | **Job-based daily exposure LEX,8h + U (ISO 9612 Clause 10).**<br>• `samples` Lp,A,eqT [dB]<br>• `effective_duration_hours` Te [h]<br>• `instrument`, `u3`<br>• `n_workers`/`sample_duration_hours`: Table 1 check | `res = job_based_exposure(samples, 7.5)`<br><br>• `ExposureResult` (Eq C.9 / Table C.4 budget) |
| `full_day_exposure` | `function` | **Full-day daily exposure LEX,8h + U (ISO 9612 Clause 11).**<br>• `samples` whole-day Lp,A,eqT [dB]<br>• `effective_duration_hours` Te [h]<br>• `instrument`, `u3`, `warn` | `res = full_day_exposure(samples, 9.25)`<br><br>• `ExposureResult`; 3 samples spanning ≥3 dB advise |
| `Task` | `dataclass` | **One task of a task-based measurement (ISO 9612 Clause 9).**<br>• `samples` [dB], `duration_hours` [h]<br>• `duration_samples`/`duration_range` (for u1b)<br>• `label`, `instrument` | `Task(samples=(80.1, 82.2), duration_hours=5.0)` |
| `ExposureResult` | `dataclass` | **Daily exposure and uncertainty (ISO 9612).**<br>• `lex_8h` [dB]<br>• `combined_standard_uncertainty` u [dB]<br>• `expanded_uncertainty` U = 1.65 u [dB]<br>• `upper_limit` = LEX,8h + U [dB]<br>• `strategy`, `sampling_advisory`, `instrument`, `tasks`<br>• `.report(path, ...)`: ISO 9612 Clause 15 measurement report with the Directive 2003/10/EC assessment → PDF | `res.report("lex.pdf", metadata=ReportMetadata(client="..."))` |
| `TaskContribution` | `dataclass` | **Per-task breakdown inside `ExposureResult.tasks` (ISO 9612 Clause 9).**<br>• `label`, `lp_aeqt` (Eq. 7), `duration_hours`<br>• `lex_8h_contribution` (Eq. 8) [dB]<br>• uncertainty terms `u1a`, `u1b`, `c1a`, `c1b`, `u2`, `u3` | `res.tasks[0].lex_8h_contribution` |
| `table_c4_contribution` | `function` | **Sampling contribution c₁u₁ [dB] from Table C.4 (ISO 9612 job/full-day).**<br>• `n_samples`: N (clamped to [3, 30])<br>• `u1`: sampling standard uncertainty [dB]<br>• bilinear interpolation, anchored at u₁ = 0 | `table_c4_contribution(6, 2.0)  # 1.4` |
| `minimum_cumulative_duration_hours` | `function` | **Minimum cumulative measurement duration [h] (ISO 9612 Table 1).**<br>• `n_workers`: group size n_G (> 40 → 17 h; the standard advises splitting the group) | `minimum_cumulative_duration_hours(18)  # 10.75` |
| `COVERAGE_FACTOR` | `float` | **ISO 9612 coverage factor k = 1.65 (Clause 14).**<br>One-sided 95 % confidence: U = 1.65 u, upper limit LEX,8h + U | `COVERAGE_FACTOR  # 1.65` |
| `INSTRUMENT_U2` | `mapping` | **Instrument standard uncertainty u2 [dB] (ISO 9612 Table C.5).**<br>Keyed by `'class1'` (0.7), `'class2'` (1.5), `'personal_exposimeter'` (1.5) | `INSTRUMENT_U2['class1']  # 0.7` |
| `OccupationalExposureWarning` | `warning class` | **ISO 9612 sampling advisory.**<br>Emitted for the 3 dB task spread (Clause 9.3), c₁u₁ > 3.5 dB (Clause 10.4) or a short Table 1 cumulative duration | `warnings.simplefilter('error', OccupationalExposureWarning)` |
| `SoundPowerWarning` | `warning class` | **ISO 3744/3746/3741/9614-2 qualification issue.**<br>Emitted when the background margin is below the criterion, K2 exceeds the validity limit, a band's power is negative, or the room fails qualification; levels are then upper bounds | `warnings.simplefilter('error', SoundPowerWarning)` |
| `AbsorptionWarning` | `warning class` | **ISO 354 advisory.**<br>Emitted for a room below 150 m³, a sample area outside 10-12 m², an out-of-range temperature, or a non-physical α_s ≤ 0; the result still returns | `warnings.simplefilter('error', AbsorptionWarning)` |
| `speech_intelligibility_index` | `function` | **Speech Intelligibility Index (ANSI S3.5-1997, one-third-octave method).**<br>• `speech_spectrum`: 18 equivalent speech spectrum levels, 160 Hz–8 kHz [dB SPL], or a vocal-effort name 'normal'/'raised'/'loud'/'shout' (Table 3)<br>• `noise_spectrum`: equivalent noise spectrum levels [dB SPL] (Default: None → quiet, −80 dB)<br>• `threshold`: equivalent hearing threshold [dB HL] (Default: None → 0) | `res = speech_intelligibility_index("normal", noise_spectrum=[40.0]*18)`<br><br>• `SIIResult`; `res.sii` = 0.066 |
| `standard_speech_spectrum` | `function` | **Standard speech spectrum level by vocal effort (ANSI S3.5-1997 Table 3).**<br>• `vocal_effort`: 'normal', 'raised', 'loud' or 'shout' (Default: 'normal') | `u = standard_speech_spectrum('raised')`<br><br>• 18 band levels [dB SPL] |
| `standard_speech_spectra` | `function` | **Plottable standard speech spectra by vocal effort (ANSI S3.5-1997 Table 3).**<br>• `vocal_efforts`: a name or sequence of 'normal'/'raised'/'loud'/'shout' (Default: the full family) | `res = standard_speech_spectra()`<br><br>• `StandardSpeechSpectrum`; `res.plot()` |
| `StandardSpeechSpectrum` | `dataclass` | **Standard speech spectrum result.**<br>• `frequencies`: the 18 band centres [Hz]<br>• `vocal_efforts`: the efforts carried<br>• `levels`: `Ui` per effort, `(len(vocal_efforts), 18)` [dB SPL]<br>• `.plot()`: the speech spectrum level vs one-third-octave band, one line per effort | `res.levels, res.vocal_efforts` |
| `SIIResult` | `dataclass` | **SII result.**<br>• `sii`: index in [0, 1]<br>• `band_audibility`: Ai per band (§5.8)<br>• `band_importance`: Ii (Table 3)<br>• `frequencies` [Hz]<br>• `speech_spectrum` / `disturbance` / `masking`: Ei′ / Di / Zi per band [dB]<br>• `.plot()` | `res.sii, res.band_audibility` |
| `stoi` | `function` | **Short-time objective intelligibility STOI / ESTOI (Taal et al. 2011; Jensen & Taal 2016).**<br>• `clean`: clean reference (1D)<br>• `degraded`: degraded/processed signal (1D, same length)<br>• `fs` [Hz] (resampled to 10 kHz internally)<br>• `extended`: use ESTOI (Default: False) | `d = stoi(clean, degraded, fs)`<br><br>• `STOIResult`; `d.value` in ~[0, 1] (1 if identical) |
| `STOIResult` | `dataclass` | **STOI / ESTOI result.**<br>• `value`: the intelligibility index<br>• `extended`: True for ESTOI<br>• `segment_scores`: per-segment intermediate<br>• `band_scores`: per-band mean correlation (STOI; None for ESTOI)<br>• `band_frequencies` [Hz]<br>• `sample_rate` (10 kHz)<br>• `.plot()` | `res.value, res.band_scores` |
| `thd` | `function` | **Total harmonic distortion (IEC 60268-3 14.12.2–3).**<br>• `signal` (1D), `fs` [Hz]<br>• `fundamental` [Hz] (Default: None → largest peak)<br>• `kind`: 'F' rel. fundamental or 'R' rel. total RMS (Default: 'F')<br>• `n_harmonics` (Default: 10)<br>• `window` (Default: 'hann') | `thd(sig, fs, 1000.0, kind="F")`<br><br>• ratio (0..) |
| `harmonic_distortion` | `function` | **nth-order harmonic distortion dₙ (IEC 60268-3 14.12.5).**<br>• `signal`, `fs`, `fundamental` [Hz], `order` n (≥ 2) | `harmonic_distortion(sig, fs, 1000.0, 2)`<br><br>• ratio (aₙ rel. total RMS) |
| `thd_plus_noise` | `function` | **THD+N ratio (AES17-2015 6.3.1).**<br>• `signal`, `fs`, `fundamental` (Default: None)<br>• `notch_q`: effective Q of the applied notch, 1.2–3 (Default: 2.0)<br>• `bandwidth`: AES17 chain upper edge [Hz] (Default: 20000; None = full Nyquist); 20 Hz high-pass included<br>• `as_db`: 20·lg(ratio) dB (Default: False)<br>• `window`: FFT window for auto-detection (Default: 'hann') | `thd_plus_noise(sig, fs, 1000.0)`<br><br>• ratio, or dB if `as_db` |
| `sinad` | `function` | **Signal-to-noise-and-distortion ratio, dB (derived from AES17 THD+N).**<br>• `signal`, `fs`, `fundamental` (Default: None), `notch_q` (Default: 2.0), `bandwidth` (Default: 20000)<br>= −(THD+N in dB) | `sinad(sig, fs, 1000.0)`<br><br>• SINAD [dB] |
| `dynamic_range` | `function` | **Dynamic range (AES17-2015 6.4.1), dB CCIR-RMS.**<br>• `signal`, `fs`, `fundamental` (Default: None → 997 Hz)<br>• `notch_q` (Default: 2.0), `bandwidth` (Default: 20000)<br>• `full_scale`: digital full-scale peak amplitude (Default: 1.0)<br>= full-scale sine / CCIR-RMS-weighted notched residual | `dynamic_range(out, fs, 997.0)`<br><br>• dB CCIR-RMS |
| `idle_channel_noise` | `function` | **Idle channel noise level (AES17-2015 6.4.2), dBFS CCIR-RMS.**<br>• `signal` (idle output, 1D), `fs`<br>• `bandwidth` (Default: 20000)<br>• `full_scale` (Default: 1.0)<br>= CCIR-RMS-weighted RMS re full scale | `idle_channel_noise(idle, fs)`<br><br>• dBFS CCIR-RMS (−inf for digital zero) |
| `weighted_thd` | `function` | **Weighted THD (IEC 60268-3 14.12.11).**<br>• `signal`, `fs`, `fundamental` (Default: None)<br>• `weighting`: '468' (ITU-R BS.468-4 / IEC 60268-1, the 14.12.11 network), 'A' or 'C' (Default: '468')<br>• `notch_q` (Default: 2.0)<br>• valid for fundamentals 31.5–400 Hz | `weighted_thd(sig, fs, 100.0)`<br><br>• ratio |
| `itu_r_468_weighting` | `function` | **ITU-R BS.468-4 weighting response (Table 1).**<br>• `frequencies` [Hz] (≥ 0)<br>• log-frequency dB interpolation per the recommendation; DC → −inf | `itu_r_468_weighting([6300.0])  # +12.2`<br><br>• dB re 1 kHz |
| `modulation_distortion` | `function` | **Modulation distortion d_m,2 / d_m,3 (IEC 60268-3 14.12.7).**<br>• `signal`, `fs`, `f_low` [Hz], `f_high` [Hz]<br>• arithmetic sideband sums over the f₂ amplitude (14.12.7.2 g–h) | `modulation_distortion(sig, fs, 60.0, 7000.0).d2`<br><br>• `ModulationDistortionResult` |
| `ModulationDistortionResult` | `dataclass` | **Modulation distortion result.**<br>• `d2` / `d3`: the IEC per-order values<br>• `smpte`: combined-RMS analyzer convention (not an IEC quantity) | `res.d2, res.d3, res.smpte` |
| `difference_frequency_distortion` | `function` | **Difference-frequency distortion d_d,n (IEC 60268-3 14.12.8).**<br>• `signal`, `fs`, `f1` < `f2` [Hz]<br>• `order`: 2 or 3 (Default: 2)<br>• ref. U₂,ref = 2·U₂,f₂; 3rd order sums arithmetically | `difference_frequency_distortion(sig, fs, 13e3, 14e3, order=2)`<br><br>• ratio |
| `total_difference_frequency_distortion` | `function` | **Total difference-frequency distortion (IEC 60268-3 14.12.10).**<br>• `signal`, `fs`<br>• `f1` (Default: 8000), `f2` (Default: 11950) [Hz]<br>= √(a²_{f₂−f₁} + a²_{2f₁−f₂}) / (a_{f₁} + a_{f₂}) | `total_difference_frequency_distortion(sig, fs)`<br><br>• ratio |
| `dynamic_intermodulation_distortion` | `function` | **Dynamic intermodulation DIM (IEC 60268-3 14.12.9).**<br>• `signal`, `fs`<br>• `f_sine` [Hz] (Default: 15000)<br>• `f_square` [Hz] (Default: 3150) | `dynamic_intermodulation_distortion(sig, fs)`<br><br>• ratio (products rel. 15 kHz sine) |
| `harmonic_analysis` | `function` | **Full harmonic analysis (THD, THD+N, SINAD).**<br>• `signal`, `fs`, `fundamental` (Default: None)<br>• `n_harmonics` (Default: 10), `notch_q` (Default: 2.0), `bandwidth` (Default: 20000)<br>• `window`: FFT window (Default: 'hann') | `res = harmonic_analysis(sig, fs, 1000.0)`<br><br>• `HarmonicDistortionResult` |
| `HarmonicDistortionResult` | `dataclass` | **Harmonic analysis result.**<br>• `fundamental` [Hz]<br>• `harmonic_frequencies` / `harmonic_amplitudes`<br>• `thd_f` / `thd_r` / `thd_plus_noise`: ratios<br>• `sinad_db` [dB]<br>• `.plot()`: annotated harmonic spectrum | `res.thd_f, res.sinad_db` |
| `transfer_function` | `function` | **Frequency-response estimate H1/H2 (Bendat & Piersol).**<br>• `x` (input), `y` (output), `fs` [Hz]<br>• `estimator`: 'H1' or 'H2' (Default: 'H1')<br>• `nperseg` (Default: None), `overlap` (Default: 0.5) | `res = transfer_function(x, y, fs)`<br><br>• `FrequencyResponseResult` |
| `coherence` | `function` | **Ordinary coherence γ² (Bendat & Piersol).**<br>• `x`, `y`, `fs` [Hz]<br>• `nperseg` (Default: None), `overlap` (Default: 0.5)<br>= \|Gxy\|²/(Gxx·Gyy) ∈ [0, 1] | `f, g = coherence(x, y, fs)` |
| `FrequencyResponseResult` | `dataclass` | **Frequency-response result.**<br>• `frequencies` [Hz]<br>• `response`: complex H(f)<br>• `magnitude_db` / `phase` [rad]<br>• `coherence`: γ²(f)<br>• `estimator`<br>• `.plot()`: Bode + coherence | `res.magnitude_db, res.coherence` |
| `synchronized_sweep_signal` | `function` | **Synchronized exponential sweep (Novak et al. 2015, Eqs. 47/49).**<br>• `fs`, `f1` < `f2` [Hz], `seconds` (quantized by the rounding)<br>• `amplitude` (Default: 1.0), `fade` (Default: 0.0)<br>Rate L = round(f1·T̃/ln(f2/f1))/f1 → f1·L integer, so a L·ln(n) shift equals the nth harmonic and harmonic phases become system properties | `x = synchronized_sweep_signal(48000, 20.0, 6000.0, 4.0)`<br><br>• sweep samples (duration L·ln(f2/f1)) |
| `swept_sine_distortion` | `function` | **Harmonic separation and THD(f) from one sweep (Farina 2000 / Novak et al. 2015).**<br>• `recorded`, `fs`, plus the generator parameters `f1`, `f2`, `seconds`<br>• `method`: 'synchronized' (Default; analytic deconvolution, meaningful phases) / 'farina' (classical ESS, magnitudes only)<br>• `n_harmonics` (Default: 5), `ir_length` (Default: largest power of two fitting the closest arrivals)<br>• `amplitude` (Default: 1.0), `fade` (Default: generator default), `remove_dc` (Default: True) | `res = swept_sine_distortion(y, fs, 20.0, 6000.0, 4.0)`<br><br>• `SweptSineDistortionResult` |
| `SweptSineDistortionResult` | `dataclass` | **Swept-sine harmonic separation.**<br>• `frequencies` [Hz], `harmonic_responses`: complex H₁..H_N, `harmonic_irs` (windowed, centred), `delays` L·ln(n) [s]<br>• `thd_frequencies` [Hz], `thd`, `distortion_ratios`: \|Hₙ(n·f)\|/\|H₁(f)\| per order<br>• `fs`, `f1`, `f2`, `duration`, `rate` L, `method`, `n_harmonics`<br>• `.plot()`: \|Hₙ\| magnitudes + THD(f) | `res.thd, res.harmonic_responses` |
| `radiating_piston` | `function` | **Radiation of a rigid baffled circular piston (Beranek & Mellow §4.19/§13.7).**<br>• `radius` a [m], `frequencies` [Hz]<br>• `speed_of_sound` (Default: 343), `density` (Default: 1.206)<br>• `angles`: directivity polar angles [rad] (Default: None) | `res = radiating_piston(0.1, freqs)`<br><br>• `RadiatingPistonResult` |
| `piston_resistance` / `piston_reactance` | `function` | **Normalized piston radiation impedance R1 = 1−2J1(x)/x, X1 = 2H1(x)/x, x = 2ka (Beranek & Mellow Eqs. 13.117/13.118).** | `piston_resistance(2.0)  # 0.4233` |
| `piston_directivity` | `function` | **Far-field piston directivity 2·J1(ka·sinθ)/(ka·sinθ).**<br>• `ka`, `theta` [rad] | `piston_directivity(5.0, 0.3)` |
| `piston_directivity_pattern` | `function` | **Far-field directivity (beam) pattern of one or more baffled pistons.**<br>• `ka` (scalar or 1-D)<br>• `angles` [rad] (Default: front hemisphere −90°…+90°) | `p = piston_directivity_pattern([3, 8, 16])`<br><br>• `PistonDirectivity` |
| `RadiatingPistonResult` | `dataclass` | **Piston radiation result.**<br>• `ka`, `resistance`/`reactance`, `radiation_resistance`/`radiation_reactance` [N·s/m], `radiation_mass` = 8ρa³/3 [kg], `directivity_index` [dB], `directivity`<br>• `.plot()`: R1/X1 vs ka | `res.radiation_mass` |
| `PistonDirectivity` | `dataclass` | **Piston directivity-pattern result.**<br>• `angles` [rad], `ka`, `directivity` (linear), `directivity_db`<br>• `.plot()`: polar beam pattern in dB (family over ka) | `p.plot()` |
| `loudspeaker_characteristics` | `function` | **Rated loudspeaker characteristics for an IEC 60268-5 report.**<br>• `frequencies`, `spl_db` (on-axis SPL), `rated_impedance` R [Ω]<br>• `input_voltage` (Default: √R → 1 W), `distance` (Default: 1 m), `sensitivity_band`, `tolerance_db`<br>• `impedance`, `distortion`, `directivity`/`polar` panels | `res = loudspeaker_characteristics(f, spl, 8.0)`<br><br>• `LoudspeakerCharacteristics` |
| `LoudspeakerCharacteristics` | `dataclass` | **Loudspeaker rated-characteristics result (IEC 60268-5).**<br>• `sensitivity_level_db` (1 W/1 m, 20.3/20.4), `effective_range` (21.2), `reference_level_db`, `characteristic_sensitivity_pa`, `minimum_impedance`<br>• `.report()`: IEC 60268-5 fiche (graphs to IEC 60263) | `res.effective_range` |
| `microphone_characteristics` | `function` | **Rated microphone characteristics for an IEC 60268-4 report.**<br>• `frequencies`, `response_db` (free-field, re the reference frequency), `sensitivity_mv_per_pa` M [mV/Pa]<br>• `reference_frequency` (Default: 1 kHz), `tolerance_db` (Default: 2), `rated_impedance`/`minimum_load_impedance` [Ω], `noise_voltage` or `equivalent_noise_level_db`, `max_spl_db`/`max_spl_thd_percent`<br>• `distortion`, `noise_spectrum`, `polar` panels; `powering`, `supply_current_ma` | `res = microphone_characteristics(f, resp, 12.5)`<br><br>• `MicrophoneCharacteristics` |
| `MicrophoneCharacteristics` | `dataclass` | **Microphone rated-characteristics result (IEC 60268-4).**<br>• `sensitivity_level_db` = 20·lg(M / 1 V/Pa) (11.1), `effective_range` (12.2), `directivity_index_db` (13.2.2), `equivalent_noise_level_db` (17.2), `max_spl_db` (15.2), `signal_to_noise_ratio_db`, `diffuse_field_sensitivity_level_db`<br>• `.report()`: IEC 60268-4 fiche (graphs to IEC 60263) | `res.sensitivity_level_db` |
| `expansion_chamber` | `function` | **Expansion-chamber silencer TL/IL (Bies Eq. 8.111, four-pole).**<br>• `frequencies`, `length` L, `chamber_area`, `pipe_area`<br>• `source_impedance`/`radiation_impedance` (Default: None → no IL) | `res = expansion_chamber(f, 0.3, 0.04, 0.01)`<br><br>• `ReactiveSilencerResult` |
| `helmholtz_resonator` / `quarter_wave_resonator` | `function` | **Side-branch resonator silencers (Bies Eqs. 8.46/8.44).**<br>• Helmholtz: `duct_area`, `neck_area`, `neck_length`, `cavity_volume`<br>• Quarter-wave: `duct_area`, `length`, `branch_area` | `quarter_wave_resonator(f, 0.01, 1.5, 2e-3)` |
| `extended_tube_chamber` | `function` | **Extended-inlet/outlet expansion chamber (Bies §8.9.7); reduces to `expansion_chamber` at zero extension.**<br>• `length`, `chamber_area`, `pipe_area`, `inlet_extension`, `outlet_extension` | `extended_tube_chamber(f, 0.4, 0.04, 0.01, inlet_extension=0.1)` |
| `ReactiveSilencerResult` | `dataclass` | **Reactive-silencer result.**<br>• `frequencies`, `transmission_loss`, `insertion_loss` (or None), `transfer_matrix`, `kind`, `resonances`<br>• `.plot()`: TL/IL vs frequency | `res.transmission_loss` |
| `end_reflection_loss` / `elbow_insertion_loss` | `function` | **HVAC duct end reflection & bend insertion loss (Bies Tables 8.14/8.11, ASHRAE).**<br>• end: `frequencies`, `diameter`, `termination` 'flush'/'free'<br>• elbow: `frequencies`, `width`, `bend_type`, `vanes`, `lined` | `end_reflection_loss(bands, 0.3)`<br><br>• `HvacSpectrumResult` |
| `plenum_attenuation` | `function` | **Plenum-chamber TL by Wells' method (Bies Eq. 8.275).**<br>• `exit_area`, `line_of_sight`, `wall_area`, `mean_absorption`, `angle` | `plenum_attenuation(0.1, 1.0, 20.0, 0.2)  # dB` |
| `flow_noise_straight_duct` / `flow_noise_bend` | `function` | **HVAC flow-generated (self) noise sound power (VDI 2081, Bies Eqs. 8.251/8.254).**<br>• `frequencies`, `flow_velocity`, `area` (+ `height` for the bend) | `flow_noise_straight_duct(bands, 10.0, 0.04)`<br><br>• `HvacSpectrumResult` |
| `HvacSpectrumResult` | `dataclass` | **Per-frequency HVAC attenuation or regenerated Lw.**<br>• `frequencies`, `values`, `quantity`, `label`<br>• `.plot()` | `res.values` |
| `enclosure_insertion_loss` | `function` | **Machine-enclosure insertion loss IL = R − C (Bies Eqs. 7.103/7.111); panel R supplied by the caller, never predicted.**<br>• `panel_transmission_loss` (per-band array or callable of f)<br>• `external_area`, `internal_area`, `internal_absorption`<br>• `frequencies` (required for a callable R) | `enclosure_insertion_loss(R, 6.0, 5.0, 0.3)`<br><br>• `EnclosureResult` |
| `EnclosureResult` | `dataclass` | **Enclosure insertion-loss result.**<br>• `panel_transmission_loss`, `correction` C, `insertion_loss`, `room_constant`, `external_area`, `internal_area`<br>• `.plot()` | `res.insertion_loss` |
| `program_loudness` | `function` | **EBU R 128 measurement set of a programme (BS.1770-5 + Tech 3341/3342).**<br>• `x`: signal (1D mono or 2D [channels, samples], 1.0 = 0 dBFS)<br>• `fs` [Hz]<br>• `weights`: per-channel Gi (Default: Table 3 by channel count)<br>• `momentary_step` [s] (Default: 0.01), `short_term_step` [s] (Default: 0.1)<br>• `oversample`: true-peak factor (Default: None → reaches 192 kHz) | `res = program_loudness(x, fs)`<br><br>• `ProgramLoudnessResult` |
| `integrated_loudness` | `function` | **Programme (integrated) loudness with the two-stage gate (BS.1770-5 Annex 1).**<br>• `x`, `fs` [Hz]<br>• `weights` (Default: Table 3 by channel count)<br>Absolute gate −70 LKFS, relative −10 LU | `integrated_loudness(x, fs)  # LUFS` |
| `loudness_range` | `function` | **Loudness range LRA (EBU Tech 3342).**<br>• `short_term_loudness`: S readings [LUFS] at ≥ 10 Hz<br>Cascaded gate (−70 LUFS abs, −20 LU rel), 10th-95th percentile spread | `loudness_range(res.short_term)  # LU` |
| `true_peak_level` | `function` | **True-peak level (BS.1770-5 Annex 2).**<br>• `x` (1.0 = 0 dBFS), `fs` [Hz]<br>• `oversample`: factor ≥ 1 (Default: None → smallest reaching 192 kHz, 4 at 48 kHz) | `true_peak_level(x, fs)  # dBTP`<br>Scalar for 1D, per-channel array for 2D |
| `k_weighting` | `function` | **Apply the two-stage K-weighting pre-filter (BS.1770-5 Annex 1).**<br>• `x`, `fs` [Hz]<br>Spherical-head shelf + RLB high-pass | `y = k_weighting(x, fs)` |
| `k_weighting_coefficients` | `function` | **K-weighting biquads (Tables 1-2).**<br>• `fs` [Hz] (≥ 16 kHz)<br>Verbatim tables at 48 kHz; analog-prototype redesign elsewhere | `(b1, a1), (b2, a2) = k_weighting_coefficients(fs)` |
| `k_weighting_response` | `function` | **K-weighting magnitude frequency response (BS.1770-5 Annex 1).**<br>• `fs` [Hz] (≥ 16 kHz, Default: 48000)<br>• `frequencies` [Hz] (Default: None → `n` log points 10 Hz→Nyquist), `n` (Default: 512)<br>Evaluates the Table 1-2 biquads with `freqz` | `k_weighting_response().plot()`<br><br>• `KWeightingResponse` |
| `channel_weight` | `function` | **Position-dependent channel weight Gi (BS.1770-5 Annex 3, Table 4).**<br>• `azimuth` [deg], `elevation` [deg] (Default: 0)<br>1.41 for mid-layer side positions, 1.0 elsewhere | `channel_weight(110, 0)  # 1.41` |
| `DEFAULT_CHANNEL_WEIGHTS` | `dict` | **Table 3 weights by channel count.**<br>1/2/5/6 channels; 5.1 order L, R, C, LFE, Ls, Rs with the LFE at 0.0 (excluded) | `DEFAULT_CHANNEL_WEIGHTS[6]` |
| `ProgramLoudnessResult` | `dataclass` | **EBU Mode measurement result.**<br>• `integrated` [LUFS], `loudness_range` [LU], `true_peak` [dBTP]<br>• `momentary` / `short_term` series with `momentary_time` / `short_term_time` [s]<br>• `max_momentary` / `max_short_term` [LUFS]<br>• `relative_threshold`, `lra_low` / `lra_high` [LUFS]<br>• `true_peak_per_channel` [dBTP], `channel_weights`, `fs`<br>• `.plot()`: M/S over time with I and LRA annotated<br>• `.report(path, *, tolerance='qc'/'live')`: R 128 fiche (±0.2 LU item i / ±1.0 LU item h) | `res.integrated, res.loudness_range` |
| `KWeightingResponse` | `dataclass` | **K-weighting magnitude frequency response (BS.1770-5 Annex 1).**<br>• `frequencies` [Hz], `magnitude_db` (combined) [dB]<br>• `shelf_db` (stage 1, +4 dB shelf), `highpass_db` (stage 2, RLB) [dB]<br>• `fs` [Hz]<br>• `.plot()`: magnitude vs frequency (log axis) with the two stages | `k_weighting_response().magnitude_db` |
| `sound_pressure_level` | `function` | **Underwater SPL (ISO 18405), dB re 1 µPa.**<br>• `pressure`: signal (1D) [Pa]<br>• `reference`: p₀ (Default: 1e-6) | `sound_pressure_level(p)` |
| `sound_exposure_level` | `function` | **Underwater SEL (ISO 18405/18406), dB re 1 µPa²·s.**<br>• `pressure` (1D) [Pa]<br>• `fs` [Hz]<br>• `reference`: E₀ (Default: 1e-12) | `sound_exposure_level(p, fs)` |
| `peak_sound_pressure_level` | `function` | **Zero-to-peak level (ISO 18406), dB re 1 µPa.**<br>• `pressure` (1D) [Pa]<br>• `reference` (Default: 1e-6) | `peak_sound_pressure_level(p)` |
| `UNDERWATER_REFERENCE_PRESSURE` / `UNDERWATER_REFERENCE_EXPOSURE` | `float` | **ISO 18405 reference quantities.**<br>Reference pressure p0 = 1 µPa [Pa] and reference exposure E0 = 1 µPa²·s [Pa²·s] | `UNDERWATER_REFERENCE_PRESSURE  # 1e-06` |
| `underwater_to_in_air_spl` / `in_air_to_underwater_spl` | `function` | **Re-reference a level between 1 µPa and 20 µPa (∓26.02 dB).**<br>• `level` [dB]<br>Reference change only, not an energy equivalence. | `underwater_to_in_air_spl(120.0)` |
| `radiated_noise_level` | `function` | **Ship radiated noise level (ISO 17208-1), dB re 1 µPa·m.**<br>• `rms_pressure` [Pa]<br>• `distance` [m]<br>= 20·lg(p/p₀)+20·lg(r/r₀) | `radiated_noise_level(2e-6, 100.0)` |
| `hydrophone_depths` | `function` | **ISO 17208-1 hydrophone depths from depression angles.**<br>• `cpa_distance` [m]<br>• `angles` (Default: (15,30,45)) [deg]<br>= cpa·tan(angle) | `hydrophone_depths(100.0)` |
| `source_level_uncertainty` | `function` | **Tabulated source-level uncertainty (ISO 17208-2).**<br>• `frequency` [Hz]<br>5 dB ≤100 Hz / 3 dB 125 Hz–16 kHz / 4 dB >16 kHz | `source_level_uncertainty(1000.0)  # 3.0` |
| `monopole_source_level` | `function` | **Equivalent monopole source level (ISO 17208-2).**<br>• `rnl`: RNL [dB re 1 µPa·m] (scalar/array)<br>• `frequency` [Hz]<br>• `draught` D [m]<br>• `c` (Default: 1500) [m/s]<br>Ls = LRN + ΔL, d_s = 0.7·D | `res = monopole_source_level(rnl, f, 6.0)`<br><br>• `ShipSourceLevelResult` |
| `ShipSourceLevelResult` | `dataclass` | **Ship source-level result.**<br>• `frequencies` [Hz]<br>• `radiated_noise_level` / `surface_correction` / `source_level` [dB]<br>• `source_depth` [m] / `sound_speed` [m/s]<br>• `.plot()`: RNL/Ls/ΔL vs frequency | `res.source_level, res.surface_correction` |
| `single_strike_sel` | `function` | **Single-strike SEL (ISO 18406), dB re 1 µPa²·s.**<br>• `pressure`: one strike (1D) [Pa]<br>• `fs` [Hz] | `single_strike_sel(p, fs)` |
| `cumulative_sel` | `function` | **Cumulative SEL over strikes (ISO 18406).**<br>• `single_sels`: per-strike SELs [dB]<br>= 10·lg(Σ 10^(SELₙ/10)) | `cumulative_sel([170, 176, 173])` |
| `cumulative_sel_identical` | `function` | **Cumulative SEL of N identical strikes.**<br>• `sel_ss` [dB]<br>• `n_strikes` N (≥ 1)<br>= sel_ss + 10·lg(N) | `cumulative_sel_identical(180.0, 50)` |
| `pile_strike_metrics` | `function` | **Per-strike pile-driving metrics (ISO 18406).**<br>• `pressure`: one strike (1D) [Pa]<br>• `fs` [Hz] | `res = pile_strike_metrics(p, fs)`<br><br>• `PileStrikeResult` |
| `sea_water_sound_speed` | `function` | **Speed of sound in sea water, m/s.**<br>• `temperature` [°C] / `salinity` [ppt] / `depth` [m]<br>• `model`: `"unesco"` (default) / `"del_grosso"` / `"mackenzie"`<br>• `latitude` (Default: 45) | `sea_water_sound_speed(25, 35, 1000)` |
| `depth_to_pressure` | `function` | **Depth→pressure (Leroy-Parthiot 1998), MPa.**<br>• `depth` [m] (≥ 0)<br>• `latitude` (Default: 45) [°] | `depth_to_pressure(1000.0)` |
| `sound_speed_profile` | `function` | **Sound-speed profile over a depth column.**<br>• `depths` (1D, increasing) [m]<br>• `temperatures` / `salinities`: array or scalar<br>• `model` / `latitude` | `sound_speed_profile(z, T, S)`<br><br>• `SoundSpeedProfile` |
| `SoundSpeedProfile` | `dataclass` | **Sound-speed profile.**<br>• `depth` [m] / `sound_speed` [m/s] / `gradient` [(m/s)/m]<br>• `model`<br>• `.plot()`: speed vs depth (depth down) | `prof.sound_speed, prof.gradient` |
| `spreading_loss` | `function` | **Geometrical spreading loss, dB.**<br>• `range_m` [m] (scalar/array)<br>• `law`: `"spherical"` / `"cylindrical"` / `"practical"`<br>• `transition_range` [m] (for `"practical"`) | `spreading_loss(1000.0)` |
| `seawater_absorption` | `function` | **Volume absorption α, dB/km.**<br>• `frequency_hz` [Hz] (scalar/array)<br>• `temperature` [°C] / `salinity` [ppt] / `depth` [m] / `ph`<br>• `model`: `"francois-garrison"` (default) / `"ainslie-mccolm"` / `"thorp"` | `seawater_absorption(10e3)` |
| `transmission_loss` | `function` | **Transmission loss TL = spreading + α·R.**<br>• `range_m` [m] / `frequency_hz` [Hz]<br>• `law` / `temperature` / `salinity` / `depth` / `ph` / `model` / `transition_range` | `transmission_loss(r, 10e3)`<br><br>• `TransmissionLossResult` |
| `TransmissionLossResult` | `dataclass` | **Transmission-loss result.**<br>• `range_m` [m] / `tl` / `spreading` / `absorption` [dB]<br>• `frequency` [Hz] / `absorption_coefficient` [dB/km]<br>• `law` / `model`<br>• `.plot()`: TL vs range | `res.tl, res.absorption_coefficient` |
| `passive_sonar_equation` | `function` | **Passive sonar equation.**<br>• `source_level` / `transmission_loss` / `noise_level` [dB]<br>• `directivity_index` / `detection_threshold` (Default: 0)<br>SE = SL − TL − (NL − DI) − DT | `passive_sonar_equation(140, 80, 60)`<br><br>• `SonarEquationResult` |
| `active_sonar_equation` | `function` | **Active (monostatic) sonar equation.**<br>• `source_level` / `transmission_loss` / `target_strength` / `noise_level` [dB]<br>• `directivity_index` / `detection_threshold` / `reverberation_level`<br>noise-limited SE = SL − 2·TL + TS − (NL − DI) − DT; with `reverberation_level` → SE = SL − 2·TL + TS − RL − DT | `active_sonar_equation(220, 70, 15, 60)`<br><br>• `SonarEquationResult` |
| `SonarEquationResult` | `dataclass` | **Sonar-equation result.**<br>• `mode` / `signal_excess` / `snr` [dB] / `figure_of_merit` [dB]<br>• `transmission_loss` / `source_level` / `noise_level` / `directivity_index` / `detection_threshold` [dB]<br>• `target_strength` [dB or None] / `reverberation_limited`<br>• `.plot()`: signal excess vs TL | `res.signal_excess, res.figure_of_merit` |
| `critical_angle` | `function` | **Critical grazing angle φc = arccos(c1/c2), degrees.**<br>• `c1` / `c2` [m/s] (needs `c2 > c1`) | `critical_angle(1500, 1650)` |
| `reflection_coefficient` | `function` | **Complex seabed Rayleigh reflection coefficient.**<br>• `grazing_angle` [°] (scalar/array)<br>• `rho1` / `c1` / `rho2` / `c2` | `reflection_coefficient(30, rho1=1000, c1=1500, rho2=1900, c2=1650)` |
| `bottom_reflection_loss` | `function` | **Seabed reflection loss BL = −20·lg\|R\|, dB.**<br>• `grazing_angle` [°]<br>• `rho1` (Default: 1000) / `c1` (Default: 1500) / `rho2` / `c2` | `bottom_reflection_loss(phi, rho2=1900, c2=1650)`<br><br>• `BottomLossResult` |
| `BottomLossResult` | `dataclass` | **Seabed reflection result.**<br>• `grazing_angle` [°] / `reflection_loss` [dB]<br>• `reflection_coefficient` [complex] / `critical_angle` [° or None]<br>• `.plot()`: bottom loss vs grazing angle | `res.reflection_loss, res.critical_angle` |
| `seabed_reflection` | `function` | **Plottable seabed reflection coefficient (Rayleigh).**<br>• `grazing_angle` [°]<br>• `rho1` (Default: 1000) / `c1` (Default: 1500) / `rho2` / `c2` | `seabed_reflection(phi, rho2=1900, c2=1650)`<br><br>• `SeabedReflection` |
| `SeabedReflection` | `dataclass` | **Seabed reflection-coefficient result.**<br>• `grazing_angle` [°] / `reflection_coefficient` [complex]<br>• `magnitude` \|R\| / `bottom_loss` [dB] / `critical_angle` [° or None]<br>• `rho1` / `c1` / `rho2` / `c2`<br>• `.plot()`: \|R\| vs grazing angle | `res.magnitude, res.critical_angle` |
| `wind_noise_spectrum` | `function` | **Wenz wind noise (rule of fives), dB re 1 µPa²/Hz.**<br>• `frequency_hz` [Hz] / `wind_speed_knots` [kn] | `wind_noise_spectrum(1000, 5)` |
| `thermal_noise_spectrum` | `function` | **Mellen thermal noise, dB re 1 µPa²/Hz.**<br>• `frequency_hz` [Hz]<br>• `temperature` (Default: 16.85) / `density` (Default: 1025) / `sound_speed` (Default: 1500) | `thermal_noise_spectrum(5e4)` |
| `ocean_ambient_noise` | `function` | **Composite ambient-noise spectrum (wind + thermal [+ shipping]).**<br>• `frequency_hz` [Hz] / `wind_speed_knots` [kn]<br>• `shipping` [dB or None] / `temperature` / `density` / `sound_speed` | `ocean_ambient_noise(f, wind_speed_knots=10)`<br><br>• `AmbientNoiseResult` |
| `AmbientNoiseResult` | `dataclass` | **Ambient-noise result.**<br>• `frequency` [Hz] / `spectrum_level` [dB re 1 µPa²/Hz]<br>• `wind` / `thermal` / `shipping` [dB or None]<br>• `wind_speed_knots` [kn]<br>• `.plot()`: composite + components vs frequency | `res.spectrum_level` |
| `ship_source_spectrum` | `function` | **Predicted ship source-level spectrum.**<br>• `speed_knots` (Default: 12) / `length_m` (Default: 100)<br>• `vessel_class` (Default: `"containership"`) / `model`: `"jomopans-echo"` (default) / `"randi"` / `"wales-heitmeyer"`<br>• `frequency_hz` (Default: decidecade 10 Hz–31.5 kHz) | `ship_source_spectrum(18, 300, vessel_class="containership")`<br><br>• `ShipTrafficSpectrum` |
| `ShipTrafficSpectrum` | `dataclass` | **Ship source-spectrum result.**<br>• `frequency` [Hz] / `source_psd` [dB re 1 µPa²/Hz at 1 m] / `band_level` [dB re 1 µPa m]<br>• `model` / `vessel_class` / `speed_knots` / `length_m`<br>• `.plot()`: source PSD vs frequency | `res.source_psd, res.band_level` |
| `VESSEL_CLASSES` | `tuple` | **The 13 JOMOPANS-ECHO vessel classes.** | `"bulker" in VESSEL_CLASSES` |
| `normal_modes` | `function` | **Normal-mode transmission loss (range-independent).**<br>• `frequency_hz` / `depths` [m] / `sound_speeds` [m/s]<br>• `source_depth` / `receiver_depth` [m] / `ranges_m` / `density` / `bottom`: `"pressure-release"`\|`"rigid"` / `n_depth_points` | `normal_modes(50, [0,200], [1500,1500], source_depth=50, receiver_depth=100)`<br><br>• `NormalModeResult` |
| `ray_trace` | `function` | **Ray tracing through a sound-speed profile (vectorised).**<br>• `depths` [m] / `sound_speeds` [m/s]<br>• `source_depth` [m] / `launch_angles_deg` / `max_range` [m] / `n_steps` | `ray_trace(z, c, source_depth=1000, launch_angles_deg=[-10,0,10])`<br><br>• `RayTraceResult` |
| `parabolic_equation` | `function` | **Split-step Fourier parabolic-equation TL field.**<br>• `frequency_hz` / `depths` [m] / `sound_speeds` [m/s]<br>• `source_depth` [m] / `max_range` [m] / `range_step` [m] / `n_depth_points` | `parabolic_equation(50, [0,200], [1500,1500], source_depth=50)`<br><br>• `ParabolicEquationResult` |
| `NormalModeResult` | `dataclass` | **Normal-mode result.**<br>• `frequency` / `wavenumbers` [rad/m] / `mode_depths` [m] / `mode_functions`<br>• `ranges` [m] / `transmission_loss` [dB] / `receiver_depth` / `source_depth`<br>• `.plot()`: TL vs range | `res.wavenumbers, res.transmission_loss` |
| `RayTraceResult` | `dataclass` | **Ray-tracing result.**<br>• `launch_angles` [°] / `ranges` [m] / `depths` [m] (both `(n_rays, n_steps)`)<br>• `source_depth` / `water_depth` [m]<br>• `.plot()`: ray paths | `res.ranges, res.depths` |
| `ParabolicEquationResult` | `dataclass` | **Parabolic-equation result.**<br>• `frequency` / `ranges` [m] / `depths` [m]<br>• `transmission_loss` [dB] `(n_depths, n_ranges)` / `source_depth`<br>• `.plot()`: TL field | `res.transmission_loss` |
| `PileStrikeResult` | `dataclass` | **Pile-strike result.**<br>• `single_strike_sel` [dB re 1 µPa²·s]<br>• `peak_spl` / `spl` [dB re 1 µPa]<br>• `pulse_duration` [s]<br>• `pressure` [Pa] / `fs` [Hz]<br>• `.plot()`: waveform + cumulative energy | `res.single_strike_sel, res.peak_spl` |
| `perceived_noisiness` | `function` | **Per-band perceived noisiness (ICAO Annex 16 App. 2), noys.**<br>• `spl`: 24 one-third-octave band levels 50 Hz–10 kHz [dB] | `perceived_noisiness(spl)` |
| `NOY_BANDS` | `array` | **The 24 noy one-third-octave bands [Hz] (ICAO Annex 16 App. 2).**<br>50 Hz to 10 kHz | `NOY_BANDS[0]  # 50.0` |
| `perceived_noise_level` | `function` | **Perceived noise level PNL (ICAO Annex 16), PNdB.**<br>• `spl`: 24 band levels [dB]<br>= 40 + (10/lg2)·lg N | `perceived_noise_level(spl)` |
| `tone_correction` | `function` | **Tone correction C (ICAO Annex 16, slope method), dB.**<br>• `spl`: 24 band levels [dB]<br>1.5 dB threshold, cap 6⅔ dB | `tone_correction(spl)` |
| `effective_perceived_noise_level` | `function` | **EPNL from a spectral time history (ICAO Annex 16), EPNdB.**<br>• `spectra`: (K, 24) band levels [dB]<br>• `dt` (Default: 0.5) [s]<br>• `reference_time` (Default: 10) [s]<br>• `procedure`: 'aeroplane' (tone correction from 80 Hz, Default) / 'helicopter' (from 50 Hz, App. 2 4.3.1)<br>EPNL = PNLTM + D | `res = effective_perceived_noise_level(spectra)`<br><br>• `EPNLResult` |
| `epnl_from_pnlt` | `function` | **EPNL + 10 dB-down limits from a PNLT series (ICAO Annex 16).**<br>• `pnlt`: PNLT(k) [PNdB]<br>• `dt` (Default: 0.5) [s]<br>• `reference_time` (Default: 10) [s] | `epnl, pnltm, kf, kl = epnl_from_pnlt(pnlt)` |
| `EPNLResult` | `dataclass` | **EPNL result.**<br>• `frequencies` [Hz] / `times` [s]<br>• `pnl` / `tone_correction` / `pnlt` [PNdB, dB]<br>• `pnltm` / `duration_correction` / `epnl`<br>• `band_limits` (kF, kL)<br>• `.plot()`: PNL/PNLT time history | `res.epnl, res.pnltm, res.band_limits` |
| `verify_aircraft_noise_system` | `function` | **IEC 61265 measurement-system verification.**<br>• `directional`: {f: {angle: \|Δsens\| dB}} (Table 1)<br>• `frequency_response` / `linearity` / `resolution`<br>filters via `verify_filter_class` | `verify_aircraft_noise_system(directional=meas)` |
| `sae_band_attenuation` | `function` | **One-third-octave-band atmospheric absorption (SAE ARP 5534).**<br>• `frequencies` [Hz] / `path_length` [m]<br>• `temperature` (Default: 25) / `relative_humidity` (Default: 70) / `pressure` (Default: 101.325)<br>δ_B from pure-tone δ_t=α·s (α from ISO 9613-1) | `sae_band_attenuation(freqs, 7620.0)`<br><br>• `AircraftBandAttenuation` |
| `AircraftBandAttenuation` | `dataclass` | **Aircraft band-absorption result.**<br>• `frequency` [Hz] / `band_attenuation` [dB] / `midband_attenuation` [dB] / `coefficient` [dB/m]<br>• `path_length` / `temperature` / `relative_humidity` / `pressure`<br>• `.plot()`: band vs pure-tone mid-band | `res.band_attenuation` |
| `npd_level` | `function` | **NPD event-level interpolation (ECAC Doc 29 §4.2).**<br>• `powers` / `distances` [m] / `levels` [dB] (shape P×D)<br>• `power` / `distance` [m]<br>linear in power (Eq. 4-3), log-linear in distance (Eq. 4-4) | `npd_level(P, D, L, 16000, 1500)` |
| `npd_curve` | `function` | **NPD level over a distance sweep at one power.**<br>• `powers` / `distances` / `levels`<br>• `power` / `query_distances` (Default: log sweep) | `npd_curve(P, D, L, 20000)`<br><br>• `NpdLevelResult` |
| `NpdLevelResult` | `dataclass` | **NPD distance-sweep result.**<br>• `distance` [m] / `level` [dB] / `power`<br>• `table_distances` / `table_levels`<br>• `.plot()`: level vs slant distance | `res.distance, res.level` |
| `lateral_attenuation` | `function` | **Excess lateral attenuation Λ(β,ℓ) (ECAC Doc 29 Eq. 4-18/4-19).**<br>• `elevation_deg` β / `lateral_m` ℓ | `lateral_attenuation(10, 500)` |
| `engine_installation_correction` | `function` | **Engine-install lateral directivity ΔI(φ) (Eq. 4-15/4-16).**<br>• `depression_deg` φ / `mounting`: `"wing"`\|`"fuselage"`\|`"propeller"` | `engine_installation_correction(20, "wing")` |
| `duration_correction` | `function` | **Duration correction ΔV = 10·lg(Vref/Vseg) (Eq. 4-14).**<br>• `reference_speed` / `segment_speed` | `duration_correction(82.3, 90)` |
| `noise_fraction` | `function` | **Finite-segment noise fraction ΔF (Eq. 4-20).**<br>• `q` [m] / `segment_length` λ [m] / `scaled_distance` dλ [m] | `noise_fraction(0, 5000, 100)` |
| `impedance_adjustment` | `function` | **Acoustic-impedance adjustment of NPD data (Eq. 4-6/4-7).**<br>• `temperature` [°C] / `pressure` [kPa]<br>= 10·lg(ρc/409.81); +0.074 dB at ISA | `impedance_adjustment(15, 101.325)` |
| `start_of_roll_directivity` | `function` | **Start-of-roll rearward directivity ΔSOR (Eq. 4-22/4-24/4-25).**<br>• `azimuth_deg` ψ (arccos q/dSOR) / `distance_m` dSOR<br>• `engine`: `"jet"`\|`"turboprop"`; 0 ahead (ψ<90°) | `start_of_roll_directivity(120, 300, "jet")` |
| `event_level` | `function` | **Single-event SEL/LAmax of a flight path at a receiver (Eq. 4-8/4-10/4-11).**<br>• `path` (N,5): x,y,z,power,speed / `observer` (x,y,z)<br>• NPD `powers` / `distances` / `exposure_levels` / `maximum_levels`<br>• `reference_speed` / `mounting` / `metric`: `"exposure"`\|`"maximum"`<br>• `temperature` / `pressure` (impedance) / `ground_roll` mask | `event_level(path, obs, P, D, SEL, LMAX)`<br><br>• `FlyoverResult` |
| `noise_contour` | `function` | **Single-event noise level over a ground grid → contour.**<br>• `path` / NPD tables / `x` / `y` grids [m]<br>• `reference_speed` / `mounting` / `metric` / `temperature` / `pressure` / `ground_roll` mask | `noise_contour(path, P, D, SEL, LMAX, x=gx, y=gy)`<br><br>• `NoiseContourResult` |
| `FlyoverResult` | `dataclass` | **Single-event result.**<br>• `level` [dB] / `metric` / `segment_levels` [dB] / `observer`<br>• `.plot()`: per-segment contributions | `res.level` |
| `NoiseContourResult` | `dataclass` | **Ground-grid contour result.**<br>• `x` / `y` [m] / `level` [dB] (Ny×Nx) / `metric`<br>• `.plot()`: filled contours | `res.level` |
| `load_anp_database` | `function` | **Load an EASA ANP fleet database (NPD curves + default profiles).**<br>• `path`: CSV export directory, or `None` for the bundled curated subset | `db = load_anp_database()`<br><br>• `AnpDatabase` |
| `AnpDatabase` | `class` | **Parsed ANP database wiring real aircraft into the Doc 29 chain.**<br>• `.aircraft(id)` / `.aircraft_ids` / `.npd_curves(id, op, metric)` / `.profile(id, op, profile_id=)`<br>• `.event_level(id, obs, op)` / `.noise_contour(id, op, x=, y=)` | `db.noise_contour("747100", "departure", x=gx, y=gy)`<br><br>• `AnpAircraft` |
| `AnpAircraft` | `dataclass` | **One ANP aircraft type: metadata + NPD/profile access + Doc 29 wiring.**<br>• `aircraft_id` / `description` / `engine_type` / `num_engines` / `weight_class` / `mounting` / `npd_id`<br>• `.npd_curves(op, metric)` / `.profile(op)` / `.event_level(obs, op)` / `.noise_contour(op, x=, y=)` | `db.aircraft("747100").mounting` |
| `AnpNpdCurves` | `dataclass` | **ANP NPD curves for one aircraft, metric and operation.**<br>• `powers` / `distances` [m] / `levels` [dB] (P×D) / `metric` / `operation`<br>• `.level(power, distance)` / `.plot()`: level vs slant distance | `db.npd_curves("747100", "departure", "SEL")` |
| `AnpProfile` | `dataclass` | **ANP default fixed-point trajectory as a Doc 29 flight path.**<br>• `path` (N,5): x,y,z,power,speed [SI] / `ground_roll` / `landing_roll` masks<br>• `.plot()`: altitude vs along-track distance | `db.profile("747100", "departure").path` |
| `RotorcraftHemisphere` | `dataclass` | **Rotorcraft noise hemisphere source (ECAC Doc 32).**<br>• `frequencies` [Hz] / `azimuth` φ / `polar` θ [°] / `levels` [dB] (A×P×F) / `distance` (60 m)<br>• `.plot()`: fore-aft directivity / `.mirrored()`: φ → −φ (Eq. 2) | `h.levels` |
| `hemisphere_source_level` | `function` | **Interpolated source level L(fc,φ,θ) (Eq. 13-15).**<br>• `hemisphere` / `azimuth_deg` φ / `polar_deg` θ<br>• energy-bilinear + nearest-bin fill | `hemisphere_source_level(h, 0, 90)` |
| `spherical_spreading_adjustment` | `function` | **ΔLs = −20·lg(r/60) (ECAC Doc 32 Eq. 24).**<br>• `distance` r [m] | `spherical_spreading_adjustment(600)` |
| `atmospheric_adjustment` | `function` | **ΔLa = −α(f)·(r−60) (Eq. 26/27; ISO 9613-1 α; Table 4).**<br>• `frequencies` [Hz] / `distance` r [m]<br>• `temperature` / `relative_humidity` / `pressure` | `atmospheric_adjustment(f, 1060)` |
| `ground_effect_adjustment` | `function` | **ΔLg over an impedance plane (Chien-Soroka, Eq. 28-35).**<br>• `frequencies` / `source_height` / `receiver_height` / `horizontal_distance`<br>• `flow_resistivity` σ or CNOSSOS class `"A"`-`"H"` | `ground_effect_adjustment(f, 150, 1.5, 500)` |
| `flight_condition_weights` | `function` | **Hemisphere blend weights for a flight condition (NORAH2 Eq. 3-10).**<br>• database `airspeeds` / `path_angles` [°] + query `airspeed` / `path_angle`<br>• Delaunay triangle blend inside the hull, nearest outside<br>• `scaling_factor` Ffc (2) / `triangles` lookup table | `flight_condition_weights(V, G, 60, 2.5)` |
| `interpolated_source_level` | `function` | **Source level between hemispheres (Eq. 8/10 over Eq. 13).**<br>• `hemispheres` + database conditions + query condition<br>• `azimuth_deg` φ / `polar_deg` θ | `interpolated_source_level(hs, V, G, 60, 2.5, 0, 90)` |
| `flight_path_kinematics` | `function` | **Track kinematics by central differences (Eq. 16-21).**<br>• `times` [s] / `positions` (N,3) [m]<br>• Vg, VA, heading, curvature, bank Φ = atan(K·Vg²/g), path angle γ | `flight_path_kinematics(t, xyz)`<br><br>• `FlightPathKinematics` |
| `FlightPathKinematics` | `dataclass` | **Track kinematics result.**<br>• `ground_speed` / `airspeed` [m/s] / `heading` / `bank_angle` / `path_angle` [°] / `curvature` [rad/m]<br>• `.plot()`: speed and angle profiles | `kin.airspeed` |
| `rotorcraft_event_level` | `function` | **Single-event time history and metrics at a receiver (Doc 32 §6.1).**<br>• `hemispheres` + conditions / `times` / `positions` / `receiver` (x,y)<br>• `receiver_height` / `ground_elevation` / `flow_resistivity`<br>• per-point `airspeed` / `path_angle` / `heading` / `bank_angle` / `level_offset`<br>• `atmospheric_method`: `"iso9613"`\|`"sae"` / `terrain` (x, y, z model) + `terrain_resolution` | `rotorcraft_event_level(hs, V, G, t, xyz, (x, y))`<br><br>• `RotorcraftEventResult` |
| `RotorcraftEventResult` | `dataclass` | **Single-event result.**<br>• `times` (recorded) / `band_levels` / `a_levels` [dB(A)]<br>• `la_max` / `sel` / `sel_10db` / `pnlt` / `pnltm` / `epnl`<br>• `.plot()`: LA(t) history with the 10 dB-down window | `res.sel, res.epnl` |
| `rotorcraft_noise_contour` | `function` | **Single-event SEL/LASmax over a ground grid (Doc 32 §6.3).**<br>• event inputs + `x` / `y` grids [m]<br>• `metric`: `"exposure"`\|`"maximum"`<br>• per-receiver `flow_resistivity` / `ground_elevation` arrays; `terrain` model | `rotorcraft_noise_contour(hs, V, G, t, xyz, x=gx, y=gy)`<br><br>• `RotorcraftNoiseContourResult` |
| `RotorcraftNoiseContourResult` | `dataclass` | **Rotorcraft ground-grid contour result.**<br>• `x` / `y` [m] / `level` [dB(A)] (Ny×Nx) / `metric`<br>• `.plot()`: filled contours | `res.level` |
| `mean_ground_plane` | `function` | **Mean ground plane of a terrain section (NORAH2 Eq. 36-40).**<br>• `distances` / `heights` [m] (polyline)<br>• continuous least squares in closed form | `mean_ground_plane(d, z)`<br><br>• `MeanGroundPlaneResult` |
| `MeanGroundPlaneResult` | `dataclass` | **Fitted plane.**<br>• `slope` a / `intercept` b [m]<br>• `.height(d)` / `.equivalent_height(d, z)` (orthogonal)<br>• `.plot()`: section + plane | `res.slope` |
| `mean_flow_resistivity` | `function` | **Log-mean flow resistivity along a path (Eq. 41).**<br>• `lengths` [m] / `resistivities` [Pa·s/m²] per segment | `mean_flow_resistivity(d, sig)` |
| `diffraction_attenuation` | `function` | **Pure diffraction ΔLd per band (Eq. 42-44).**<br>• `path_difference` δ [m] (negative allowed) / `edge_height` h0 [m]<br>• `edge_span` e (C″, multiple edges) / `capped` (25 dB) | `diffraction_attenuation(f, 0.5, edge_height=10)` |
| `terrain_screening_adjustment` | `function` | **Ground + screening over a vertical section (§A.4.4-A.4.5).**<br>• `source` / `receiver` (d, z) [m] / `distances` / `heights` (terrain)<br>• `flow_resistivity`: value, class or per segment (Eq. 41)<br>• clear path → mean-plane ground effect; blocked → rubber band + Eq. 45-47 | `terrain_screening_adjustment(f, S, R, d, z)`<br><br>• `TerrainScreeningResult` |
| `TerrainScreeningResult` | `dataclass` | **Section result.**<br>• `adjustment` [dB] (replaces the flat ΔLg) / `screened` / `path_difference` δ [m] / `diffraction_points`<br>• `.plot()`: section geometry | `res.adjustment` |
| `slant_distance` | `function` | **Rotor-centre-to-microphone slant distance (IEC 61400-11).**<br>• `hub_height` H [m]<br>• `rotor_diameter` D [m]<br>• `rotor_axis` (Default: "horizontal" → R0 = H+D/2, Formula 1; "vertical" → R0 = H+D, Formula 2)<br>= √(H² + R0²) | `slant_distance(80.0, 100.0)` |
| `apparent_sound_power_level` | `function` | **Apparent sound power level (IEC 61400-11 Formula 26), dB re 1 pW.**<br>• `band_levels`: background-corrected A-weighted band SPL [dB]<br>• `r1`: slant distance [m]<br>= L_p − 6 + 10·lg(4π R1²/S0) | `apparent_sound_power_level(levels, r1)` |
| `wind_turbine_tonality` | `function` | **Tonal audibility from a narrowband spectrum (IEC 61400-11), with the 9.5.2 possible-tone screening; tone lines and La anchor to the highest classified line (9.5.3/9.5.4).**<br>• `levels` [dB] / `frequencies` [Hz]: 1-D, equal length (≥ 3), strictly increasing and uniformly spaced (narrowband), covering the whole critical band<br>• `tone_frequency`: optional [Hz] (≥ 20 Hz) | `res = wind_turbine_tonality(levels, freqs)`<br><br>• `WindTurbineTonalityResult` |
| `WindTurbineTonalityResult` | `dataclass` | **Wind-turbine tonality result.**<br>• `tone_frequency` [Hz] / `critical_bandwidth` [Hz]<br>• `tone_level` / `masking_level` / `tonality` [dB]<br>• `audibility_criterion` / `tonal_audibility` [dB]<br>• `is_audible` / `has_identified_tone` (False → exclude from 9.5.1 bin averaging)<br>• `.plot()`: spectrum + critical band + masking | `res.tonal_audibility, res.is_audible` |
| `WindTurbineNoiseWarning` | `warning class` | **IEC 61400-11 advisory.**<br>Emitted when the tonality inputs leave the standard's stated domain of validity | `warnings.simplefilter('error', WindTurbineNoiseWarning)` |
| `noise_criterion` | `function` | **NC rating, clause 5.2.2 two-step (ANSI/ASA S12.2-2019).**<br>• `levels`: octave-band SPL [dB] (the 10 bands 16 Hz–8 kHz without `frequencies`)<br>• `frequencies`: optional band centres [Hz] (subset allowed) | `nc = noise_criterion(levels)`<br><br>• `NCResult`; NC-(SIL) designation, tangency when exceeded |
| `room_criterion` | `function` | **RC Mark II rating (ANSI/ASA S12.2-2019 Annex D).**<br>• `levels`: octave-band SPL [dB]<br>• `frequencies`: optional band centres [Hz] | `rc = room_criterion(levels)`<br><br>• `RCResult`; LMF average + 'N'/'R'/'H'/'RH' tag |
| `nc_curve` | `function` | **NC curve levels (Table 1).**<br>• `index`: NC designation 15–70 (intermediate values interpolated band by band) | `nc_curve(35)  # [82, 71, 60, ...]`<br><br>• 10 band levels [dB], 16 Hz–8 kHz |
| `rc_curve` | `function` | **RC Mark II curve (Table D.1).**<br>• `index`: RC designation (value at 1000 Hz) | `rc_curve(35)`<br><br>• −5 dB/octave line, 10 bands [dB] |
| `NCResult` | `dataclass` | **NC rating result.**<br>• `rating`: NC designation (NaN outside NC-15…NC-70, see `out_of_range`)<br>• `sil`, `tangency_rating`, `method`, `label`<br>• `governing_frequency`: tangency band [Hz]<br>• `frequencies` [Hz], `levels` [dB]<br>• `.plot()` | `nc.rating, nc.label` |
| `RCResult` | `dataclass` | **RC Mark II result.**<br>• `rating`: LMF rounded [dB], int<br>• `lmf`: 500/1000/2000 Hz average [dB]<br>• `classification`: 'N'/'R'/'H'/'RH'<br>• `reference_curve` [dB], `frequencies` [Hz], `levels` [dB]<br>• `.plot()` | `rc.rating, rc.classification` |
| `age_threshold` | `function` | **Age-related hearing threshold distribution (ISO 7029:2017).**<br>• `age`: years (≥ 18)<br>• `sex`: 'male'/'female' (Default: 'male')<br>• `fractile`: population fractile in (0, 1) (Default: 0.5)<br>• `frequencies`: subset of the 11 audiometric frequencies [Hz] (Default: None → 125–8000 Hz) | `at = age_threshold(60, 'male')`<br><br>• `AgeThresholdResult`; median at 4 kHz = 20.2 dB |
| `reference_threshold` | `function` | **Reference threshold of hearing, 0 dB HL (ISO 389-7:2005 Table 1).**<br>• `field`: 'free-field' or 'diffuse-field' (Default: 'free-field')<br>• `frequencies`: optional subset [Hz] | `t = reference_threshold()`<br><br>• dB SPL per audiometric frequency (1 kHz → 2.4) |
| `AgeThresholdResult` | `dataclass` | **Age threshold distribution.**<br>• `age`, `sex`, `fractile`<br>• `frequencies` [Hz]<br>• `median`: deviation from age 18 [dB]<br>• `spread_upper` / `spread_lower`: half-Gaussian su/sl [dB]<br>• `threshold`: value at `fractile` [dB]<br>• `.plot()` | `at.median, at.threshold` |
| `nipts` | `function` | **Noise-induced permanent threshold shift (ISO 1999:2013 §6.3).**<br>• `l_ex`: LEX,8h [dB]<br>• `years`: exposure duration (10–40 established; 1–10 extrapolated by Formula 3)<br>• `fractile`: (0, 1) (Default: 0.5)<br>• `frequencies`: subset [Hz] (Default: None → 500–6000 Hz) | `n = nipts(95.0, 20.0)`<br><br>• `NiptsResult`; N50 at 4 kHz = 23.0 dB |
| `htlan` | `function` | **Threshold associated with age and noise, H′ = H + N − HN/120 (ISO 1999 Formula 1).**<br>• `age`: years (≥ 18), `sex`: 'male'/'female'<br>• `l_ex`: LEX,8h [dB], `years`<br>• `fractile`: (0, 1) applied to both components (Default: 0.5)<br>• `frequencies` | `h = htlan(60, 'male', 95.0, 20.0)`<br><br>• `HtlanResult`; H′ at 4 kHz = 39.3 dB |
| `NiptsResult` | `dataclass` | **NIPTS distribution.**<br>• `l_ex`, `years`, `fractile`<br>• `frequencies` [Hz]<br>• `median`: N50 (Formula 2/3) [dB]<br>• `value`: NIPTS at `fractile` (Formula 4/5) [dB]<br>• `spread_upper` / `spread_lower`: du/dl [dB]<br>• `.plot()` | `n.median, n.value` |
| `HtlanResult` | `dataclass` | **Combined HTLAN result.**<br>• `age`, `sex`, `l_ex`, `years`, `fractile`<br>• `frequencies` [Hz]<br>• `htla`: age component H [dB]<br>• `nipts`: noise component N [dB]<br>• `threshold`: combined H′ [dB]<br>• `.plot()` | `h.htla, h.nipts, h.threshold` |
| `predicted_prominence` | `function` | **Predicted prominence P of an impulse (NT ACOU 112 Formula 1).**<br>• `onset_rate`: slope of the A/F level onset [dB/s] (> 0; qualifies above 10 dB/s)<br>• `level_difference`: level rise over the onset [dB] (> 0) | `predicted_prominence(50.0, 20.0)  # 7.7`<br><br>• P = 3 lg(rate) + 2 lg(diff) |
| `impulse_adjustment` | `function` | **LAeq adjustment KI (Formula 2).**<br>• `prominence`: P | `impulse_adjustment(7.7)  # 4.86`<br><br>• 1.8(P − 5) dB for P > 5, else 0 |
| `impulse_prominence` | `function` | **Governing prominence and adjustment of a set of impulses (clauses 7–8); only onset rates > 10 dB/s qualify (clause 4.5).**<br>• `onset_rates` [dB/s]<br>• `level_differences` [dB] | `r = impulse_prominence([50, 120], [20, 15])`<br><br>• `ImpulseProminenceResult` (P = 8.59, KI = 6.46 dB) |
| `rating_level` | `function` | **Rating level LAr,T over a reference time (clause 8 Note 1).**<br>• `laeq`: LAeq,N per sub-interval [dB]<br>• `adjustment`: KI,N per sub-interval [dB]<br>• `durations`, `reference_time`: same time unit | `rating_level([55, 60], [0, 4.9], [20, 10], 30)  # 60.9` |
| `ImpulseProminenceResult` | `dataclass` | **Impulse-prominence verdict.**<br>• `onset_rates` [dB/s], `level_differences` [dB]<br>• `per_impulse`: P of each impulse<br>• `qualifies`: onset rate > 10 dB/s mask (clause 4.5)<br>• `prominence`: governing (highest qualifying) P<br>• `adjustment`: KI of the governing qualifying impulse [dB] (0 when none qualifies)<br>• `.plot()` | `r.prominence, r.adjustment` |
| `ImpulseProminenceWarning` | `warning class` | **NT ACOU 112 advisory.**<br>Emitted when a supplied level rise does not qualify as an impulse (clause 4.5) | `warnings.simplefilter('error', ImpulseProminenceWarning)` |
| `impulsive_sound_adjustment` | `function` | **Objective impulsive-sound adjustment from a calibrated signal (ISO/PAS 1996-3:2022).**<br>• `signal`: sound pressure [Pa], `fs` [Hz]<br>• `dt`: LpAF sampling interval [s] (10–25 ms; Default 0.02)<br>• `onset_rate_method`: 'least_squares' or 'upper_half' pass-by variant<br>• `calibration_offset` [dB], `laeq` [dB] | `r = impulsive_sound_adjustment(sig, fs)`<br><br>• `ImpulsiveSoundResult` (P, KI, category) |
| `sound_pressure_level_history` | `function` | **A-weighted, F time-weighted level history LpAF (ISO/PAS 1996-3 Clause 4).**<br>• `signal` [Pa], `fs` [Hz]<br>• `dt`: sampling interval [s] (10–25 ms; Default 0.02)<br>• `reference_pressure` [Pa], `calibration_offset` [dB] | `t, lpaf = sound_pressure_level_history(sig, fs)` |
| `detect_onsets` | `function` | **Detect LpAF onsets: start/end points, level difference and least-squares onset rate (ISO/PAS 1996-3 Clause 4, procedures a–d).**<br>• `levels`: LpAF [dB], `dt` [s]<br>• `onset_rate_method`: 'least_squares' / 'upper_half' | `onsets = detect_onsets(lpaf, 0.02)` |
| `ImpulsiveSoundResult` | `dataclass` | **Objective impulsive-sound verdict (ISO/PAS 1996-3).**<br>• `times` [s], `levels`: LpAF [dB], `dt` [s]<br>• `onsets`: detected `ImpulseOnset`s<br>• `prominence`: governing P, `adjustment`: KI [dB]<br>• `category`: 'not impulsive' / 'regular impulsive' / 'highly impulsive'<br>• `laeq`, `adjusted_laeq` [dB]<br>• `.governing_onset`, `.plot()` | `r.adjustment, r.category` |
| `ImpulseOnset` | `dataclass` | **A single detected LpAF onset (ISO/PAS 1996-3 Clause 3).**<br>• `index_start`/`index_end`, `time_start`/`time_end` [s]<br>• `level_start`/`level_end` [dB]<br>• `level_difference`: LD = Le − Ls [dB]<br>• `onset_rate`: OR [dB/s]<br>• `prominence`: P, `qualifies`: OR > 10 dB/s | `o.onset_rate, o.level_difference` |
| `ImpulsiveSoundWarning` | `warning class` | **ISO/PAS 1996-3 advisory.**<br>Emitted when no onset with a gradient above 10 dB/s is found (adjustment is 0 dB) | `warnings.simplefilter('error', ImpulsiveSoundWarning)` |
| `multiple_shock_assessment` | `function` | **Full multiple-shock assessment from seat acceleration (ISO 2631-5:2018).**<br>• `acceleration`: vertical seat az(t) [m/s²], `fs` [Hz]<br>• `start_age`: years, `years`: exposure years, `days_per_year`<br>• `exposure_time` / `measurement_time`: scale Dz to a daily dose (Default: None)<br>• `sex`: 'male'/'female' (Default: 'male')<br>• `mz`: MPa per m/s² (Default: sex-specific) | `res = multiple_shock_assessment(az, fs, start_age=25, years=30, days_per_year=220)`<br><br>• `MultipleShockResult` |
| `seat_to_spine_transfer` | `function` | **Seat-to-spine transfer function H(ω) (clause 5.2 Formula 1).**<br>• `frequencies` [Hz] | `H = seat_to_spine_transfer(freqs)`<br><br>• Complex response; unity at 0 Hz |
| `spinal_response` | `function` | **Vertical spinal response Az(t) (Formula 2).**<br>• `acceleration`: seat az(t) [m/s²]<br>• `fs` [Hz] | `Az = spinal_response(az, fs)`<br><br>• Same length as the input [m/s²] |
| `response_peaks` | `function` | **Positive response peaks Az,i (clause 5.3).**<br>• `response`: Az(t) | `peaks = response_peaks(Az)`<br><br>• Maxima between zero crossings [m/s²] |
| `dose_from_peaks` | `function` | **Acceleration dose Dz from peaks (Formula 3).**<br>• `peaks`: Az,i [m/s²] | `dz = dose_from_peaks(peaks)`<br><br>• Dz = 1.07 (Σ Az,i⁶)^(1/6) [m/s²] |
| `acceleration_dose` | `function` | **Acceleration dose Dz from a time history (Formulas 2 + 3).**<br>• `acceleration`: seat az(t) [m/s²], `fs` [Hz] | `dz = acceleration_dose(az, fs)`<br><br>• Dz [m/s²] |
| `daily_dose` | `function` | **Daily dose Dzd (Formula 4).**<br>• `dose`: Dz [m/s²]<br>• `exposure_time` td / `measurement_time` tm: same unit | `daily_dose(4.0, 8.0, 2.0)  # 5.04`<br><br>• Dz (td/tm)^(1/6) [m/s²] |
| `daily_dose_multi` | `function` | **Daily dose from several exposure conditions (Formula 5).**<br>• `doses`: Dz,j [m/s²]<br>• `exposure_times` / `measurement_times`: per condition | `dzd = daily_dose_multi(dz, td, tm)`<br><br>• [Σ Dz,j⁶ (td,j/tm,j)]^(1/6) [m/s²] |
| `compression_dose` | `function` | **Daily compressive stress Sd (Annex C Formula C.1).**<br>• `daily_dose_value`: Dzd [m/s²]<br>• `mz`: MPa per m/s² (Default: 0.029, 82 kg male) | `compression_dose(5.0)  # 0.145`<br><br>• Sd = mz·Dzd [MPa] |
| `static_stress` | `function` | **Static compressive stress Sstat = mz·9.81 (Annex C).**<br>• `mz` (Default: 0.029) | `static_stress()  # 0.284`<br><br>• [MPa] |
| `ultimate_strength` | `function` | **Ultimate lumbar strength Su at an age (Formula C.4).**<br>• `age`: years<br>• `sex`: 'male'/'female' (Default: 'male') | `ultimate_strength(45.0)  # 4.41`<br><br>• 6.75 − Sage·age [MPa] |
| `injury_risk` | `function` | **Cumulative injury stress variable R (Formula C.3).**<br>• `daily_compression`: Sd [MPa]<br>• `start_age`, `years`, `days_per_year`<br>• `sex`, `mz` | `R = injury_risk(0.5, start_age=25, years=30, days_per_year=220)  # 0.509` |
| `injury_probability` | `function` | **Probability of lumbar injury P(R) (Formula C.5, Weibull).**<br>• `risk`: R<br>• `sex` (Default: 'male') | `injury_probability(0.509)  # 0.0389`<br><br>• 1 − exp(−(R/α)^β) in 0–1 |
| `MultipleShockResult` | `dataclass` | **Multiple-shock health assessment.**<br>• `acceleration_dose` Dz, `daily_dose` Dzd [m/s²]<br>• `compression_dose` Sd [MPa]<br>• `risk` R, `probability` P(R)<br>• `sex`, `start_age`, `years`, `days_per_year`<br>• `peaks` [m/s²], `risk_thresholds`: R at 10/50/90 % (Table C.2)<br>• `.plot()` | `res.risk, res.probability` |
| `object_fraction` | `function` | **Object fraction ψ of an enclosed space (EN 12354-6 Formula 3).**<br>• `object_volumes` [m³]<br>• `volume`: empty space V [m³] | `object_fraction([12.0, 8.0], 500.0)  # 0.04` |
| `hard_object_absorption` | `function` | **Equivalent absorption area of a hard object (Formula 4).**<br>• `object_volume`: Vobj [m³] | `hard_object_absorption(8.0)  # 4.0`<br><br>• Aobj = Vobj^(2/3) [m²] |
| `air_absorption_area` | `function` | **Equivalent absorption area of the air (Formula 2).**<br>• `m`: power attenuation of air [Np/m]<br>• `volume` V [m³]<br>• `object_fraction` ψ (Default: 0.0) | `air_absorption_area(0.001, 500.0)  # 2.0`<br><br>• Aair = 4mV(1 − ψ) [m²] |
| `equivalent_absorption_area` | `function` | **Total equivalent sound absorption area (Formula 1).**<br>• `surfaces`: sequence of (area, absorption_coefficient) pairs (coefficient scalar or per band)<br>• `objects`: object areas Aobj [m²] (Default: ())<br>• `air_area`: Aair [m²] (Default: 0.0) | `A = equivalent_absorption_area([(100.0, 0.03), (50.0, 0.6)], objects=[4.0], air_area=2.0)  # 39.0` |
| `reverberation_time` | `function` | **Reverberation time from the absorption area (Formula 5).**<br>• `absorption_area` A [m²]<br>• `volume` V [m³]<br>• `object_fraction` ψ (Default: 0.0)<br>• `speed_of_sound` c0 [m/s] (Default: 345.6 → factor 0.16) | `reverberation_time(39.0, 500.0)  # 2.05`<br><br>• T = 55.3/c0 · V(1 − ψ)/A [s] |
| `enclosed_space_reverberation` | `function` | **Predicted A and T per octave band (EN 12354-6 Clause 4).**<br>• `surfaces`: (area, per-band α) pairs<br>• `volume` V [m³]<br>• `objects` [m²], `object_fraction` ψ<br>• `air_condition`: air-attenuation key, e.g. '20C_50-70' (Default: None → neglect air)<br>• `frequencies` [Hz] (Default: 125–8000 Hz octaves)<br>• `speed_of_sound` [m/s] | `res = enclosed_space_reverberation(surfaces, 500.0, air_condition="20C_50-70")`<br><br>• `ReverberationResult` |
| `ReverberationResult` | `dataclass` | **Enclosed-space absorption result.**<br>• `frequencies` [Hz]<br>• `absorption_area`: A per band [m²]<br>• `reverberation_time`: T per band [s]<br>• `volume` [m³], `object_fraction`<br>• `.plot()` | `res.absorption_area, res.reverberation_time` |
| `sabine_reverberation_time` / `eyring_reverberation_time` / `millington_sette_reverberation_time` | `function` | **Statistical RT prediction (T = k·V/(term + 4mV), k = 24 ln10 / c0).**<br>• `volume` V [m³]<br>• `surfaces`: (area, α) pairs (α scalar or per band)<br>• `air_attenuation`: m [Np/m] (Default: 0.0; see `air_attenuation_m`)<br>• `speed_of_sound` (Default: 343 → k = 0.161)<br>Term: Sabine ΣSᵢαᵢ · Eyring −S·ln(1−ᾱ) · Millington −ΣSᵢln(1−αᵢ) | `eyring_reverberation_time(120.0, [(40,0.2),(40,0.2),(24,0.2),(24,0.2),(15,0.2),(15,0.2)])  # 0.548 s` |
| `fitzroy_reverberation_time` / `arau_puchades_reverberation_time` | `function` | **Anisotropic RT prediction for a shoebox room.**<br>• `dimensions`: (Lx, Ly, Lz) [m]<br>• `absorptions`: mean α of the (x, y, z) wall pairs (scalar or per band)<br>• `air_attenuation` [Np/m], `speed_of_sound`<br>Fitzroy = area-weighted arithmetic mean of the three axial Eyring times; Arau-Puchades = geometric mean (Acustica 65, 1988) | `arau_puchades_reverberation_time((8,5,3), (0.5,0.1,0.1))  # 0.812 s` |
| `mean_absorption` | `function` | **Area-weighted mean absorption ᾱ = ΣSᵢαᵢ / ΣSᵢ.**<br>• `surfaces`: (area, α) pairs | `mean_absorption([(90.0, 0.1), (10.0, 0.9)])  # 0.18` |
| `reverberation_time_models` | `function` | **All five RT models for a shoebox room, per band.**<br>• `dimensions` (Lx, Ly, Lz) [m]<br>• `absorptions`: (αx, αy, αz) wall-pair means (scalar or per band)<br>• `air_attenuation` [Np/m], `frequencies` [Hz], `speed_of_sound` | `res = reverberation_time_models((10,7,3.5), (ax, ay, az), frequencies=f)`<br><br>• `ReverberationModelResult` |
| `ReverberationModelResult` | `dataclass` | **Five-model RT comparison.**<br>• `frequencies` [Hz]<br>• `sabine`/`eyring`/`millington_sette`/`fitzroy`/`arau_puchades`: T per band [s]<br>• `volume` [m³], `surface_area` [m²]<br>• `.models`: dict keyed by name<br>• `.plot()` | `res.arau_puchades, res.models['Fitzroy']` |
| `apparent_dynamic_stiffness` | `function` | **Apparent dynamic stiffness s't (EN 29052-1 Formula 4).**<br>• `resonant_frequency` fr [Hz] (scalar/array)<br>• `total_mass_per_area` m't [kg/m²]<br>s't = 4π²·m't·fr² [N/m³] | `apparent_dynamic_stiffness(25.0, 200.0)  # 4.935e6 N/m³` |
| `enclosed_gas_stiffness` | `function` | **Enclosed-gas dynamic stiffness s'a (EN 29052-1 Formula 7).**<br>• `thickness` d [m]<br>• `porosity` ε (0-1)<br>• `atmospheric_pressure` p₀ [Pa] (Default: 1e5 = 0,1 MPa)<br>s'a = p₀/(d·ε); NOTE ≈ 111/d MN/m³ (d in mm) | `enclosed_gas_stiffness(0.020, 0.9)  # 5.56e6 N/m³` |
| `installed_dynamic_stiffness` | `function` | **Installed s' by airflow resistivity (EN 29052-1 clause 8.2).**<br>• `apparent_stiffness` s't [N/m³]<br>• `airflow_resistivity` r [kPa·s/m²]<br>• `gas_stiffness` s'a [N/m³]<br>r≥100 → s't · 10≤r<100 → s't+s'a · r<10 → s't if s'a negligible else nan (warns) | `installed_dynamic_stiffness(20e6, 50.0, gas_stiffness=3e6)  # 23e6` |
| `natural_frequency` | `function` | **Floating-floor natural frequency f0 (EN 29052-1 Formula 2).**<br>• `dynamic_stiffness` s' [N/m³] (scalar/array)<br>• `mass_per_area` m' [kg/m²]<br>f0 = (1/2π)√(s'/m') | `natural_frequency(10e6, 120.0)  # 45.9 Hz` |
| `floating_floor_resonance` | `function` | **Full EN 29052-1 chain → result.**<br>• `resonant_frequency`, `total_mass_per_area`, `floor_mass_per_area`<br>• `airflow_resistivity` (Default: inf), `thickness`, `porosity`, `atmospheric_pressure` | `res = floating_floor_resonance(25.0, 200.0, 120.0)`<br><br>• `DynamicStiffnessResult` |
| `DynamicStiffnessResult` | `dataclass` | **Dynamic-stiffness measurement result.**<br>• `apparent_stiffness`/`gas_stiffness`/`dynamic_stiffness` [N/m³]<br>• `resonant_frequency` [Hz], `floor_mass_per_area` [kg/m²]<br>• `natural_frequency` [Hz]<br>• `.plot()` | `res.dynamic_stiffness, res.natural_frequency` |
| `DynamicStiffnessWarning` | `warning class` | **EN 29052-1 advisory.**<br>Emitted when the enclosed-gas term makes s′ unresolvable (clause 8.2) | `warnings.simplefilter('error', DynamicStiffnessWarning)` |
| `convert_frf` | `function` | **Convert between any two FRFs (ISO 7626-1 Table 1).**<br>• `value`: complex FRF value(s) of kind *source*<br>• `frequency` f [Hz] (scalar/array, broadcast)<br>• `source`/`target`: `receptance`/`mobility`/`accelerance`/`dynamic_stiffness`/`impedance`/`apparent_mass`<br>Pivots through the receptance H | `convert_frf(2e-3, 80.0, "mobility", "impedance")  # 500 N.s/m` |
| `FRF_UNITS` | `mapping` | **SI unit per FRF form (ISO 7626-1 Table 1, read-only).**<br>Keyed by `'receptance'`, `'mobility'`, `'accelerance'`, ... | `FRF_UNITS['mobility']  # 'm/(N·s)'` |
| `sdof_receptance` / `sdof_mobility` / `sdof_accelerance` | `function` | **Closed-form SDOF resonator FRFs (ISO 7626-1 Table 1 / 3.1.2 definitions).**<br>• `frequency` f [Hz] (scalar/array)<br>• `mass` m [kg], `stiffness` k [N/m], `damping` c [N·s/m]<br>H = 1/(k − ω²m + jωc); Y = jωH; A = −ω²H | `sdof_mobility(10.07, 2.0, 8000.0, 5.0)  # |Y|=1/c on resonance` |
| `resonance_frequency` | `function` | **Undamped SDOF natural frequency (closed form).**<br>• `mass` m [kg], `stiffness` k [N/m]<br>f0 = (1/2π)√(k/m) | `resonance_frequency(2.0, 8000.0)  # 10.07 Hz` |
| `rigid_mass_calibration_check` | `function` | **Operational rigid-mass calibration (ISO 7626-2 7.5.2).**<br>• `frf`: measured FRF (complex or magnitude)<br>• `frequencies` [Hz], `mass` m [kg]<br>• `quantity`: 'accelerance' (\|A\| = 1/m) / 'mobility' (\|Y\| = 1/(ωm))<br>• `tolerance` (Default: 0.05 = ±5 %) | `res = rigid_mass_calibration_check(frf, f, 10.0)`<br><br>• `RigidMassCalibrationResult` |
| `RigidMassCalibrationResult` | `dataclass` | **Rigid-mass calibration verdict (ISO 7626-2 7.5.2).**<br>• `frequencies` [Hz], `measured`/`expected`/`deviation` per band<br>• `within_tolerance`: per-band flags, `passed`: overall<br>• `mass` [kg], `quantity`, `tolerance` | `res.passed, res.deviation` |
| `random_error_percent` | `function` | **Normalized random error of an averaged FRF (ISO 7626-2 Annex A).**<br>• `coherence`: γ² per frequency, in (0, 1]<br>• `n_averages`: n ≥ 1<br>ε = √((1−γ²)/(2nγ²)) [%]; 8.1.3 requires < 5 % at resonances | `random_error_percent(0.8, 75)  # 4.08 %` |
| `sdof_mobility_result` | `function` | **SDOF driving-point mobility → result.**<br>• `frequency` f [Hz] (array)<br>• `mass`, `stiffness`, `damping` | `res = sdof_mobility_result(f, 2.0, 8000.0, 5.0)`<br><br>• `MobilityResult` |
| `MobilityResult` | `dataclass` | **Mobility FRF over frequency (ISO 7626-1).**<br>• `frequencies` [Hz], `mobility` Y [m/(N·s)]<br>• `driving_point`: bool (i = j)<br>• `.magnitude` / `.phase`<br>• `.to(target)`: any Table-1 kind<br>• `.plot()`: |Y(f)| with the resonance marked | `res.magnitude, res.to("impedance")` |
| `transfer_stiffness_level` / `loss_factor` | `function` | **Transfer-stiffness level & loss factor (ISO 10846-2/-3 3.17, -1 3.8).**<br>• `transfer_stiffness_level(k, reference=1.0)`: Lₖ = 20 lg(\|k\|/k₀) [dB re 1 N/m]<br>• `loss_factor(k)`: η = Im(k)/Re(k) | `transfer_stiffness_level(1e6)  # 120 dB` |
| `transfer_stiffness_direct` | `function` | **Direct method (ISO 10846-2).**<br>• `blocking_force` F₂,b [N]<br>• `input_displacement` u₁ [m]<br>k₂,₁ = F₂,b/u₁ | `transfer_stiffness_direct(5.0, 1e-6)  # 5e6 N/m` |
| `transfer_stiffness_indirect` | `function` | **Indirect method (ISO 10846-3 Formula 1).**<br>• `frequency` f [Hz] (scalar/array)<br>• `transmissibility` T = u₂/u₁ (complex)<br>• `blocking_mass` m₂ [kg]<br>• `flange_mass` m_f [kg] (Default: 0.0)<br>k₂,₁ = −(2πf)²(m₂+m_f)T; warns (`PhonometryWarning`) where \|T\| > 0.1 (Inequality 2: ΔL1,2 < 20 dB) | `transfer_stiffness_indirect(500.0, 0.01, blocking_mass=10.0)` |
| `TRANSMISSIBILITY_LIMIT` | `float` | **Indirect-method validity limit (ISO 10846-3 6.1, Inequality 2).**<br>0.1: \|T\| ≤ 0.1 ⇔ ΔL1,2 ≥ 20 dB keeps Formula (1) within 1 dB (12 %) | `TRANSMISSIBILITY_LIMIT  # 0.1` |
| `REFERENCE_STIFFNESS` | `float` | **Reference stiffness k0 for the level Lk [N/m] (ISO 10846-2/-3, 3.17).**<br>1.0 | `REFERENCE_STIFFNESS  # 1.0` |
| `blocking_force_ratio` | `function` | **Delivered/blocking force ratio (ISO 10846-1 Eq. 6).**<br>• `driving_point_stiffness` k₂,₂ [N/m] (complex)<br>• `termination_stiffness` k_t [N/m] (complex, non-zero)<br>F₂/F₂,b = 1/(1 + k₂,₂/k_t); within 10 % of 1 for \|k₂,₂\| < 0.1\|k_t\| | `blocking_force_ratio(1e5, 1e6)  # 0.909` |
| `base_transmissibility` | `function` | **Mass-loaded Kelvin-Voigt transmissibility (model).**<br>• `frequency` f [Hz]<br>• `mass` m [kg], `stiffness` k [N/m], `damping` c [N·s/m] (Default: 0.0)<br>T = (k+jωc)/(k−ω²m+jωc) | `base_transmissibility(f, 8.0, 1e6, 120.0)` |
| `indirect_transfer_stiffness_result` | `function` | **Indirect-method sweep → result.**<br>• `frequency` f [Hz] (array)<br>• `transmissibility` T (complex)<br>• `blocking_mass` m₂ [kg], `flange_mass` (Default: 0.0) | `res = indirect_transfer_stiffness_result(f, t, 8.0)`<br><br>• `TransferStiffnessResult` |
| `TransferStiffnessResult` | `dataclass` | **Dynamic transfer stiffness over frequency (ISO 10846).**<br>• `frequencies` [Hz], `transfer_stiffness` k₂,₁ [N/m]<br>• `blocking_mass` m₂ [kg] or None<br>• `.magnitude` / `.level` (dB re 1 N/m) / `.loss_factor`<br>• `.to(target)`: "impedance"/"apparent_mass"<br>• `.plot()`: Lₖ(f) | `res.level, res.loss_factor` |
| `infinite_plate_impedance` / `infinite_plate_mobility` / `infinite_plate_point_mobility` | `function` | **Thin-plate point mobility Z = C√(B'm'') (Cremer Table 5.1).**<br>• `bending_stiffness` B' [N·m], `mass_per_area` m'' [kg/m²]<br>• `location`: 'centre' (C=8) / 'edge' (C=3.5); real, frequency-independent | `infinite_plate_impedance(1e4, 10)`<br><br>• float or `MobilityResult` |
| `infinite_beam_mobility` / `infinite_beam_impedance` / `infinite_beam_moment_mobility` / `infinite_beam_point_mobility` | `function` | **Slender-beam point mobility Y = (1−j)/(4m'cB) (Cremer Table 5.1).**<br>• `frequency` [Hz], `bending_stiffness` B [N·m²], `mass_per_length` m' [kg/m]<br>• `location`: 'centre'/'end'; 45°, ∝ ω^−½ | `infinite_beam_mobility(100, 200, 5)`<br><br>• complex or `MobilityResult` |
| `longitudinal_rod_impedance` / `injected_power` / `plate_bending_stiffness` | `function` | **Rod point impedance ρcₗS; injected power W = ½\|F\|²Re{Y} (Cremer 5.23); plate B' = Eh³/12(1−ν²).** | `injected_power(10.0, y)` |
| `radiation_efficiency` / `coincidence_frequency` | `function` | **Plate radiation efficiency σ(f) (Hopkins 2.9, Leppington/Maidanik).**<br>• `frequency` [Hz], `length_x`/`length_y` [m], `critical_frequency` fc [Hz]<br>• `boundary`: 'simply_supported'/'clamped', `baffle`: 'infinite'/'perpendicular'<br>• σ → 1 above fc; fc = (c₀²/2π)√(m''/B') | `radiation_efficiency(f, 1.5, 1.25, 2100)`<br><br>• `RadiationEfficiencyResult` |
| `RadiationEfficiencyResult` | `dataclass` | **Plate radiation efficiency over frequency (Hopkins 2.9.4).**<br>• `radiation_efficiency` σ, `radiation_index` 10 lg σ [dB]<br>• `critical_frequency` fc, `.plot()`; feeds `sound_power_from_vibration` as ε | `res.radiation_efficiency` |
| `junction_transmission` | `function` | **Bending-wave transmission of a rigid plate junction (Hopkins 5.2.1.3, Cremer 1973, Craik 1981/1996).**<br>• `junction`: 'X'/'T1'/'T2'/'L'<br>• two plates' `thickness` h, `wave_speed` cL, `surface_density` ρs<br>• `angles_deg` grid (Default: 0–90°) | `junction_transmission('X', 0.1, 3200, 240, 0.1, 3200, 240)`<br><br>• `JunctionTransmissionResult` |
| `JunctionTransmissionResult` | `dataclass` | **Angle-resolved bending-wave transmission at a rigid junction (Hopkins 5.2.1.3).**<br>• `chi`, `psi`, `critical_frequency1`/`critical_frequency2` fc [Hz], `angles_deg`, `corner` τ12(θ), `straight` τ13(θ) or None<br>• `corner_average`/`straight_average` (Eq. 5.6), `corner_reduction_index` Kij (symmetric), `.plot()` | `res.corner_average  # 1/12 for identical X` |
| `junction_wave_parameters` | `function` | **Wave parameters χ, ψ of a plate pair (Hopkins 5.10/5.11).**<br>• two plates' h [m], cL [m/s], ρs [kg/m²]<br>• χ = √(h₁cL₁/h₂cL₂) = √(fc₂/fc₁), ψ = h₂cL₂ρs₂/(h₁cL₁ρs₁) | `junction_wave_parameters(0.1, 3200, 240, 0.2, 3200, 480)  # (√0.5, 4)` |
| `corner_transmission_coefficient` / `straight_transmission_coefficient` | `function` | **τ12(θ) around a corner (Hopkins 5.12) / τ13(θ) across a straight section (5.13).**<br>• `angle` θ [rad], `chi`, `psi`, `junction`<br>• corner is 0 for χ < sinθ; straight only for 'X'/'T1' | `corner_transmission_coefficient(0.0, 1.0, 1.0, 'X')  # 1/8` |
| `inline_transmission_coefficient` | `function` | **Normal-incidence transmission across an in-line junction (Hopkins 5.14, Cremer 1973).**<br>• `chi`, `psi`; τ = 1 for identical plates | `inline_transmission_coefficient(1.0, 1.0)  # 1.0` |
| `angular_average_transmission_coefficient` | `function` | **Diffuse-field angular average ∫₀^{π/2} τ(θ)cosθ dθ (Hopkins 5.6).**<br>• `chi`, `psi`, `junction`, `section`: 'corner'/'straight' | `angular_average_transmission_coefficient(1.0, 1.0, 'X')  # 1/12` |
| `coupling_loss_factor` | `function` | **SEA coupling loss factor from τ (Hopkins 2.154).**<br>• `transmission_coefficient` τ, `group_velocity` cg [m/s]<br>• `junction_length` L [m], `frequency` f [Hz], `plate_area` S [m²]<br> η = cg·L·τ/(2π²fS) | `coupling_loss_factor(1/12, 200, 4, 500, 10)` |
| `wave_vibration_reduction_index` | `function` | **Wave-approach vibration reduction index Kij (Hopkins 5.116).**<br>• `transmission_coefficient` τ, `critical_frequency_receiver` fc_j [Hz]<br>Kij = 10 lg(1/τ) + 5 lg(fc_j/f_ref), f_ref = 1000 Hz (symmetric: Kij = Kji) | `wave_vibration_reduction_index(1/12, 1000.0)  # 10.8 dB` |
| `velocity_level` / `velocity_level_from_acceleration` | `function` | **Vibratory velocity level (ISO/TS 7849-1 Eq. 3/8).**<br>• `velocity_level(v, reference=5e-8)`: 20 lg(v/v₀) [dB]<br>• `velocity_level_from_acceleration(a_peak, f)`: 20 lg(â/(2πf·v₀·√2)) (sinusoidal calibration) | `velocity_level_from_acceleration(9.81, 100.0)  # 106.9 dB` |
| `REFERENCE_VELOCITY` | `float` | **Reference velocity v0 [m/s] (ISO/TS 7849-1).**<br>5e-8 | `REFERENCE_VELOCITY  # 5e-08` |
| `NORMALIZED_IMPEDANCE` | `float` | **Normalized characteristic impedance Zc,n of air [N·s/m³] (23 °C, 101,3 kPa).**<br>411.0 | `NORMALIZED_IMPEDANCE  # 411.0` |
| `mean_velocity_level` | `function` | **Mean surface velocity level (ISO/TS 7849-1 Eq. 10/11).**<br>• `levels` L_v,i [dB]<br>• `areas` S_i (Eq. 11) or None → energetic mean (Eq. 10) | `mean_velocity_level([60, 66, 63])` |
| `radiation_factor` | `function` | **A-weighted radiation factor ε (ISO/TS 7849 Eq. 4/8).**<br>• `sound_power` P [W], `area` S [m²]<br>• `mean_square_velocity` ⟨v²⟩ [(m/s)²]<br>• `impedance` Z_c (Default: 411 N·s/m³)<br>ε = P/(Z_c·⟨v²⟩·S) | `radiation_factor(3e-4, 2.0, 1e-6)  # 0.365` |
| `radiated_sound_power_level` | `function` | **Sound power level from vibration (ISO/TS 7849-1 Eq. 12, -2 Eq. 15).**<br>• `velocity_level` L_v [dB]<br>• `area` S [m²]<br>• `radiation_factor` ε (Default: 1.0 → Part 1 upper limit)<br>L_W = L_v + 10 lg(S/S₀) + 10 lg(ε) + 10 lg(411/400) | `radiated_sound_power_level(80.0, 1.6)` |
| `extraneous_velocity_correction` | `function` | **Correction K1A for extraneous vibration (ISO/TS 7849-1 Table 2).**<br>• `level_difference` ΔLv [dB]; ΔLv≥10→0, ΔLv<3→3 | `extraneous_velocity_correction(6.0)  # 1.0 dB` |
| `sound_power_from_vibration` | `function` | **Bundle a vibration → power determination.**<br>• `velocity_level` L_v per band [dB]<br>• `area` S [m²], `radiation_factor` ε (Default: 1.0)<br>• `frequencies` [Hz] or None | `res = sound_power_from_vibration(lv, 1.6, radiation_factor=eps, frequencies=f)`<br><br>• `VibrationSoundPowerResult` |
| `VibrationSoundPowerResult` | `dataclass` | **Sound power radiated by surface vibration (ISO/TS 7849).**<br>• `velocity_level` / `sound_power_level` / `radiation_factor` per band<br>• `area` S [m²], `frequencies` [Hz] or None<br>• `.total_level`: band-summed L_W [dB]<br>• `.plot()` | `res.sound_power_level, res.total_level` |
| `spatial_mean_velocity_level` / `plate_loss_factor` | `function` | **Reception-plate helpers (EN 15657 Formula 12/13).**<br>• `spatial_mean_velocity_level(levels)`: 10 lg(mean 10^(Lv,i/10)) [dB]<br>• `plate_loss_factor(f, Ts)`: η = 2.2/(f·Ts) | `spatial_mean_velocity_level([78, 80, 82])` |
| `mean_free_velocity_level` | `function` | **Mean free velocity level (ISO 9611:1996 eq. (9)).**<br>• `levels`: free-velocity levels at the N contact points [dB re 5e-8 m/s]<br>Energy mean over positions | `mean_free_velocity_level([70, 72, 74])  # 72.3 dB` |
| `structure_borne_power_level` | `function` | **Reception-plate injected power level (EN 15657 Formula 14).**<br>• `velocity_level` L_v [dB re 1e-9 m/s]<br>• `frequency` f [Hz], `mass_per_area` m [kg/m²], `area` S [m²]<br>• `loss_factor` η > 0<br>L_Ws = 10 lg(2πfηmS) + L_v − 60 (plate-specific; convert via Formulae 15/17 before EN 12354-5) | `structure_borne_power_level(80, 1000, 10, 1, 0.01)  # 47.98 dB` |
| `equivalent_blocked_force_level` / `characteristic_reception_plate_power` | `function` | **Source quantities (EN 15657 Formulae 15/17).**<br>• `equivalent_blocked_force_level(L_Ws_low, Y_plate)`: L_Fb,eq = L_Ws − 10 lg(Re Y/Y0) [dB re 1e-6 N]<br>• `characteristic_reception_plate_power(L_Fb,eq)`: L_Wsn = L_Fb,eq + 10 lg(Y_R,∞,low/Y0), Y_R,∞,low = 5e-6 m/(N·s) | `lwsn = characteristic_reception_plate_power(equivalent_blocked_force_level(61.7, 5.34e-6))` |
| `equivalent_free_velocity_level` / `source_mobility_from_levels` | `function` | **Source quantities (EN 15657 Formulae 18/19).**<br>• `equivalent_free_velocity_level(L_Ws_high, Y_plate)`: L_vf,eq [dB re 1e-9 m/s]<br>• `source_mobility_from_levels(L_vf,eq, L_Fb,eq)`: \|Y_S,eq\| [m/(N·s)] | `y_s = source_mobility_from_levels(lvf, lfb)` |
| `reception_plate_power` | `function` | **Reception-plate determination → result (EN 15657 clause 7).**<br>• `velocity_level` L_v (per band), `frequency` [Hz]<br>• `mass_per_area`, `area`<br>• `loss_factor` η **or** `reverberation_time` Ts | `res = reception_plate_power(lv, f, 600, 2.0, reverberation_time=0.8)`<br><br>• `StructureBornePowerResult` |
| `StructureBornePowerResult` | `dataclass` | **Reception-plate injected structure-borne power (EN 15657).**<br>• `power_level` L_Ws / `velocity_level` / `loss_factor` per band<br>• `mass_per_area`, `area`, `frequencies` [Hz] or None<br>• `.total_level`: band-summed L_Ws [dB]<br>• `.plot()` | `res.power_level, res.total_level` |
| `coupling_term` / `coupling_term_force_source` / `coupling_term_velocity_source` | `function` | **Coupling term D_C (EN 12354-5 Formula 19b/c/d).**<br>• `coupling_term(Ys, Yi, transfer_mobility=0)`: 10 lg(\|Ys+Yi+Yk\|²/(\|Ys\|·Re Yi))<br>• force source: 10 lg(\|Ys\|/Re Yi)<br>• velocity source: −10 lg(\|Ys\|·Re Zi) | `coupling_term(2e-4+1e-4j, 3e-5+1e-5j)` |
| `installed_structure_borne_power_level` | `function` | **Installed power (EN 12354-5 Formula 18b).**<br>• `characteristic_power_level` L_Ws,c [dB] (the converted EN 15657 level, not the raw Formula 14 plate power)<br>• `coupling_term` D_C [dB]<br>L_Ws,inst = L_Ws,c − D_C | `installed_structure_borne_power_level(82.0, 8.5)` |
| `installed_power_from_reception_plate` | `function` | **Annex I mobility correction (EN 12354-5).**<br>• `reception_plate_level` L_Ws,n [dB]<br>• `receiver_mobility` Y_∞,i [m/(N·s)]<br>• `plate_mobility` Y_∞,rec (Default: 5e-6)<br>L_Ws,inst = L_Ws,n + 10 lg(Y_∞,i/Y_∞,rec); with the source mobility it yields L_Ws,c | `installed_power_from_reception_plate(67.6, 1.25e-6)  # -6 dB` |
| `structure_borne_pressure_level_path` / `total_structure_borne_pressure_level` | `function` | **Path & total normalised SPL (EN 12354-5 Formula 18a/17).**<br>• path: L_Ws,inst − D_sa − R_ij,ref − 10 lg(S/S0) − 10 lg(A0/4)<br>• total: 10 lg(Σ 10^(L/10)) over paths (axis 0) | `total_structure_borne_pressure_level(path_levels)` |
| `REFERENCE_AREA` | `float` | **Reference area S0 = A0 [m²] (EN 12354-5 Formula 18a).**<br>10.0 | `REFERENCE_AREA  # 10.0` |
| `installed_source_prediction` | `function` | **Full installed-source prediction → result (EN 12354-5).**<br>• `characteristic_power_level` L_Ws,c, `coupling_term` D_C<br>• `paths`: dicts with `adjustment_term`, `flanking_reduction_index`, `element_area`<br>• `frequencies` [Hz] or None | `res = installed_source_prediction(lwc, dc, paths, frequencies=f)`<br><br>• `InstalledSourceResult` |
| `InstalledSourceResult` | `dataclass` | **Installed structure-borne sound prediction (EN 12354-5).**<br>• `path_levels` (paths×bands), `total_level` L_n,s per band<br>• `installed_power_level` per band, `frequencies` [Hz] or None<br>• `.overall_level`: band-summed total [dB]<br>• `.plot()`: the cascade | `res.total_level, res.overall_level` |
| `combine_uncertainty` | `function` | **GUM law of propagation of uncertainty (ISO/IEC Guide 98-3 clause 5).**<br>• `model`: measurement function f(x1…xN)<br>• `quantities`: input `Quantity` objects, in argument order<br>• `correlation`: optional N×N matrix r_ij (Default: None → uncorrelated; non-identity with finite input dof → effective dof undefined, `expanded()` needs `coverage_factor_override`) | `u = combine_uncertainty(lambda a, b: a*b, [Quantity(10.0, 0.1), Quantity(5.0, 0.2)])`<br><br>• `UncertaintyResult`; uc = 2.062 |
| `monte_carlo` | `function` | **Monte Carlo propagation (Guide 98-3-1, Supplement 1).**<br>• `model`: vectorised f(x1…xN)<br>• `quantities`: input `Quantity` objects<br>• `trials`: M ≥ 2 (Default: 1000000; fixed, no adaptive 7.9)<br>• `coverage`: interval probability (Default: 0.95)<br>• `seed`: reproducibility (Default: None)<br>• inputs sampled independently (no 6.4.8 multivariate path) | `mc = monte_carlo(model, quantities, seed=1)`<br><br>• `MonteCarloResult` (mean, u, coverage interval) |
| `rectangular` | `function` | **Type B quantity, rectangular PDF (GUM 4.3.7).**<br>• `value`, `half_width` a, `name` | `rectangular(20.0, 0.5)`<br><br>• `Quantity` with u = a/√3 = 0.289 |
| `triangular` | `function` | **Type B quantity, triangular PDF (GUM 4.3.9).**<br>• `value`, `half_width` a, `name` | `triangular(20.0, 0.5)`<br><br>• `Quantity` with u = a/√6 |
| `u_shaped` | `function` | **Type B quantity, U-shaped (arcsine) PDF.**<br>• `value`, `half_width` a, `name` | `u_shaped(20.0, 0.5)`<br><br>• `Quantity` with u = a/√2 |
| `Quantity` | `dataclass` | **Input quantity of a measurement model (GUM clause 4).**<br>• `value`: estimate xi<br>• `uncertainty`: u(xi) ≥ 0<br>• `distribution`: 'gaussian'/'rectangular'/'triangular'/'u-shaped' (Default: 'gaussian')<br>• `dof`: degrees of freedom (Default: inf)<br>• `name`: budget label | `Quantity(94.0, 0.3, name="calibrator")` |
| `UncertaintyResult` | `dataclass` | **GUM propagation result.**<br>• `value`: y = f(x1…xN)<br>• `combined_uncertainty`: uc(y)<br>• `sensitivities`: ci = ∂f/∂xi<br>• `contributions`: \|ci\|·u(xi)<br>• `effective_dof`: Welch–Satterthwaite<br>• `names`<br>• `.plot()`: uncertainty budget | `u.combined_uncertainty, u.contributions` |
| `MonteCarloResult` | `dataclass` | **Monte Carlo result.**<br>• `value`: sample mean<br>• `standard_uncertainty`: sample std<br>• `interval`: (low, high) coverage interval (§7.7)<br>• `coverage`, `trials` | `mc.value, mc.interval` |
| `UncertaintyWarning` | `warning class` | **GUM propagation advisory.**<br>Emitted when a propagation falls back outside its nominal assumptions | `warnings.simplefilter('error', UncertaintyWarning)` |
| `trend_test` | `function` | **Nonparametric trend test on a sequence (Bendat & Piersol 4.5.2).**<br>• `values`: ≥ 10 observations or estimates<br>• `method`: 'reverse_arrangements' (Default; Table A.6 acceptance regions, exact Mahonian p-value to N = 100) / 'runs' (about the median, exact Wald–Wolfowitz distribution; median ties discarded)<br>• `alpha`: two-sided significance (Default: 0.05) | `res = trend_test(values)`<br><br>• `TrendTestResult`; B&P Example 4.4: A = 86, accepted in (64, 125] |
| `TrendTestResult` | `dataclass` | **Trend-test verdict.**<br>• `statistic`: reverse arrangements A or runs r<br>• `bounds`: acceptance region (lower, upper], `p_value`, `trend_free`<br>• `mean`, `std`: null moments (Eqs. 4.54–4.55)<br>• `values`, `method`, `n`, `alpha`, `median` (runs-classification median)<br>• `.plot()`: tested sequence with the verdict | `res.statistic, res.bounds, res.trend_free` |
| `stationarity_test` | `function` | **Stationarity test on segment statistics (Bendat & Piersol 10.3.1.1).**<br>• `x`, `fs`<br>• `n_segments` (Default: 20, as B&P Example 10.3), `statistic`: 'mean_square' (Default) / 'rms' / 'mean' / 'variance'<br>• `method`, `alpha` as `trend_test`<br>Trailing samples beyond equal segments are discarded | `res = stationarity_test(x, fs)`<br><br>• `StationarityTestResult` |
| `StationarityTestResult` | `dataclass` | **Stationarity verdict on a record.**<br>• `segment_values`, `segment_times` [s], `segment_duration` [s]<br>• `count`, `bounds`, `p_value`, `stationary`, `mean`, `std`<br>• `statistic`, `method`, `alpha`, `n_segments`, `fs`<br>• `.plot()`: segment sequence with the verdict | `res.stationary, res.segment_values` |
| `level_crossing_rate` | `function` | **Level-crossing rates vs the Rice expectation (Bendat & Piersol 5.5.1).**<br>• `x`, `fs` (mean removed first; oversample the band)<br>• `levels` [signal units] (Default: 13 levels over ±3 RMS)<br>• `nperseg`: Welch length for the spectral moments<br>Gaussian: N0 = 2√(m2/m0), Na = N0·exp(−a²/2σ²) | `res = level_crossing_rate(x, fs)`<br><br>• `LevelCrossingResult` |
| `LevelCrossingResult` | `dataclass` | **Crossing rates (both slopes).**<br>• `levels`, `rates` [1/s], `rice_rates` [1/s]<br>• `zero_crossing_rate`, `zero_crossing_rate_rice`, `apparent_frequency` [Hz] = N0/2<br>• `sigma`, `duration` [s], `fs`<br>• `.plot()`: measured dots vs the Rice curve | `res.zero_crossing_rate, res.apparent_frequency` |
| `peak_statistics` | `function` | **Peak rate, irregularity factor and peak heights (Bendat & Piersol 5.5.2–5.5.4).**<br>• `x`, `fs` (mean removed; band-limit before: m4 weights G(f) by f⁴)<br>• `nperseg`: Welch length for the moments<br>M = √(m4/m2), r = N0/2M ∈ (0, 1] | `res = peak_statistics(x, fs)`<br><br>• `PeakStatisticsResult` |
| `PeakStatisticsResult` | `dataclass` | **Peak (maxima) statistics.**<br>• `peak_rate`, `peak_rate_rice` [1/s], `zero_crossing_rate_rice`, `irregularity_factor`<br>• `peak_values`: sorted standardized heights z = a/σ<br>• `.peak_exceedance(z)` / `.peak_density(z)`: Rice mixture (Eqs. 5.217/5.223; Rayleigh at r = 1, Gaussian at r → 0)<br>• `.plot()`: empirical exceedance vs the Rice curves | `res.irregularity_factor, res.peak_exceedance(4.0)` |
| `power_spectral_density` | `function` | **Welch PSD with statistical error analysis (Bendat & Piersol Ch. 8).**<br>• `x`, `fs`<br>• `window` (Default: 'hann'), `nperseg` (Default: bin spacing of at most 4 Hz; the resolution bandwidth Be also depends on the taper ENBW), `overlap` (Default: 0.5)<br>• `scaling`: 'density' [units²/Hz] / 'spectrum' [units²]<br>• `confidence`: chi-square CI level (Default: 0.95) | `res = power_spectral_density(x, fs)`<br><br>• `SpectralDensityResult` (psd, CI, nd, ε) |
| `cross_spectral_density` | `function` | **Welch cross-spectral density with magnitude/phase errors (Eqs. 9.33/9.52).**<br>• `x`, `y`, `fs`<br>• `window`, `nperseg`, `overlap`, `scaling` as above | `res = cross_spectral_density(x, y, fs)`<br><br>• `CrossSpectralDensityResult` |
| `coherent_output_spectrum` | `function` | **Gvv = γ²·Gyy, noise remainder and spectral SNR (Eqs. 9.55–9.56, 9.73).**<br>• `x` (input), `y` (output), `fs`<br>• `window`, `nperseg`, `overlap`, `scaling` as above | `res = coherent_output_spectrum(x, y, fs)`<br><br>• `CoherentOutputSpectrumResult` |
| `fractional_octave_smoothing` | `function` | **Constant-power 1/n-octave smoothing of a spectrum.**<br>• `frequencies`, `values`<br>• `fraction`: the n of 1/n octave (Default: 3)<br>• `domain`: 'power'/'amplitude'/'db' (Default: 'power') | `s = fractional_octave_smoothing(f, psd, 3.0)`<br><br>• smoothed array, same domain; flat spectra unchanged |
| `miso_coherence` | `function` | **Multiple & partial coherence of a MISO system (Bendat & Piersol Ch. 7).**<br>• `inputs`: q input records, q ≥ 2 (sequence of 1-D arrays or a (q, n) array), `output`, `fs`<br>• `order`: conditioning order (Default: 0..q−1)<br>• `window`, `nperseg`, `overlap`, `scaling` as above | `res = miso_coherence([x1, x2], y, fs)`<br><br>• `MISOCoherenceResult` |
| `MISOCoherenceResult` | `dataclass` | **Multiple/partial coherence of q correlated inputs and one output.**<br>• `ordinary_coherence` (q×F), `multiple_coherence` γ²y:x, `partial_coherence` (q×F, conditioned per `order`)<br>• `coherent_output_spectra` Gvi (q×F, Σ Gvi + `noise_psd` = `output_psd`)<br>• `multiple_coherence_random_error` (Eq. 9.98), `coherent_output_random_error` (Eq. 9.100)<br>• `.dominant_input()`: per-band index of the strongest source<br>• `.plot()`: coherent output spectra + coherences | `res.multiple_coherence, res.dominant_input()` |
| `resolution_bias_error` | `function` | **First-order resolution bias at a resonance peak, εb ≈ −(Be/Br)²/3 (Eq. 8.141).**<br>• `resolution_bandwidth` Be [Hz]<br>• `half_power_bandwidth` Br [Hz] | `resolution_bias_error(1.0, 4.0)  # -1/48` |
| `noise_signal` | `function` | **Colored Gaussian noise with an exact power-law PSD slope.**<br>• `fs`, `seconds` (Default: 1.0)<br>• `color`: 'white'/'pink'/'red'/'blue'/'violet' (0/−3.01/−6.02/+3.01/+6.02 dB/oct)<br>• `rms` (Default: 1.0)<br>• `seed`: bit-reproducible per seed | `pink = noise_signal(48000, 10.0, color='pink', seed=7)` |
| `tone_burst` | `function` | **IEC 60268-1 tone burst (Clause A2): zero-crossing start, integral full periods.**<br>• `fs`, `frequency`, `cycles`<br>• `amplitude` (Default: 1.0)<br>• `repetitions` + `repetition_rate` [bursts/s]: repetitive train (Clause A2.2)<br>• `pre_silence`, `post_silence` [s] | `res = tone_burst(48000, 5000, 25, repetition_rate=10, repetitions=4)`<br><br>• `ToneBurstResult` |
| `resample_signal` | `function` | **Polyphase resampling with an explicit anti-alias spec (Kaiser FIR designed here).**<br>• `x`, `fs`, `fs_new` (rational ratio, e.g. 160/147)<br>• `stopband_attenuation_db` (Default: 120)<br>• `transition_width`: fraction of the smaller Nyquist (Default: 0.05)<br>• `max_denominator` (Default: 1000) | `res = resample_signal(x, 44100, 48000)`<br><br>• `ResampledSignalResult` (signal + designed taps) |
| `fractional_delay` | `function` | **Band-limited delay by a fractional number of samples (phase ramp).**<br>• `x`, `delay` [samples] (fractional, negative = advance)<br>• `mode`: 'linear' (zero-padded, for transients; Default) / 'circular' (periodic records, machine-exact on bin-centered tones) | `y = fractional_delay(x, 0.37)` |
| `window_metrics` | `function` | **Figures of merit of any scipy window (Harris 1978).**<br>• `window`: name or (name, param) tuple<br>• `n`: length (Default: 1024), DFT-even sampling as in Welch | `m = window_metrics('hann', 2048)`<br><br>• `WindowMetricsResult` |
| `multitaper_psd` | `function` | **Thomson multitaper PSD from one whole record (Percival & Walden Ch. 7).**<br>• `x`, `fs`<br>• `time_half_bandwidth`: NW (Default: 4), `n_tapers`: K (Default: 2·NW−1, capped at 2·NW)<br>• `adaptive`: Thomson weights (Default: True)<br>• `scaling`, `confidence` as above | `res = multitaper_psd(x, fs)`<br><br>• `MultitaperSpectralDensityResult` |
| `ToneBurstResult` | `dataclass` | **Tone-burst record.**<br>• `signal`, `envelope` (rectangular gate), `fs`<br>• `burst_seconds`, `burst_samples`, `onset_sample`<br>• `repetition_rate`, `period_samples`, `duty_cycle`<br>• `.plot()`: waveform + gating envelope | `res.signal, res.duty_cycle` |
| `ResampledSignalResult` | `dataclass` | **Resampled record with its anti-alias design.**<br>• `signal`, `fs`, `original_fs`, `up`, `down`<br>• `filter_taps`, `n_taps`, `passband_edge_hz`, `stopband_edge_hz`<br>• `stopband_attenuation_db`, `transition_width` | `res.signal, res.stopband_attenuation_db` |
| `WindowMetricsResult` | `dataclass` | **Window figures of merit.**<br>• `enbw_bins`, `.enbw_hz(fs)`, `coherent_gain`<br>• `scalloping_loss_db`, `worst_case_processing_loss_db` (positive losses)<br>• `highest_sidelobe_db` (negative, re main lobe), `mainlobe_width_3db_bins`<br>• `.plot()`: window + spectrum with metrics marked | `m.enbw_bins  # 1.5 for Hann` |
| `SpectralDensityResult` | `dataclass` | **Welch PSD with its statistical quality.**<br>• `frequencies`, `psd`, `ci_lower`/`ci_upper`, `confidence`<br>• `random_error` = 1/√nd, `n_segments`, `n_averages` (effective nd), `degrees_of_freedom`<br>• `resolution_bandwidth` Be [Hz]<br>• `.plot()`: PSD in dB with the CI band | `res.psd, res.n_averages, res.random_error` |
| `MultitaperSpectralDensityResult` | `dataclass` | **Multitaper PSD with per-frequency dof.**<br>• `frequencies`, `psd`, `ci_lower`/`ci_upper`, `confidence`<br>• `degrees_of_freedom` ν(f), `random_error` = √(2/ν)<br>• `weights` (K×F), `eigenvalues` λk, `time_half_bandwidth`, `n_tapers`, `resolution_bandwidth` 2W [Hz], `adaptive`<br>• `.plot()`: density with the CI band | `res.psd, res.degrees_of_freedom` |
| `CrossSpectralDensityResult` | `dataclass` | **Welch CSD with per-bin errors.**<br>• `csd` (complex), `magnitude`, `phase` (unwrapped), `coherence`<br>• `magnitude_random_error`, `phase_std` [rad]<br>• `.plot()`: magnitude, phase ±σ, coherence | `res.magnitude, res.phase_std` |
| `CoherentOutputSpectrumResult` | `dataclass` | **SISO output decomposition.**<br>• `output_psd` Gyy, `coherent_psd` Gvv, `noise_psd` Gnn<br>• `snr`, `snr_db`, `random_error` (Eq. 9.73), `snr_random_error`, `coherence_bias`<br>• `.plot()`: spectra + SNR panel | `res.coherent_psd, res.snr_db` |
| `spectrogram` | `function` | **Calibrated STFT power spectrogram (B&P 12.6.4.2): the Welch segmentation without the averaging.**<br>• `x`, `fs`<br>• `window`, `nperseg`, `overlap`, `scaling` as above<br>Column mean = Welch PSD bin by bin; a tone reads A²/2 ('spectrum') in every column | `res = spectrogram(x, fs, nperseg=1024, overlap=0.75)`<br><br>• `SpectrogramResult` |
| `zoom_fft` | `function` | **Narrow-band spectrum on a fine grid via chirp-Z (B&P 11.5.4).**<br>• `x`, `fs`, `f_min`, `f_max`<br>• `n_points` (Default: one per record resolution fs/N)<br>• `window` (Default: 'hann')<br>Tone on an analysis frequency reads amplitude A / power A²/2 exactly | `res = zoom_fft(x, fs, 980.0, 1016.0)`<br><br>• `ZoomFFTResult` |
| `SpectrogramResult` | `dataclass` | **STFT power over the time-frequency plane.**<br>• `times`, `frequencies`, `power` (freq × time)<br>• `time_resolution` T_B [s], `resolution_bandwidth` Be [Hz], `random_error` (= 1, unaveraged), `n_segments`, `hop`<br>• `.plot()`: dB image (raster) | `res.power[:, 0], res.time_resolution` |
| `ZoomFFTResult` | `dataclass` | **Zoom spectrum with amplitude calibration.**<br>• `frequencies`, `spectrum` (complex, \|·\| = tone amplitude), `amplitude`, `power` (= A²/2)<br>• `bin_spacing` (grid) vs `resolution_bandwidth` Be (true resolution)<br>• `.plot()`: power in dB over the band | `res.frequencies[res.amplitude.argmax()]` |
| `correlation` | `function` | **Auto/cross-correlation via zero-padded FFT (B&P 11.4.2).**<br>• `x`, `y` (Default: None → autocorrelation), `fs`<br>• `normalization`: 'biased' (1/N) / 'unbiased' (1/(N−\|r\|)) / 'coefficient' (ρ ∈ [−1, 1]) (Default: 'unbiased')<br>• `max_lag` [s] (Default: full N−1) | `res = correlation(x, y, fs, normalization='coefficient')`<br><br>• `CorrelationResult` |
| `correlation_random_error` | `function` | **ε[R̂xy(τ)] = [1+ρ⁻²]^½/√(2BT) (Eqs. 8.109/8.112).**<br>• `coefficient` ρxy(τ)<br>• `signal_bandwidth` B [Hz], `duration` T [s]<br>Valid for T ≥ 10·\|τ\|, BT ≥ 5 | `correlation_random_error(1/11, 100.0, 5.0)  # 0.349 (Example 8.5)` |
| `time_delay` | `function` | **TDE: direct correlator, GCC (Knapp & Carter) or phase slope (Eq. 5.101b).**<br>• `x`, `y`, `fs`<br>• `method`: 'gcc' (Default) / 'direct' / 'phase'<br>• `weighting`: 'none'/'roth'/'scot'/'phat' (Default)/'ml' (Table I)<br>• `window`, `nperseg`, `overlap`: shared Welch core ('gcc'/'phase')<br>• `max_delay` [s], `interpolation`: 'parabolic' (Default)/'none', `upsample` (Default: 1)<br>• `signal_bandwidth` [Hz]: enables the Eq. 8.129 delay uncertainty | `res = time_delay(x, y, fs, weighting='phat', upsample=16)`<br><br>• `TimeDelayResult` |
| `impulse_response_delay` | `function` | **Sub-sample IR delay [s]: peak location refined by local upsampling + parabola.**<br>• `ir`, `fs`<br>• `reference`: optional IR the delay is measured against (direct correlator)<br>• `interpolation` (Default: 'parabolic'), `upsample` (Default: 8) | `t0 = impulse_response_delay(ir, fs)  # ~1e-3-sample accuracy` |
| `align_impulse_responses` | `function` | **Align an IR onto a reference by its estimated sub-sample delay.**<br>• `ir`, `reference`, `fs`<br>• `interpolation`, `upsample` as above<br>Exact band-limited fractional shift (zero-padded phase ramp) | `res = align_impulse_responses(ir_b, ir_a, fs)`<br><br>• `AlignedImpulseResponseResult` |
| `envelope` | `function` | **Hilbert envelope, instantaneous phase & frequency (B&P Ch. 13).**<br>• `x`, `fs`<br>• `decimation_factor` (Default: 1)<br>• `antialias`: zero-phase FIR decimation (Default: True; False = plain subsampling, the ECMA-internal convention) | `res = envelope(x, fs, decimation_factor=32)`<br><br>• `EnvelopeResult` |
| `CorrelationResult` | `dataclass` | **Correlation estimate.**<br>• `lags` [s], `values`, `coefficient` (always carried), `normalization`, `kind`<br>• `.random_error(signal_bandwidth)`: per-lag ε (Eqs. 8.109/8.112)<br>• `.plot()` | `res.lags, res.values, res.random_error(2000.0)` |
| `TimeDelayResult` | `dataclass` | **Time-delay estimate.**<br>• `delay` [s], `delay_samples` (fractional), `method`, `weighting`<br>• `lags`, `correlation` (the searched curve), `peak_correlation` ρ̂xy<br>• `delay_std` (Eq. 8.129), `delay_interval` ±2σ (Eq. 8.130) with `signal_bandwidth`<br>• `.plot()`: correlation with the delay marked | `res.delay, res.delay_std` |
| `AlignedImpulseResponseResult` | `dataclass` | **Aligned IR pair.**<br>• `aligned`, `reference`, `delay` [s], `delay_samples`<br>• `.plot()`: overlay | `res.aligned, res.delay_samples` |
| `EnvelopeResult` | `dataclass` | **Envelope analysis.**<br>• `times` [s], `envelope`, `phase` [rad, unwrapped], `instantaneous_frequency` [Hz]<br>• `fs` (output rate), `signal`, `signal_fs`, `decimation_factor`, `antialias`<br>• `.plot()`: signal + envelope, instantaneous frequency | `res.envelope, res.instantaneous_frequency` |
| `envelope_spectrum` | `function` | **Amplitude spectrum of the envelope: modulations as lines (B&P 13.3).**<br>• `x`, `fs`<br>• `kind`: 'magnitude' (Default) / 'squared' (square-law detector, Fig. 13.11)<br>• `window` (Default: 'hann', coherent-gain corrected), `nfft`<br>• `remove_dc` (Default: True; mean kept in `mean_level`)<br>AM tone A0, m: line A0·m at fm ('magnitude') | `res = envelope_spectrum(x, fs)`<br><br>• `EnvelopeSpectrumResult` |
| `EnvelopeSpectrumResult` | `dataclass` | **Envelope spectrum.**<br>• `frequencies` [Hz], `amplitude` (line heights), `mean_level`, `kind`<br>• `times`, `envelope` (detector output), `window`, `remove_dc`, `fs`, `nfft`<br>• `.plot()`: envelope + spectrum | `res.amplitude, res.mean_level` |
| `time_synchronous_average` | `function` | **Extract a periodic waveform of known period by time domain averaging (McFadden 1987 Eq. 5).**<br>• `x`, `fs`, `period` [s] (one revolution)<br>• `n_averages`: whole periods to average (Default: as many as the record holds; choose N so N·q is integer to place a comb node on an interfering order q)<br>• `n_harmonics`: comb-response span (Default: 8)<br>Non-integer fs·period aligned by band-limited fractional delay | `res = time_synchronous_average(x, fs, 1/32)`<br><br>• `SynchronousAverageResult` |
| `SynchronousAverageResult` | `dataclass` | **Time synchronous average.**<br>• `period_waveform`, `times` [s], `residual`, `residual_rms`<br>• `n_averages`, `samples_per_period`, `period`, `fs`, `interpolated`<br>• `noise_reduction_db` = 10·log₁₀N, `amplitude_snr_gain` = √N<br>• `comb_frequencies` [Hz], `comb_response` (\|C(f)\|)<br>• `.plot()`: averaged waveform + comb filter | `res.period_waveform, res.noise_reduction_db` |
| `comb_filter_response` | `function` | **Magnitude of the N-period synchronous-averaging comb filter (McFadden 1987 Eq. 8).**<br>• `frequencies` [Hz], `period` [s], `n_averages`<br>\|C(f)\| = \|sin(N·π·f·T)/(N·sin(π·f·T))\|: unit teeth at harmonics k/T, nodes at j/(N·T) | `c = comb_filter_response(freqs, 1/32, 20)` |
| `regularized_inverse_filter` | `function` | **Kirkeby frequency-dependent regularized inversion (Kirkeby & Nelson 1999 Eq. (17)).**<br>• `response`: measured IR (array or `ImpulseResponseResult`; its `fs` rides along)<br>• `fs`: Sample rate [Hz]<br>• `f_range`: (f1, f2) equalized to unity (Required)<br>• `regularization_inside` (Default: 1e-6) / `regularization_outside` (Default: 1.0), fractions of max\|H\|²<br>• `transition_octaves` (Default: 1/3), `n_fft`, `delay` (Default: n_fft//2) | `inv = regularized_inverse_filter(ir, f_range=(100, 10000))`<br><br>• `InverseFilterResult` |
| `InverseFilterResult` | `dataclass` | **Regularized inverse filter.**<br>• `inverse` (time domain), `spectrum` (with modeling delay), `response_spectrum`, `regularization` = ε(f), `frequencies`, `f_range`, `delay`, `fs`<br>• `flatness_db`: worst in-band deviation of \|H·H_inv\| from 0 dB<br>• `max_gain_db`: out-of-band boost (≤ the 1/(2√ε) cap)<br>• `.apply(x)`: equalize, delay removed; `.plot()` | `flat = inv.apply(recording)` |
| `cepstrum` | `function` | **Power/real/complex cepstrum (Havelock Chs. 27/87).**<br>• `x`, `fs`<br>• `kind`: 'power' (Default, IDFT of ln\|X\|²) / 'real' (ln\|X\|) / 'complex' (invertible, phase unwrapped)<br>• `nfft`: even, ≥ record (Default: record length)<br>Echo a at t0: rahmonics (−1)^(n+1)·aⁿ/n at n·t0 | `res = cepstrum(x, fs, kind='complex')`<br><br>• `CepstrumResult` |
| `CepstrumResult` | `dataclass` | **Cepstrum.**<br>• `quefrencies` [s], `cepstrum`, `kind`, `fs`, `nfft`, `linear_phase_samples`<br>• `.invert()`: homomorphic round trip (complex kind only)<br>• `.plot()`: cepstrum vs quefrency | `res.cepstrum, res.invert()` |
| `lifter` | `function` | **Lifter a log spectrum: envelope vs fine structure (Havelock Ch. 27).**<br>• `x`, `fs`, `cutoff` [s]<br>• `mode`: 'lowpass' (Default, spectral envelope) / 'highpass' (ripple)<br>• `nfft`<br>Modes exactly complementary in dB | `res = lifter(x, fs, cutoff=0.004)`<br><br>• `LifterResult` |
| `LifterResult` | `dataclass` | **Liftered log spectrum.**<br>• `frequencies` [Hz], `spectrum_db`, `liftered_db`<br>• `quefrencies`, `cepstrum` (real), `cutoff`, `mode`, `fs`, `nfft`<br>• `.plot()`: cepstrum + cutoff, spectrum overlay | `res.liftered_db` |
| `echo_detection` | `function` | **Echo delay + reflection coefficient off the power cepstrum.**<br>• `x`, `fs`<br>• `min_quefrency` [s] (Default: 16 samples), `max_quefrency` [s] (Default: nfft/2)<br>• `nfft`<br>Peak height = a exactly for one in-record echo | `res = echo_detection(ir, fs, min_quefrency=0.002)`<br><br>• `EchoDetectionResult` |
| `EchoDetectionResult` | `dataclass` | **Detected echo.**<br>• `delay` [s], `delay_samples`, `reflection_coefficient`<br>• `quefrencies`, `cepstrum`, `search_range`, `fs`, `nfft`<br>• `.plot()`: cepstrum with the peak marked | `res.delay, res.reflection_coefficient` |
| `minimum_phase` | `function` | **Minimum-phase response from \|H\| via the real cepstrum (B&P 13.1.4).**<br>• `response`: one-sided response or plain magnitude, rfft layout (DC–Nyquist)<br>• `oversample`: trig-interpolated cepstral anti-aliasing factor (Default: 8)<br>Input phase ignored; magnitude zeros floored at 1e-15 of the peak | `h_min = minimum_phase(np.abs(H))`<br><br>• complex minimum-phase response, same bins |
| `group_delay` | `function` | **Group delay τ_g = −(1/2π)·dφ/df of a sampled response.**<br>• `response`: one-sided complex, rfft layout<br>• `fs` [Hz]<br>Unwrapped phase, central differences; needs < π phase advance per bin | `tau = group_delay(H, fs)  # seconds` |
| `excess_phase` | `function` | **Excess (all-pass) phase: unwrap(arg H) − φ_min.**<br>• `response`: one-sided complex, rfft layout<br>• `oversample` (Default: 8)<br>0 for minimum phase, −2πf·t₀ for pure latency; the realizability limit of any stable causal inverse | `phi_x = excess_phase(H)  # rad, 0 at DC` |
| `phase_decomposition` | `function` | **Minimum-phase / all-pass decomposition of a response.**<br>• `response`: one-sided complex, rfft layout (e.g. `np.fft.rfft(ir)`)<br>• `fs` [Hz]<br>• `oversample` (Default: 8) | `res = phase_decomposition(np.fft.rfft(ir), fs)`<br><br>• `PhaseDecompositionResult` |
| `PhaseDecompositionResult` | `dataclass` | **Phase decomposition.**<br>• `frequencies` [Hz], `magnitude`, `phase` (measured, unwrapped, 0 at DC)<br>• `minimum_phase`, `excess_phase` [rad], `group_delay`, `excess_group_delay` [s]<br>• `minimum_phase_response` (complex), `fs`<br>• `.plot()`: magnitude, phases, group delays | `res.excess_phase, res.excess_group_delay` |
| `sound_power_anechoic` | `function` | **Precision sound power in an (hemi-)anechoic room (ISO 3745:2012).**<br>• `levels_positions`: (NM, NB) position levels [dB]<br>• `surface`: 'sphere'/'hemisphere'<br>• `radius` r [m]<br>• `background_levels` + `frequencies`: for K1i<br>• `areas`: partial areas Si (Eq. 13) (Default: equal-area Eq. 12)<br>• `temperature` [°C] (Default: 23), `static_pressure` [kPa] (Default: 101.325)<br>• `air_absorption_coefficient`: α(f) [dB/m] for C3<br>• `sigma_omc` [dB] (Default: 0), `coverage_factor` k (Default: 2.0) | `res = sound_power_anechoic(levels, 'hemisphere', radius=2.0, frequencies=f)`<br><br>• `PrecisionSoundPowerResult` |
| `PrecisionSoundPowerResult` | `dataclass` | **ISO 3745 sound power result.**<br>• `sound_power_level` [dB], `sound_power_level_a` [dB]<br>• `surface_pressure_level`, `mean_pressure_level` [dB]<br>• `background_correction`: K1i (NM, NB) [dB]<br>• `c1`, `c2`, `c3`: meteorological corrections [dB]<br>• `directivity_index` DIi, `non_uniformity_index` VIr [dB]<br>• `surface_area` [m²], `surface`<br>• `uncertainty`, `uncertainty_bands`, `coverage_factor`<br>• `.plot()` | `res.sound_power_level, res.uncertainty` |
| `precision_positions` | `function` | **ISO 3745 microphone coordinates (Annex D/E).**<br>• `surface`: 'sphere' (Table D.1) / 'hemisphere' (Tables E.1/E.2)<br>• `radius` r [m]<br>• `array`: 'general'/'broadband' (Default: 'general')<br>• `count`: 20 or 40 (Default: 40) | `xyz = precision_positions('hemisphere', radius=2.0)`<br><br>• (40, 3) coordinates [m] |
| `precision_background_correction` | `function` | **Per-position background correction K1i (ISO 3745 Eq. 11).**<br>• `source_levels` / `background_levels`: (NM, NB) [dB]<br>• `frequencies` [Hz]: per-band criterion (10 dB for 250–5000 Hz, 6 dB outside) | `k1 = precision_background_correction(src, bg, f)`<br><br>• K1i [dB]; clamped + `SoundPowerWarning` below the criterion |
| `meteorological_corrections` | `function` | **Corrections C1, C2, C3 (ISO 3745 Eq. 14 block).**<br>• `temperature` θ [°C] (Default: 23), `static_pressure` ps [kPa] (Default: 101.325)<br>• `air_absorption_coefficient`: α(f) [dB/m] for C3 (Default: None → C3 = 0)<br>• `radius` r [m] (Default: 1.0) | `met = meteorological_corrections(23.0, 101.325)`<br><br>• `MeteorologicalCorrection`; C1 = −0.128 dB, C2 = 0 at reference |
| `MeteorologicalCorrection` | `dataclass` | **C1/C2/C3 corrections.**<br>• `c1`: reference-quantity correction [dB]<br>• `c2`: radiation-impedance correction [dB]<br>• `c3`: air-absorption correction [dB], scalar or per band | `met.c1, met.c2, met.c3` |
| `precision_uncertainty` | `function` | **Expanded uncertainty U = k·√(σR0² + σomc²) (ISO 3745 Eq. 24/25).**<br>• `sigma_r0`: reproducibility (Tables 2/3) [dB]<br>• `sigma_omc` [dB] (Default: 0.0)<br>• `coverage_factor` k (Default: 2.0; 1.6 one-sided) | `precision_uncertainty(0.5)  # 1.0`<br><br>• U [dB], scalar or per band |
| `sound_power_intensity_precision` | `function` | **Sound power by intensity scanning, precision (ISO 9614-3:2002).**<br>• `partial_intensity`: (N, NB) signed In,i [W/m²]<br>• `areas`: partial areas Si [m²]<br>• `frequencies` [Hz]: for LWA<br>• `temperature` [°C] (Default: 23), `barometric_pressure` [Pa] (Default: 101325): for LW0 (Eq. 10) | `res = sound_power_intensity_precision(In, areas, frequencies=f)`<br><br>• `PrecisionIntensityResult` |
| `PrecisionIntensityResult` | `dataclass` | **ISO 9614-3 scanning result.**<br>• `partial_power`: Pi = In,i·Si [W]<br>• `sound_power` P, `sound_power_level` LW [dB] (NaN where P ≤ 0)<br>• `sound_power_level_normalized`: LW0 [dB]<br>• `not_applicable_band`: per-band bool<br>• `surface_area` [m²], `sound_power_level_a` [dB]<br>• `.plot()` | `res.sound_power_level, res.not_applicable_band` |
| `precision_field_indicators` | `function` | **ISO 9614-3 Annex B field indicators.**<br>• `segment_intensity`: (N, NB) signed In,j [W/m²]<br>• `segment_pressure_levels`: (N, NB) Lpj [dB]<br>• `time_window_intensity`: (M, NB) for FT (Default: None) | `fi = precision_field_indicators(In, lp)`<br><br>• `PrecisionFieldIndicators` |
| `PrecisionFieldIndicators` | `dataclass` | **Annex B indicators (per band).**<br>• `ft`: temporal variability (= F1) or None<br>• `f_pi_unsigned`: F_pIn unsigned (= F2)<br>• `f_pi_signed`: F_pIn signed (= F3), ≥ unsigned<br>• `fs`: field non-uniformity FS (= F4) | `fi.f_pi_signed, fi.fs` |
| `precision_qualification` | `function` | **The five ISO 9614-3 Annex C acceptance criteria.**<br>• `indicators`: `PrecisionFieldIndicators`<br>• `scan_intensity_level_1`/`_2`: LIn per scan [dB] (criterion 1)<br>• `pressure_residual_index`: δpI0 [dB] (criterion 2, K = 10)<br>• `field_nonuniformity_1`/`_2`: FS per scan density (criterion 5)<br>• `frequencies` [Hz] or `repeatability_limit`: Table 1 limit s | `q = precision_qualification(fi, pressure_residual_index=18.0)`<br><br>• `PrecisionCriteria` |
| `PrecisionCriteria` | `dataclass` | **Annex C pass/fail per band.**<br>• `criterion_1`…`criterion_5`: bool arrays or None where not evaluable<br>• `qualified`: conjunction of criteria 1–4 or None | `q.qualified, q.criterion_2` |
| `plane_wave_frequency_range` | `function` | **Working plane-wave range (f_l, f_u) (ISO 10534-2 §4.2–4.5).**<br>• `spacing` s [m]<br>• `speed_of_sound` c0 [m/s]<br>• `diameter` d [m] (Default: None → spacing bound only)<br>• `shape`: 'circular'/'rectangular' (Default: 'circular') | `plane_wave_frequency_range(0.05, 343.2, diameter=0.1)  # (343.2, 1990.6)`<br><br>• [Hz] |
| `speed_of_sound_iso` | `function` | **Speed of sound (ISO 10534-2 Eq. 5).**<br>• `temperature` T [K] | `speed_of_sound_iso(293.0)  # 343.2`<br><br>• c0 = 343.2 √(T/293) [m/s] |
| `air_density_iso` | `function` | **Air density (ISO 10534-2 Eq. 7).**<br>• `temperature` T [K]<br>• `atmospheric_pressure` [kPa] (Default: 101.325) | `air_density_iso(293.0)  # 1.186`<br><br>• ρ [kg/m³] |
| `speed_of_sound_astm` | `function` | **Speed of sound (ASTM E2611-19 Eq. 4).**<br>• `temperature` T [°C] | `speed_of_sound_astm(20.0)  # 343.2`<br><br>• 20.047 √(273.15 + T) [m/s] |
| `air_density_astm` | `function` | **Air density (ASTM E2611-19 Eq. 5).**<br>• `temperature` T [°C]<br>• `atmospheric_pressure` P [kPa] (Default: 101.325) | `air_density_astm(20.0)  # 1.202`<br><br>• ρ [kg/m³] |
| `characteristic_impedance` | `function` | **Characteristic impedance of air ρc.**<br>• `density` ρ [kg/m³]<br>• `speed_of_sound` c [m/s] | `characteristic_impedance(1.186, 343.2)  # 407.0`<br><br>• [rayl] |
| `tube_attenuation_constant` | `function` | **Lower-bound tube attenuation k0″ (ISO 10534-2 Eq. A.18).**<br>• `frequency` f [Hz]<br>• `speed_of_sound` c0 [m/s]<br>• `diameter` d [m] (hydraulic for rectangular) | `tube_attenuation_constant(1000.0, 343.2, 0.1)  # 0.0179`<br><br>• [Np/m] |
| `tube_wavenumber` | `function` | **Complex wavenumber k0 = k0′ − j k0″ (ISO 10534-2 §2.6).**<br>• `frequency` f [Hz]<br>• `speed_of_sound` c0 [m/s]<br>• `attenuation`: k0″ [Np/m] (Default: None → lossless) | `tube_wavenumber(1000.0, 343.2, attenuation=0.018)`<br><br>• 18.308 − 0.018j [1/m] |
| `mic_calibration_factor` | `function` | **Microphone-mismatch calibration factor Hc (ISO 10534-2 Eq. 10).**<br>• `h12_config1`: H12 in the standard configuration<br>• `h12_config2`: H12 with the microphones interchanged | `hc = mic_calibration_factor(h12_a, h12_b)`<br><br>• Hc = √(H12ᴵ/H12ᴵᴵ) (complex) |
| `apply_mic_calibration` | `function` | **Apply the calibration factor (Eq. 13).**<br>• `h12_uncorrected`<br>• `calibration_factor`: Hc | `h12 = apply_mic_calibration(h12_raw, hc)`<br><br>• H12 = H12,raw/Hc |
| `reflection_factor` | `function` | **Complex reflection factor at the sample surface (ISO 10534-2 Eq. 17).**<br>• `h12`: corrected transfer function<br>• `spacing` s [m]<br>• `x1`: sample to the farther microphone [m]<br>• `wavenumber`: complex k0 | `r = reflection_factor(h12, spacing=0.05, x1=0.15, wavenumber=k0)`<br><br>• r = (H12 − HI)/(HR − H12)·e^(+2jk0x1) |
| `absorption_from_reflection` | `function` | **Normal-incidence absorption coefficient (Eq. 18).**<br>• `reflection`: complex r | `absorption_from_reflection(0.5)  # 0.75`<br><br>• α = 1 − \|r\|² |
| `surface_impedance` | `function` | **Absolute surface impedance Z (Eq. 19).**<br>• `reflection`: complex r<br>• `characteristic_impedance`: ρc0 [rayl] | `surface_impedance(0.5, 407.0)  # 1221`<br><br>• Z = ρc0(1 + r)/(1 − r) [rayl] |
| `normalized_surface_impedance` | `function` | **Normalised surface impedance Z/(ρc0) (Eq. 19).**<br>• `reflection`: complex r | `normalized_surface_impedance(0.5)  # 3.0` |
| `normalized_surface_admittance` | `function` | **Normalised surface admittance Gρc0 (Eq. 20).**<br>• `reflection`: complex r | `normalized_surface_admittance(0.5)  # 0.333`<br><br>• (1 − r)/(1 + r) |
| `two_microphone_impedance` | `function` | **Full two-microphone reduction (ISO 10534-2 Clause 7).**<br>• `h12`: corrected transfer function<br>• `frequency` f [Hz]<br>• `spacing` s [m], `x1` [m]<br>• `speed_of_sound` c0 [m/s], `characteristic_impedance` ρc0 [rayl]<br>• `attenuation`: k0″ [Np/m] (Default: None)<br>• `diameter` + `shape`: activate the plane-wave range check | `res = two_microphone_impedance(h12, frequency=f, spacing=0.05, x1=0.15, speed_of_sound=343.2, characteristic_impedance=407.0)`<br><br>• `ImpedanceTubeResult` |
| `ImpedanceTubeResult` | `dataclass` | **Two-microphone result per frequency.**<br>• `frequency` [Hz]<br>• `reflection`: complex r (Eq. 17)<br>• `surface_impedance` [rayl], `normalized_impedance` (Eq. 19)<br>• `absorption`: α = 1 − \|r\|² (Eq. 18) | `res.absorption, res.normalized_impedance` |
| `ImpedanceTubeWarning` | `warning class` | **ISO 10534-2 advisory.**<br>Emitted by `two_microphone_impedance` for frequencies outside the plane-wave working range (Eqs. 1–4); the results are still returned | `warnings.simplefilter('error', ImpedanceTubeWarning)` |
| `standing_wave_ratio_from_level` | `function` | **Standing-wave ratio from ΔL (ISO 10534-1 Eq. 15).**<br>• `level_difference`: Lmax − Lmin [dB] | `standing_wave_ratio_from_level(20.0)  # 10.0`<br><br>• s = 10^(ΔL/20) |
| `standing_wave_reflection_magnitude` | `function` | **Reflection magnitude from the SWR (Eq. 14).**<br>• `swr`: s ≥ 1 | `standing_wave_reflection_magnitude(10.0)  # 0.818`<br><br>• \|r\| = (s − 1)/(s + 1) |
| `standing_wave_reflection` | `function` | **Complex reflection factor from the standing wave (Eqs. 17–23).**<br>• `swr`: s<br>• `first_min_distance`: x_min1 [m]<br>• `wavelength`: λ0 [m] | `standing_wave_reflection(10.0, 0.05, 0.4)  # -0.818j`<br><br>• phase φ = π(4x_min1/λ0 − 1) |
| `standing_wave_absorption` | `function` | **Absorption from the SWR (Eqs. 9 + 14).**<br>• `swr`: s ≥ 1 | `standing_wave_absorption(10.0)  # 0.331`<br><br>• α = 4s/(s + 1)² |
| `standing_wave_normalized_impedance` | `function` | **Normalised impedance from the standing wave (Eqs. 24–26).**<br>• `swr`, `first_min_distance` [m], `wavelength` [m] | `standing_wave_normalized_impedance(10.0, 0.05, 0.4)`<br><br>• 0.198 − 0.98j |
| `wave_decomposition` | `function` | **Decompose the field into (A, B, C, D) (ASTM E2611-19 Eqs. 17–20).**<br>• `h1`…`h4`: microphone transfer functions<br>• `l1`, `s1`, `l2`, `s2`: geometry [m]<br>• `wavenumber` k | `A, B, C, D = wave_decomposition(h1, h2, h3, h4, l1=0.2, s1=0.05, l2=0.2, s2=0.05, wavenumber=k)`<br><br>• Forward/backward amplitudes, both sides |
| `face_quantities` | `function` | **Face pressures and velocities (Eq. 21).**<br>• `a`, `b`, `c`, `d`: wave amplitudes<br>• `wavenumber` k, `thickness` d [m], `characteristic_impedance` ρc | `p0, pd, u0, ud = face_quantities(A, B, C, D, wavenumber=k, thickness=0.05, characteristic_impedance=407.0)` |
| `transfer_matrix_two_load` | `function` | **Two-load transfer matrix (ASTM E2611-19 Eqs. 17–22).**<br>• `load_a`, `load_b`: (H1, H2, H3, H4) per termination<br>• `l1`, `s1`, `l2`, `s2`, `thickness` [m]<br>• `wavenumber`, `characteristic_impedance` | `T = transfer_matrix_two_load(load_a, load_b, l1=0.2, s1=0.05, l2=0.2, s2=0.05, thickness=0.05, wavenumber=k, characteristic_impedance=407.0)`<br><br>• `TransferMatrix` |
| `transfer_matrix_one_load` | `function` | **One-load transfer matrix, symmetric specimen (Eqs. 23–24).**<br>• `load`: (H1, H2, H3, H4)<br>• Same geometry parameters as `transfer_matrix_two_load` | `T = transfer_matrix_one_load(load, l1=0.2, s1=0.05, l2=0.2, s2=0.05, thickness=0.05, wavenumber=k, characteristic_impedance=407.0)`<br><br>• Requires reciprocity + symmetry |
| `air_layer_transfer_matrix` | `function` | **Analytic loss-free air-layer matrix (validation reference).**<br>• `wavenumber` k<br>• `thickness` d [m]<br>• `characteristic_impedance` ρc [rayl] | `T = air_layer_transfer_matrix(k, 0.05, 407.0)`<br><br>• det(T) = 1, T11 = T22 |
| `TransferMatrix` | `dataclass` | **Acoustic transfer matrix [[T11, T12], [T21, T22]] (ASTM E2611-19 Eq. 16).**<br>• `t11`, `t12`, `t21`, `t22`: complex, scalar or per frequency | `T.t11, T.t12` |
| `airflow_resistance` | `function` | **Airflow resistance R = Δp/qv (ISO 9053-1:2018 §3.1).**<br>• `pressure_drop` Δp [Pa]<br>• `volume_flow_rate` qv [m³/s] | `airflow_resistance(2.0, 0.0005)  # 4000.0`<br><br>• [Pa·s/m³] |
| `specific_airflow_resistance` | `function` | **Specific airflow resistance Rs (§3.2).**<br>• `resistance` R + `area` A, **or** `pressure_drop` Δp + `velocity` u | `specific_airflow_resistance(4000.0, 0.01)  # 40.0`<br><br>• Rs = R·A = Δp/u [Pa·s/m] |
| `airflow_resistivity` | `function` | **Airflow resistivity σ = Rs/d (§3.3).**<br>• `specific_resistance` Rs [Pa·s/m]<br>• `thickness` d [m] | `airflow_resistivity(40.0, 0.05)  # 800.0`<br><br>• [Pa·s/m²] |
| `linear_airflow_velocity` | `function` | **Linear airflow velocity u = qv/A (§3.4).**<br>• `volume_flow_rate` qv [m³/s]<br>• `area` A [m²] | `linear_airflow_velocity(5e-6, 0.01)  # 0.0005`<br><br>• [m/s] |
| `static_airflow_resistance` | `function` | **Stepwise static-method determination (ISO 9053-1 §7.5).**<br>• `velocities` u [m/s], `pressure_drops` Δp [Pa] (≥ 2 steps)<br>• `area` A [m²]<br>• `thickness` d [m] (Default: None → no σ)<br>• `evaluation_velocity` [m/s] (Default: 0.0005) | `res = static_airflow_resistance([0.0005, 0.001, 0.002], [0.02, 0.041, 0.086], 0.01, 0.05)`<br><br>• `StaticAirflowResult` (Rs = 40.0, σ = 800) |
| `StaticAirflowResult` | `dataclass` | **Static-method result at the evaluation velocity.**<br>• `resistance` R [Pa·s/m³], `specific_resistance` Rs [Pa·s/m]<br>• `resistivity` σ [Pa·s/m²] or None<br>• `evaluation_velocity` [m/s], `pressure_drop` [Pa]<br>• `linear_coefficient` a (zero-velocity Rs), `quadratic_coefficient` b | `res.specific_resistance, res.resistivity` |
| `piston_volume_flow_rate` | `function` | **RMS piston volume flow qv = 2πf·h·AP (ISO 9053-2 §6.2).**<br>• `frequency` f [Hz]<br>• `stroke_amplitude` h [m]<br>• `piston_area` AP [m²] | `piston_volume_flow_rate(2.0, 0.005, 0.01)  # 0.000628`<br><br>• [m³/s] |
| `alternating_airflow_resistance` | `function` | **Alternating-method resistance (ISO 9053-2:2020 Formula 2).**<br>• `level_specimen` Lps / `level_termination` Lpt [dB]<br>• `piston_stroke_specimen` hs / `piston_stroke_termination` ht [m]<br>• `frequency` f [Hz] (1–4 Hz), `cavity_volume` V [m³]<br>• `static_pressure` [Pa] (Default: 101325)<br>• `kappa_prime` κ′ (Default: 1.4; use `effective_kappa` for Annex A conformity)<br>• `background_level` Lpb [dB] (Default: None) | `r = alternating_airflow_resistance(78.0, 60.0, piston_stroke_specimen=5e-3, piston_stroke_termination=5e-4, frequency=2.0, cavity_volume=7.854e-4)`<br><br>• R [Pa·s/m³]; `AirflowResistanceWarning` when criteria fail |
| `thermal_boundary_layer_thickness` | `function` | **Thermal boundary-layer thickness b (ISO 9053-2 Formulas A.4/A.5).**<br>• `frequency` f [Hz]<br>• Air properties (Default: Annex A.3 values) | `thermal_boundary_layer_thickness(2.0)  # 0.00183`<br><br>• [m] |
| `effective_kappa` | `function` | **Effective ratio of specific heats κ′ (Formula A.7).**<br>• `cavity_surface` S [m²], `cavity_volume` V [m³]<br>• `frequency` f [Hz]<br>• Air properties (Default: Annex A.3 values) | `effective_kappa(0.0471, 7.854e-4, 2.0)  # 1.37`<br><br>• The Annex A.3 worked example |
| `delany_bazley` | `function` | **Delany–Bazley one-parameter porous model (Mechel 2e G.11; Bies 5e Table D.1).**<br>• `frequency` f [Hz]<br>• `flow_resistivity` σ [Pa·s/m²]<br>• `coefficients`: preset name or (C1…C8) (Default: 'delany_bazley' rockwool/fibreglass)<br>• `speed_of_sound`, `air_density` (Default: 343.0, 1.205)<br>• Warns outside 0.01 < X < 1 (X = ρf/σ) | `med = delany_bazley(f, 20000.0)`<br><br>• `PorousMediumResult` |
| `miki` | `function` | **Miki (1990) positive-real revision of Delany–Bazley.**<br>• `frequency` f [Hz]<br>• `flow_resistivity` σ [Pa·s/m²]<br>• `speed_of_sound`, `air_density`<br>• Stays passive below the fit range; warns outside 0.01 < f/σ < 1 | `med = miki(f, 20000.0)`<br><br>• `PorousMediumResult` |
| `johnson_champoux_allard` | `function` | **JCA five-parameter rigid-frame model (Cox & D'Antonio 3e Eqs. 6.19–6.25).**<br>• `frequency` f [Hz], `flow_resistivity` σ [Pa·s/m²]<br>• `porosity` φ, `tortuosity` T = α∞<br>• `viscous_length` Λ / `thermal_length` Λ′ [m]<br>• Air state: `viscosity`, `prandtl_number`, `heat_capacity_ratio`, `atmospheric_pressure` | `med = johnson_champoux_allard(f, 20000.0, porosity=0.98, tortuosity=1.05, viscous_length=8.7e-5, thermal_length=1.7e-4)`<br><br>• `PorousMediumResult` |
| `PorousMediumResult` | `dataclass` | **Equivalent-fluid characterisation.**<br>• `characteristic_impedance` Zc [Pa·s/m], `wavenumber` k [rad/m] (Im < 0)<br>• `effective_density`, `bulk_modulus` (surface-normalised)<br>• `.normalized_impedance`, `.normalized_wavenumber`<br>• `.plot()`: normalised Zc/k components | `med.characteristic_impedance, med.plot()` |
| `DELANY_BAZLEY_COEFFICIENTS` | `mapping` | **Bies 5e Table D.1 coefficient presets (C1…C8).**<br>'delany_bazley' (rockwool/fibreglass), 'garai_pompoli' (polyester), 'dunn_davern' / 'wu' (foams) | `DELANY_BAZLEY_COEFFICIENTS['garai_pompoli']` |
| `DELANY_BAZLEY_VALIDITY` | `tuple` | **Stated fit range in X = ρf/σ.**<br>(0.01, 1.0) | `DELANY_BAZLEY_VALIDITY  # (0.01, 1.0)` |
| `MIKI_VALIDITY` | `tuple` | **Miki fit range in f/σ.**<br>(0.01, 1.0) | `MIKI_VALIDITY  # (0.01, 1.0)` |
| `layered_absorber` | `function` | **Transfer-matrix multilayer prediction at one angle (Cox & D'Antonio Eq. 2.29; Bies Eq. D.95; Mechel D.4).**<br>• `frequency` f [Hz]<br>• `layers`: stack from the incidence side (`AirLayer`, `PorousLayer`, `PerforatedPlateLayer`, `MicroperforatedPlateLayer`, `MembraneLayer`)<br>• `angle` θ [rad] (Default: 0)<br>• `termination`: 'rigid'/'free'/complex Z [Pa·s/m] (Default: 'rigid')<br>• `speed_of_sound`, `air_density`, `viscosity` | `res = layered_absorber(f, [PorousLayer(0.05, med)])`<br><br>• `LayeredAbsorberResult` |
| `LayeredAbsorberResult` | `dataclass` | **Oblique-incidence prediction.**<br>• `surface_impedance` Zs, `normalized_impedance`<br>• `reflection` R(θ), `absorption` α(θ)<br>• `transfer_matrix`: (2, 2, n) chain matrix (det = 1)<br>• `.plot()`: α(f) with \|R\| overlaid | `res.absorption, res.surface_impedance` |
| `diffuse_field_absorption` | `function` | **Random-incidence (Paris) absorption (Mechel D.5 Eq. 9).**<br>• `frequency`, `layers`, `termination` as `layered_absorber`<br>• `angle_limit` [rad] (Default: π/2; 75°–87° truncations in use)<br>• `quadrature_points` (Default: 64, Gauss–Legendre) | `dif = diffuse_field_absorption(f, layers)`<br><br>• `DiffuseFieldAbsorptionResult` |
| `DiffuseFieldAbsorptionResult` | `dataclass` | **Paris-integral result.**<br>• `absorption`: α_dif(f)<br>• `angle_limit` [rad]<br>• `.plot()` | `dif.absorption` |
| `statistical_absorption` | `function` | **Closed-form Paris integral, locally reacting plane (Mechel D.5 Eq. 10).**<br>• `normalized_impedance` z = Zs/(ρc) (Re z > 0)<br>• `angle_limit` [rad] (Default: π/2)<br>• Maximum over passive z is the published 0.951 | `statistical_absorption(1.567 + 0j)  # 0.951` |
| `AirLayer` | `dataclass` | **Plain air gap.**<br>• `thickness` d [m] (0 allowed → transparent) | `AirLayer(0.05)` |
| `PorousLayer` | `dataclass` | **Porous layer.**<br>• `thickness` d [m]<br>• `medium`: `PorousMediumResult` on the solver frequency grid | `PorousLayer(0.05, med)` |
| `PerforatedPlateLayer` | `dataclass` | **Rigid perforated plate.**<br>• `thickness` t, `hole_radius` a [m]<br>• `open_area` ε (0–1)<br>• `end_correction` δ per end (Default: None → Fok/Nesterov of ε) | `PerforatedPlateLayer(0.006, 0.0025, 0.05)` |
| `MicroperforatedPlateLayer` | `dataclass` | **Maa microperforated plate.**<br>• `thickness` t, `hole_radius` a [m] (submillimetre)<br>• `open_area` ε<br>• `end_correction` δ (Default: 0.85) | `MicroperforatedPlateLayer(0.0002, 0.0001, 0.005)` |
| `MembraneLayer` | `dataclass` | **Limp impervious membrane.**<br>• `surface_density` m [kg/m²]<br>• `resistance` r [Pa·s/m] (Default: 0) | `MembraneLayer(5.0)` |
| `perforated_plate_impedance` | `function` | **Perforated-plate transfer impedance (Cox & D'Antonio Eqs. 7.6/7.12).**<br>• `frequency`, `thickness`, `hole_radius`, `open_area`, `end_correction`<br>• `air_density`, `viscosity` | `z = perforated_plate_impedance(f, thickness=0.006, hole_radius=0.0025, open_area=0.05)`<br><br>• complex [Pa·s/m] |
| `microperforated_plate_impedance` | `function` | **Maa's exact MPP impedance (Cox & D'Antonio Eqs. 7.33–7.35).**<br>• `frequency`, `thickness`, `hole_radius`, `open_area`<br>• `end_correction` δ (Default: 0.85)<br>• Bessel circular-capillary kernel | `z = microperforated_plate_impedance(f, thickness=0.0002, hole_radius=0.0001, open_area=0.005)`<br><br>• complex [Pa·s/m] |
| `membrane_impedance` | `function` | **Membrane transfer impedance r + jωm (Cox Eq. 7.14; Bies Eq. D.96).**<br>• `frequency`, `surface_density` m [kg/m²]<br>• `resistance` r (Default: 0) | `z = membrane_impedance(f, surface_density=5.0)`<br><br>• complex [Pa·s/m] |
| `perforation_end_correction` | `function` | **End-correction factor δ(ε) = 0.85(1 − 1.47√ε + 0.47ε^1.5) (Cox Table 7.1).**<br>• `open_area` ε | `perforation_end_correction(0.05)  # 0.575`<br><br>• per orifice end |
| `helmholtz_resonance_frequency` | `function` | **Shallow-cavity perforate resonance (Cox Eq. 7.4).**<br>• `cavity_depth` d, `plate_thickness` t, `hole_radius` a [m]<br>• `open_area` ε, `end_correction` δ<br>• `speed_of_sound` | `helmholtz_resonance_frequency(cavity_depth=0.025, plate_thickness=0.006, hole_radius=0.0025, open_area=0.05)`<br><br>• f0 = (c/2π)√(ε/(t′d)) [Hz] |
| `membrane_resonance_frequency` | `function` | **Membrane mass-spring resonance (Cox Eqs. 7.9/7.10).**<br>• `surface_density` m [kg/m²], `cavity_depth` d [m]<br>• `isothermal` (Default: False)<br>• `speed_of_sound`, `air_density` | `membrane_resonance_frequency(surface_density=5.0, cavity_depth=0.05)  # ≈120`<br><br>• ≈ 60/√(md) (50/√(md) isothermal) [Hz] |
| `PorousAbsorberWarning` | `warning class` | **Porous-model advisory.**<br>Emitted when the Delany–Bazley / Miki regressions are evaluated outside their published fit range; values are still returned | `warnings.simplefilter('error', PorousAbsorberWarning)` |
| `slit_helmholtz_absorber` | `function` | **Slit panel loaded with Helmholtz resonators (Jiménez et al. Appl. Sci. 2017).**<br>• `frequency` f [Hz], `resonators`: one/many `HelmholtzResonator`<br>• `slit_height` h, `lattice_step` a, `period` d [m]<br>• `angle` θ [rad] (Default: 0)<br>• `end_correction`, `slit_radiation` (Default: True)<br>• visco-thermal slit + square-duct losses | `res = slit_helmholtz_absorber(f, hr, slit_height=1e-3, lattice_step=3e-2, period=5e-2)`<br><br>• `SlitResonatorAbsorberResult` |
| `SlitResonatorAbsorberResult` | `dataclass` | **Slow-sound panel prediction.**<br>• `surface_impedance` Z = T11/T21, `normalized_impedance`<br>• `reflection` R(θ), `absorption` α = 1 − \|R\|²<br>• `effective_wavenumber`, `effective_impedance`<br>• `transfer_matrix`: (2, 2, n)<br>• `.plot()`: α(f) with \|R\| overlaid | `res.absorption, res.plot()` |
| `critical_coupling_design` | `function` | **Solve geometry for perfect absorption at a frequency (critical coupling, Eq. 9).**<br>• `target_frequency` f0 [Hz], base `resonator`<br>• `lattice_step` a, `period` d [m], `angle` θ<br>• tunes cavity length + slit height so the reflection zero is real<br>• warns if α does not reach ≈1 | `d = critical_coupling_design(300.0, hr, lattice_step=3e-2, period=5e-2)`<br><br>• `CriticalCouplingResult` |
| `CriticalCouplingResult` | `dataclass` | **Perfect-absorption design outcome.**<br>• `resonator`, `slit_height`: solved geometry<br>• `absorption` (≈1), `normalized_impedance` (≈1)<br>• `converged`, `target_frequency`, `angle` | `d.resonator, d.slit_height, d.absorption` |
| `HelmholtzResonator` | `dataclass` | **Square-cross-section Helmholtz resonator.**<br>• `neck_length` l_n, `neck_side` w_n [m]<br>• `cavity_length` l_c, `cavity_side` w_c [m] | `HelmholtzResonator(1e-3, 3e-3, 30e-3, 27e-3)` |
| `helmholtz_resonator_impedance` | `function` | **Resonator acoustic impedance Z_HR with visco-thermal losses (Jiménez et al. APL 2016 Eq. A23).**<br>• `frequency`, `resonator`<br>• `slit_height`, `lattice_step` for neck→slit end correction<br>• `end_correction` (Default: True) | `z = helmholtz_resonator_impedance(f, hr)`<br><br>• complex [Pa·s/m³] |
| `slit_effective_properties` | `function` | **Narrow-slit visco-thermal ρ_s, κ_s (Stinson 1991; Eq. 6).**<br>• `frequency`, `slit_height` h [m]<br>• air state kwargs<br>• limit jωρ_s → 12η/h² as ω → 0 | `rho_s, kap_s = slit_effective_properties(f, slit_height=1.2e-3)` |
| `rectangular_duct_properties` | `function` | **Square-duct visco-thermal ρ, κ (Stinson 1991; Eqs. 7–8).**<br>• `frequency`, `side` [m]<br>• `sum_terms` (Default: 40)<br>• limit jωρ → 28.454η/side² as ω → 0 | `rho, kap = rectangular_duct_properties(f, side=3e-3)` |
| `SlowSoundAbsorberWarning` | `warning class` | **Slow-sound absorber advisory.**<br>Emitted when `critical_coupling_design` cannot reach perfect absorption within tolerance | `warnings.simplefilter('error', SlowSoundAbsorberWarning)` |
| `AirflowResistanceWarning` | `warning class` | **ISO 9053 advisory.**<br>Emitted for a velocity above the 15 mm/s static limit, a piston frequency outside 1–4 Hz, or a failed Formula 3/4 validity criterion | `warnings.simplefilter('error', AirflowResistanceWarning)` |
| `practical_absorption_coefficient` | `function` | **Practical coefficients αp (ISO 11654 §4.1).**<br>• `third_octave_alpha_s`: 15 one-third-octave αs, 200–5000 Hz (sequence or mapping keyed by band) | `ap = practical_absorption_coefficient(alpha_s)`<br><br>• 5 octave values (250–4000 Hz), 0.05 steps, capped at 1.00 |
| `weighted_absorption` | `function` | **Weighted absorption αw + class (ISO 11654 §4.2).**<br>• `alpha_p`: the 5 octave practical coefficients | `w = weighted_absorption([0.25, 0.7, 0.95, 1.0, 0.85])`<br><br>• `AbsorptionRatingResult` (αw = 0.55, class D, 'MH') |
| `weighted_absorption_from_third_octave` | `function` | **αw from 15 one-third-octave αs, retaining them for the fiche (ISO 11654 §4.1–4.2).**<br>• `third_octave_alpha_s`: 15 αs, 200–5000 Hz (sequence or mapping keyed by band) | `w = weighted_absorption_from_third_octave(alpha_s)`<br><br>• `AbsorptionRatingResult` carrying `third_octave_alpha_s` / `third_octave_bands` |
| `absorption_class` | `function` | **Sound absorption class (Table B.1).**<br>• `alpha_w`: multiple of 0.05 in [0, 1] | `absorption_class(0.7)  # 'C'`<br><br>• 'A'–'E' or 'Not classified' |
| `AbsorptionRatingResult` | `dataclass` | **αw rating result.**<br>• `alpha_w`: shifted curve read at 500 Hz<br>• `shape_indicator`: 'L'/'M'/'H' concatenation or ''<br>• `absorption_class`: 'A'–'E'/'Not classified'<br>• `shift`, `unfavourable_sum` (≤ 0.10)<br>• `band_centers` [Hz], `measured`, `shifted_reference`<br>• `.plot()` | `w.alpha_w, w.absorption_class` |
| `OCTAVE_BANDS` | `tuple` | **ISO 11654 octave rating bands [Hz].**<br>(250, 500, 1000, 2000, 4000) | `OCTAVE_BANDS  # (250, ..., 4000)` |
| `THIRD_OCTAVE_BANDS` | `tuple` | **ISO 11654 one-third-octave input bands [Hz].**<br>200 Hz to 5000 Hz (15 bands) | `THIRD_OCTAVE_BANDS[0]  # 200` |
| `REFERENCE_CURVE` | `mapping` | **ISO 11654 Figure 1 reference curve (read-only).**<br>Keyed by octave band [Hz] → coefficient | `REFERENCE_CURVE[250]  # 0.8` |
| `speed_of_sound` | `function` | **Speed of sound (ISO 17497-1 Eq. 2).**<br>• `temperature` t [°C] | `speed_of_sound(20.0)  # 343.2`<br><br>• 343.2 √((273.15 + t)/293.15) [m/s] |
| `air_attenuation_coefficient` | `function` | **Energy attenuation m from ISO 9613-1 α (ISO 17497-1 Eq. 3).**<br>• `pressure_attenuation_db_per_m`: α [dB/m] | `air_attenuation_coefficient(0.005)  # 0.00115`<br><br>• m ≈ α/4.343 [1/m] |
| `random_incidence_absorption` | `function` | **Random-incidence absorption αs (ISO 17497-1 Eq. 1).**<br>• `volume` V [m³], `area` S [m²]<br>• `c1`/`T1`: static base plate, no sample<br>• `c2`/`T2`: with the test sample<br>• `m1`/`m2`: air attenuation [1/m] (Default: 0) | `a_s = random_incidence_absorption(200.0, 10.8, c1=343.0, T1=2.5, c2=343.2, T2=1.8)  # 0.463` |
| `specular_absorption_coefficient` | `function` | **Specular absorption αspec (Eq. 4).**<br>• `volume`, `area`<br>• `c3`/`T3`: rotating base plate, no sample<br>• `c4`/`T4`: sample on the rotating turntable<br>• `m3`/`m4` (Default: 0) | `a_spec = specular_absorption_coefficient(200.0, 10.8, c3=c3, T3=t3, c4=c4, T4=t4)`<br><br>• Includes the energy lost to scattering |
| `scattering_coefficient` | `function` | **Random-incidence scattering coefficient s (Eq. 5).**<br>• `alpha_spec`, `alpha_s`<br>• `truncate_negative`: clip s < 0 to 0 (Default: True); s > 1 is kept | `scattering_coefficient(0.45, 0.30)  # 0.214`<br><br>• s = (αspec − αs)/(1 − αs) |
| `scattering_coefficient_spectrum` | `function` | **Scattering spectrum s(f) (Eq. 5).**<br>• `frequencies`: one-third-octave centres [Hz]<br>• `specular_absorption`, `random_absorption`: per band<br>• `truncate_negative` (Default: True) | `res = scattering_coefficient_spectrum(f, a_spec, a_s)`<br><br>• `ScatteringResult` |
| `ScatteringResult` | `dataclass` | **Scattering spectrum result.**<br>• `frequencies` [Hz]<br>• `scattering`: s per band<br>• `random_incidence`: αs, `specular`: αspec<br>• `.plot()` | `res.scattering` |
| `base_plate_scattering` | `function` | **Scattering of the base plate alone (Eq. 6).**<br>• `volume`, `area`<br>• `c1`/`T1`: static, `c3`/`T3`: rotating<br>• `m1`/`m3` (Default: 0) | `s_base = base_plate_scattering(200.0, 10.8, c1=c1, T1=t1, c3=c3, T3=t3)`<br><br>• Quality metric vs Table 1 |
| `check_base_plate_scattering` | `function` | **Verify the base plate against Table 1 (Clause 6.2).**<br>• `scattering`: mapping by band [Hz] or 18 values ordered as `BASE_PLATE_BANDS` | `check_base_plate_scattering(s_base)  # ()`<br><br>• Offending band centres; `ScatteringDiffusionWarning` if any |
| `BASE_PLATE_BANDS` | `tuple` | **ISO 17497-1 base-plate check bands [Hz].**<br>100 Hz to 5000 Hz (18 one-third octaves) | `BASE_PLATE_BANDS[0]  # 100` |
| `BASE_PLATE_MAX_SCATTERING` | `mapping` | **Table 1 base-plate scattering limits (read-only).**<br>Keyed by band [Hz] → maximum s | `BASE_PLATE_MAX_SCATTERING[500]  # 0.05` |
| `reverberation_time_uncertainty` | `function` | **Standard uncertainty of a mean T (ISO 17497-1 Eq. A.1).**<br>• `times`: N ≥ 2 spatially-averaged measurements [s] | `reverberation_time_uncertainty([2.31, 2.28, 2.35])  # 0.0203`<br><br>• Standard error of the mean [s] |
| `absorption_coefficient_uncertainty` | `function` | **Uncertainty of a Sabine coefficient (Eqs. A.3/A.4).**<br>• `volume`, `area`<br>• `c` [m/s]<br>• `T_a`/`u_a`, `T_b`/`u_b`: the two situations [s] | `u_alpha = absorption_coefficient_uncertainty(200.0, 10.8, c=343.2, T_a=2.5, u_a=0.02, T_b=1.8, u_b=0.02)` |
| `scattering_coefficient_uncertainty` | `function` | **Uncertainty of the scattering coefficient (Eq. A.5).**<br>• `alpha_spec`, `alpha_s`<br>• `u_alpha_spec`, `u_alpha_s` | `u = scattering_coefficient_uncertainty(0.45, 0.30, 0.02, 0.02)`<br><br>• `ScatteringUncertainty` (U = 2u, 95 %) |
| `ScatteringUncertainty` | `dataclass` | **Scattering uncertainty result.**<br>• `u_scattering`: combined standard u_s<br>• `expanded`: U = 2u_s | `u.u_scattering, u.expanded` |
| `directional_diffusion_coefficient` | `function` | **Directional diffusion coefficient d_θ (ISO 17497-2 Formulas 5/6).**<br>• `levels`: n ≥ 2 reflected SPL [dB] (−inf = zero energy)<br>• `area_weights`: Ni (Formula 8) (Default: None → equal-area Formula 5) | `directional_diffusion_coefficient([-10., -12., -15., -11., -13.])  # 0.854` |
| `directional_diffusion` | `function` | **Polar response + its coefficient.**<br>• `angles` [°], `levels` [dB]<br>• `weights`: Ni (Default: None) | `res = directional_diffusion(angles, levels)`<br><br>• `DiffusionResult` |
| `DiffusionResult` | `dataclass` | **Polar diffusion result.**<br>• `angles` [°], `levels` [dB]<br>• `coefficient`: d_θ (autocorrelation)<br>• `.plot()`, `.report()` | `res.coefficient` |
| `diffusion_spectrum` | `function` | **Diffusion spectrum d(f) (ISO 17497-2 Clause 8.5).**<br>• `frequencies`: one-third-octave centres [Hz]<br>• `diffusion`: d per band (directional, or random-incidence via Clause 8.4)<br>• `normalized`: d_n per band (Default: None) | `res = diffusion_spectrum(f, d, normalized=d_n)`<br><br>• `DiffusionSpectrum` |
| `DiffusionSpectrum` | `dataclass` | **Diffusion spectrum result.**<br>• `frequencies` [Hz]<br>• `diffusion`: d per band<br>• `normalized`: d_n per band or None<br>• `.plot()`, `.report()` | `res.diffusion` |
| `normalized_diffusion_coefficient` | `function` | **Normalised coefficient d_θ,n (Formula 7).**<br>• `d_theta`: test surface<br>• `d_theta_reference`: flat reference | `normalized_diffusion_coefficient(0.6, 0.2)  # 0.5`<br><br>• (d − d_r)/(1 − d_r) |
| `area_factors` | `function` | **Per-receiver area weights Ni (Clause 8.3 Formula 8).**<br>• `elevations`: θ [°], 0–90<br>• `delta_theta` [°]<br>• `delta_phi` [°] (Default: None → `delta_theta`) | `n_i = area_factors([0, 15, 30, 45, 60, 75, 90], delta_theta=15.0)`<br><br>• Dimensionless, min 1 |
| `random_incidence_diffusion` | `function` | **Random-incidence diffusion coefficient d (Clause 8.4).**<br>• `directional_coefficients`: d_θ per source<br>• `weights`: source weights (Default: None → equal; 2-D uses `TWO_DIMENSIONAL_SOURCE_WEIGHTS`) | `d = random_incidence_diffusion(d_thetas, weights=TWO_DIMENSIONAL_SOURCE_WEIGHTS)` |
| `TWO_DIMENSIONAL_SOURCE_WEIGHTS` | `tuple` | **ISO 17497-2 single-plane source weights.**<br>(1, 3, 3, 3, 3) for 0°, ±30°, ±60° | `TWO_DIMENSIONAL_SOURCE_WEIGHTS` |
| `ScatteringDiffusionWarning` | `warning class` | **ISO 17497 advisory.**<br>Emitted for out-of-range scattering/diffusion measurement conditions (e.g. a base plate over the Table 1 limits) | `warnings.simplefilter('error', ScatteringDiffusionWarning)` |
| `quadratic_residue_sequence` | `function` | **Quadratic residue sequence s_n (Cox & D'Antonio Eq. 10.2).**<br>• `prime`: odd prime generator N | `quadratic_residue_sequence(7)  # [0 1 4 2 2 4 1]`<br><br>• s_n = n² mod N |
| `qrd_well_depths` | `function` | **QRD well depths d_n (Cox & D'Antonio Eq. 10.3).**<br>• `prime`: generator N<br>• `design_frequency` f0 [Hz]<br>• `speed_of_sound` c [m/s] (Default: 343) | `qrd_well_depths(7, 500.0)  # d_max 0.196 m`<br><br>• d_n = s_n λ0/(2N) |
| `predict_diffuser_polar_response` | `function` | **Predicted far-field polar response (Cox & D'Antonio Eq. 5.8).**<br>• `well_width` w [m], `frequency` f [Hz]<br>• `depths` d_n [m] or `reflection` R_n (exactly one)<br>• `angles` [°] (Default: semicircle), `source_angle` ψ [°]<br>• `periods` Np (Default: 1) | `s = predict_diffuser_polar_response(0.10, 2000.0, depths=d, periods=5)`<br><br>• `DiffuserPolarResponse` |
| `predicted_diffusion_spectrum` | `function` | **Predicted diffusion spectrum d(f) of a design.**<br>• `well_width` [m], `frequencies` [Hz]<br>• `depths` d_n [m]<br>• `periods` (Default: 1)<br>• `normalize`: also d_n vs flat reference (Default: True) | `res = predicted_diffusion_spectrum(0.10, f, depths=d, periods=5)`<br><br>• `DiffusionSpectrum` |
| `DiffuserPolarResponse` | `dataclass` | **Predicted diffuser polar response.**<br>• `frequency` [Hz]<br>• `angles` [°], `levels` [dB] (peak at 0)<br>• `coefficient`: d_θ<br>• `.plot()` | `s.coefficient` |
| `DEFAULT_POLAR_ANGLES` | `tuple` | **ISO 17497-2 single-plane receiver angles.**<br>−90° to 90° in 5° steps (37 receivers) | `DEFAULT_POLAR_ANGLES[0]  # -90` |
| `adrienne_window` | `function` | **Adrienne temporal window (ISO 13472-1 Clause 6.4).**<br>• `fs` [Hz]<br>• `flat_duration` [s] (Default: 0.005)<br>• `leading_duration` [s] (Default: 0.0005), `trailing_duration` [s] (Default: 0.005)<br>• `leading_edge`/`trailing_edge`: 'blackman-harris' or 'cosine-squared' | `w = adrienne_window(48000)`<br><br>• Rising edge + flat top + falling edge, peak 1.0 |
| `geometric_spreading_factor` | `function` | **Geometrical-spreading factor Kr (Clause 4.1).**<br>• `source_height` ds [m] (Default: 1.25)<br>• `mic_height` dm [m] (Default: 0.25) | `geometric_spreading_factor()  # 0.6667`<br><br>• Kr = (ds − dm)/(ds + dm) |
| `geometric_spreading_factor_angle` | `function` | **Oblique factor Kr,θ (Annex F).**<br>• `incidence_angle` θ [rad]<br>• `source_height`, `mic_height` | `geometric_spreading_factor_angle(np.pi/6)  # 0.764` |
| `reflected_path_delay` | `function` | **Reflected-path delay Δτ = 2dm/c (Annex C).**<br>• `mic_height` dm [m] (Default: 0.25)<br>• `speed_of_sound` c [m/s] (Default: 340.0) | `reflected_path_delay()  # 0.001471`<br><br>• [s] |
| `insitu_reflection_factor` | `function` | **Complex reflection factor r(f) (ISO 13472-1 Clause 4.1).**<br>• `incident_ir` / `reflected_ir`: windowed impulse responses<br>• `source_height`, `mic_height` [m]<br>• `incidence_angle` [rad] (Default: 0)<br>• `fs` + `delay`: undo the reflected-path offset (Default: None)<br>• `n`: FFT length | `r = insitu_reflection_factor(hi, hr, fs=48000, delay=dtau)`<br><br>• (1/Kr)·Hr(f)/Hi(f) at the rfft bins |
| `insitu_absorption_from_reflection` | `function` | **α from the reflection factor (Clause 4.1).**<br>• `reflection`: complex r | `alpha = insitu_absorption_from_reflection(r)`<br><br>• α = 1 − \|r\|² |
| `power_reflection_coefficient` | `function` | **Power reflection factor QW(f), direct energy route.**<br>• `incident_ir`, `reflected_ir`<br>• `source_height`, `mic_height`, `incidence_angle`, `n` | `qw = power_reflection_coefficient(hi, hr)`<br><br>• (1/Kr²)\|Hr/Hi\|², offset-independent |
| `insitu_absorption_coefficient` | `function` | **Narrow-band absorption α(f) (Clause 4.1).**<br>• Same parameters as `power_reflection_coefficient` | `alpha = insitu_absorption_coefficient(hi, hr)`<br><br>• α = 1 − QW(f) |
| `one_third_octave_absorption` | `function` | **Aggregate narrow-band α into one-third octaves.**<br>• `frequency` [Hz], `absorption`<br>• `f_min` (Default: 250), `f_max` (Default: 4000; 1600 for Part 2) [Hz]<br>• `clip_negative` (Default: True) | `fc, ab = one_third_octave_absorption(f, alpha)`<br><br>• Band centres + linear-averaged α (nan if empty) |
| `insitu_absorption_spectrum` | `function` | **End-to-end in-situ spectrum (ISO 13472-1).**<br>• `incident_ir`, `reflected_ir`, `fs` [Hz]<br>• geometry + `incidence_angle`<br>• `f_min`/`f_max` [Hz], `clip_negative` | `res = insitu_absorption_spectrum(hi, hr, 48000)`<br><br>• `InsituAbsorptionResult` |
| `InsituAbsorptionResult` | `dataclass` | **In-situ absorption spectrum.**<br>• `frequencies`: one-third-octave centres [Hz]<br>• `absorption`: α per band (nan when empty)<br>• `.plot()` | `res.absorption` |
| `absorption_reference_corrected` | `function` | **Reference-corrected road absorption (Annex B).**<br>• `road_reflection` / `reference_reflection`: measured Qp (complex, same geometry) | `alpha = absorption_reference_corrected(q_road, q_ref)`<br><br>• 1 − \|Qp,road/Qp,ref\|²; removes chain error and Kr |
| `max_sampled_area_radius` | `function` | **Maximum sampled-area radius (Annex A).**<br>• `window_width` Tw [s]<br>• `source_height`, `mic_height`, `speed_of_sound` | `max_sampled_area_radius(0.005)  # 1.34`<br><br>• [m], the Annex A worked example |
| `msa_major_axis` | `function` | **Major axis of the oblique sampled ellipsoid (Annex F).**<br>• `window_width` Tw [s]<br>• `projected_distance` dp [m]<br>• `source_height`, `mic_height`, `speed_of_sound` | `msa_major_axis(0.005, 0.0)  # 3.2`<br><br>• a = cTw + √((ds + dm)² + dp²) [m] |
| `spot_tube_upper_frequency` | `function` | **Spot-tube upper frequency (ISO 13472-2 §5.4.1).**<br>• `diameter` d [m]<br>• `speed_of_sound` (Default: 340.0) | `spot_tube_upper_frequency(0.1)  # 1972`<br><br>• f_u = 0.58c0/d [Hz] |
| `spot_microphone_spacing_bounds` | `function` | **Spacing bounds (s_min, s_max) (§5.4.2).**<br>• `speed_of_sound` (Default: 340.0)<br>• `f_min` (Default: 220), `f_max` (Default: 1800) [Hz] | `spot_microphone_spacing_bounds()  # (0.0773, 0.085)`<br><br>• [m], brackets the nominal 81 mm |
| `check_spot_frequency_range` | `function` | **Advise outside 250–1600 Hz (ISO 13472-2 Scope).**<br>• `frequency` [Hz] | `check_spot_frequency_range(f)`<br><br>• `RoadAbsorptionWarning` out of range |
| `spot_internal_loss_correction` | `function` | **Internal-loss (system) correction (Annex A).**<br>• `measured_absorption`, `system_absorption`: same bands<br>• `clip_negative` (Default: True) | `spot_internal_loss_correction([0.12, 0.10], [0.02, 0.03])  # [0.1, 0.07]`<br><br>• Subtractive Part-2 correction |
| `DEFAULT_SOURCE_HEIGHT` | `float` | **ISO 13472-1 mandatory source height ds [m].**<br>1.25 | `DEFAULT_SOURCE_HEIGHT  # 1.25` |
| `DEFAULT_MIC_HEIGHT` | `float` | **ISO 13472-1 mandatory microphone height dm [m].**<br>0.25 | `DEFAULT_MIC_HEIGHT  # 0.25` |
| `DEFAULT_SPEED_OF_SOUND` | `float` | **Default speed of sound for the road methods [m/s].**<br>340.0 | `DEFAULT_SPEED_OF_SOUND  # 340.0` |
| `PART1_FREQUENCY_RANGE` | `tuple` | **ISO 13472-1 valid band range [Hz].**<br>(250.0, 4000.0) | `PART1_FREQUENCY_RANGE` |
| `SPOT_FREQUENCY_RANGE` | `tuple` | **ISO 13472-2 valid band range [Hz].**<br>(250.0, 1600.0) | `SPOT_FREQUENCY_RANGE` |
| `SPOT_NARROW_BAND_RANGE` | `tuple` | **ISO 13472-2 narrow-band range [Hz].**<br>(220.0, 1800.0) | `SPOT_NARROW_BAND_RANGE` |
| `RoadAbsorptionWarning` | `warning class` | **ISO 13472 advisory.**<br>Emitted for frequencies outside the valid in-situ road-absorption ranges; results there are advisory | `warnings.simplefilter('error', RoadAbsorptionWarning)` |
| `frequency_weighting` | `function` | **Vibration frequency weighting H(f) (ISO 8041-1:2017 Formula 5).**<br>• `name`: one of `WEIGHTING_NAMES`<br>• `frequencies` [Hz] (> 0) | `wr = frequency_weighting('Wk', [1.0, 8.0, 63.0])`<br><br>• `WeightingResponse`; \|H\| = [0.482, 1.036, 0.186] |
| `weighting_factors` | `function` | **Weighting factors \|H(f)\| (the Wi of ISO 2631-1 Eq. 9).**<br>• `name`, `frequencies` [Hz] | `weighting_factors('Wh', [16.0])`<br><br>• Magnitude per frequency |
| `apply_weighting` | `function` | **Apply a weighting to a time signal (frequency domain, exact response).**<br>• `signal`: acceleration (1D) [m/s²]<br>• `fs` [Hz]<br>• `name`: one of `WEIGHTING_NAMES` | `aw_t = apply_weighting(a, fs, 'Wk')`<br><br>• Weighted signal, same length (circular FFT filtering) |
| `WeightingResponse` | `dataclass` | **Weighting response.**<br>• `name`<br>• `frequencies` [Hz]<br>• `response`: complex H<br>• `magnitude`, `magnitude_db` [dB]<br>• `.plot()` | `wr.magnitude, wr.magnitude_db` |
| `WEIGHTING_NAMES` | `tuple` | **ISO 8041-1 weighting names.**<br>('Wb', 'Wc', 'Wd', 'We', 'Wf', 'Wh', 'Wj', 'Wk', 'Wm') | `'Wk' in WEIGHTING_NAMES  # True` |
| `weighted_acceleration` | `function` | **Weighted r.m.s. from a band spectrum (ISO 2631-1 Eq. 9 / ISO 5349-1 Eq. A.1).**<br>• `band_accelerations`: ai per band [m/s²]<br>• `frequencies`: band centres [Hz]<br>• `weighting`: name | `ws = weighted_acceleration([0.1, 0.3, 0.2], [4.0, 8.0, 16.0], 'Wk')`<br><br>• `WeightedSpectrum`; aw = 0.36 m/s² |
| `WeightedSpectrum` | `dataclass` | **Weighted band spectrum.**<br>• `frequencies` [Hz], `band_accelerations` [m/s²]<br>• `weighting_name`, `weighting_factors`<br>• `weighted`: Wi·ai [m/s²]<br>• `overall`: aw [m/s²]<br>• `.plot()` | `ws.overall` |
| `running_rms` | `function` | **Running r.m.s. of a weighted signal (ISO 2631-1 Eqs. 2/3).**<br>• `signal` [m/s²], `fs` [Hz]<br>• `integration_time` τ [s] (Default: 1.0)<br>• `method`: 'linear' (Eq. 2) or 'exponential' (Eq. 3) (Default: 'linear') | `env = running_rms(aw_t, fs)`<br><br>• aw(t0) per sample [m/s²] |
| `mtvv` | `function` | **Maximum transient vibration value (Eq. 4).**<br>• `signal` [m/s²], `fs` [Hz]<br>• `integration_time` [s] (Default: 1.0) | `mtvv(aw_t, fs)`<br><br>• max aw(t0) [m/s²] |
| `vibration_dose_value` | `function` | **Vibration dose value VDV (Eq. 5).**<br>• `signal`: weighted acceleration [m/s²]<br>• `fs` [Hz] | `vdv = vibration_dose_value(aw_t, fs)`<br><br>• (∫aw⁴dt)^(1/4) [m/s^1.75] |
| `motion_sickness_dose_value` | `function` | **Motion sickness dose value MSDV (ISO 2631-1 clause 9).**<br>• `signal`: Wf-weighted acceleration [m/s²]<br>• `fs` [Hz] | `msdv = motion_sickness_dose_value(aw_t, fs)`<br><br>• (∫aw²dt)^(1/2) [m/s^1.5] |
| `crest_factor` | `function` | **Crest factor of a weighted signal (clause 6.2.1).**<br>• `signal` [m/s²] | `crest_factor(aw_t)`<br><br>• peak/r.m.s.; `HumanVibrationWarning` above 9 |
| `vibration_total_value` | `function` | **Vibration total value av/ahv (ISO 2631-1 Eq. 10).**<br>• `components`: axis-weighted r.m.s. [m/s²]<br>• `k`: per-axis factors (Default: None → 1, the ISO 5349-1 vector sum) | `vibration_total_value([0.3, 0.4, 0.5], k=[1.4, 1.4, 1.0])  # 0.86`<br><br>• √(Σ kj²awj²) [m/s²] |
| `wbv_exposure_basis` | `function` | **Whole-body A(8) basis of Directive 2002/44/EC (Annex Part B).**<br>• `a_wx`, `a_wy`: Wd-weighted axis r.m.s. [m/s²]<br>• `a_wz`: Wk-weighted axis r.m.s. [m/s²] | `wbv_exposure_basis(0.35, 0.28, 0.62)  # 0.62`<br><br>• max(1.4·awx, 1.4·awy, awz) [m/s²], the dominant axis (not the vector total av) |
| `daily_exposure` | `function` | **Daily exposure A(8) for one operation (ISO 5349-1 Eq. 2).**<br>• `total_value`: ahv (hand-arm) or aw,max (whole-body) [m/s²]<br>• `duration_s`: T [s] | `daily_exposure(3.0, 4*3600)  # 2.12`<br><br>• ahv √(T/8h) [m/s²] |
| `partial_exposure` | `function` | **Partial exposure Ai(8) of one operation (Eq. 2).**<br>• `total_value` [m/s²], `duration_s` [s] | `partial_exposure(3.0, 2*3600)  # 1.5` |
| `combine_partial_exposures` | `function` | **Combine partial exposures (Eq. 3).**<br>• `partials`: Ai(8) [m/s²] | `combine_partial_exposures([1.5, 2.1])  # 2.58`<br><br>• √(Σ Ai(8)²) [m/s²] |
| `hav_daily_exposure` | `function` | **A(8) for several operations (ISO 5349-1 Eq. 3).**<br>• `total_values`: ahvi [m/s²]<br>• `durations_s`: Ti [s] | `hav_daily_exposure([3.0, 5.0], [2*3600, 3600])  # 2.32` |
| `energy_equivalent_acceleration` | `function` | **Energy-equivalent magnitude aw,e (ISO 2631-1 Eq. B.3).**<br>• `magnitudes` [m/s²], `durations_s` [s] | `energy_equivalent_acceleration([0.5, 1.0], [3600, 1800])  # 0.707` |
| `hav_vwf_lifetime_years` | `function` | **Years to 10 % vibration-white-finger prevalence (ISO 5349-1 Eq. C.1).**<br>• `a8`: A(8) [m/s²] (> 0) | `hav_vwf_lifetime_years(2.5)  # 12.0`<br><br>• Dy = 31.8 A(8)^−1.06 [years] |
| `exposure_assessment` | `function` | **Assess a daily exposure (Directive 2002/44/EC Article 3).**<br>• `value`: A(8) [m/s²] or VDV [m/s^1.75]<br>• `kind`: 'hav'/'wbv'<br>• `metric`: 'a8' (Default) or 'vdv' (whole-body only) | `ea = exposure_assessment(3.0, kind='hav')`<br><br>• `ExposureAssessment` (zone 'action') |
| `ExposureAssessment` | `dataclass` | **Directive assessment.**<br>• `value`, `kind`, `metric`<br>• `action_value` (EAV), `limit_value` (ELV)<br>• `exceeds_action`, `exceeds_limit`<br>• `zone`: 'below action'/'action'/'limit' | `ea.zone, ea.exceeds_limit` |
| `daily_vibration_exposure` | `function` | **A(8) from several operations, assessed (ISO 5349 + Directive).**<br>• `total_values` [m/s²], `durations_s` [s]<br>• `kind`: 'hav'/'wbv'<br>• `labels` (Default: None → 'op 1', …) | `res = daily_vibration_exposure([3.0, 5.0], [2*3600, 3600], kind='hav')`<br><br>• `DailyVibrationExposure` (A(8) = 2.32) |
| `DailyVibrationExposure` | `dataclass` | **Assessed daily exposure.**<br>• `a8` [m/s²]<br>• `labels`, `total_values`, `durations_s`, `partials`<br>• `assessment`: `ExposureAssessment`<br>• `.plot()` | `res.a8, res.assessment.zone` |
| `HumanVibrationWarning` | `warning class` | **Human-vibration advisory.**<br>Emitted for a crest factor above 9 (ISO 2631-1 6.2.2) or other out-of-range measurement conditions | `warnings.simplefilter('error', HumanVibrationWarning)` |
| `REFERENCE_ACCELERATION` | `float` | **Vibration reference acceleration [m/s²].**<br>1e-6 (ISO 1683 acceleration level reference) | `REFERENCE_ACCELERATION  # 1e-06` |
| `REFERENCE_DURATION_S` | `float` | **Daily-exposure reference duration T0 [s].**<br>28800 (8 h) | `REFERENCE_DURATION_S  # 28800.0` |
| `HAV_EAV_A8` | `float` | **Hand-arm exposure action value [m/s²].**<br>2.5 (Directive 2002/44/EC) | `HAV_EAV_A8  # 2.5` |
| `HAV_ELV_A8` | `float` | **Hand-arm exposure limit value [m/s²].**<br>5.0 | `HAV_ELV_A8  # 5.0` |
| `WBV_EAV_A8` | `float` | **Whole-body A(8) action value [m/s²].**<br>0.5 | `WBV_EAV_A8  # 0.5` |
| `WBV_ELV_A8` | `float` | **Whole-body A(8) limit value [m/s²].**<br>1.15 | `WBV_ELV_A8  # 1.15` |
| `WBV_EAV_VDV` | `float` | **Whole-body VDV action value [m/s^1.75].**<br>9.1 | `WBV_EAV_VDV  # 9.1` |
| `WBV_ELV_VDV` | `float` | **Whole-body VDV limit value [m/s^1.75].**<br>21.0 | `WBV_ELV_VDV  # 21.0` |
| `fdtd_simulation` | `function` | **2D acoustic FDTD wave simulation (staggered grid, leapfrog).**<br>• `c`: sound-speed map [m/s], `(ny, nx)` array or scalar with `shape`<br>• `dx`: grid spacing [m]<br>• `duration`: physical time to simulate [s]<br>• `sources`: `GaussianPulse` \| `CWSource` \| `SignalSource` list<br>• `probes`: `(ix, iy)` pressure-probe cells<br>• `boundaries`: `"rigid"` \| `"absorbing"` \| per-side mapping (name or real impedance [Pa·s/m])<br>• `obstacle_mask`: boolean `(ny, nx)` rigid-cell map / `rho` / `cfl` / `damping` / `absorbing_layer_cells` / `snapshot_every` | `res = fdtd_simulation(343, 0.01, 0.02, shape=(200, 300), sources=[GaussianPulse(ix=60, iy=100, width=3e-4)], probes=[(200, 100)])`<br><br>• `FDTDResult` |
| `FDTDResult` | `dataclass` | **FDTD simulation result.**<br>• `times` [s] / `pressures` [Pa] per probe / `probes` / `probe_positions` [m]<br>• `dx` / `dt` / `shape` / `size` [m] / `sources` / `snapshots` / `snapshot_times` / `obstacle_mask`<br>• `.plot()`: probe histories; `.plot(kind="snapshot")`: pressure field | `res.pressures, res.times`<br>`res.plot()` |
| `FDTD2D` | `class` | **FDTD stepping engine (frame-by-frame access).**<br>• `c` [m/s] / `dx` [m] / `rho` [kg/m³] / `cfl` / `shape`<br>• `sponge_width` / `sponge_sides` / `sponge_reflection` / `damping`<br>• `edge_impedance`: per-side real impedance [Pa·s/m] / `obstacle_mask` | `sim = FDTD2D(343, 0.01, shape=(200, 300))`<br>`sim.add_source(src); sim.step(); sim.run(400, record_every=10)`<br>• `sim.p` / `sim.vx` / `sim.vy` / `sim.dt` / `sim.time` / `sim.energy()` |
| `GaussianPulse` | `dataclass` | **Gaussian pulse source for the FDTD solver.**<br>• `ix` / `iy`: source cell<br>• `width` [s] / `t0` [s] (Default: `4*width`) / `amplitude` [Pa] | `GaussianPulse(ix=60, iy=100, width=3e-4)` |
| `CWSource` | `dataclass` | **Continuous sine source with raised-cosine onset for the FDTD solver.**<br>• `ix` / `iy`: source cell<br>• `frequency` [Hz] / `amplitude` [Pa] / `ramp_cycles` | `CWSource(ix=25, iy=25, frequency=170)` |
| `SignalSource` | `dataclass` | **Arbitrary sampled waveform source for the FDTD solver.**<br>• `ix` / `iy`: source cell<br>• `samples` [Pa] / `sample_rate` [Hz] / `amplitude`<br>Linearly interpolated onto the simulation time steps | `SignalSource(ix=60, iy=100, samples=sig, sample_rate=48000)` |
| `PhonometryWarning` | `warning class` | **Base class for all phonometry warnings.**<br>Catch or silence every library advisory at once | `warnings.simplefilter('error', PhonometryWarning)` |
| `FilterBankWarning` | `warning class` | **Fractional-octave filter-bank advisory.**<br>Emitted for filter-bank processing pitfalls | `warnings.simplefilter('error', FilterBankWarning)` |
| `TonalityWarning` | `warning class` | **Tonality advisory.**<br>Emitted for biased tonality estimates (e.g. coarse FFT resolution) | `warnings.simplefilter('error', TonalityWarning)` |
| `STIWarning` | `warning class` | **STI/STIPA advisory.**<br>Emitted for suspect speech-intelligibility measurements or inputs | `warnings.simplefilter('error', STIWarning)` |
| `octavefilter` / `getansifrequencies` / `normalizedfreq` / `calculate_sensitivity` / `coverage_factor` / `expanded_uncertainty` | `function` | **Deprecated aliases (warn on use; removal in 4.0).**<br>New names: `octave_filter`, `nominal_frequencies`, `normalized_frequencies`, `sensitivity`, `insulation_coverage_factor`, `insulation_expanded_uncertainty` | `octave_filter(x, fs)  # not octavefilter` |
| `__version__` | `str` | **Package version string.**<br>(no parameters) | `phonometry.__version__  # '3.2.0'` |
| `.plot()` | `method` | **One-line canonical figure on every result object (soft matplotlib dependency).**<br>Available on `ZwickerLoudness`, `MooreGlasbergLoudness`, `MooreGlasbergTimeVaryingLoudness`, `EcmaLoudness`, `EcmaTonality`, `EcmaRoughness`, `PsychoacousticAnnoyanceResult`, `FluctuationStrengthResult`, `ProgramLoudnessResult`, `KWeightingResponse`, `STIResult`, `SIIResult`, `StandardSpeechSpectrum`, `NCResult`, `RCResult`, `AgeThresholdResult`, `NiptsResult`, `HtlanResult`, `ImpulseProminenceResult`, `ImpulsiveSoundResult`, `MultipleShockResult`, `ImpulseResponseResult`, `DecayCurve`, `RoomAcousticsResult`, `ReverberationResult`, `ReverberationModelResult`, `DynamicStiffnessResult`, `MobilityResult`, `TransferStiffnessResult`, `VibrationSoundPowerResult`, `StructureBornePowerResult`, `InstalledSourceResult`, `WeightedRatingResult`, `ImpactRatingResult`, `FacadeInsulationResult`, `LabAirborneInsulationResult`, `LabImpactInsulationResult`, `SoundPowerResult`, `ReverberationSoundPowerResult`, `SoundPowerIntensityResult`, `PrecisionSoundPowerResult`, `PrecisionIntensityResult`, `IntensityResult`, `UncertaintyResult`, `AbsorptionRatingResult`, `ScatteringResult`, `DiffusionResult`, `DiffusionSpectrum`, `InsituAbsorptionResult`, `WeightingResponse`, `WeightedSpectrum` and `DailyVibrationExposure`.<br>• `ax`: existing Axes, or None to build a fresh figure (Default: None)<br>• returns the Matplotlib `Axes` (an array of Axes for multi-panel figures); never calls `plt.show()`<br>• needs matplotlib (`pip install phonometry[plot]`) | `res.plot()`<br>`decay_curve(ir, fs).plot()` |

## Notes

- `zero_phase=True` (in `OctaveFilterBank.filter` and `spectrogram`) filters
  forward-backward (`sosfiltfilt`): no group delay, doubled effective
  attenuation, offline analysis only. Incompatible with `stateful=True`. The
  passband also narrows, lowering the measured broadband band level by ~0.2 to
  0.3 dB per band (a pure in-band tone is unaffected); prefer forward filtering
  when the absolute band SPL must match single-pass conventions, and reserve
  zero-phase for when the temporal envelope matters (e.g. reverberation decay).
- `mode='peak'` includes the filter's onset transient; a tone that starts
  abruptly can overshoot by ~1 dB. See [Calibration and dBFS](calibration.md).
- `octave_filter()` caches filter bank designs internally (32 entries), so
  repeated calls with the same parameters skip the design phase. For explicit
  control use `OctaveFilterBank`.
- Deprecated aliases (kept for one cycle, warn on use, removal in 4.0):
  `octavefilter` → `octave_filter`, `getansifrequencies` →
  `nominal_frequencies`, `normalizedfreq` → `normalized_frequencies`,
  `calculate_sensitivity` → `sensitivity`, `coverage_factor` →
  `insulation_coverage_factor`, `expanded_uncertainty` →
  `insulation_expanded_uncertainty`, plus the renamed names
  `OCTAVE_BANDS_HZ` → `OCTAVE_BANDS`, `THIRD_OCTAVE_BANDS_HZ` →
  `THIRD_OCTAVE_BANDS`, `BASE_PLATE_BANDS_HZ` → `BASE_PLATE_BANDS` and
  `ExposureWarning` → `OccupationalExposureWarning`.
