API Reference

September 24, 2026 · View on GitHub

← Documentation index

API Reference

All core functionality lives in twenty-one subpackages, and every public name is reached through the one that owns it. The top-level phonometry package publishes those twenty-one and four names that belong to none of them: Signal, ReportMetadata, PhonometryWarning and __version__.

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.

Namespaces

The library is organized into twenty-one subpackages, and importing the namespace is the primary form used throughout the documentation:

from phonometry import aircraft

contour = aircraft.noise_contour(..., x=..., y=...)   # the shape of every call
SubpackageScope
phonometry.filtersOctave and fractional-octave filter banks, frequency weightings and time weighting, parametric EQ, IEC 61260-1 and IEC 61672-1 class verification
phonometry.signalsLevels (Leq, LAeq, percentiles), Welch and multitaper spectra, coherence, time-frequency, correlation, envelope, cepstrum, phase, synchronous averaging, test signals
phonometry.metrologyCalibration, GUM uncertainty and Monte Carlo, data qualification (stationarity, trends, peak statistics), the ISO 1683 reference values
phonometry.fluidsThe state of the propagating medium: humid air from IEC 61094-2:2009 Annex F (CIPM-2007), with the conditions it was computed for and the domain its model states for itself
phonometry.solidsThe elastic constants of a solid and the three longitudinal wave speeds that follow from them, named apart by the shape the wave travels in (beam, plate, unbounded), with the inverse of each and the h f_c a materials table prints
phonometry.ioMeasurement audio files: WAV/BWF/RF64 read and write with bext provenance (EBU Tech 3285), headers-only info, block streaming, lossless conversion, calibration sidecar; FLAC, AIFF, Ogg/Opus and MP3 via the [audio] extra
phonometry.psychoacousticsTwo families: loudness (ISO 532-1 Zwicker, ISO 532-2 and ISO 532-3 Moore-Glasberg, ECMA-418-2, ISO 226 equal-loudness contours) and quality (sharpness, roughness, fluctuation strength, tonality, tone audibility, annoyance), plus the ERB scale both measure on
phonometry.speechSpeech Transmission Index (IEC 60268-16), Speech Intelligibility Index (ANSI S3.5), STOI and ESTOI
phonometry.hearingAudiometric thresholds (ISO 7029/389-7), noise-induced hearing loss (ISO 1999), occupational exposure (ISO 9612)
phonometry.emissionSound power (ISO 3740 family), sound intensity and the IEC 61043 instrument class it is measured with, vibration-based power
phonometry.roomRoom acoustics (ISO 3382), impulse responses, open-plan, room-noise criteria, reverberation prediction, EN 12354-6
phonometry.buildingThree subgroups: measurement (field, laboratory, survey and intensity methods with their ISO 717 ratings and ISO 12999 uncertainty), prediction (EN 12354 global and detailed models, facades, panels, apertures, plenums and resilient layers) and regulation (national codes)
phonometry.materialsFour families by what the material does: absorbers (ISO 354, ISO 11654, ISO 12999-2, impedance tube ISO 10534-2, airflow resistance ISO 9053, porous and multilayer models, Biot, slow-sound metamaterials), diffusers (Schroeder design, metadiffusers, scattering and diffusion ISO 17497), surfaces (in-situ road absorption ISO 13472) and resilient (dynamic stiffness EN 29052-1)
phonometry.vibrationThree families: structural (mobility ISO 7626, plate junctions, radiation, experimental SEA, transfer stiffness ISO 10846), human (ISO 2631/5349/8041 exposure and multiple shocks) and machinery (fault frequencies and condition monitoring)
phonometry.environmentThree subgroups: sources (CNOSSOS road and rail emission, wind-turbine apparent sound power), propagation (ISO 9613-1/-2, ground effect and barriers, refraction by ray tracing and the parabolic equation) and assessment (ISO 1996-1/-2 rating and measurement, impulsive prominence, RD 1367/2007)
phonometry.aircraftEPNL (ICAO Annex 16), SAE ARP 5534 absorption, airport contours (ECAC Doc 29), rotorcraft (ECAC Doc 32)
phonometry.underwaterThree families: sources (ISO 17208 ship radiated noise, traffic, pile driving, wind and thermal ambient noise), propagation (closed-form and Weston propagation loss, normal modes, rays, Gaussian beams and the parabolic equation, seabed reflection, sound speed) and bioacoustics (marine-mammal audiograms and regulatory auditory weighting), over the ISO 18405 quantities and the sonar equation at the root
phonometry.electroacousticsDistortion (IEC 60268-3 / AES17), transfer function and coherence, radiating piston
phonometry.noise_controlReactive silencers (four-pole method), HVAC duct attenuation, machine-enclosure insertion loss
phonometry.broadcastProgramme loudness and true peak (ITU-R BS.1770-5, EBU R 128 with Tech 3341/3342)
phonometry.simulation2D acoustic FDTD wave simulation (staggered grid, sources, probes, impedance boundaries, obstacles)

The table below lists each name unqualified, the way its own page titles it; the usage snippet shows the namespace to import and call it through. The module paths of every earlier layout were removed in 4.0 along with the shims that served them, so phonometry.metrology.levels, phonometry.environmental and the rest of the pre-4.0 spellings raise ModuleNotFoundError. The paths in force are the ones the generated reference documents, one page per module.

Reading the input column. Every function that consumes a recording accepts a phonometry.io.Signal wherever the table writes a signal argument, and then fs is optional: the object carries it, and an explicit value that disagrees with it raises rather than overriding it. A bare array still requires fs by name. A calibrated Signal is analysed in pascals, with four documented exemptions (the EBU R 128 family, the dbfs=True paths, quantities that are not pressures, and metrology.sensitivity, which is what produces a calibration factor). Each function's own page states which of these applies to it.

NameTypeDescription (Inputs)Usage Snippet (Outputs)
octave_filterfunctionHigh-level analysis.
• x: Signal array
• fs: Sample rate [Hz]
• fraction: 1, 3, etc. (Default: 1)
• order: Filter order (Default: 6)
• limits: [f_min, f_max] (Default: [12, 20000])
• sigbands: Return time signals (Default: False)
• detrend: Remove DC offset (Default: True)
• mode: 'rms' or 'peak' (Default: 'rms')
• nominal: IEC 61260-1 nominal labels (Default: False)
• design: FilterDesign (family, ripple, attenuation, decimation)
• calibration: LevelCalibration (factor, dBFS)
• response_plot: ResponsePlot (show, file)
r = filters.octave_filter(x, fs, ...)
• r.levels: band levels [dB]
• r.frequencies: band centres [Hz]
• r.bands: one waveform per band, or None

With sigbands=True:
bands = filters.octave_filter(x, fs, sigbands=True).require_bands()

Calibrated usage:
filters.octave_filter(x, fs, calibration=filters.LevelCalibration(factor=0.05)).levels
OctaveFilterResultdataclassWhat a filter bank gives back for one signal.
• levels: band levels [dB], (bands,) or (channels, bands), None when the call asked for no level
• frequencies: one band centre per level, exact or IEC 61260-1 nominal labels
• bands: one waveform per band, None unless sigbands=True
• .require_levels() / .require_bands(): the value, or a ValueError naming the argument that was missing
• .plot(): the band spectrum on a log frequency axis
r = filters.octave_filter(x, fs, fraction=3)
r.levels[r.frequencies.index(1000.0)]

• ax = r.plot()
OctaveFilterBankclassEfficient bank implementation.
• fs: Sample rate [Hz]
• fraction: 1, 3, etc.
• order: Filter order
• limits: [f_min, f_max] (Default: [12, 20000])
• design: FilterDesign (family, ripple, attenuation, decimation)
• calibration: LevelCalibration (factor, dBFS)
• block_processing: BlockProcessing (stateful, steady_ic)
• response_plot: ResponsePlot (show, file)
bank = filters.OctaveFilterBank(fs=48000, fraction=3, order=6, design=filters.FilterDesign(filter_type='butter'))
r = bank.filter(x, sigbands=False, mode='rms', detrend=True, zero_phase=False)
• r.levels, r.frequencies, r.bands (an OctaveFilterResult)

• bank: Instance of the filter bank
• bank.freq / bank.freq_d / bank.freq_u / bank.sos: computed properties
FilterDesigndataclassHow the band filters are designed.
• filter_type: 'butter', 'cheby1', 'cheby2', 'ellip', 'bessel' (Default: 'butter')
• ripple: Passband ripple [dB] (for cheby1/ellip; Default: 0.1)
• attenuation: Stopband attenuation [dB] (Default: 72; cheby2 needs >= 70 dB for class 1)
• resample: Multirate decimation (Default: True)
OctaveFilterBank(48000, 3, design=filters.FilterDesign(filter_type='cheby2'))
LevelCalibrationdataclassHow band energy becomes a level.
• factor: Sensitivity multiplier, Pa per digital unit (Default: 1.0)
• dbfs: Output in dBFS instead of dB SPL (Default: False)
octave_filter(x, fs, calibration=filters.LevelCalibration(factor=0.05))
BlockProcessingdataclassFilter state carried between calls.
• stateful: Carry filter state between calls (Default: False)
• steady_ic: Steady-state initial conditions (Default: False)
OctaveFilterBank(48000, 1, design=filters.FilterDesign(resample=False), block_processing=filters.BlockProcessing(stateful=True))
ResponsePlotdataclassResponse plot drawn while designing.
• show: Show the plot (Default: False)
• file: Path to save the plot (Default: None)
OctaveFilterBank(48000, 3, response_plot=filters.ResponsePlot(show=True))
OctaveFilterBank.spectrogrammethodBand levels over time.
• x: Signal array (1D or 2D)
• window_time: Window length [s] (Default: 0.125)
• overlap: Fraction in [0, 1) (Default: 0.5)
• mode: 'rms' or 'peak'
• zero_phase: Group-delay-free frames (Default: False)
levels, freq, times = bank.spectrogram(x)

• levels: (bands, frames) or (channels, bands, frames)
• times: window centers [s]
weighting_filterfunctionAcoustic weighting.
• x: Signal array
• fs: Sample rate [Hz]
• curve: 'A', 'C' (IEC 61672-1), 'B' (ANSI S1.4-1983, historical), 'D' (withdrawn IEC 537, aircraft), 'G' (ISO 7196 infrasound), 'AU' (IEC 61012), '468' (ITU-R BS.468-4 psophometric) or 'Z' (Default: 'A')
• high_accuracy: fit the analog prototype at fs instead of transforming it blind, for IEC class 1 accuracy at every rate (Default: True; '468' requires it)
y = filters.weighting_filter(x, fs, curve='A')

• y: weighted signal
WeightingFilterclassReusable weighting filter.
• fs: Sample rate [Hz]
• curve: 'A', 'B', 'C', 'D', 'G', 'AU', '468' or 'Z'
• stateful: Block processing (Default: False)
• steady_ic: Steady-state initial conditions (Default: False)
• high_accuracy: Fitted design, independent of stateful (Default: True; '468' refuses False)
wf = filters.WeightingFilter(fs, 'A')
y = wf.filter(x)
time_weightingfunctionEnergy capture.
• x: Raw signal array (squared internally; time is the last axis)
• fs: Sample rate [Hz]
• mode: 'fast', 'slow', or 'impulse'
• initial_state: None, 'zero', 'first', scalar, or array (Default: None)
env = filters.time_weighting(x, fs, mode='fast')

• env: energy envelope (Mean Square), same shape as x
TimeWeightedEnvelopedataclassExponentially averaged mean square of a record, with its rate.
• mean_square [Pa² when calibrated], fs [Hz], mode, calibrated
• stands in for the bare array it replaced (np.asarray, indexing, shape)
• returned by time_weighting/TimeWeighting.process for a Signal input; a mean square is not a pressure record, so it is not a Signal
env = filters.time_weighting(filters.weighting_filter(sig, curve='A'), mode='fast')
env.plot() # the L_pAF trace in dB
TimeWeightingclassStateful time weighting.
• fs: Sample rate [Hz]
• mode: 'fast', 'slow', 'impulse' (Default: 'fast')
tw = filters.TimeWeighting(fs, mode='fast')
env = tw.process(block) per block
tw.reset() to start over
leqfunctionEquivalent level (Leq).
• x: Signal array (1D or 2D) or a phonometry.io.Signal
• calibration_factor: Sensitivity multiplier (Default: None: a calibrated Signal's factor, else 1.0; explicit wins)
• dbfs: Output in dBFS (Default: False)
level = signals.leq(x, calibration_factor=s)

• level: Scalar (1D) or per-channel array (2D)
laeqfunctionA-weighted Leq (LAeq).
• x: Signal array (1D or 2D) or a phonometry.io.Signal
• fs: Sample rate [Hz] (taken from x when x is a Signal)
• calibration_factor / dbfs: as leq
level = signals.laeq(x, fs, calibration_factor=s)

• level: Scalar (1D) or per-channel array (2D)
ln_levelsfunctionStatistical levels (LN).
• x: Signal array (1D or 2D) or a phonometry.io.Signal
• fs: Sample rate [Hz] (taken from x when x is a Signal)
• n: Exceedance percentiles (Default: (10, 50, 90))
• mode: 'fast', 'slow', 'impulse' (Default: 'fast')
• weighting: any weighting_filter curve, 'A', 'B', 'C', 'D', 'G', 'AU', '468' or 'Z', or None (Default: None)
• calibration_factor / dbfs: as leq
stats = signals.ln_levels(x, fs, n=(10, 50, 90), weighting='A')

• stats: Dict {10: L10, 50: L50, 90: L90}
lc_peakfunctionC-weighted peak (LCpeak).
• x: Signal array (1D or 2D) or a phonometry.io.Signal
• fs: Sample rate [Hz] (taken from x when x is a Signal)
• calibration_factor: as leq
• dbfs: 0 dBFS = full-scale peak (amplitude 1.0), unlike the RMS reference of leq
• oversample: HF inter-sample peak recovery (Default: 8; 1 = on-grid, under-reads up to ~1.15 dB at 48 kHz)
peak = signals.lc_peak(x, fs)

• IEC 61672-1 §5.13; verified against Table 5
selfunctionSound exposure level (SEL/LAE).
• x: Whole-event signal (1D or 2D) or a phonometry.io.Signal
• fs: Sample rate [Hz] (taken from x when x is a Signal)
• weighting: any weighting_filter curve, 'A', 'B', 'C', 'D', 'G', 'AU', '468' or 'Z', or None (Default: None)
• calibration_factor / dbfs: as leq
lae = signals.sel(x, fs, weighting='A')

• Event level normalized to 1 s
sound_exposurefunctionA-weighted exposure E (IEC 61252).
• x: Signal (1D or 2D) or a phonometry.io.Signal
• fs: Sample rate [Hz] (taken from x when x is a Signal)
• duration_hours: exposure period represented (Default: recording length)
• calibration_factor
E = signals.sound_exposure(x, fs, duration_hours=8)

• E: Pa²·h
lex_8hfunctionDaily exposure LEX,8h / LEP,d.
• Same params as sound_exposure
lex = signals.lex_8h(x, fs, duration_hours=4)

• Normalized 8 h level [dB]
loudness_zwickerfunctionZwicker loudness (ISO 532-1:2017).
• x: Calibrated signal in Pa (1D)
• fs: Sample rate [Hz]
• field: 'free' or 'diffuse' (Default: 'free')
• stationary: Clause 5 stationary method (Default: False)
• time_skip: seconds excluded from the stationary mean square (Annex B.1 uses 0.2 s; Default: 0.0)
• calibration_factor: Digital units to Pa (Default: 1.0)
res = psychoacoustics.loudness_zwicker(x, fs)

• ZwickerLoudness; time-varying runs add N5/N10 and the 500 Hz N(t) trace
loudness_zwicker_from_spectrumfunctionStationary loudness from band levels.
• levels: 28 one-third-octave levels, 25 Hz-12.5 kHz [dB SPL]
• field: 'free' or 'diffuse' (Default: 'free')
res = psychoacoustics.loudness_zwicker_from_spectrum(levels)

• res.loudness [sone], res.loudness_level [phon]
ZwickerLoudnessdataclassLoudness result.
• loudness: N [sone]
• loudness_level: LN [phon]
• specific: N′(z), 240 bins of 0.1 Bark
• n5 / n10: percentile loudness (time-varying only)
• times / loudness_vs_time: 500 Hz trace
• field: sound field assumed ('free'/'diffuse')
res.loudness, res.n5

• Time-varying fields are None for stationary results
sharpness_dinfunctionSharpness in acum (DIN 45692).
• x: Signal (1D)
• fs: Sample rate [Hz]
• field: 'free' or 'diffuse' (Default: 'free')
• method: 'din', 'aures' or 'bismarck' (Default: 'din')
• calibration_factor: Digital units to Pa (Default: 1.0)
s = psychoacoustics.sharpness_din(x, fs)

• s: sharpness [acum]
sharpness_din_from_specificfunctionSharpness from a specific-loudness pattern.
• specific: N′(z), 240 values at 0.1 Bark (e.g. ZwickerLoudness.specific)
• method: 'din', 'aures' or 'bismarck' (Default: 'din')
s = psychoacoustics.sharpness_din_from_specific(res.specific)

• s: sharpness [acum]
erb_bandwidthfunctionAuditory-filter equivalent rectangular bandwidth ERB_N (Glasberg & Moore 1990; Moore 6e p. 76).
• frequency [Hz] (scalar or array, ≥ 0)
• ERB_N = 24.673(0.004368 f + 1) [Hz]
erb_bandwidth(1000.0) # 132.4
cam_from_frequency / frequency_from_camfunctionThe Cam (ERB_N-number) frequency scale, one unit per auditory-filter width.
• cam_from_frequency(f) = 21.366 log10(0.004368 f + 1) [Cam]
• frequency_from_cam(i): the exact inverse [Hz]
cam_from_frequency(1000.0) # 15.59
frequency_from_cam(15.59)
ERB_C1 / ERB_C2 / CAM_CconstantConstants of the ERB_N fit shared with the ISO 532-2 loudness model.
• ERB_C1 = 24.673 [Hz], ERB_C2 = 0.004368 [1/Hz], CAM_C = 21.366 [Cam]
ERB_C1 * (ERB_C2 * f + 1)
loudness_moore_glasbergfunctionMoore-Glasberg loudness (ISO 532-2:2017).
• x: Calibrated signal in Pa (1D)
• fs: Sample rate [Hz]
• field: 'free', 'diffuse' or 'eardrum' (Default: 'free')
• presentation: 'binaural'/'diotic' or 'monaural' (Default: 'binaural')
res = psychoacoustics.loudness_moore_glasberg(x, fs)

• MooreGlasbergLoudness (roex excitation pattern)
loudness_moore_glasberg_from_spectrumfunctionExact loudness from sinusoidal components (ISO 532-2 §5.2/5.4).
• components: sequence of (frequency [Hz], level [dB SPL]) pairs
• field: 'free'/'diffuse'/'eardrum' (Default: 'free')
• presentation: (Default: 'binaural')
res = psychoacoustics.loudness_moore_glasberg_from_spectrum([(1000.0, 40.0)])

• 1 kHz/40 dB → 1.000 sone
loudness_moore_glasberg_from_third_octavefunctionLoudness from 29 one-third-octave band levels (ISO 532-2 §5.5).
• band_levels: 29 levels, 25 Hz–16 kHz [dB SPL]
• field / presentation: as above
res = psychoacoustics.loudness_moore_glasberg_from_third_octave(levels)

• MooreGlasbergLoudness
MooreGlasbergLoudnessdataclassMoore-Glasberg loudness result.
• loudness: N [sone]
• loudness_level: LN [phon]
• specific: N′(i), 372 bins of 0.1 Cam
• erb_number / centre_frequencies: Cam / Hz axes
• field / presentation
• .plot(): specific loudness N′(i) over Cam
res.loudness, res.loudness_level
loudness_moore_glasberg_timefunctionTime-varying loudness (ISO 532-3:2023).
• signal: Calibrated Pa; 1D (diotic) or (n, 2) ears
• fs: Sample rate [Hz]
• field: 'free'/'diffuse'/'eardrum' (Default: 'free')
• presentation: (Default: 'binaural')
• percentiles: exceedance % (Default: (1,5,10,50,90,95))
res = psychoacoustics.loudness_moore_glasberg_time(x, fs)

• MooreGlasbergTimeVaryingLoudness
MooreGlasbergTimeVaryingLoudnessdataclassTime-varying loudness result.
• times: 1 ms grid [s]
• short_term_loudness / long_term_loudness: S′(t)/S″(t) [sone]
• short_term_loudness_level / long_term_loudness_level [phon]
• n_max / loudness_level_max: peak long-term loudness
• percentiles: dict {percent: sone}
• .plot(): STL and LTL vs time
res.n_max, res.percentiles[5.0]
loudness_ecmafunctionSottek Hearing Model loudness (ECMA-418-2:2025).
• signal_in: Calibrated signal in Pa (1D)
• fs: Sample rate [Hz] (resampled to 48 kHz)
• field: 'free' or 'diffuse' (Default: 'free')
res = psychoacoustics.loudness_ecma(x, fs)

• EcmaLoudness; 1 kHz/40 dB ≈ 1 sone_HMS
EcmaLoudnessdataclassSottek loudness result.
• loudness: N [sone_HMS]
• specific_loudness: N′(z), 53 Bark_HMS bands
• bark / centre_frequencies: z / Hz axes
• times / loudness_vs_time: N(l) at 187.5 Hz
• field
• .plot(): N′(z) + N(l)
res.loudness, res.specific_loudness
tonality_ecmafunctionSottek tonality (ECMA-418-2:2025).
• signal_in: Calibrated signal in Pa (1D)
• fs: Sample rate [Hz] (resampled to 48 kHz)
• field: 'free' or 'diffuse' (Default: 'free')
• f_low / f_high: optional user band [Hz] (Default: None)
res = psychoacoustics.tonality_ecma(x, fs)

• EcmaTonality; 1 kHz/40 dB ≈ 1 tu_HMS
EcmaTonalitydataclassSottek tonality result.
• tonality: T [tu_HMS]
• specific_tonality: T′(z), 53 bands
• tonal_frequencies: f_ton,z per band [Hz]
• bark / centre_frequencies
• times / tonality_vs_time / tonal_frequency_vs_time: T(l), f_ton(l)
• field
• .plot(): T′(z) + T(l)
res.tonality, res.tonal_frequencies
roughness_ecmafunctionSottek roughness (ECMA-418-2:2025), new capability.
• signal_in: Calibrated signal in Pa (1D)
• fs: Sample rate [Hz] (resampled to 48 kHz)
• field: 'free' or 'diffuse' (Default: 'free')
res = psychoacoustics.roughness_ecma(x, fs)

• EcmaRoughness; 1 kHz/70 Hz/100 %-AM/60 dB ≈ 1 asper
EcmaRoughnessdataclassSottek roughness result.
• roughness: R [asper] (90th percentile of R(l50))
• specific_roughness: R′(z), 53 bands
• bark / centre_frequencies
• times / roughness_vs_time: R(l50) at 50 Hz
• specific_roughness_vs_time: (n_times, 53)
• field
• .plot(): R(l50) + specific-roughness heatmap
res.roughness, res.specific_roughness
fluctuation_strength_ecmafunctionSottek fluctuation strength (ECMA-418-2:2025 Clause 9), new capability.
• signal_in: Calibrated signal in Pa (1D)
• fs: Sample rate [Hz] (resampled to 48 kHz)
• field: 'free' or 'diffuse' (Default: 'free')
res = psychoacoustics.fluctuation_strength_ecma(x, fs)

• EcmaFluctuationStrength; 1 kHz/4 Hz/100 %-AM/60 dB ≈ 1 vacil_HMS
EcmaFluctuationStrengthdataclassSottek fluctuation-strength result.
• fluctuation_strength: F [vacil_HMS] (90th percentile of F(l50))
• specific_fluctuation_strength: F′(z), 53 bands
• bark / centre_frequencies
• times / fluctuation_strength_vs_time: F(l50) at 50 Hz
• specific_fluctuation_strength_vs_time: (n_times, 53)
• field
• .plot(): F(l50) + specific-fluctuation-strength heatmap
res.fluctuation_strength, res.specific_fluctuation_strength
psychoacoustic_annoyancefunctionPsychoacoustic annoyance PA (Fastl & Zwicker Eqs 16.2–16.4), exact model.
• n5: percentile loudness N5 [sone]
• sharpness S [acum]
• fluctuation_strength F [vacil]
• roughness R [asper]
res = psychoacoustics.psychoacoustic_annoyance(30, 2.0, 0.5, 0.3)

• PsychoacousticAnnoyanceResult; res.annoyance == 37.0478
psychoacoustic_annoyance_from_signalfunctionPA from a calibrated signal (convenience, engineering estimate).
• x: Calibrated signal in Pa (1D)
• fs: Sample rate [Hz]
• field: 'free' or 'diffuse' (Default: 'free')
• calibration_factor (Default: 1.0)
Mixes Zwicker N5/S + Sottek R + Osses F.
res = psychoacoustics.psychoacoustic_annoyance_from_signal(x, fs)

• PsychoacousticAnnoyanceResult
PsychoacousticAnnoyanceResultdataclassPsychoacoustic annoyance result.
• annoyance: PA
• n5 [sone] / sharpness [acum] / fluctuation_strength [vacil] / roughness [asper]: the four inputs
• w_s: sharpness weighting wS
• w_fr: roughness/fluctuation weighting wFR
• .plot(): term-contribution bar
res.annoyance, res.w_s, res.w_fr
fluctuation_strength_am_noisefunctionFluctuation strength of AM broadband noise (Fastl & Zwicker Eq. 10.2), exact closed form.
• level_db L [dB]
• modulation_factor m (0–1)
• mod_frequency fmod [Hz]
fluctuation_strength_am_noise(60, 1.0, 4.0) # 3.6943 vacil
fluctuation_strengthfunctionFluctuation strength F (Osses 2016 signal model), no numeric standard, free-field.
• signal_in: Calibrated signal in Pa (1D)
• fs: Sample rate [Hz]
res = psychoacoustics.fluctuation_strength(x, fs)

• FluctuationStrengthResult; 1 kHz/60 dB/m=1/4 Hz AM ≈ 1 vacil
FluctuationStrengthResultdataclassFluctuation strength result.
• fluctuation_strength: F [vacil]
• specific: F′(z), 47 values
• bark_axis: z [Bark], 47 values
• time_dependent: F(t) per frame
• .plot(): specific F′(z) over the Bark axis
res.fluctuation_strength, res.specific
equal_loudness_contourfunctionISO 226:2023 equal-loudness contour.
• phon: Loudness level, 20-90 phon
freqs, spl = psychoacoustics.equal_loudness_contour(40.0)

• SPL at the 29 preferred frequencies
equal_loudness_contoursfunctionISO 226:2023 equal-loudness contour family (plottable).
• phons: Loudness levels [phon] (Default: 20-90 in 10-phon steps)
• frequencies: Grid [Hz] (Default: the 29 preferred)
res = psychoacoustics.equal_loudness_contours()

• EqualLoudnessContours; res.plot()
EqualLoudnessContoursdataclassEqual-loudness contour family result.
• frequencies: grid [Hz]
• phons: contour levels [phon]
• contours: SPL, (len(phons), len(frequencies)) [dB] (nan where undefined)
• threshold: hearing threshold TfT_f [dB]
• .plot(): the iconic ISO 226 chart
res.contours, res.threshold
loudness_levelfunctionLoudness level of a pure tone (phon).
• spl: Tone SPL [dB]
• frequency: One of the 29 Table 1 frequencies [Hz]
phon = psychoacoustics.loudness_level(73.0, 63.0)
hearing_thresholdfunctionThreshold of hearing (ISO 226 Table 1).
• (no parameters)
freqs, tf = psychoacoustics.hearing_threshold()
tone_to_noise_ratiofunctionTone-to-noise ratio (ECMA-418-1 §11).
• x: Signal (1D)
• fs: Sample rate [Hz]
• tone_freq: Tone to assess [Hz] (Default: highest peak)
• resolution_hz: FFT bin spacing (Default: 1.0)
r = psychoacoustics.tone_to_noise_ratio(x, fs)

• ToneAssessment(frequency, ratio_db, criterion_db, prominent)
prominence_ratiofunctionProminence ratio (ECMA-418-1 §12).
• Same params as tone_to_noise_ratio
r = psychoacoustics.prominence_ratio(x, fs, tone_freq=1000)

• ToneAssessment(...)
ToneAssessmentdataclassTone prominence verdict.
• frequency: Assessed tone [Hz]
• ratio_db: TNR or PR [dB]
• criterion_db: Prominence limit at that frequency [dB]
• prominent: bool
r = psychoacoustics.tone_to_noise_ratio(x, fs)
if r.prominent: ...
tone_audibilityfunctionTone audibility ΔL = LT−LG−av (ISO/PAS 20065 Formulae 12–14).
• tone_level LT, mean_narrowband_level LS [dB]
• tone_frequency fT [Hz], line_spacing Δf [Hz]
tone_audibility(67.96, 49.22, 137.3, 2.7) # 5.01 dB
assess_tonesfunctionAudibility of a spectrum's tones (ISO/PAS 20065).
• tone_frequencies [Hz], tone_levels LT, mean_narrowband_levels LS [dB]
• line_spacing Δf [Hz]
• extended_uncertainties: attach the Clause 5.4 U per tone (Default: True)
res = psychoacoustics.assess_tones(fT, LT, LS, 2.7)

• ToneAudibilityResult
critical_bandwidth_engineeringfunctionCritical bandwidth Δfc about a tone (Formula 2).
• tone_frequency fT [Hz]
critical_bandwidth_engineering(137.3) # 101.36 Hz
critical_band_cornersfunctionCorner frequencies (f₁, f₂) of the critical band (Formulae 3–5).
• tone_frequency fT [Hz]
f1, f2 = psychoacoustics.critical_band_corners(137.3)
critical_band_levelfunctionMasking-noise level LG = LS+10lg(Δfc/Δf) (Formula 12).
• 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_indexfunctionMasking index av = −2−lg[1+(f/502)²·⁵] (Formula 13).
• frequency f [Hz]
masking_index(137.3) # -2.02 dB
audibility_from_levelsfunctionΔL = LT − LG − av (Formula 14).
• 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_levelfunctionEnergy sum of lines with window correction (Formulae 7/8).
• line_levels Li [dB]; a single line (K = 1) takes its level unchanged (Formula 7, no correction)
• effective_bandwidth_factor Δfe/Δf (Default: 1.5, Hanning; K > 1 only)
energy_sum_level([80, 80]) # 81.25 dB
mean_narrowband_levelfunctionMasking-noise level LS from a critical-band spectrum (Formula 6, iterative Annex D).
• levels Li [dB], frequencies [Hz]
• tone_frequency fT [Hz]
• effective_bandwidth_factor (Default: 1.5)
mean_narrowband_level(levels, freqs, 137.3) # 49.22 dB
tone_levelfunctionTone level LT from the tonal lines about a peak (Formulae (7)/(8): single lines take (7), without the Hanning bandwidth correction).
• levels Li [dB], frequencies [Hz]
• tone_frequency fT [Hz], mean_narrowband_level LS [dB]
• effective_bandwidth_factor (Default: 1.5)
tone_level(levels, freqs, 137.3, ls) # 67.96 dB
audibility_uncertainty / mean_audibility_uncertaintyfunctionExtended uncertainty U of the audibility (ISO/PAS 20065 Clause 5.4/6, 90 % bilateral).
• per tone: audibility_uncertainty(tone_line_levels, noise_line_levels, tone_frequency, line_spacing)
• mean: U of the energy-averaged audibility over the per-spectrum (ΔL, U) pairs
Mandatory when fewer than 12 spectra are averaged (Clause 6)
u = psychoacoustics.audibility_uncertainty(lt_lines, ls_lines, 137.3, 2.7)

• U [dB]
analyze_spectrumfunctionDetect & rate the audible tones of a spectrum (Clause 5.3.8 + distinctness 5.3.4), incl. Step 3 same-band FG combination (Formula 17).
• levels Li [dB], frequencies [Hz]
• line_spacing Δf [Hz]
• effective_bandwidth_factor (Default: 1.5)
res = psychoacoustics.analyze_spectrum(levels, freqs, 2.7)

• ToneAudibilityResult of detected tones + FG entries (group_sizes)
combined_tone_levelfunctionMulti-tone FG combined level (Formula 17).
• levels Li [dB], frequencies [Hz]
• tone_frequencies [Hz], mean_narrowband_levels LS [dB]
• effective_bandwidth_factor (Default: 1.5)
combined_tone_level(lv, f, [118.4,137.3,158.8], ls) # 72.15 dB
two_tone_separation_frequencyfunctionTwo-tone separation threshold fD = 21·10^(1.2·|lg(fT/212)|^1.8) Hz (Formula 19).
• tone_frequency fT [Hz] (more prominent tone)
two_tone_separation_frequency(212.0) # 21.0 Hz
resolve_tones_separatelyfunctionRate two tones <1000 Hz separately vs combined (Formulae 18/19).
• tone1_frequency, tone2_frequency [Hz]
• audibility1, audibility2 ΔL [dB]
resolve_tones_separately(200., 260., 3., 2.) # True
mean_audibilityfunctionEnergy-mean mean audibility over spectra (Formula 20).
• decisive_audibilities ΔLj [dB]; no-tone spectra use −10 dB
mean_audibility([9.18, 6.04, 7.46]) # dB
ToneAudibilityResultdataclassTonal audibility of a spectrum's tones (ISO/PAS 20065).
• audibilities ΔL, critical_band_levels LG, masking_indices av [dB]
• critical_bandwidths Δfc, lower_corners/upper_corners [Hz]
• audible: ΔL > 0 mask
• extended_uncertainties: Clause 5.4 U per tone [dB]
• group_sizes: 1 = single tone, N ≥ 2 = Step 3 FG entry (None from assess_tones)
• decisive_audibility / decisive_frequency
• .plot(): per-tone ΔL vs frequency
res.decisive_audibility, res.audible
HANNING_BANDWIDTH_FACTORfloatHanning effective-bandwidth factor Δfe/Δf (ISO/PAS 20065 Annex A).
1.5
HANNING_BANDWIDTH_FACTOR # 1.5
NO_TONE_AUDIBILITYfloatAudibility reported when no tone is found [dB] (ISO/PAS 20065 Formula 21).
-10.0
NO_TONE_AUDIBILITY # -10.0
sti_from_impulse_responsefunctionFull STI, indirect method (IEC 60268-16 Ed. 5).
• ir: Impulse response (1D)
• fs: Sample rate [Hz] (>= 22500)
• snr: SNR [dB], scalar or 7 bands (Default: None)
• levels: 7 speech band levels [dB SPL]; enables masking + reception threshold (Default: None)
• ambient: 7 noise band levels [dB SPL]; requires levels
res = speech.sti_from_impulse_response(ir, fs, snr=25.0)

• STIResult with `mtf$ (7 \times 14)
$stipa`functionSTIPA direct method (Annex B).
• x: Recorded STIPA signal (1D), 15-25 s
• fs: Sample rate [Hz] (>= 22500)
• reference: Measured source signal instead of the nominal m = 0.55 (Default: None)
• levels / ambient: as sti_from_impulse_response
• warns (UserWarning) if the recording is < 15 s (STI biased low)
res = speech.stipa(recording, fs)

• STIResult with `mtf$ (7 \times 2)
$stipa_signal`functionSTIPA test-signal generator (A.4/A.6.1).
• fs: Sample rate [Hz] (>= 22500)
• seconds: Duration [s] (Default: 18.0)
• level_db: RMS level [dB SPL] (Default: None → RMS 0.1)
• seed: Pink-noise seed (Default: None)
sig = speech.stipa_signal(48000, seconds=18.0)

• 1D test signal, Ed. 5 male spectrum
sti_adjusted_for_levelsfunctionOccupancy-noise and speech-level adjustment (Ed. 4 Annex M).
• mtf$: \text{measured} \text{m} \text{matrix} (7 \times \text{n}), \text{noise} \text{and} \text{masking} \text{included}<\text{br}>• $measured_levels: 7 band levels [dB SPL] during the measurement
• measured_ambient: same, background noise (Default: None)
• operational_levels: 7 band levels [dB SPL] of the condition simulated
• operational_ambient: same, occupancy noise (Default: None)
res = speech.sti_adjusted_for_levels(mtf, measured_levels=lm, measured_ambient=nm, operational_levels=lo, operational_ambient=no)

• STIResult at the operational levels
STIResultdataclassSTI result.
• sti: 0 to 1
• mti: band indices (7,)
• mtf$: \text{corrected} \text{m} \text{values} (7 \times 14 \text{or} 7 \times 2)<\text{br}>• $band_levels / ambient_levels: levels used or None
• rating: Annex F letter 'A+'…'U'
• .adjusted_for_levels(operational_levels=…, operational_ambient=…): the same result at another condition (Annex M)
res = speech.stipa(x, fs)
print(res.sti, res.rating)
sound_intensityfunctionp-p sound intensity (IEC 61043).
• p1, p2: Microphone signals [Pa], equal length
• fs: Sample rate [Hz]
• spacing: Microphone separation Δr [m]
• density: Air density (Default: 1.204)
• speed_of_sound: Speed of sound (Default: 343.0)
• fraction: None, 1 or 3 (Default: None)
• limits: [f_min, f_max] (Default: [12, 20000])
• bias_correct: undo finite-difference under-read of band/broadband totals near max_valid_frequency (Default: False)
res = emission.sound_intensity(p1, p2, fs, spacing=0.012, fraction=3)

• IntensityResult
plot_pp_probe_geometryfunctionFace-to-face p-p probe to scale.
• spacing dr [m] (Default: 12 mm)
• language
plot_pp_probe_geometry()

• Also IntensityResult.plot_geometry()
IntensityResultdataclassIntensity result.
• Per band (with fraction): frequencies, intensity [W/m²], intensity_level, pressure_level, pressure_intensity_index, direction (±1), bias_correction
• Broadband: total_* counterparts
• max_valid_frequency: 0.1·c/Δr
res.total_intensity_level
res.total_direction
field_indicatorsfunctionISO 9614-1 Annex A field indicators.
• pressure_levels: Lpi per position [dB]
• normal_intensity: Signed Ini per position [W/m²]
• temporal_intensity: optional M short-time Ink samples at one fixed position, filling f1
fi = emission.field_indicators(lp, i_n)

• FieldIndicators(f2, f3, f4, f1)
FieldIndicatorsdataclassISO 9614-1 Annex A indicators.
• f1: temporal variability indicator (Eq. A.1), or None when no temporal_intensity was given
• f2: surface pressure-intensity indicator (Eq. A.3)
• f3: negative partial power indicator (Eq. A.6)
• f4: field non-uniformity indicator (Eq. A.8)
• f3 − f2 > 0 reveals negative partial power
• .field_is_stationary(limit=0.6): Table B.3 check on F1
fi.f2, fi.f3, fi.f4

• Criteria: Ld > F2, N > C·F4²
dynamic_capability_indexfunctionDynamic capability Ld (ISO 9614-1 §3.12).
• pressure_residual_intensity_index: δpI0 [dB]
• bias_error_factor: K [dB] (Default: 10.0)
ld = emission.dynamic_capability_index(18.0)

• Adequate when Ld > F2 (criterion 1)
temporal_variability_indicatorfunctionISO 9614-1 temporal variability F1 (Eq. A.1).
• short_time_intensity: M short-time-averaged signed In samples at one fixed position [W/m²], 1D (samples,) or 2D (samples, bands)
f1 = emission.temporal_variability_indicator(samples)

• Coefficient of variation of the M samples; Table B.3 acts above 0.6
TEMPORAL_VARIABILITY_LIMITconstantISO 9614-1 Table B.3 limit on F1 (0.6): above it the field is too variable and action code (e) appliesfi.field_is_stationary(TEMPORAL_VARIABILITY_LIMIT)
residual_index_limitsfunctionIEC 61043 Table 2 minimum δpI0.
• device: 'probe', 'processor' or 'instrument' (Default: 'instrument')
• spacing: microphone separation [m] (Default: 0.025; Note 1 adds 10 lg(x/25))
• frequencies: bands to report (Default: all 22, 50 Hz to 6.3 kHz)
f, c1, c2 = emission.residual_index_limits("probe", spacing=0.012)

• (frequencies, class1, class2) minima [dB]
verify_intensity_classfunctionIEC 61043 Table 2 class check.
• residual_index: measured δpI0 per band [dB]
• frequencies: band centres [Hz]
• keyword-only: device, spacing, as above
res = emission.verify_intensity_class(d, f, spacing=0.012)
res.report("iec61043.pdf")

• IntensityInstrumentComplianceResult
IntensityInstrumentComplianceResultdataclassIEC 61043 instrument class verdict.
• overall_class: loosest class every band meets (1/2), or None
• bands, frequencies, residual_index, limit_class1, limit_class2
• spacing, spacing_offset_db, device, range_limited
• .binding_margin() / .failing_bands() / .reference_class()
• .phase_mismatch(speed_of_sound=343.0): equivalent channel phase error per band [deg]
• .plot(): measured δpI0 over the two Table 2 masks
• .report(path, *, metadata=None): one-page PDF fiche
res.overall_class, res.binding_margin()
instrument_class_from_componentsfunctionIEC 61043 clause 8 combination rule.
• probe_class, processor_class: 1 or 2
instrument_class_from_components(1, 2)

• 1 only when both are class 1, else 2
phase_mismatch_from_residual_indexfunctionδpI0 → channel phase mismatch.
• residual_index: δpI0 [dB]
• frequency [Hz], spacing [m], speed_of_sound (Default: 343.0)
• φs = kd·10^(−δpI0/10)
phase_mismatch_from_residual_index(20.0, 1000.0, 0.025)

• 0.26 degrees
residual_index_from_phase_mismatchfunctionChannel phase mismatch → δpI0.
• phase_mismatch: φs [deg], > 0
• frequency [Hz], spacing [m], speed_of_sound (Default: 343.0)
• δpI0 = 10 lg(kd/φs)
residual_index_from_phase_mismatch(0.05, 1000.0, 0.012)

• 24.0 dB
CalibrationWarningwarning classUnreliable calibration recording.
Emitted by sensitivity (with fs given and validate=True) when the tone is unstable (IEC 60942 limit) or too short
warnings.simplefilter("error", CalibrationWarning)
ldenfunctionDay-evening-night level (ISO 1996-1 §3.6.4).
• lday/levening/lnight: LAeq per period [dB]
• hours: Period durations (Default: (12, 4, 8))
l = environment.lden(63.2, 58.1, 51.4)
ldnfunctionDay-night level (ISO 1996-1 §3.6.5).
• lday/lnight: LAeq per period [dB]
• hours: Default (15, 9)
l = environment.ldn(63.2, 51.4)
composite_rating_levelfunctionWhole-day composite rating (ISO 1996-1 §6.5).
• periods: list of (level_db, hours, adjustment_db) summing 24 h
r = environment.composite_rating_level([(63, 12, 0), (58, 4, 5), (51, 8, 10)])
assess_tonal_audibilityfunctionTonal audibility & adjustment (ISO 1996-2 Annex C).
• tone_level Lpt, masking_noise_level Lpn [dB]
• centre_frequency fc [Hz]
res = environment.assess_tonal_audibility(54.1, 45.2, 430.0)

• TonalAssessmentResult (.audibility, .adjustment, .plot())
tonal_audibilityfunctionΔLta = Lpt−Lpn+2+lg[1+(fc/502)²·⁵] (Formula C.3).
• tone_level, masking_noise_level [dB], centre_frequency [Hz]
d = environment.tonal_audibility(54.1, 45.2, 430.0) # 11.1 dB
tonal_adjustmentfunctionKt(ΔLta) piecewise (Formulae C.4-C.6).
• audibility ΔLta [dB]
tonal_adjustment(7.0) # 3.0 dB
tonal_adjustment_from_mean_audibilityfunctionKt from mean audibility ΔL (ISO 1996-2 Table J.1).
• mean_audibility [dB], coarse (Default: False)
tonal_adjustment_from_mean_audibility(5.0) # 3
critical_bandwidthfunctionCritical bandwidth (ISO 1996-2 Table C.1).
• centre_frequency [Hz] (100 Hz ≤ 500 Hz, else 20 %·fc)
critical_bandwidth(4000.0) # 800 Hz
tonal_seeking_surveyfunctionOne-third-octave tonal screen (ISO 1996-2 Annex K).
• levels [dB], frequencies [Hz] (15/8/5 dB neighbour rule)
flags = environment.tonal_seeking_survey(levels, freqs)
NoisePhasedataclassNoise phase Ti of steady emission (RD 1367/2007 Annex IV A.3.4.2 b).
• hours Ti [h], laeq background-corrected LAeq,Ti [dB]
• kt, kf, ki corrections [dB]; label
• .correction (capped at 9 dB), .lkeq
NoisePhase(6, 50.0, kt=6, kf=3) # LKeq,Ti = 59 dB
tonal_correctionfunctionKt from an unweighted 1/3-octave spectrum (Annex IV A.3.3).
• levels [dB], frequencies [Hz]
• Lt = Lf − Ls against the arithmetic mean of the two neighbours; 8/12, 5/8 and 3/5 dB thresholds by band range
res = environment.tonal_correction(levels, freqs)

• TonalCorrectionResult (.correction, .plot())
TonalCorrectionResultdataclassRD 1367/2007 tonal correction.
• correction Kt [dB] (0/3/6), governing_frequency
• differences Lt and band_corrections per band (NaN where not evaluable)
• frequencies, levels
res.correction, res.governing_frequency
low_frequency_correctionfunctionKf from Lf = LCeq,Ti − LAeq,Ti (Annex IV A.3.3).
• lceq, laeq [dB], background-corrected
low_frequency_correction(63.0, 50.0) # 3.0 dB
impulsive_correctionfunctionKi from Li = LAIeq,Ti − LAeq,Ti (Annex IV A.3.3).
• laieq, laeq [dB], background-corrected
impulsive_correction(67.0, 50.0) # 6.0 dB
total_correctionfunctionK = Kt + Kf + Ki, capped at 9 dB (Annex IV A.3.3).
• kt, kf, ki [dB]
total_correction(6, 3, 0) # 9.0
corrected_levelfunctionLKeq,T = LAeq,T + Kt + Kf + Ki (Annex I A.2 c).
• laeq [dB]; kt, kf, ki [dB]
corrected_level(50.0, kt=6, kf=3) # 59.0 dB
evaluation_period_levelfunctionLKeq,T from its noise phases (Annex IV A.3.4.2 b).
• phases: NoisePhase list
• hours T [h] (None = sum of Ti)
evaluation_period_level(phases, hours=12)
long_term_corrected_levelfunctionAnnual LK,x, energy mean of the daily levels (Annex I A.2 d).
• daily_levels [dB]; weights: days each level represents
long_term_corrected_level([57, 0], weights=[303, 62]) # 56.2
round_reported_levelfunctionRounding of Annex IV A.3.4.2: add 0,5 dB, take the integer part.
• value [dB]
round_reported_level(56.82) # 57
outdoor_quality_objectivesfunctionOutdoor quality objectives Ld/Le/Ln (Annex II Table A).
• area_type: 'e','a','d','c','b' or an alias
• urbanisation: 'existing' or 'new' (−5 dB, Article 14.2)
outdoor_quality_objectives("a") # 65/65/55 dB
indoor_quality_objectivesfunctionIndoor quality objectives (Annex II Table B).
• building_use: 'residential','sanitary','educational'
• room_type: 'living','bedrooms','classrooms','reading_rooms'
indoor_quality_objectives("residential", "bedrooms")
vibration_quality_objectivefunctionIndoor vibration objective Law [dB] (Annex II Table C).
• building_use
vibration_quality_objective("residential") # 75.0
infrastructure_limitsfunctionImmission limits for new transport infrastructure (Annex III Table A1).
• area_type
infrastructure_limits("a") # 60/60/50 dB
max_infrastructure_limitfunctionLAmax limit for rail and airport infrastructure (Annex III Table A2).
• area_type
max_infrastructure_limit("a") # 85.0 dB
activity_limitsfunctionOutdoor limits for activities and ports (Annex III Table B1).
• area_type
activity_limits("a") # LK,d/e/n = 55/55/45 dB
adjacent_premises_limitsfunctionNoise transmitted to acoustically adjacent premises (Annex III Table B2).
• building_use, room_type
adjacent_premises_limits("residential", "bedrooms")
RegulationLimitsdataclassA day/evening/night limit triple of RD 1367/2007.
• day, evening, night [dB]; index, reference, description
• Indexable by period; .as_dict()
lim["night"]
assess_activityfunctionArticle 25 compliance of an activity or port.
• measurements: phases keyed by period
• limits: a RegulationLimits row
• long_term_levels or operating_days / year_days / closed_level
• new_activity (Default: True; False = Article 25.2)
• period_hours
v = environment.assess_activity({"day": day}, environment.activity_limits("a"), operating_days=303)

• ActivityAssessment
ActivityAssessmentdataclassRD 1367/2007 activity verdict.
• periods: PeriodAssessment tuple; limits; new_activity
• .complies
• .plot(); .report(path, language='es'): one-page inspection fiche → PDF
v.complies
v.report("acta.pdf")
PeriodAssessmentdataclassOne evaluation period against its limit.
• evaluation_period_level, reported_level (rounded)
• long_term_corrected_level, reported_long_term
• limit, daily_limit (+3), phase_limit (+5), max_phase_level
• phase_pass, daily_pass, long_term_pass, .complies
p.reported_level, p.long_term_pass
ACOUSTIC_AREA_TYPESconstantAcoustic area types of Article 7 of Ley 37/2003, keyed by letter.
e sanitary/educational/cultural, a residential, d tertiary, c recreational, b industrial, f transport systems
ACOUSTIC_AREA_TYPES["a"]
RD1367_EVALUATION_PERIODSconstantThe three daily evaluation periods (Annex I A.1).("day", "evening", "night")
RD1367_PERIOD_HOURSconstantDefault period durations [h] (Annex I A.1 a).{"day": 12, "evening": 4, "night": 8}
RD1367_PERIOD_CLOCK_LIMITSconstantLocal-time start/end hour of each period (Annex I A.1 b).{"day": (7, 19), ...}
RD1367_CORRECTION_VALUESconstantThe only values a single correction takes (Annex IV A.3.3).
Each table grades its parameter 0, 3 or 6 dB
RD1367_CORRECTION_VALUES # (0.0, 3.0, 6.0)
RD1367_MAX_CORRECTIONconstantCap on Kt + Kf + Ki [dB] (Annex IV A.3.3).9.0
residual_sound_correctionfunctionResidual-noise correction L = 10 lg(10^(L'/10)−10^(Lres/10)) (Formula 16).
• measured_level L', residual_level Lres [dB]
res = environment.residual_sound_correction(58.0, 50.0)

• ResidualCorrectionResult (.corrected_level, .reportable_upper_bound, .reliable)
gaussian_residual_levelfunctionResidual Leq from percentiles (ISO 1996-2 Annex I).
• l50 [dB]; exactly one of l90 / l95 (must not exceed l50)
gaussian_residual_level(50.0, l90=40.0)
combined_standard_uncertaintyfunctionu = √(Σ(cj·uj)²) (ISO 1996-2 Formula 2).
• contributions: cj·uj products or (uj, cj) pairs
u = environment.combined_standard_uncertainty([0.59, 0.3, 2.0, 0.40, 0.38]) # 2.18
environmental_expanded_uncertaintyfunctionU = k·u (ISO 1996-2 §4).
• standard_uncertainty [dB], confidence 0.95 (k=2) / 0.80 (k=1.3)
environment.environmental_expanded_uncertainty(2.18) # 4.36
residual_correction_uncertaintyfunctionUncertainty of the residual-corrected level (Formulae F.7-F.9).
• measured_level, residual_level, measured_uncertainty, residual_uncertainty [dB]
residual_correction_uncertainty(58, 50, 0.5, 2.0)
uncertainty_from_repeated_measurementsfunctionEnergy mean & uncertainty from repeats: primary Formulae (17)+(19) route, Formula (20) approximation alongside.
• levels [dB] (≥ 2); warns when they spread > 3 dB
res = environment.uncertainty_from_repeated_measurements(levels)

• RepeatedMeasurementResult
TonalAssessmentResultdataclassTonal assessment (ISO 1996-2).
• audibility ΔLta, adjustment Kt [dB]
• centre_frequency, critical_bandwidth; .plot()
res.audibility, res.adjustment
ResidualCorrectionResultdataclassResidual-corrected level (ISO 1996-2).
• 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
EnvironmentalMeasurementWarningwarning classUnreliable environmental-noise determination (ISO 1996-2:2017).
• Residual within 3 dB of the measured level: no correction is allowed and only reportable_upper_bound may be reported (10.4)
• Repeated levels spreading more than 3 dB: approximate_uncertainty (Formula (20)) is unreliable there (10.5 Note 2)
• Subclass of PhonometryWarning
warnings.simplefilter('error', EnvironmentalMeasurementWarning)
Emitted by environment.assessment.measurement
RepeatedMeasurementResultdataclassRepeat-measurement mean & uncertainty (ISO 1996-2).
• mean_level, standard_uncertainty (Formulae (17)+(19)), approximate_uncertainty (Formula (20)) [dB], n
res.mean_level, res.standard_uncertainty
linkwitz_rileyfunctionAudio crossover.
• x: Signal array
• fs: Sample rate [Hz]
• frequency: Crossover frequency [Hz]
• order: Any even number (Default: 4)
lo, hi = filters.linkwitz_riley(x, fs, frequency=1000, order=4)

• lo: Low-pass filtered signal
• hi: High-pass filtered signal
parametric_eqfunctionParametric EQ, one shot (RBJ Audio EQ Cookbook).
• x: Signal array (1D or 2D [channels, samples])
• fs: Sample rate [Hz]
• sections: an EQSection or a sequence of them
y = filters.parametric_eq(x, fs, sections=filters.EQSection("peaking", 1000, gain_db=6.0))
ParametricEQclassReusable parametric-EQ cascade (RBJ Audio EQ Cookbook).
• fs: Sample rate [Hz]
• sections: EQSection or sequence of them (cascade order)
• stateful: Block processing (Default: False)
• steady_ic: Steady-state initial conditions (Default: False)
• .sos: the designed cascade, .filter(x), .response()
eq = filters.ParametricEQ(fs, sections)
y = eq.filter(x)
res = eq.response()
EQSectiondataclassOne cookbook biquad specification.
• filter_type: 'peaking', 'lowshelf', 'highshelf', 'lowpass', 'highpass', 'bandpass', 'bandpass_skirt', 'notch', 'allpass'
• f0: Centre/corner frequency [Hz]
• gain_db: Gain (peaking/shelves) [dB]
• One of q (Default: 1/√2), bw [octaves] or slope (shelves)
EQSection("peaking", 1000.0, gain_db=-6.0, bw=1.0)
EQResponseResultdataclassParametric-EQ cascade response.
• frequencies [Hz], magnitude_db [dB], phase_rad [rad]
• section_magnitude_db: per-section magnitudes [dB]
• sos: the cascade, fs, sections; .plot() magnitude + phase
res = eq.response()
res.plot()
sensitivityfunctionSPL Calibration.
• ref_signal: Calibration signal
• target_spl: Level of calibrator (Default: 94.0)
• reference_pressure_pa: Reference pressure (Default: 20e-6)
• frequency, calibrator_class: select the IEC 60942 Table 2 fluctuation limit the take is screened with (Default: 1000.0, '1')
• narrowband: coherent Goertzel tone estimate that rejects broadband hum/noise (needs fs; Default: False)
s = sensitivity(ref_signal, target_spl=94.0)

• s: Float (multiplier for pressure)
readfunctionRead a measurement audio file into a Signal.
• path: WAV/BWF/RF64 in the base install; FLAC, AIFF, Ogg/Opus, MP3 with [audio]
• calibration_factor: digital units → Pa (Default: None; an existing sidecar is applied automatically, an explicit value wins)
Native fs kept, no downmix, no normalization; int PCM scaled by 2^(bits−1); lossy sources raise LossyCompressionWarning
sig = io.read("night.wav")

• sig: Signal (float64, (channels, samples), with fs, calibration, bext, labels)
infofunctionDescribe a file from its headers alone.
• path: any supported container
No sample is decoded, so a 12-hour RF64 answers instantly; compressed WAV that read refuses still describes itself
meta = io.info("night.wav")

• meta: AudioFileInfo
read_blocksfunctionStream a file block by block.
• path, block_size [samples]
• overlap: samples shared between consecutive blocks (Default: 0)
• calibration_factor: as in read; None takes the sidecar's (Default: None)
Yields exactly what read returns, in slices: feeds BlockProcessing(stateful=True) unchanged
for block in io.read_blocks(p, 65536): ...

• each block: a Signal with the rate, calibration, labels and provenance read gives
writefunctionWrite WAV/BWF (FLAC with [audio]) without touching the level.
• path, x (array or Signal), fs (taken from x when x is a Signal)
• subtype: 'PCM_16'/'PCM_24'/'PCM_32'/'FLOAT'/'DOUBLE' (Default: FLOAT for float data, the matching depth for integer pass-through; FLAC: PCM up to 24)
• bext: None (Default) carries a Signal's own provenance; "loudness" also measures the five EBU R 128 fields in-house; a BroadcastMetadata is written as given
• dither: 'tpdf' at PCM_16 only (Default: None)
• rng: numpy.random.Generator or int seed for the dither noise, for byte-reproducible writes (Default: None = fresh entropy)
• sidecar: write the calibration sidecar too (Default: False)
Never normalizes; clipping saturates, is counted and warns (ClippingWarning); RF64 automatic past 4 GiB
io.write("out.wav", sig, subtype="PCM_24")
convertfunctionConvert between lossless containers with the measurement intact.
• src, dst: WAV/BWF/RF64 ↔ FLAC (lossy targets refused)
Samples bit-exact at full precision, bext carried (into FLAC via the riff APPLICATION block), sidecar copied byte for byte, CodingHistory extended one line; streams, so an hour of RF64 converts flat
io.convert("night.wav", "night.flac")
SignaldataclassSamples plus the metadata they need.
• data: (channels, samples) float64
• fs [Hz]
• calibration_factor: Pa per digital unit, or None until known
• channel_labels, provenance (bext), source (SignalOrigin)
np.asarray(sig) yields the bare array (1D mono), so every (x, fs, ...) function accepts it; leq/laeq/ln_levels/sel/lc_peak/sound_exposure/lex_8h read fs and calibration from it directly
sig.duration, sig.n_channels
sig.plot() draws the calibrated waveform
SignalOrigindataclassWhere a Signal came from.
• path, container, format_name
• bit_depth: valid bits, None for lossy codecs
• lossy: the read-time warning, kept attached to the data
sig.source.lossy
AudioFileInfodataclassEverything info() reads from the headers.
• container, format_name, fs, channels, frames, duration, bit_depth, lossy
• channel_mask / channel_labels (EXTENSIBLE speaker positions)
• bext, has_ixml, cue_points
io.info(p).duration
BroadcastMetadatadataclassThe bext chunk of EBU Tech 3285 v2, field by field.
• description, originator, originator_reference, origination_date/_time
• time_reference: 64-bit samples since midnight
• version, umid
• v2 loudness: loudness_value, loudness_range, max_true_peak_level, max_momentary_loudness, max_short_term_loudness (0x7FFF sentinel → None)
• coding_history (EBU R98)
io.info(p).bext.time_reference
CuePointdataclassOne marker of a WAV cue chunk.
• cue_id, position [samples], plus the raw chunk_id/chunk_start/block_start/sample_offset fields of the spec
io.info(p).cue_points
CalibrationSidecardataclassThe versioned JSON sidecar that carries the calibration.
• calibration_factor, reference_spl, calibrator_frequency, calibrator_model, channel_labels, phonometry_version
Lives at <audio>.phonometry.json; applied automatically by read
io.read("m.wav").calibration_factor
read_sidecar / write_sidecar / sidecar_pathfunctionSidecar round-trip.
• read_sidecar(path): the sidecar next to an audio file, or None (foreign or newer schema refused loudly)
• write_sidecar(path, calibration_factor, ...): write one, with the optional calibrator tone metadata
• sidecar_path(path): where it lives
io.write_sidecar("m.wav", cal, reference_spl=94.0)
LossyCompressionWarningwarning classA lossy decoder produced these samples (MP3/Ogg/Opus/ADPCM): levels are not metrologically defensible. Subclass of PhonometryWarning
Emitted by io.read / io.read_blocks / io.convert
warnings.simplefilter('error', io.LossyCompressionWarning)
ClippingWarningwarning classSamples clipped while quantizing on write: count and peak overshoot in dBFS; the file is written with saturated codes rather than wrapped ones. Subclass of PhonometryWarning
Emitted by io.write
warnings.simplefilter('error', io.ClippingWarning)
CatalogueRowdataclassThe row every published catalogue hands out, with what each cell said.
• name, source (document, table, PDF page and printed folio), table, variant, group, note
• A quantity is None when the page had something other than a number there, and ranges, bounded_above / bounded_below, reported, unquantified, uncertainty, not_derivable and misprinted say what
• basis: field or 'row' → what the source claims the value is, one of CATALOGUE_BASES; .basis_of(field) reads it, and '' means the source does not say
• derived: field → how this library computed it, written by .from_printed on every row the library builds (one passed to Cls(...) is the caller's, and .printed_fields() leaves it out with its value); converted: field → the page's figure and its unit, (figure, unit), for a value held in a unit the page does not use; carried: field → the row the page gives it on, for a value it gives by reference to another row
• .from_printed(**cells) builds a row and fills what follows from its cells, .printed_fields() gives the cells back; .printed(field) narrows or refuses, .why_missing(field) says what the page had, .is_derived(field), .is_approximate(field)
• Checks itself when built, whoever builds it, and raises CatalogueError for a cell nothing downstream can read: a number that is NaN, a bool or a text, a hedge on a field the class does not have, a bound with no range, a value beside misprinted, a density or a length below zero, a porosity above 1; sets and mappings frozen all the way down
Frozen and keyword-only; a subclass leaves out slots=True and annotates its fields float | None, int | None, bool, str, frozenset[str] or Mapping[str, ...], anything else (a bare float or int too) a TypeError
row = solids.PUBLISHED_SOLIDS['hopkins-2007-table-a2/aircrete']
row.basis_of('poisson_ratio') # 'estimated'
BandedRowdataclassA catalogue row that prints one value per frequency band.
• One field per band, so every hedge of CatalogueRow applies to a band as to any other cell
• .bands(): the bands the row prints; .spectrum(): {band_hz: value} over them, a band the page left empty left out rather than read as zero; .values_at(frequencies_hz): the row at an array of frequencies
materials.PUBLISHED_ABSORPTION['bies-2017-table-6-2/unoccupied_heavily_upholstered_seats'].spectrum()[500] # 0.81
CatalogueRow.from_printedclassmethodA row built from the cells its page prints, completed and marked.
• **cells: the printed cells under the class's field names, with their hedges, as a data file writes them
• Checks every cell as the constructor does, then fills what follows from them (a modulus from a plate speed, a density and a Poisson ratio) and names each filled value in derived, never over a printed value or a hedged cell; when the printed cells a value rests on do not share one basis, the text names the basis of each
• Cells the arithmetic refuses (a modulus and a shear modulus no isotropic solid has together) raise CatalogueError naming them, unless not_derivable says the value does not follow
• A figure under a unit the class takes as an alias of its own (absorption_area_125_ft2 on AbsorptionAreaSpectrum) is converted on its digits with an exact factor, rounded once, and recorded in converted
• The one path that works anything out, and every packaged catalogue is built through it; Cls(...) stays literal. A derived among the cells raises CatalogueError
row = solids.SolidMaterial.from_printed(name='Board', source='...', density_kg_m3=860.0, plate_longitudinal_speed_m_s=1490.0, poisson_ratio=0.3)
row.is_derived('youngs_modulus_pa') # True
CatalogueRow.printed_fieldsmethodThe cells the page prints, as from_printed takes them.
• Every field, hedges, converted and carried included, without the derived values, without derived, and without a field left at a default that holds nothing; an empty per stays, since its default is a person
• type(row).from_printed(**row.printed_fields()) is the row again for every row .from_printed builds. Change a cell here and build again to edit a row: dataclasses.replace keeps derived values that no longer follow from the cell that changed
cells = row.printed_fields()
cells['density_kg_m3'] = 2400.0
row = type(row).from_printed(**cells)
BandedRow.values_atmethodThe row at an array of frequencies, one band per frequency.
• frequencies_hz: band centres [Hz], any shape; each matches the band whose centre is nearest on a logarithmic scale, within a sixth of the band spacing, so a nominal, an exact base-ten and an exact base-two centre read the same band
• A band the row does not print raises ValueError with what the page had there, never a zero; a frequency between bands raises naming the nearest
• For a function that takes one value per band by position: the surfaces of room.sabine_reverberation_time, or noise_control.enclosure_insertion_loss given row.values_at as its transmission loss
seats.values_at([125.0, 250.0, 500.0])

• a new float64 array of the frequencies' shape
CatalogueErrorexceptionA catalogue that does not say what a reader needs to trust it.
A table without its citation or its rows, two rows under one key, a NaN or a name written twice in its JSON, a / in a row key; a row that breaks the contract it is checked against when built, from a file or by hand. Subclass of ValueError
except io.CatalogueError: ...
CATALOGUE_BASESconstantWhat a source can claim a value is.
'measured', 'declared', 'calculated', 'estimated' and 'extended'; no entry means the source does not say
'estimated' in io.CATALOGUE_BASES # True
verify_filter_classfunctionIEC 61260 class check of a bank design. For '2014' it grades Table 1 (5.10), the effective bandwidth deviation (5.12) and the summation of output signals (5.16), the last two as IEC 61260-2:2016 tests them (Formulas (1) to (3)); '1995' grades its Table 1 alone.
• bank: an OctaveFilterBank
• keyword-only: num_points, frequency grid points per band (Default: 32768)
• keyword-only: edition, '2014' (classes 1/2, default) or '1995' (IEC 61260:1995 / ANSI S1.11-2004, adds class 0)
• keyword-only: points_per_bandwidth, S of IEC 61260-2 Formula (1), at least 24 (Default: 24)
result = filters.verify_filter_class(bank)
result.requirement_class("summation")

• FilterComplianceResult
FilterComplianceResultdataclassIEC 61260 filter class-compliance result.
• overall_class: strictest class every band meets on every requirement graded: 1/2 ('2014'), 0/1/2 ('1995'), or None
• bands: per-band verdict dictionaries, with bandwidth_deviation_db and summation_min_db / summation_max_db for '2014'
• requirements, .requirement_class(name), .binding_margin_db(name, cls): each requirement on its own
• range_limited: stop-band mask beyond the processing Nyquist not exercised
• .available_classes() / .reference_class(): the edition's classes and the fiche's reference class
• .plot(requirement=...): the relative attenuation over its corridor (default), 'effective_bandwidth' or 'summation'
• .report(path, *, metadata=None, required_class via metadata): one-page PDF fiche
verify_filter_class(bank).report("iec61260.pdf")
verify_time_invariancefunctionTime-invariant operation of a bank, IEC 61260-1:2014 5.14 (IEC 61260-2:2016 7.4). An exponential sweep through the bank itself, decimation included, against Formula (17), ±0.4 dB (class 1) or ±0.6 dB (class 2).
• bank: an OctaveFilterBank
• keyword-only: seconds_per_decade, the sweep rates, each 2 s to 5 s (Default: (2.0, 5.0))
res = filters.verify_time_invariance(bank)

• TimeInvarianceResult
TimeInvarianceResultdataclassThe swept verdict of a bank.
• output_levels_db / expected_levels_db: (rates, bands), re the sweep level; deviations_db
• band_classes, overall_class, worst_deviation_db
• seconds_per_decade, start_frequency_hz, end_frequency_hz, sweep_durations_s, averaging_times_s
• no truth value; .plot() draws each band's deviation per rate
res.overall_class
swept_band_levelfunctionIEC 61260-1:2014 Formula (17): the time-averaged output of an exponential sweep.
• input_level_db
• keyword-only: fraction, sweep_duration_s, averaging_time_s, start_frequency_hz, end_frequency_hz, reference_attenuation_db (Default: 0)
filters.swept_band_level(127.0, fraction=3, sweep_duration_s=30, averaging_time_s=30, start_frequency_hz=0.01, end_frequency_hz=1e6)

• 107.969... (IEC 61260-2 and -3 Annex B, 107,97 dB)
swept_level_uncertaintyfunctionThe standard uncertainty of Formula (17) from the sweep, Annex A of IEC 61260-2 and -3. Formula (A.2) with the square its printed form drops (see the errata registry)
• keyword-only: input_level_uncertainty_db, sweep_duration_s, sweep_duration_uncertainty_s, averaging_time_s, averaging_time_uncertainty_s, start_frequency_hz, start_frequency_uncertainty_hz, end_frequency_hz, end_frequency_uncertainty_hz, display_resolution_db (Default: 0)
u = filters.swept_level_uncertainty(...)

• u [dB], standard; 2 * u the expanded (0.115 dB in A.3.5)
periodic_test_frequenciesfunctionThe 15 test frequencies of IEC 61260-3:2016 Clause 13, Formulas (1) and (2), k = -7 .. 7, any bandwidth designator
• fraction: b (1, 3, ...)
omega = filters.periodic_test_frequencies(3)

• read-only array of Ω_k; omega[8] # 1.02667 (Table C.1)
PERIODIC_TEST_ATTENUATION_LIMITS_DBmappingIEC 61260-3:2016 Table 1: class → the minimum and maximum relative attenuation [dB] for |k| = 0 .. 7, the stop-band maximum inffilters.PERIODIC_TEST_ATTENUATION_LIMITS_DB[1][7] # (70.0, inf)
verify_filter_periodicfunctionThe periodic tests of IEC 61260-3:2016 on a laboratory's results. Each clause (10.2 or 10.3, 11.7, 11.9, 13) judged by metrology.verify_conformance with the maxima of IEC 61260-1:2014 Annex B; results 5.3 makes unusable are named
• filter_class: 1 or 2
• measurements: a FilterPeriodicMeasurements
• keyword-only: fraction, b of the filters of Clause 13
• keyword-only: pattern_approval_public, whether the model's IEC 61260-2 approval is public (Default: False)
res = filters.verify_filter_periodic(1, record, fraction=3)

• FilterPeriodicVerification
FilterPeriodicMeasurementsdataclassWhat a laboratory measured in the periodic tests, each result with its expanded uncertainty: midband_attenuations_db (10.2), bandwidth_deviations_db (10.3), linearity_deviations_db with linearity_levels_below_upper_db (11.7), range_linearity_deviations_db (11.9), relative_attenuations_db rows of 15 with NaN where 13.4 drops a frequency (13), and optional set_midband_frequencies_hz / tested_midband_frequencies_hz / linearity_midband_frequencies_hz labels, which let the verdict check the three filters of 11.3 and the frequencies of 13.4filters.FilterPeriodicMeasurements(midband_attenuations_db=[0.1], midband_uncertainties_db=[0.15])
PeriodicTestClausedataclassThe verdict on one clause of IEC 61260-3.
• clause, title, labels, verifications (one ConformanceVerification per result)
• passes, failed, unusable (5.3)
• no truth value; .plot() as Figure C.1, clause 13 as margins against Ω_k
res.clause("13").failed
FilterPeriodicVerificationdataclassThe IEC 61260-3:2016 verdict.
• filter_class, fraction, pattern_approval_public, measurements, clauses; clause(id)
• passes: every clause a complete test grades was measured on the filters and frequencies it requires and every result conforms
• missing, incomplete (11.3, 13.1, 13.4), coverage_checked, failed, unusable
• statement: the text of Clause 14 k), l) or m), with the caveat of 1.5 when the pattern approval is not public
• no truth value; .plot() draws every result's margin, clause by clause
res.passes, res.statement
class_limitsfunctionIEC 61260 Table 1 acceptance limits.
• fraction: bandwidth designator denominator b (1, 3, ...)
• filter_class: 1 or 2 ('2014'); 0, 1 or 2 ('1995')
• omega: normalized frequencies f/fm
• edition: '2014' (default) or '1995'
lo, hi = filters.class_limits(3, 0, omega, edition="1995")

• lo / hi: min/max relative attenuation [dB] (hi is inf outside the pass-band)
verify_weighting_classfunctionWeighting 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. edition="1979" grades against IEC 651:1979 Table V instead, which publishes the laboratory-grade Type 0 (A, B and C).
• wf: a WeightingFilter (A, B, C, AU or Z)
• keyword-only: sweep_points (Default: 4096)
• keyword-only: edition (Default: "2013"; "1979" for Types 0-3)
result = filters.verify_weighting_class(wf)

• WeightingComplianceResult
WeightingComplianceResultdataclassWeighting class verdict of a WeightingFilter.
• overall_class: 1, 2 or None (0-3 or None for '1979')
• bands: per-frequency class, deviation and margin_class<c>_db [dB]
• between_nominals: the 5.5.7 sweep, or None when no row was in range
• curve, edition, fs [Hz], sweep_points
• range_limited: finite-lower-limit rows beyond Nyquist
result.overall_class, result.range_limited
weighting_class_limitsfunctionIEC 61672-1:2013 Table 3 acceptance limits, or the IEC 651:1979 Table V ones with edition="1979".
• weighting_class: 1 or 2 (0-3 for "1979", where class N is instrument Type N)
• edition (Default: "2013")
f, lo, hi = filters.weighting_class_limits(1)

• f: 34 nominal frequencies [Hz]
• lo / hi: lower/upper deviation limits [dB] (lo is -inf where one-sided)
nominal_frequenciesfunctionANSI Frequency generator.
• fraction: 1, 3, etc. (Required)
• limits: [f_min, f_max] (Default: [12, 20000])
f_cen, f_low, f_high, labels = filters.nominal_frequencies(fraction=3)

• f_cen: List of center frequencies [Hz]
• f_low: List of lower edges [Hz]
• f_high: List of upper edges [Hz]
• labels: IEC nominal frequency labels
normalized_frequenciesfunctionStandard IEC Frequencies.
• fraction: 1 or 3
freqs = filters.normalized_frequencies(fraction=3)

• freqs: List of standard center frequencies [Hz]
sweep_signalfunctionESS excitation (ISO 18233 Annex B).
• fs: Sample rate [Hz]
• f1: Start frequency [Hz]
• f2: Stop frequency [Hz] (≤ fs/2)
• seconds: Duration [s]
• amplitude: Peak (Default: 1.0)
• fade: Half-Hann fraction (Default: 0.01)
s = room.sweep_signal(48000, 20, 20000, 3.0)

• 1D exponential sine sweep
inverse_filterfunctionFarina inverse filter for an ESS.
• Same parameters as sweep_signal
inv = room.inverse_filter(48000, 20, 20000, 3.0)

• Time-reversed, +6 dB/oct compensated sweep
impulse_responsefunctionSweep deconvolution (ISO 18233 B.5).
• recorded: Recorded response (1D)
• reference: Emitted sweep (1D)
• fs: Sample rate [Hz]
• method: 'spectral' (Default) or 'farina'
• f_range: (f1, f2) for 'farina'
• regularization: Tikhonov term (Default: 1e-6)
• length: causal samples (Default: len(recorded))
• return_full: keep distortion tail (Default: False)
ir = room.impulse_response(rec, sweep, fs)

• ImpulseResponseResult (array-like; .plot())
mls_signalfunctionMaximum-length sequence (ISO 18233 Annex A).
• order: Register length N, 2-20
mls = room.mls_signal(16)

• Bipolar sequence, length 2**N − 1
mls_impulse_responsefunctionIR from a periodic MLS.
• recorded: Response spanning whole MLS periods (1D)
• mls: Excitation sequence
• length: IR samples (Default: 2**N − 1)
• fs: optional sample rate for the plot time axis
ir = room.mls_impulse_response(rec, mls)

• ImpulseResponseResult (array-like; .plot())
ImpulseResponseResultdataclassRecovered impulse response with metadata.
• ir: IR samples
• fs [Hz] or None (e.g. an MLS recovery without one)
• method: 'spectral'/'farina'/'mls'/'golay'
• array-like: np.asarray(res), indexing, len() and shape/dtype forward to ir
• .plot()
ir = room.impulse_response(rec, sweep, fs)
room_parameters(ir, fs) # drop-in array
golay_pairfunctionComplementary Golay pair (Havelock Pt. I Ch. 6).
• order: recursion steps n, 1-22; each code has 2**n samples
Periodic autocorrelations sum to an exact 2L·delta
a, b = room.golay_pair(14)

• Two bipolar codes, length 2**n
golay_impulse_responsefunctionIR from a periodic Golay-pair excitation.
• recorded_a / recorded_b: steady-state responses to each code (whole periods)
• pair: the (a, b) codes
• length: IR samples (Default: 2**n)
• fs: optional sample rate for the plot time axis
Noiseless LTI recovery is exact (machine precision)
ir = room.golay_impulse_response(rec_a, rec_b, pair)

• ImpulseResponseResult (array-like; .plot())
shaped_sweep_signalfunctionSweep with an arbitrary target spectrum (Mueller & Massarani Secs. 4.2-4.3).
• fs, f1, f2, seconds
• target: 'pink' (Default), 'white' or (frequencies_hz, magnitude_db)
• amplitude (Default: 1.0), start_delay (Default: 0.05·seconds), fade (Default: 0.01)
Group delay grows with the target power: near-constant envelope
sweep = room.shaped_sweep_signal(fs, 50, 5000, 2, target="pink")

• ShapedSweepResult (array-like; .plot())
ShapedSweepResultdataclassSynthesized shaped sweep.
• signal, fs, frequencies, magnitude (imposed, peak 1), group_delay [s], f_range, crest_factor_db
• array-like: usable directly as the deconvolution reference
• .plot(): waveform + Welch spectrum vs target
ir = room.impulse_response(rec, np.asarray(sweep), fs)
ImpulseResponseWarningwarning classSuspect recovered impulse response.
Emitted e.g. for MLS aliasing in the recovery
warnings.simplefilter('error', ImpulseResponseWarning)
plot_excitationfunctionPlot an excitation signal.
• signal: sweep or MLS samples (1D)
• fs: Sample rate [Hz]
• kind: 'sweep' (default) or 'mls'
plot_excitation(sweep, fs, kind="sweep")

• waveform + spectrogram / spectrum axes
decay_curvefunctionSchroeder decay curve (ISO 3382-1 5.3.3).
• ir: Impulse response (1D)
• fs: Sample rate [Hz]
• band: Band centre [Hz] (Default: None → broadband)
• fraction: 1 or 3 (Default: 1)
• zero_phase: forward-backward band filtering, halves the 125 Hz short-T bias (Default: False)
dc = room.decay_curve(ir, fs) → DecayCurve
times, levels = dc still unpacks (times [s], levels [dB], 0 dB at t=0)
dc.plot() draws the decay + EDT/T20/T30 fits
DecayCurvedataclassSchroeder decay curve (ISO 3382-1 5.3.3).
• times: from the direct sound [s]
• levels: decay [dB], 0 dB at t = 0, up to the noise truncation point
• band: centre [Hz] or None (broadband)
• iterable: unpacks as times, levels
• .plot(): decay + EDT/T20/T30 fits
dc = room.decay_curve(ir, fs)
dc.times, dc.levels, dc.band
room_parametersfunctionRoom acoustics (ISO 3382-1/2).
• ir: Impulse response (1D)
• fs: Sample rate [Hz]
• limits: (f_min, f_max) or None (Default: (125, 4000))
• fraction: 1 or 3 (Default: 1)
• zero_phase: forward-backward octave filtering, halves the 125 Hz short-T T30 bias (Default: False)
res = room.room_parameters(ir, fs)

• RoomAcousticsResult per band
RoomAcousticsResultdataclassPer-band room parameters.
• frequencies [Hz]
• edt, t20, t30 [s]
• c50, c80 [dB], d50, ts [s]
• dynamic_range [dB]
• edt_valid/t20_valid/t30_valid
• curvature [%]
res.t30, res.c80, res.t30_valid

• Arrays with one entry per band
sound_strengthfunctionSound strength G (ISO 3382-1 A.2.1, Eq. (A.1)).
• ir: hall impulse response (1D)
• reference_ir: same source at 10 m in a free field (1D)
• fs: Sample rate [Hz]
• reference_level: L_pE,10 [dB] instead of reference_ir (exactly one of the two)
• limits: (f_min, f_max) or None (Default: (125, 4000))
• fraction: 1 or 3 (Default: 1)
res = room.sound_strength(ir, ref, fs)

• SoundStrengthResult per band
SoundStrengthResultdataclassPer-band sound strength.
• frequencies [Hz] or None
• strength: G [dB]
• exposure_level: L_pE [dB]
• reference_level: L_pE,10 [dB]
• .plot(): G against the Table A.1 typical range
res.strength, res.exposure_level

• strength == exposure_level - reference_level
sound_pressure_exposure_levelfunctionL_pE of an impulse response (ISO 3382-1 Eq. (A.2)).
• ir: Impulse response (1D)
• fs: Sample rate [Hz]
• limits: (f_min, f_max) or None (Default: (125, 4000))
• fraction: 1 or 3 (Default: 1)
lpe = room.sound_pressure_exposure_level(ir, fs)

• [dB] re 20 uPa, one per band
free_field_reference_levelfunctionRefer a free-field level to 10 m (ISO 3382-1 Eqs. (A.4)/(A.8)).
• level: measured level [dB]
• distance: of that measurement [m], printed for >= 3 m
room.free_field_reference_level(75.03, 5.0)

• 69.0094 dB
reverberation_room_reference_levelfunctionFree-field reference from a diffuse-field reading (ISO 3382-1 Eq. (A.5)).
• reverberation_room_level: spatial-average L_pE in that room [dB]
• absorption_area: A [m2]
room.reverberation_room_reference_level(80.0, 10.0)

• 53.0 dB
sound_strength_from_powerfunctionG from the source's power level (ISO 3382-1 Eq. (A.9)).
• pressure_level: L_p in the room [dB]
• power_level: L_W of the source [dB]
room.sound_strength_from_power(80.0, 100.0)

• 11.0 dB
directivity_energy_averagefunctionEnergy mean over bearings round the source (ISO 3382-1, note to Eq. (A.4)).
• levels: one per bearing [dB], evenly spaced over a full turn, at least 29
room.directivity_energy_average(levels)

• [dB]; raises below 29 bearings
early_lateral_energy_fractionfunctionEarly lateral energy fraction (ISO 3382-1 Eqs. (A.14)/(A.15)).
• ir: omnidirectional response at the point (1D), which also sets t = 0
• lateral_ir: figure-of-eight response at the same point (1D)
• fs: Sample rate [Hz]
• weighting: 'squared' (J_LF) or 'cosine' (J_LFC)
• limits: (f_min, f_max) or None (Default: (125, 4000))
• fraction: 1 or 3 (Default: 1)
res = room.early_lateral_energy_fraction(omni, fig8, fs)

• LateralEnergyResult per band
LateralEnergyResultdataclassPer-band lateral energy fraction.
• frequencies [Hz] or None
• energy_fraction: J_LF or J_LFC, dimensionless
• weighting: which of the two was computed
• .plot(): against the Table A.1 range
res.energy_fraction, res.weighting
LATERAL_WEIGHTINGSconstant('squared', 'cosine'), the two angular weightings Eqs. (A.14) and (A.15) print.room.LATERAL_WEIGHTINGS
EARLY_LATERAL_WINDOW_Sconstant(0.005, 0.080) s, the numerator window of Eqs. (A.14)/(A.15) from the direct sound.room.EARLY_LATERAL_WINDOW_S
EARLY_ENERGY_LIMIT_Sconstant0.080 s, the upper limit of their denominator.room.EARLY_ENERGY_LIMIT_S
late_lateral_sound_levelfunctionLate lateral sound level (ISO 3382-1 Eq. (A.16)).
• ir: omnidirectional response at the point (1D), for t = 0
• lateral_ir: figure-of-eight response at the same point (1D)
• reference_ir: same source at 10 m in a free field (1D)
• fs: Sample rate [Hz]
• reference_level: L_pE,10 [dB] instead of reference_ir
• limits, fraction: as above
res = room.late_lateral_sound_level(omni, fig8, ref, fs)

• LateLateralResult per band
LateLateralResultdataclassPer-band late lateral level.
• frequencies [Hz] or None
• levels: L_J [dB]
• reference_level: L_pE,10 [dB]
• .plot(): against the Table A.1 range, with the Eq. (A.17) average
res.levels, res.reference_level
late_lateral_averagefunctionEnergy average of L_J over four octave bands (ISO 3382-1 Eq. (A.17)).
• levels: the 125 Hz, 250 Hz, 500 Hz and 1 kHz values [dB], exactly four
room.late_lateral_average([-8.0] * 4)

• -8.0 dB; four equal values are unchanged
LATE_LATERAL_START_Sconstant0.080 s, where the numerator of Eq. (A.16) starts.room.LATE_LATERAL_START_S
LATE_LATERAL_AVERAGE_BANDS_HZconstant(125, 250, 500, 1000) Hz, the four bands Eq. (A.17) averages.room.LATE_LATERAL_AVERAGE_BANDS_HZ
interaural_cross_correlationfunctionInteraural cross correlation (ISO 3382-1 Eqs. (B.1)/(B.2)).
• left, right: ear-canal responses (1D, same length)
• fs: Sample rate [Hz]
• window: (t1, t2) [s] from the direct sound, t2 None for the end (Default: (0.0, None))
• limits, fraction: as above
res = room.interaural_cross_correlation(left, right, fs)

• InterauralCorrelationResult per band
InterauralCorrelationResultdataclassPer-band interaural correlation.
• frequencies [Hz] or None
• coefficient: IACC
• delay: lag of the maximum [s], positive when the right ear lags
• lag [s] and correlation: the function itself, one row per band
• .plot(): the function over the search window
res.coefficient, res.delay
IACC_SEARCH_Sconstant0.001 s, the half-width of the Eq. (B.2) search window.room.IACC_SEARCH_S
IACC_EARLY_WINDOW_Sconstant(0.0, 0.080) s, the early window of B.4.room.IACC_EARLY_WINDOW_S
IACC_LATE_START_Sconstant0.080 s, where B.4's reverberant window starts.room.IACC_LATE_START_S
IACC_JNDconstant0.075, the just-noticeable difference B.4 assumes for IACC.room.IACC_JND
stage_supportfunctionEarly and late stage support (ISO 3382-1 Eqs. (C.1)/(C.2)).
• ir: platform response 1,0 m from the source (1D)
• fs: Sample rate [Hz]
• limits: (f_min, f_max) or None (Default: (250, 2000), the bands C.2.4 averages)
• fraction: 1 or 3 (Default: 1)
res = room.stage_support(ir, fs)

• StageSupportResult per band
StageSupportResultdataclassPer-band stage support.
• frequencies [Hz] or None
• early: ST_Early [dB]
• late: ST_Late [dB]
• .plot(): both against the Table C.1 ranges
res.early, res.late
STAGE_DIRECT_WINDOW_Sconstant(0.0, 0.010) s, the direct-sound window both equations divide by.room.STAGE_DIRECT_WINDOW_S
EARLY_SUPPORT_WINDOW_Sconstant(0.020, 0.100) s, the numerator of Eq. (C.1); it starts at 20 ms, not at 10 ms.room.EARLY_SUPPORT_WINDOW_S
LATE_SUPPORT_WINDOW_Sconstant(0.100, 1.000) s, the numerator of Eq. (C.2); it stops at one second.room.LATE_SUPPORT_WINDOW_S
STAGE_SUPPORT_DISTANCE_Mconstant1.0 m between source and microphone (C.2.1).room.STAGE_SUPPORT_DISTANCE_M
STAGE_SUPPORT_HEIGHTS_Mconstant(1.0, 1.5) m, the two heights C.2.3 permits for both.room.STAGE_SUPPORT_HEIGHTS_M
STAGE_SUPPORT_BANDS_HZconstant(250, 500, 1000, 2000) Hz, the bands C.2.4 averages.room.STAGE_SUPPORT_BANDS_HZ
STAGE_SUPPORT_POSITIONSconstant3 positions C.2.3 asks for and C.2.4 averages over.room.STAGE_SUPPORT_POSITIONS
STAGE_SUPPORT_STANDARD_DEVIATION_DBconstant1.0 dB for one band in one position (C.2.4).room.STAGE_SUPPORT_STANDARD_DEVIATION_DB
STAGE_SUPPORT_SINGLE_NUMBER_STANDARD_DEVIATION_DBconstant0.3 dB for the single number (C.2.4); it is 1 dB over the root of the twelve readings.room.STAGE_SUPPORT_SINGLE_NUMBER_STANDARD_DEVIATION_DB
reverberation_time_standard_deviationfunctionStandard deviation of a measured T (ISO 3382-1 Eqs. (4)/(5)).
• reverberation_time [s]
• bandwidth [Hz], from filter_bandwidth
• evaluation_range: 20 or 30 [dB] (Default: 30)
• decays: n per position (Default: 10, what 7.2 values an integrated response at)
• positions: N source-receiver combinations (Default: 1)
room.reverberation_time_standard_deviation(2.0, 710.0, positions=12)

• 0.009044 s
filter_bandwidthfunctionBandwidth of a fractional-octave filter (ISO 3382-1 7.1).
• centre: mid-band frequency [Hz]
• fraction: 1 or 3 (Default: 1)
room.filter_bandwidth(1000.0) → 710.0 Hz
minimum_reliable_reverberation_timefunctionShortest decay a forward analysis can resolve (ISO 3382-1 Eqs. (6)/(7)).
• bandwidth [Hz]
• detector_time: T of the averaging detector [s] (Default: 0.0, no detector)
room.minimum_reliable_reverberation_time(88.75)

• 0.1803 s
FILTER_BANDWIDTH_FRACTIONconstant{1: 0.71, 3: 0.23}, the two bandwidths 7.1 prints as a fraction of the centre.room.FILTER_BANDWIDTH_FRACTION[1] → 0.71
DECAY_UNCERTAINTY_COEFFICIENTSconstant{20.0: (0.88, 1.90), 30.0: (0.55, 1.52)}, the printed pairs of Eqs. (4) and (5).room.DECAY_UNCERTAINTY_COEFFICIENTS[30.0]
INTEGRATED_RESPONSE_DECAYSconstant10, the decays per position 7.2 values an integrated impulse response at.room.INTEGRATED_RESPONSE_DECAYS
MINIMUM_BANDWIDTH_TIME_PRODUCTconstant16.0, the B·T of Eq. (6).room.MINIMUM_BANDWIDTH_TIME_PRODUCT
MINIMUM_DETECTOR_MULTIPLEconstant2.0, the multiple of the detector's own T in Eq. (7).room.MINIMUM_DETECTOR_MULTIPLE
TABLE_A1constantISO 3382-1 Table A.1, keyed by the symbol the standard prints: G, EDT, C80, D50, Ts, J_LF, L_J.
• each value is an AuditoriumQuantity
room.TABLE_A1['G'].averaging_bands_hz → (500.0, 1000.0)
AuditoriumQuantitydataclassOne row of Table A.1.
• symbol, aspect, unit
• averaging_bands_hz: the bands its single number averages, two or four
• just_noticeable_difference: None for L_J, whose JND the table prints as 'Not known'
• relative_jnd: True only for EDT's 'Rel. 5 %'
• typical_range, energy_averaged
room.TABLE_A1['L_J'].energy_averaged → True
single_number_averagefunctionThe Table A.1 single number of one quantity (A.5).
• symbol: as TABLE_A1 keys it
• values: per-band values
• frequency: the band centres [Hz]
room.single_number_average('G', g, freqs)

• arithmetic, except L_J, which goes through Eq. (A.17)
octave_pair_averagesfunctionThe low, mid and high pair averages of A.5.
• values: per-band values
• frequency: the band centres [Hz], all six octaves
room.octave_pair_averages(v, freqs)

• {'low': ..., 'mid': ..., 'high': ...}
perceptibly_differentfunctionWhether two values differ by the Table A.1 JND.
• symbol, first, second
• relative for EDT, absolute otherwise; raises for L_J
room.perceptibly_different('EDT', 0.5, 0.56) → True
minimum_receiver_positionsfunctionFewest microphone positions a hall wants (Table A.2).
• seats: the number of seats
room.minimum_receiver_positions(1000) → 8.0

• clamped to the 6 to 10 A.4 authorises
gliding_directivity_deviationfunctionDeviation of each gliding 30 degree arc from the whole turn (4.2.1).
• levels: one per bearing [dB], evenly spaced over a full turn
room.gliding_directivity_deviation(levels)

• one deviation per bearing [dB]
source_directivity_limitfunctionThe Table 1 limit for one octave band.
• centre: nominal band centre [Hz], one of the six the table prints
room.source_directivity_limit(4000.0) → 6.0 dB
MAX_SOURCE_DIRECTIVITY_DEVIATION_DBconstantTable 1, six octave bands to their maximum deviation in dB: 1, 1, 1, 3, 5, 6.room.MAX_SOURCE_DIRECTIVITY_DEVIATION_DB[1000.0] → 3.0
DIRECTIVITY_ARC_DEGconstant30.0 degrees, the arc each gliding average of 4.2.1 covers.room.DIRECTIVITY_ARC_DEG
DIRECTIVITY_STEP_DEGconstant5.0 degrees, the step 4.2.1 asks for without a turntable; it divides a turn into 72.room.DIRECTIVITY_STEP_DEG
DIRECTIVITY_SURVEY_DISTANCE_Mconstant1.5 m, the shortest source-to-microphone distance 4.2.1 allows in a survey.room.DIRECTIVITY_SURVEY_DISTANCE_M
OCTAVE_PAIRS_HZconstantThe three A.5 pairs: low 125+250, mid 500+1000, high 2000+4000 Hz.room.OCTAVE_PAIRS_HZ['mid']
MID_FREQUENCY_OCTAVES_HZconstant(500, 1000) Hz, the octave route of Clause 9.1 to T30,mid.room.MID_FREQUENCY_OCTAVES_HZ
MID_FREQUENCY_THIRD_OCTAVES_HZconstant(400, 500, 630, 800, 1000, 1250) Hz, the other route Clause 9.1 prints, and the one a one-third-octave analysis takes.room.MID_FREQUENCY_THIRD_OCTAVES_HZ
TEST_REPORT_ITEMSconstantThe fifteen items Clause 9.2 says a test report shall include, a) to o), in order. Clause 9 is normative.len(room.TEST_REPORT_ITEMS) → 15
AuditoriumWarningwarning classA measurement outside the conditions ISO 3382-1 prints for it.
• emitted for a room response cut short of the 30 dB of A.2.1
• for a response of either kind that ends before its lowest band's filter has rung down
• and for a free-field distance under 3 m
warnings.simplefilter('error', room.AuditoriumWarning)
REFERENCE_DISTANCE_Mconstant10.0 m, the free-field distance G is referenced to (ISO 3382-1 A.2.1).room.REFERENCE_DISTANCE_M → 10.0
MINIMUM_REFERENCE_DISTANCE_Mconstant3.0 m, the shortest distance Eqs. (A.4)/(A.8) are printed for.room.MINIMUM_REFERENCE_DISTANCE_M → 3.0
MAXIMUM_DIRECTIVITY_STEP_DEGconstant12.5 deg, the coarsest bearing step the note to Eq. (A.4) allows.room.MAXIMUM_DIRECTIVITY_STEP_DEG → 12.5
SOUND_STRENGTH_POWER_OFFSET_DBconstant31.0 dB, the printed offset of Eq. (A.9); 10 lg(4 pi 10210^{2}) = 30.9921 dB rounded.room.SOUND_STRENGTH_POWER_OFFSET_DB → 31.0
DIFFUSE_FIELD_REFERENCE_OFFSET_DBconstant37.0 dB, the printed offset of Eq. (A.5); 10 lg(16 pi 10210^{2}) = 37.0127 dB rounded.room.DIFFUSE_FIELD_REFERENCE_OFFSET_DB → 37.0
open_plan_metricsfunctionOpen-plan office metrics (ISO 3382-3).
• positions_m: Source distances [m] (≥ 4)
• spl_a_speech: A-weighted speech level per position [dB]
• sti_values: STI per position
m = room.open_plan_metrics(r, lp, sti)

• OpenPlanResult
plot_open_plan_geometryfunctionOpen-plan measurement line to scale.
• positions [m] (1-D)
• rd, rp [m] (markers)
• language
plot_open_plan_geometry([2, 4, 6, 8, 12, 16], rd=6.5, rp=13.0)

• Also OpenPlanResult.plot_geometry()
OpenPlanResultdataclassOpen-plan single numbers.
• d2s: Spatial decay rate [dB/doubling]
• lp_as_4m: Speech level at 4 m [dB]
• rd: Distraction distance [m]
• rp: Privacy distance [m]
m.d2s, m.rd, m.rp

• nan when undefined
image_source_rirfunctionImage-source room impulse response (Kuttruff 4.1 / Vorländer 11).
• dimensions: (Lx, Ly, Lz) [m]
• source/receiver: (x, y, z) [m]
• absorption: scalar / (6,) per-wall / per-band / (6, n) [0, 1]
• fs [Hz], max_order (Default: 20)
• air_attenuation: intensity m [1/m]
• frequencies [Hz] for a per-band RIR
res = room.image_source_rir((7,5,3), (2,1.6,1.5), (5.2,3.4,1.7), 0.12, fs=48000)

• ImageSourceResult
ImageSourceResultdataclassSynthetic RIR by image sources.
• ir: sampled RIR (1D or per-band)
• exact reflection table times/distances/orders/amplitudes/image_positions
• direct_time [s]
• .plot(), .plot_geometry() (room plan with the image lattice): reflectogram
res.ir, res.times, res.orders
res.plot()
audible_image_count / reflection_densityfunctionShoebox image count (Kuttruff Eq. 9.23) and reflection density (Eq. 4.6).
• audible_image_count(order): (2/3)(2i³+3i²+4i)
• reflection_density(t, volume, speed_of_sound=343): 4πc³t²/V
audible_image_count(10) # 1560
reflection_density(0.1, 120.0)
steady_state_fieldfunctionSteady-state room field (Bies 6.4).
• sound_power_level Lw [dB]
• surface_area S [m²], mean_absorption ᾱ (0, 1)
• distances [m] (Default: 0.1–10 rc)
• directivity Q (Default: 1)
• characteristic_impedance [Pa·s/m] for the ρc term
f = room.steady_state_field(90.0, 100.0, 0.2)

• SteadyFieldResult
SteadyFieldResultdataclassSPL vs distance, direct/reverberant/total.
• distances [m]
• direct/reverberant/total [dB]
• critical_distance [m], room_constant [m²]
• .plot()
f.total, f.critical_distance
f.plot()
room_constant / sabine_absorption_area / critical_distance / schroeder_frequency / steady_state_spl / SOURCE_POWER_MODELSfunction / mappingSteady-field building blocks (Bies 6.43/6.44, Kuttruff 3.44/5.44, VDI 2081-1 Eq. 36/37).
• room_constant(S, ᾱ) = Sᾱ/(1-ᾱ) [m²]
• sabine_absorption_area(V, T, speed_of_sound=343) = 24 ln10/c₀ · V/T [m²]
• critical_distance(R | absorption_area=A, directivity=1) = √(QR/16π), or √(QA/16π) from the absorption area [m]
• schroeder_frequency(T, V) = 2000√(T/V) [Hz]
• steady_state_spl(Lw, r, R | absorption_area=A, directivity=1, source_model='constant_power') = Lw + 10 lg(Q/4πr² + 4/R), with 4/A in place of 4/R from the absorption area [dB]; r=None gives the reverberant field alone; exactly one absorption measure, directivity scalar or per band
• SOURCE_POWER_MODELS: 'constant_power' / 'constant_volume' (Π₀Q, conservative) / 'constant_pressure' (Π₀/Q), Norton Table 4.5
R = room.room_constant(100, 0.2)
critical_distance(R)
steady_state_spl(90, None, R)
room_modesfunctionNormal modes of a rectangular room (Long, Architectural Acoustics 2e, Eq. 8.43).
• dimensions: (lx, ly, lz) [m]
• max_frequency [Hz] (Default: 200)
• speed_of_sound [m/s] (Default: 343)
• reverberation_time [s] (optional, adds the Schroeder frequency)
m = room.room_modes((7, 5, 3), max_frequency=100.0)

• RoomModesResult
RoomModesResultdataclassSorted mode list of a shoebox.
• orders: (N, 3) (nx, ny, nz)
• frequencies [Hz], ascending
• kinds: 'axial'/'tangential'/'oblique'
• volume, surface_area, edge_length, schroeder_frequency
• count_by_kind(), density(f)
• .plot(): mode ladder by family + modal density
m.frequencies[0], m.count_by_kind()
m.plot()
room_mode_frequency / room_mode_count / room_modal_densityfunctionMode building blocks (Long Eqs. 8.43, 8.45, 8.46).
• room_mode_frequency(orders, dimensions) = (c0/2)√((nx/lx)²+(ny/ly)²+(nz/lz)²) [Hz]
• room_mode_count(f, dimensions): Morse/Pierce smooth count
• room_modal_density(f, dimensions) [modes/Hz]
room_mode_frequency((1, 0, 0), (7, 5, 3))
room_modal_density(1000.0, (7, 5, 3))
MODE_KINDSconstantMode families, strongest first: ('axial', 'tangential', 'oblique').MODE_KINDS[0] # 'axial'
crowd_noisefunctionSelf-generated crowd noise vs occupancy (Long Ch. 17, Eqs. 17.50–17.52).
• absorption_areas: total room absorption [m²] (scalar or 1-D)
• talkers: occupancy axis N (Default: 1..20)
• distance r [m] (Default: 1.2), sound_power_level Lw [dB] (Default: 70), directivity Q (Default: 2)
c = room.crowd_noise([20.0, 190.0])

• CrowdNoiseResult
CrowdNoiseResultdataclassCrowd self-noise result.
• talkers, absorption_areas, levels [dB] (areas × talkers)
• signal_level [dB], communication_level [dB], distance, sound_power_level, directivity
• speech_to_noise() [dB]
• .plot(): level vs occupancy per absorption
c.levels, c.signal_level
c.plot()
speech_direct_level / crowd_noise_level / speech_to_noise_ratio / absorption_per_tablefunctionCrowd-noise building blocks (Long Eqs. 17.50–17.54).
• speech_direct_level(r) = Lw + 10 lg(Q/4πr²) [dB]
• crowd_noise_level(N, A) = Lw + 10 lg N + 10 lg(4/A) [dB]
• speech_to_noise_ratio(r, A_tab) [dB]
• absorption_per_table(r, L_SN) [m²]: the inverse
crowd_noise_level(20, 20.0) # 76
absorption_per_table(1.0, -6.0) # 6.31
NORMAL_VOICE_POWER_LEVEL / TALKER_DIRECTIVITY / COMMUNICATION_SNR / PRIVACY_SNRconstantCrowd-noise defaults (Long Ch. 17).
• 70 dB re 1 pW per talker, Q = 2
• −6 dB communication limit (Eq. 17.53), −9 dB privacy limit (Eq. 17.54)
absorption_per_table(1.0, COMMUNICATION_SNR)
sound_distribution_value / reference_distribution_value / ISO14257_REFERENCE_DISTANCE_M / FREE_FIELD_OFFSET_DBfunction / constantThe curve a workroom is judged by, ISO 14257 Eqs. (1) and (2).
• sound_distribution_value(levels, power_levels): D = L_p − L_W, the level at a position referred to the power of the source that made it
• reference_distribution_value(distances): D_ref = 20 lg(r_0/r) − 11 dB, the free field the same source would give, with r_0 = 1 m
• the 11 dB is 10 lg(4 π r_0²) rounded, which is why a free field slopes 6 dB per doubling and starts where it does
d = room.sound_distribution_value(levels, 110.8)
room.reference_distribution_value([2.0, 4.0]) # -17.02, -23.04
spectrum_distribution_value / normalized_distribution_value / PINK_NOISE_WEIGHTS_DB / NORMALIZED_OFFSET_DBfunction / mapping / constantThe six bands collapsed into one number, Eqs. (3) and (4).
• spectrum_distribution_value(values, machine_power_levels): the curve weighted by the spectrum of the machine that will stand there
• normalized_distribution_value(values): the same sum with A-weighted pink noise fixed as the spectrum, Table 1, minus the printed 6,2 dB; the six printed weights sum to 6,251 5 dB, so a flat curve comes back 0,05 dB high, and spectrum_distribution_value(values, list(PINK_NOISE_WEIGHTS_DB.values())) is the exact normalisation Annex C used
• 4.2.3 says why that spectrum is a normalisation and not an average machine: real spectra are too varied for an average to mean anything
room.normalized_distribution_value(d_by_band)
spatial_decay_rate / DECADE_TO_DOUBLINGfunction / constantDL2, the rate of spatial decay per distance doubling, Eq. (5).
• the least-squares slope of D against lg r, times 0,3, sign flipped so a decay is positive
• 6 dB is the free field; a workroom gives less, and how much less is what the room is worth
• DECADE_TO_DOUBLING is the printed 0,3, which is lg 2 rounded
room.spatial_decay_rate(d, distances) # 4.39
level_excess / mean_level_excess / level_excess_at / EVALUATION_DISTANCES_Mfunction / mappingDLf, how far the room sits above a free field, Eqs. (6) to (8).
• level_excess: D − D_ref at every position
• mean_level_excess: the average of Eq. (7), a trapezoid over lg r, so the wide gaps of a logarithmic distribution weigh what they should
• level_excess_at: the height of the fitted line over the free-field line at one distance, which a single outlying position moves much less
• EVALUATION_DISTANCES_M: 4 m, 10 m and 30 m, the conventional distances 6.4.3 reads the line at
room.mean_level_excess(d, distances) # 6.73
spatial_decay_curve / SpatialDecayResultfunction / dataclassOne region of the path, with both descriptors, clause 6.
• region: 'near', 'middle', 'far' or 'whole'; near_limit_m d₁ and far_limit_m d₂ place the boundaries
• result: distances_m, distribution_values_db, reference_values_db, level_excess_db, decay_rate_db, mean_excess_db, region, band_hz
• .plot(): the curve, the free field it is judged by, and the fitted slope
res = room.spatial_decay_curve(d, distances, region="middle")

• res.decay_rate_db, res.mean_excess_db
distance_region / NEAR_REGION_START_M / TYPICAL_NEAR_LIMIT_M / TYPICAL_FAR_LIMIT_M / PREFERRED_MIDDLE_LIMIT_Mfunction / constantThe three distance ranges of 6.2.
• near from 1 m to d₁, middle from d₁ to d₂, far beyond d₂, with 5 m and 16 m the typical pair
• the middle region is the one health and safety work reads, and 6.2 b) asks for it to reach 24 m whenever the room allows
• distances are measured from the acoustical centre of the source
room.distance_region(12.0) # 'middle'
floor_reference_value / corrected_distribution_value / SOURCE_ON_FLOOR_HEIGHT_Mfunction / constantTaking the source's own curve back out, Annex B.
• floor_reference_value(distances, source_height_m=…, path_height_m=…): D_ref plus 10 lg(1 + r²/(r² + 4 h_S h_P)), which is Eq. (B.4)'s 3 dB for a source on the floor
• corrected_distribution_value(values, measured_reference, distances, …): Eq. (B.1) swaps the measured free-field curve of that source for the theoretical one, so what is left is the room
• a source is "on the floor" at 0,5 m or under, which is where the half-space form applies
room.corrected_distribution_value(d, d_free, distances, source_height_m=0.0)
omnidirectionality_tolerance_db / OMNIDIRECTIONAL_TOLERANCE_DB / OMNIDIRECTIONAL_RAMP_HZ / MAX_DIRECTIVITY_INDEX_DB / ADJACENT_BAND_LIMIT_DB / STABILITY_TOLERANCE_DBfunction / constant / mappingWhat makes a source fit for the test, Annex A.
• ± 2 dB up to 630 Hz, a linear rise to ± 8 dB at 1 kHz and ± 8 dB from there to 5 kHz, taken across the three one-third-octave bands that span the rise
• the source's own spectrum may not step more than 8 dB between adjacent one-third octaves, and its output must hold to 1 dB below 160 Hz and 0,5 dB above 200 Hz
room.omnidirectionality_tolerance_db(800.0) # 5.0
SPATIAL_DECAY_BANDS_HZ / ISO14257_MIN_SIGNAL_TO_BACKGROUND_DB / ISO14257_PREFERRED_SIGNAL_TO_BACKGROUND_DB / MIN_SOURCE_TO_WALL_MconstantThe conditions of clause 5, as numbers.
• the six octave bands from 125 Hz to 4 kHz the curve is measured in
• the source at least 10 dB over the background at every position; between 6 dB and 10 dB an ISO 3744 correction is made, and under 6 dB there is no measurement
• the acoustical centre of the source at least 3 m from any wall or reflecting object other than the floor
room.SPATIAL_DECAY_BANDS_HZ # (125.0, ..., 4000.0)
check_background_margin / BackgroundMarginCheckfunction / dataclassDoes the source stand clear of the background? 5.1.4.
• levels_db with the source running and background_levels_db without it, one octave band at a time
• result: margins_db, needs_correction (under 10 dB and over 6 dB, where the clause asks for the ISO 3744 correction), unusable (6 dB or less, which it offers no correction for), satisfied
• the verdict is returned and never applied: the correction belongs to the standard that prints it
• Emitted by room.spatial_decay: SpatialDecayWarning when any margin is under 10 dB
check = room.check_background_margin(levels, background)
check.satisfied # False
SpatialDecayWarningwarning classThe measurement is outside a condition ISO 14257 states.
• a region holding the two positions a regression needs and no more, so the rate is the line through them (5.3.2)
• a margin over the background under the 10 dB of 5.1.4
• level_excess_at reading the fitted line outside the distances it was fitted over, which the 30 m of 6.4.3 asks of a path that stops at 24 m
• Emitted by room.spatial_decay
warnings.simplefilter('error', SpatialDecayWarning)
prediction_method / PREDICTION_METHODS / PredictionMethodfunction / mapping / dataclassThe four ways ISO 11690-3 lets you predict a workroom, Table 4.
• '1' is the diffuse-field method, for a room whose field may be treated as diffuse; '2a', '2b' and '2c' are geometrical, in growing order of what they model
• PredictionMethod: category, family, rooms, and the detail levels Table E.1 asks it to be fed (room_detail, fitting_detail, source_detail)
room.prediction_method("2b").family # 'geometrical'
detail_is_sufficient / DetailVerdict / RECOMMENDED_DETAILfunction / dataclass / mappingWhether the data in hand is what the method asks for, Table E.1.
• detail_is_sufficient(category, room_detail=…, fitting_detail=…, source_detail=…)
• verdict: satisfied, and room_ok / fittings_ok / sources_ok so a refusal says which of the three is short
• the annex is a recommendation, so this reports rather than raises
room.detail_is_sufficient("2c", room_detail=2, fitting_detail=2, source_detail=1)
ROOM_DETAIL_LEVELS / FITTING_DETAIL_LEVELS / SOURCE_DETAIL_LEVELSmappingHow much of the room, the fittings and the sources a model carries, Tables 1 to 3.
• room: from the volume and one mean absorption coefficient up to the actual shape with absorption distributed over it
• fittings: from ignored up to their real shape and location, with shielding and reflection
• sources: omnidirectional points, points with a directivity, complex sources
room.ROOM_DETAIL_LEVELS[2]
fitting_densityfunctionq = S/4V, the density of the fittings, NOTE 3 of 6.2.2.
• surface_area_m2: the total surface of everything standing in the room
• volume_m3: the volume they stand in
room.fitting_density(480.0, 1200.0) # 0.1
workstation_level_increase / workstation_level / total_workstation_levelfunctionWhat the room adds at the machine's own workstation, Annex C.
• workstation_level_increase(sound_power_level_db=…, emission_level_db=…, absorption_area_m2=…): 10 lg(1 + 4S/A) with S = 10^((L_WA − L_pA)/10), the room reflecting back what the machine emits
• workstation_level: the emission level with that increase on it
• total_workstation_level(contributions, existing_level_db=…): the energy sum of every machine, and of what was already there
room.workstation_level(sound_power_level_db=95.0, emission_level_db=85.0, absorption_area_m2=200.0)
typical_decay_range / typical_excess_range / TYPICAL_DECAY_RANGE_DB / TYPICAL_EXCESS_RANGE_DBfunction / mappingWhat 4.3 says the two descriptors usually are, region by region.
• DL2: 5 dB to 6 dB near, 2 dB to 5 dB in the middle, over 6 dB far away
• DLf: 2 dB to 10 dB in the middle region, which is the one the clause prints a range for
• an open bound comes back as None, so a range is a pair to read rather than a limit to enforce
room.typical_decay_range("middle") # (2.0, 5.0)
airborne_insulationfunctionField airborne insulation (ISO 16283-1).
• l1/l2: Source/receiving levels [dB], 1D or (positions, bands)
• t2: Receiving-room T per band [s]
• area: Partition S [m²] (for R')
• volume: Receiving V [m³] (for R')
• t0: Reference T0 [s] (Default: 0.5)
• frequencies [Hz] (required with either low-frequency argument)
• source_low_frequency / receiver_low_frequency: LowFrequencyProcedure per room (ISO 16283-1 Clause 8)
• Warns (LowFrequencyWarning) when volume rounds below 25 m³, frequencies names 50/63/80 Hz and no receiver_low_frequency is given
ins = building.airborne_insulation(l1, l2, t2, area=10, volume=50)

• AirborneInsulationResult
weighted_ratingfunctionSingle-number rating + C/Ctr (ISO 717-1).
• values_by_band: 16 thirds or 5 octaves [dB]
• bands: 'third-octave', 'octave' or None
w = building.weighted_rating(R)

• WeightedRatingResult (Rw, C, Ctr)
weighted_rating_extendedfunctionRating + enlarged-range terms (ISO 717-1 Annex B).
• values_by_band [dB] with frequencies [Hz] (None = the 16 core bands)
• one_decimal: 0.1 dB shift + one-decimal reductions for uncertainty statements (Default: False)
ext = building.weighted_rating_extended(r, freqs)

• ExtendedWeightedRatingResult (rating, c, ctr, c_50_3150 … ctr_100_5000)
ExtendedWeightedRatingResultdataclassWeighted rating with the enlarged-range adaptation terms (ISO 717-1 Annex B).
• rating + c, ctr
• c_50_3150, c_50_5000, c_100_5000 and the ctr_ twins
• core: the base WeightedRatingResult
res = building.weighted_rating_extended(freqs, r)
db_hr_global_indexfunctionA-weighted global index Ix = −10 lg Σ 10^((Lx,i−Xi)/10) (CTE DB-HR Annex A, A.5-A.7).
• band_values Xi [dB] over the 18 bands 100 Hz-5 kHz
• spectrum: 'pink','traffic','railway','aircraft'
• frequencies [Hz], name
idx = building.db_hr_global_index(r, "pink")

• DbHrGlobalIndexResult
rafunctionRA for pink noise (DB-HR Annex A).
• reduction_index R or R' [dB]; frequencies
ra(r_prime).intermediate # 51.4 dBA
ra_trfunctionRA,tr for road-traffic noise (DB-HR Annex A).
• reduction_index [dB]; frequencies
ra_tr(r).reported
dnt_afunctionDnT,A between rooms, pink noise (Formula A.7).
• level_difference DnT [dB]; frequencies
dnt_a(dnt).reported
d2m_nt_afunctionD2m,nT,A of a facade (Formula A.5).
• level_difference D2m,nT [dB]; frequencies
• spectrum: 'pink' (Default) or 'railway'
• Clause 3.1.3.4 point 1: the quantity a railway-dominant site is assessed in
d2m_nt_a(d, spectrum='railway').name # 'D2m,nT,A'
d2m_nt_atrfunctionD2m,nT,Atr of a facade (Formula A.6).
• level_difference D2m,nT [dB]; frequencies
• spectrum: 'traffic' (Default) or 'aircraft'
• Railway noise is D2m,nT,A via (A.5): use d2m_nt_a
d2m_nt_atr(d).intermediate # 32.8 dBA
DbHrGlobalIndexResultdataclassA DB-HR A-weighted global index.
• value (exact), intermediate (1 decimal), reported (integer, 3.1.3.1 point 4)
• name, spectrum, reference
• frequencies, band_values, spectrum_levels, band_contributions
• .plot()
idx.value, idx.intermediate, idx.reported
DB_HR_FREQUENCIESconstantThe eighteen 1/3-octave centres of DB-HR Annex A, 100 Hz to 5 kHz.DB_HR_FREQUENCIES[0] # 100.0
DB_HR_NORMALISED_SPECTRAconstantNormalised A-weighted source spectra [dBA] of Annex A Tables A.2-A.5.
'pink' (A.5), 'traffic' (A.3), 'railway' (A.4, equal to A.3), 'aircraft' (A.2)
DB_HR_NORMALISED_SPECTRA["pink"]
window_size_correctionfunctionWindow-size correction of RA / RA,tr [dB] (CTE Catálogo de Elementos Constructivos).
• area [m²]: 0 up to 2,7; −1 to 3,6; −2 to 4,6; −3 above
26 + building.window_size_correction(4.0) # 24 dBA
db_hr_facade_requirementfunctionRequired D2m,nT,Atr (DB-HR Table 2.1).
• ld [dBA], building_use, room_type
• dominant_noise: 'road','railway','aircraft' (+4 dBA)
• quiet_facade: assess with Ld − 10 dBA
db_hr_facade_requirement(62, "residential", "bedrooms") # 32 dBA
db_hr_airborne_requirementfunctionAirborne requirements between rooms (DB-HR 2.1.1).
• receiving_room: 'protected'/'habitable'
• source_room: 'same_unit','other_unit','installations','activity'
• shared_opening: the RA pair on the door/window and its enclosure
(req,) = building.db_hr_airborne_requirement("protected", "other_unit") # 50 dBA
db_hr_party_wall_requirementfunctionParty wall between two buildings (DB-HR 2.1.1 c), alternatives.
• quantity: 'D2m,nT,Atr' (40 dBA per leaf) or 'DnT,A' (50 dBA for both)
db_hr_party_wall_requirement()
db_hr_impact_requirementfunctionImpact requirement L'nT,w (DB-HR 2.1.2).
• receiving_room, source_room (65 dB against another use unit, 60 dB otherwise)
db_hr_impact_requirement("protected", "other_unit") # ≤ 65 dB
db_hr_reverberation_requirementfunctionReverberation / absorption requirement (DB-HR 2.2).
• room_use: 'classroom','restaurant','common_area' (or aliases)
• furnished: classroom with seating (0,5 s)
db_hr_reverberation_requirement("classroom") # ≤ 0.7 s
DbHrRequirementdataclassA single DB-HR performance requirement.
• quantity, limit, direction ('min'/'max'), unit
• decimals: rounding before the comparison
• reference, description
req.quantity, req.limit
check_db_hr_requirementfunctionCheck an achieved value against a requirement.
• value, requirement
• Rounds as DB-HR prescribes, then compares
check_db_hr_requirement(32.8, req)

• DbHrCheck
DbHrCheckdataclassA DB-HR requirement checked.
• requirement, value, reported, margin, complies
chk.reported, chk.complies
assess_db_hrfunctionCheck a set of (value, requirement) pairs.
• items
assess_db_hr([(33.0, req)])

• DbHrAssessment
DbHrAssessmentdataclassA set of DB-HR requirement checks.
• checks; .complies
• .plot()
a.complies
energy_average_levelfunctionEnergy-average level (ISO 16283-1 (9)).
• levels: Levels [dB] to average
• axis: Averaging axis (Default: -1)
L = building.energy_average_level([60, 66])

• 10 lg( mean(10^(Li/10)) )
AirborneInsulationResultdataclassField insulation per band.
• d: Level difference D [dB]
• dnt: Standardized DnT [dB]
• r_prime: Apparent R' [dB] or None
• l1, l2, t2, t0: retained measurement chain (or None)
• source_low_frequency, receiver_low_frequency: LowFrequencyResult or None
• .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))
WeightedRatingResultdataclassWeighted rating result.
• rating: Rw/DnT,w … [dB], int
• c: Spectrum term C, int
• ctr: Spectrum term Ctr, int
• unfavourable_sum: [dB]
• band_centers: Measured-curve centres [Hz] or None
• measured: Measured band values [dB] or None
• shifted_reference: Shifted Table 3 reference [dB] or None
w.rating, w.c, w.ctr
impact_insulationfunctionField impact insulation (ISO 16283-2).
• li: Impact SPL [dB], 1D or (positions, bands)
• t2: Receiving-room T per band [s]
• volume: Receiving V [m³] (for L'n)
• t0: Reference T0 [s] (Default: 0.5)
• frequencies [Hz] (required with low_frequency)
• low_frequency: receiving-room LowFrequencyProcedure (ISO 16283-2 Clause 8)
• Warns (LowFrequencyWarning) when volume rounds below 25 m³, frequencies names 50/63/80 Hz and no low_frequency is given
imp = building.impact_insulation(li, t2, volume=50)

• ImpactInsulationResult (l_n_t, l_n)
weighted_impact_ratingfunctionSingle-number impact rating + CI (ISO 717-2).
• values_by_band: 16 thirds (100-3150 Hz) or 5 octaves (125-2000 Hz) [dB]
• bands: 'third-octave', 'octave' or None
r = building.weighted_impact_rating(imp.l_n_t)

• ImpactRatingResult (Ln,w, CI); octave rating carries the -5 dB rule
weighted_impact_rating_extendedfunctionImpact rating + CI,50-2500 (ISO 717-2:2020 A.2.1 NOTE).
• values_by_band [dB] with frequencies [Hz] (None = the 16 core bands)
• 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 = building.weighted_impact_rating_extended(ln, freqs)

• ExtendedImpactRatingResult (rating, ci, ci_50_2500)
ExtendedImpactRatingResultdataclassWeighted impact rating with CI,50-2500 (ISO 717-2:2020 A.2.1).
• rating, ci, ci_50_2500
• core: the base ImpactRatingResult
res = building.weighted_impact_rating_extended(freqs, ln)
weighted_impact_improvementfunctionWeighted improvement ΔLw (ISO 717-2 §5).
• delta_l: 16 one-third-octave ΔL (100-3150 Hz) [dB]
Applies the Table 4 reference floor: ΔLw = 78 − Ln,r,w
weighted_impact_improvement(delta_l)

• ΔLw [dB] (e.g. 19)
impact_improvement_adaptation_termfunctionSpectrum adaptation term CI,Δ (ISO 717-2:2020 Formula (A.4)).
• delta_l: 16 one-third-octave ΔL (100-3150 Hz) [dB]
CI,Δ = CI,r,0 − CI,r (CI,r,0 = −11 dB); ISO 16251-1 clause 8 e)
impact_improvement_adaptation_term(delta_l)

• CI,Δ [dB], int
impact_improvementfunctionFloor-covering improvement ΔL (ISO 16251-1).
• bare, with_covering: acceleration levels L0/L1 per band [dB]
• frequencies [Hz] (a clause 6.3 spectrum is rated on its 100-3150 Hz sub-range)
• background: optional Lb per band [dB] (Formula 2)
res = building.impact_improvement(l0, l1, f)

• FloorCoveringImprovementResult
acceleration_levelfunctionVibratory acceleration level La (ISO 16251-1 Formula 1).
• acceleration: RMS a per band [m/s²]
• reference: a0 (Default: 1e-6)
acceleration_level(1e-3) # 60 dB
background_corrected_levelfunctionBackground correction (ISO 16251-1 Formula 2).
• signal_and_background, background [dB]
L, limited = building.background_corrected_level(lp, lb)

• (corrected [dB], limit-of-measurement mask)
improvement_octave_bandsfunctionThirds → octaves for ΔL (ISO 16251-1 Formula 5).
• improvement, frequencies (whole octave triplets)
f_oct, dl_oct = building.improvement_octave_bands(dl, f)
FloorCoveringImprovementResultdataclassFloor-covering improvement (ISO 16251-1).
• improvement ΔL [dB], delta_lw, ci_delta (or None)
• limited: > ΔL mask; .octave_bands(), .plot()
res.delta_lw, res.ci_delta
ImpactInsulationResultdataclassImpact insulation per band.
• l_n_t: Standardized L'nT [dB]
• l_n: Normalized L'n [dB] or None
• li, t2, t0: retained measurement chain (or None)
• low_frequency: LowFrequencyResult or None
• .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))
ImpactRatingResultdataclassWeighted impact rating.
• rating: Ln,w/L'n,w/L'nT,w [dB], int
• ci: Spectrum term CI, int
• unfavourable_sum: [dB]
• band_centers: Measured-curve centres [Hz] or None
• measured: Measured impact levels [dB] or None
• shifted_reference: Shifted impact reference [dB] or None
r.rating, r.ci
ReportMetadatadataclassMetadata for the accredited ISO 717 .report() PDF fiche.
• All fields optional; only the supplied ones render
• specimen, client, manufacturer, test_room, instrumentation, calibration, mounting, measurement_standard, test_date
• numeric (finite, positive): area, mass_per_area, source_volume, receiving_volume, temperature_c, relative_humidity_percent, static_pressure_kpa, requirement
• laboratory, operator, report_id, notes
w.report("f.pdf", metadata=ReportMetadata(area=10.0, requirement=52.0))
facade_insulationfunctionField façade insulation (ISO 16283-3).
• l1_2m/l2: Level 2 m in front / receiving levels [dB], 1D or (positions, bands)
• t2: Receiving-room T per band [s]
• area: Element S [m²], volume: Receiving V [m³], surface_level: L1,s [dB] (all three for R')
• method: 'loudspeaker' (−1.5 dB) / 'road_traffic' (−3 dB)
• t0: Reference T0 [s] (Default: 0.5)
• frequencies [Hz] (required with low_frequency)
• low_frequency: receiving-room LowFrequencyProcedure (ISO 16283-3 Clause 7.3); loudspeaker methods only
• Warns (LowFrequencyWarning) when a loudspeaker-method volume rounds below 25 m³, frequencies names 50/63/80 Hz and no low_frequency is given
fac = building.facade_insulation(l1_2m, l2, t2, volume=50, area=11.5, surface_level=ls)

• FacadeInsulationResult
FacadeInsulationResultdataclassFaçade insulation per band.
• d_2m: Level difference D2m [dB]
• d_2m_nt: Standardized D2m,nT [dB]
• d_2m_n: Normalized D2m,n [dB] or None
• r_prime: Apparent R'45°/R'tr,s [dB] or None
• frequencies [Hz] or None
• method: the incidence correction used
• low_frequency: LowFrequencyResult or None
• .plot()
fac.d_2m_nt, fac.r_prime
LowFrequencyProceduredataclassISO 16283 low-frequency measurements of one room (Clause 8 / 7.3).
• volume: Room V [m³]; must round below 25 m³
• corner_levels: (corners, 3) or (positions, corners, 3) at 50/63/80 Hz [dB]
• reverberation_63_octave: 63 Hz octave T [s] (receiving room, Clause 10.4 / 8.4)
lf = building.LowFrequencyProcedure(volume=18.0, corner_levels=c, reverberation_63_octave=0.72)
low_frequency_procedure_appliesfunctionThe printed 25 m³ trigger.
• volume: Room V [m³], rounded to the nearest cubic metre (half away from zero)
• True only for a rounded volume strictly below 25 m³
building.low_frequency_procedure_applies(18.0) # True
corner_levelfunctionCorner level L_Corner (ISO 16283-1 (12) / -2 (15)).
• corner_levels: (corners, bands) or (positions, corners, bands) [dB]
• Highest corner per band, then energy-averaged over source positions
lc = building.corner_level(corners)
low_frequency_levelfunctionCombination L_LF (ISO 16283-1 (13) / -2 (16) / -3 (5)).
• level: Default-procedure L [dB]
• corner: L_Corner [dB]
• 10 lg[(10^(0,1 Lc) + 2·10^(0,1 L))/3]
llf = building.low_frequency_level(l, lc)
apply_low_frequency_procedurefunctionRun the procedure over a whole band vector.
• level, frequencies, procedure
• reverberation_time: measured T per band (receiving room)
• room: 'receiving' (Clause 10.4 applies) or 'source'
res = building.apply_low_frequency_procedure(l2, f, lf, reverberation_time=t2)
LowFrequencyResultdataclassWhat the procedure did to one room.
• levels, reverberation_time: full band vectors after substitution
• l_default, l_corner, l_lf: the three-band chain [dB]
• low_frequency_bands [Hz], volume [m³], reverberation_63_octave [s]
• .plot()
res.l_lf, res.reverberation_time
LOW_FREQUENCY_BANDStupleThe three one-third-octave bands the procedure covers (50, 63, 80 Hz).building.LOW_FREQUENCY_BANDS
LOW_FREQUENCY_VOLUME_LIMITfloatRoom volume the procedure stops at, 25 m³ to the nearest cubic metre, strictly.building.LOW_FREQUENCY_VOLUME_LIMIT # 25.0
LowFrequencyWarningwarning classAn ISO 16283 low-frequency requirement the measurement does not meet.
• Fewer corners than the printed minimum of four; the arithmetic is unaffected
• A room under the 25 m³ trigger whose 50/63/80 Hz bands are about to be answered from the default procedure alone, which Clause 8.1 forbids and which does move the number
• Filter the two apart by message, not by class
warnings.simplefilter('error', building.LowFrequencyWarning)
Emitted by building.measurement.low_frequency
lab_airborne_insulationfunctionLaboratory airborne insulation (ISO 10140-2).
• l1/l2: Source/receiving levels [dB], 1D or (positions, bands)
• t2: Receiving-room T per band [s]
• area: Free test-opening S [m²]
• volume: Receiving V [m³]
lab = building.lab_airborne_insulation(l1, l2, t2, area=10, volume=50)

• LabAirborneInsulationResult
lab_impact_insulationfunctionLaboratory impact insulation (ISO 10140-3).
• li: Tapping-machine impact SPL [dB], 1D or (positions, bands)
• t2: Receiving-room T per band [s]
• volume: Receiving V [m³]
imp = building.lab_impact_insulation(li, t2, volume=50)

• LabImpactInsulationResult
intensity_sound_reductionfunctionIntensity sound reduction index RI (ISO 15186-1 Formula (7)).
• lp1: Source-room level [dB], 1D or (positions, bands)
• l_in: Normal intensity level over the surface [dB]
• measurement_area: Surface Sm [m²], area: Specimen S [m²]
• kc: Adaptation term per band [dB] for RI,M (Default: None)
res = building.intensity_sound_reduction(lp1, l_in, measurement_area=12, area=10)

• IntensityReductionResult (r_i, r_i_modified, rating, rating_modified)
adaptation_term_kcfunctionAdaptation term Kc (ISO 15186-1 Annex B).
• frequencies: Midband frequencies [Hz]
• boundary_area/volume: Room Sb2/V2 for Formula (B.1); omit both for the 10 lg(1+61,4/f) approximation (B.2)
kc = building.adaptation_term_kc(freqs)

• Kc per band [dB]
intensity_element_normalized_differencefunctionIntensity element normalized level difference DI,n,e (ISO 15186-1 Formula (8)).
• lp1/l_in: Source level / surface intensity level [dB]
• measurement_area: Surface Sm [m²]
• n: Element units N (Default: 1)
d = building.intensity_element_normalized_difference(lp1, l_in, measurement_area=10)

• IntensityElementNormalizedResult (d_i_n_e, rating)
surface_pressure_intensity_indicator / combine_subareasfunctionSurface indicator FpI and subarea combination (ISO 15186-1 Formulas (10)-(12)).
• lp/l_in: Surface pressure / intensity levels [dB]
• combine_subareas(l_in, measurement_area): (subareas, bands) levels + per-subarea areas (negative area = reverse-flow subarea, Clause 6.4.6)
fpi = building.surface_pressure_intensity_indicator(lp, l_in)

• FpI array; (LIn, Sm = Σ abs(Smi))
IntensityReductionResult / IntensityElementNormalizedResultdataclassISO 15186-1 intensity insulation results.
• r_i / r_i_modified per band with rating / rating_modified
• d_i_n_e per band with rating
res = building.intensity_sound_reduction(...)
low_frequency_intensity_reductionfunctionLow-frequency intensity sound reduction index RI (ISO 15186-3 Formula (7)).
• lp_surface: Level over the surface of the specimen [dB], 1D or (positions, bands)
• l_in: Normal intensity level over the measurement surface [dB]
• measurement_area: Surface Sm [m²], area: Specimen S [m²]
• l_p: Receiving-side pressure on the measurement surface [dB] for FpI (Default: None)
• frequencies: 50 Hz to 160 Hz only (Clause 6.6) (Default: None)
• absorbing_specimen_surface: Tightens the Clause 6.4.2 limit to 6 dB (Default: False)
res = building.low_frequency_intensity_reduction(lps, l_in, measurement_area=12.6, area=10)

• LowFrequencyIntensityResult (r_i, surface_pressure_intensity_indicator, qualified, indicator_limit)
low_frequency_element_normalized_differencefunctionLow-frequency element normalized level difference DI,n,e (ISO 15186-3 Formula (8)).
• lp_surface/l_in: Surface level / measurement-surface intensity level [dB]
• measurement_area: Surface Sm [m²]
• elements: Element units N, added as +10 lg N (Default: 1)
• l_p: Receiving-side pressure on the measurement surface [dB] for FpI (Default: None)
• frequencies: 50 Hz to 160 Hz only (Clause 1.1) (Default: None)
• absorbing_specimen_surface: Tightens the Clause 6.4.2 limit to 6 dB (Default: False)
d = building.low_frequency_element_normalized_difference(lps, l_in, measurement_area=2.0)

• LowFrequencyElementResult (d_i_n_e, surface_pressure_intensity_indicator, qualified, indicator_limit)
limp_panel_reduction_indexfunctionCalculated limp-panel sound reduction index (ISO 15186-3 Annex A, Formulas (A.1)-(A.5)).
• frequencies: Mid-band frequencies [Hz]
• surface_mass: Panel mass m [kg/m²], area: Panel S [m²] (≥ 1 m²)
• temperature_c/static_pressure_pa: Climate of (A.4) and (A.5) (Default: 23 °C, 101 300 Pa)
r = building.limp_panel_reduction_index(freqs, surface_mass=10.0, area=10.0)

• R array [dB]; a measurement must agree within 4,0 dB from 50 Hz to 160 Hz
LowFrequencyIntensityResult / LowFrequencyElementResultdataclassISO 15186-3 low-frequency intensity results.
• r_i / d_i_n_e per band, no rating (six bands cannot feed ISO 717-1)
• surface_pressure_intensity_indicator and qualified, or None when l_p was not given
• indicator_limit: The Clause 6.4.2 limit the bands were judged by, 10 dB or 6 dB
res = building.low_frequency_intensity_reduction(...)
reverberation_index / estimate_reverberation_indexfunctionSurvey reverberation index k (ISO 10052:2021 Clause 3.3 / Table 4).
• reverberation_index(t): k = 10 lg(T/0.5) per band
• 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 = building.reverberation_index(t)

• k per band [dB]
survey_airborne_insulationfunctionSurvey airborne insulation (ISO 10052:2021 Clauses 3.2-3.6).
• l1/l2: source/receiving levels [dB]
• reverberation_index: k per band [dB]
• volume (for Dn/R'), area (R', V/7.5 rule)
res = building.survey_airborne_insulation(l1, l2, k, volume=50, area=12)

• SurveyAirborneResult (d, d_nt, d_n, r_prime, rating, r_prime_rating)
survey_impact_insulation / survey_facade_insulationfunctionSurvey impact & façade insulation (ISO 10052:2021 Clauses 3.7-3.9 / 3.13-3.15).
• li (impact) or l1_2m/l2 (façade), reverberation_index, volume
imp = building.survey_impact_insulation(li, k, volume=50)

• SurveyImpactResult / SurveyFacadeResult
survey_service_equipment_levelfunctionService-equipment noise LXY (ISO 10052:2021 Clauses 3.16-3.18).
• measurements: three A/C-weighted positions [dB]
• reverberation_index: k (scalar or per band)
• volume (for LXY,n)
se = building.survey_service_equipment_level([35, 30, 32], 3.0, volume=50)

• SurveyServiceEquipmentResult (l_xy, l_xy_nt, l_xy_n)
SurveyAirborneResult / SurveyImpactResult / SurveyFacadeResult / SurveyServiceEquipmentResultdataclassISO 10052 survey-method results.
• per-band quantities (d, d_nt, d_n, r_prime; l_i, l_nt, l_n; d_2m...; l_xy...)
• weighted rating where the method defines one
res = building.survey_airborne_insulation(...)
background_correctionfunctionBackground-noise correction (ISO 10140-4 §4.3).
• signal_and_background: Combined Lsb per band [dB]
• background: Lb per band [dB]
• 6–15 dB margin corrected, ≤6 dB capped at 1.3 dB, ≥15 dB unchanged
L = building.background_correction(lsb, lb)

• Corrected levels [dB] (LabInsulationWarning at the limit of measurement)
LabAirborneInsulationResultdataclassLaboratory airborne result.
• r: Sound reduction index R [dB]
• absorption: A = 0.16 V/T [m²]
• rating: WeightedRatingResult or None
• .plot() (needs the rating)
• .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
LabImpactInsulationResultdataclassLaboratory impact result.
• l_n: Normalized impact level Ln [dB]
• absorption: A [m²]
• rating: ImpactRatingResult or None
• .plot() (needs the rating)
• .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
LabInsulationWarningwarning classLimit-of-measurement condition (ISO 10140-4).
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_insulationfunctionPredicted apparent airborne R'w (EN 12354-1 Formula 26).
• r_direct: Separating-element Rs,w [dB]
• flanking_paths: sequence of FlankingPath (Default: ())
• delta_r_direct: Lining ΔRDd,w [dB] (Default: 0)
res = building.predicted_airborne_insulation(r_direct=57, flanking_paths=paths)

• AirbornePredictionResult
predicted_impact_insulationfunctionPredicted apparent impact L'n,w (EN 12354-2 Formula 21).
• ln_w_eq: Bare-floor equivalent Ln,w,eq [dB]
• delta_l_w: Covering improvement ΔLw [dB] (Default: 0)
• k_correction: Flanking K [dB] (Default: 0)
imp = building.predicted_impact_insulation(ln_w_eq=76.2, delta_l_w=33, k_correction=2)

• ImpactPredictionResult
junction_vibration_reductionfunctionVibration reduction index Kij (EN 12354-1 Annex E.3-E.9).
• junction_type: 'rigid_cross'/'rigid_t'/'flexible_t'/'lightweight_facade'/'lightweight_double_homogeneous'/'lightweight_double_coupled'/'corner'/'thickness_change'
• path: 'through' (K13) / 'corner' (K12=K23) / 'double_leaf' (K24)
• mass_ratio: m'⊥,i/m'i
• frequency [Hz] (Default: 500), f1 [Hz] (Default: 125)
k = building.junction_vibration_reduction('rigid_cross', 'through', 1.61)

• Kij [dB]
junction_min_vibration_reductionfunctionMinimum Kij,min (EN 12354-1 Formula 29).
• coupling_length: lf [m]
• s_i, s_j: Element areas [m²]
kmin = building.junction_min_vibration_reduction(4.5, 11.5, 11.5)

• Kij,min [dB]
flanking_pathfunctionOne flanking path Rij,w (EN 12354-1 Formula 28a).
• label, kind: 'Ff'/'Df'/'Fd'
• r_source/r_receive: element indices [dB]
• k_ij [dB], separating_area Ss [m²], coupling_length lf [m]
• delta_r [dB] (Default: 0), kij_min [dB] clamp (Default: None)
p = building.flanking_path(label='f', kind='Ff', r_source=49, r_receive=49, k_ij=12.4, separating_area=11.5, coupling_length=4.5)

• FlankingPath
flanking_elementfunctionThe three paths (Ff, Df, Fd) of one flanking element.
• label, r_flanking, r_separating [dB]
• k_ff/k_fd/k_df [dB]
• separating_area Ss [m²], coupling_length lf [m]
• delta_r_ff/delta_r_fd/delta_r_df [dB] (Default: 0)
• flanking_area SF [m²] (Default: None): enables the automatic Kij,min clamp (Clause 4.4.2 / Formula 29)
ff, df, fd = building.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_liningsfunctionCombine two lining improvements (EN 12354-1 Formulas 30/31).
• delta_a, delta_b [dB] (pass 0 for a single lining)
dr = building.combine_linings(14.0, 14.0)

• max(a,b) + min(a,b)/2 = 21.0 [dB]
equivalent_impact_levelfunctionBare-floor equivalent Ln,w,eq (EN 12354-2 Annex B).
• mass_per_area: m' [kg/m²]
lneq = building.equivalent_impact_level(322.0)

• 164 − 35 lg(m') = 76.2 [dB]
impact_flanking_correctionfunctionFlanking correction K (EN 12354-2 Table 1).
• separating_mass, flanking_mass [kg/m²] (nearest tabulated)
k = building.impact_flanking_correction(322.0, 145.0)

• K = 2 [dB], int
standardized_impact_levelfunctionStandardized L'nT,w (EN 12354-2 Formula 3, exact 0.032·V form).
• l_prime_n_w: L'n,w [dB]
• volume: Receiving V [m³] (Annex E.3's V/30 is the standard's own rounding)
lnt = building.standardized_impact_level(45.2, 50.0)

• L'nT,w = 43.2 [dB]
standardized_level_differencefunctionDnT,w from R'w (EN 12354-1 Formula 5b, exact 0.32·V/Ss form).
• r_prime_w: R'w [dB]
• volume V [m³], separating_area Ss [m²]
dnt = building.standardized_level_difference(52.2, 50.0, 11.5)

• DnT,w = 53.6 → 54 [dB]
facade_sound_reductionfunctionPredicted façade insulation D2m,nT (EN 12354-3 Formula 10/13).
• elements: sequence of FacadeElement
• area: Façade S [m²], volume: Receiving V [m³]
• delta_l_fs: ΔLfs [dB] (Default: 0), bands
• frequencies: band centres [Hz] (Default: None; length must equal the band count), carried on the result for plotting
fac = building.facade_sound_reduction(elements, area=11.3, volume=50.0, bands="octave")

• FacadePredictionResult
plot_facade_elementsfunctionComposite façade elevation, element areas to scale.
• elements: FacadeElement sequence
• language
plot_facade_elements(elements)

• Also FacadePredictionResult.plot_geometry()
FacadePredictionResultdataclassPredicted façade airborne insulation (EN 12354-3:2000).
• r_prime, r_45, r_tr_s, d_2m_nt per band
• r_tr_s_w, d_2m_nt_w, c_tr single numbers
res = building.facade_sound_reduction(...)
radiated_sound_powerfunctionRadiated sound power LW (EN 12354-4 Formula 2/3).
• elements, lp_in: Inside Lp,in [dB]
• area: Segment S [m²]
• 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 = building.radiated_sound_power(elements, lp_in=lp, area=200.0, c_d=-5.0)

• RadiatedPowerResult
RadiatedPowerResultdataclassSound power radiated outside by a façade segment (EN 12354-4).
• l_w, r_prime per band
• l_w_dba: A-weighted total
res = building.radiated_sound_power(...)
outdoor_attenuationfunctionFinite radiating-side attenuation A'tot (EN 12354-4 Annex E).
• width, height: Side dimensions [m]
• distance: Perpendicular d [m]
a = building.outdoor_attenuation(60.0, 10.0, 5.0)

• A'tot = 26.3 [dB]
outdoor_levelfunctionExterior level Lp (EN 12354-4 Formula E.1).
• l_w: Radiated LW [dB], scalar or per-side
• attenuation: A'tot [dB], scalar or per-side
lp = building.outdoor_level(62.9, 26.3)

• Lp = 36.6 [dB]
facade_shape_level_differencefunctionFaçade-shape term ΔLfs (EN 12354-3 Annex C, Figure C.2).
• shape: 'plane_facade'/'gallery_2'…'gallery_5'/'balcony_6'…'balcony_8'/'terrace_open'/'terrace_closed'
• line_of_sight h [m] (Default: 0), absorption αw (Default: 0.3, interpolated)
dlfs = building.facade_shape_level_difference('balcony_6', line_of_sight=2.0, absorption=0.6)

• ΔLfs = 1 [dB]
FacadeElementdataclassOne façade transmission path (EN 12354-3/-4).
• give exactly one of r: area element [dB] / dn_e: small element [dB] / insertion_loss: opening [dB]
• area: Sᵢ [m²] (for r / insertion_loss)
FacadeElement("window", area=4.5, r=[23, 22, 30, 36, 37])
AirbornePredictionResultdataclassPredicted airborne insulation.
• r_prime_w: Apparent R'w [dB]
• r_direct_w: Direct RDd,w [dB]
• paths: tuple of PathContribution
• dominant: highest-energy path
res.r_prime_w, res.dominant.label
ImpactPredictionResultdataclassPredicted impact insulation.
• l_prime_n_w: Apparent L'n,w [dB]
• ln_w_eq, delta_l_w, k_correction [dB]
imp.l_prime_n_w
FlankingPathdataclassOne flanking transmission path.
• label, kind: 'Ff'/'Df'/'Fd'
• r_ij_w: Flanking index Rij,w [dB]
p.r_ij_w
HomogeneousElementdataclassA Type A homogeneous element of the ISO 12354 detailed model.
• label, area S [m²], length1/length2 [m]
• mass_per_area m' [kg/m²], critical_frequency fc [Hz]
• internal_loss_factor ηint (Default: 0.01)
• perimeter_absorption Σ lk αk [m] (Default: 0)
• density ρ [kg/m³] / longitudinal_velocity cL [m/s] (Default: None; enable the Formula B.10 plateau)
floor = building.HomogeneousElement('floor', 20.0, 5.0, 4.0, 484.0, 76.8, 0.005, 2.66, 2200.0, 3800.0)
in_situ_elementfunctionWhole in-situ chain of one element, per band (ISO 12354-1 Clause 4.2.2).
• element: HomogeneousElement, frequencies [Hz]
• bands: 'third'/'octave', resonant_only (Default: False)
• fluid: Fluid (Default: EN_12354_AIR, the Annex A speed of sound with the Annex B density)
el = building.in_situ_element(floor, bands) (floor is a HomogeneousElement)

• InSituElementResult
EN_12354_AIRFluidThe air the EN/ISO 12354 detailed model is written around.
340 m/s (Annex A), 1,29 kg/m³ (Annex B)
• the fluid default of in_situ_element, in_situ_total_loss_factor and perimeter_absorption_coefficient
• a phonometry.fluids.Fluid: pass a computed one to predict in the air of the building instead of the air of the standard
building.EN_12354_AIR.speed_of_sound # 340.0
InSituElementResultdataclassPer-band in-situ element description.
• radiation_factor σ, forced_radiation_factor σf
• total_loss_factor ηtot,situ, reverberation_time Ts,situ [s]
• absorption_length asitu [m]
• sound_reduction_index Rsitu [dB], impact_level Ln,situ [dB]
• .plot()
el.sound_reduction_index, el.absorption_length
bending_radiation_factorfunctionRadiation factor for free bending waves σ (ISO 12354-1 Formulae B.4-B.6).
• frequencies [Hz], critical_frequency fc [Hz]
• length1, length2 [m], speed_of_sound [m/s]
s = building.bending_radiation_factor(f, critical_frequency=76.8, length1=5.0, length2=4.0)

• σ ≤ 2 per band
forced_radiation_factorfunctionRadiation factor for forced waves σf (Formula B.3, Table B.1).
• frequencies [Hz], length1, length2 [m], speed_of_sound
sf = building.forced_radiation_factor(f, length1=3.75, length2=2.65)

• σf ≤ 2 per band
calculated_sound_reduction_indexfunctionR of a homogeneous element (Formulae B.2/B.10).
• frequencies, mass_per_area m', critical_frequency fc
• total_loss_factor, radiation_factor, forced_radiation_factor
• bands, resonant_only (Default: False)
• density, longitudinal_velocity (Default: None; high-frequency plateau)
r = building.calculated_sound_reduction_index(f, mass_per_area=484, critical_frequency=76.8, total_loss_factor=eta, radiation_factor=s, forced_radiation_factor=sf)
bare_floor_impact_levelfunctionLn of a bare monolithic floor (ISO 12354-2 Formula B.2).
• frequencies, mass_per_area m'
• structural_reverberation_time Ts [s], radiation_factor σ
ln = building.bare_floor_impact_level(f, mass_per_area=484, structural_reverberation_time=ts, radiation_factor=s)

• 155 − 30 lg m' + 10 lg Ts + 10 lg σ + 10 lg(f/fref)
reciprocity_impact_levelfunctionLn from R by reciprocity (ISO 12354-2 Formulae B.3/B.4).
• sound_reduction_index [dB], frequencies [Hz]
• bands: 'third' (38) / 'octave' (43)
ln = building.reciprocity_impact_level(r, f)

• R + Ln = 38 + 30 lg f
perimeter_absorption_coefficientfunctionBending-wave absorption at one border αk (Formula C.4).
• critical_frequencies fc,j [Hz] of the connected elements
• vibration_reduction_indices Kij [dB]
a = building.perimeter_absorption_coefficient([92.6, 92.6], [6.4, 6.4])

• Σ √(fc,j/fref)·10^(−Kij/10)
in_situ_total_loss_factorfunctionηtot,situ (Formula C.1).
• frequencies, internal_loss_factor ηint, mass_per_area, area
• critical_frequency, radiation_factor
• perimeter_absorption Σ lk αk [m], fluid (Default: EN_12354_AIR)
eta = building.in_situ_total_loss_factor(f, internal_loss_factor=0.005, mass_per_area=484, area=20, critical_frequency=76.8, radiation_factor=s, perimeter_absorption=2.66)
laboratory_total_loss_factorfunctionηtot,lab ≈ ηint + m'/(485 √f) (Formula C.3).
• frequencies, mass_per_area, internal_loss_factor (Default: 0.01)
eta = building.laboratory_total_loss_factor(f, mass_per_area=484)
structural_reverberation_timefunctionTs = 2,2/(f ηtot) (Formula C.1).
• frequencies [Hz], total_loss_factor ηtot
ts = building.structural_reverberation_time(f, eta)

• Ts per band [s]
in_situ_reduction_index / in_situ_impact_levelfunctionLaboratory → in-situ transfer (Formula 9 / Part 2 Formula 5).
• sound_reduction_index or impact_level [dB]
• situ_reverberation_time, laboratory_reverberation_time [s]
r = building.in_situ_reduction_index(r_lab, ts_situ, ts_lab)

• R − 10 lg(Ts,situ/Ts,lab); Ln + 10 lg(...)
in_situ_equivalent_absorption_lengthfunctionasitu = 2,2 π² S √(fref/f)/(co Ts,situ) (Formula 11).
• frequencies, area S [m²], situ_reverberation_time [s], speed_of_sound
a = building.in_situ_equivalent_absorption_length(f, area=20.0, situ_reverberation_time=ts)
in_situ_velocity_level_differencefunctionDv,ij,situ = Kij − 10 lg(lij/√(ai aj)), ≥ 0 dB (Formula 10).
• vibration_reduction_index Kij [dB]
• coupling_length lij [m], absorption_length_i/absorption_length_j [m]
dv = building.in_situ_velocity_level_difference(6.4, coupling_length=4.0, absorption_length_i=ai, absorption_length_j=aj)
direct_reduction_index / direct_impact_levelfunctionDirect paths (Formula 14 / Part 2 Formula 11).
• separating_index Rs,situ or floor_level Ln,situ [dB]
• delta_r_source/delta_r_receiving, or delta_l/delta_l_ceiling [dB]
rdd = building.direct_reduction_index(r_situ, delta_r_source=dl)

• RDd; Ln,d
flanking_reduction_indexfunctionFlanking Rij per band, Type A (Formula 15).
• index_i, index_j [dB], velocity_level_difference Dv,ij,situ [dB]
• separating_area Ss, area_i Si, area_j Sj [m²]
• delta_r_i, delta_r_j [dB]
rij = building.flanking_reduction_index(index_i=ri, index_j=rj, velocity_level_difference=dv, separating_area=20.0, area_i=20.0, area_j=11.0)
flanking_impact_levelfunctionFlanking Ln,ij per band, Type A (ISO 12354-2 Formula 12).
• floor_level Ln,situ, index_i, index_j, velocity_level_difference
• area_i, area_j [m²], delta_l, delta_r_j [dB]
lnij = building.flanking_impact_level(floor_level=ln, index_i=ri, index_j=rj, velocity_level_difference=dv, area_i=20.0, area_j=11.0)
flanking_reduction_index_from_normalized_difference / flanking_impact_level_from_normalized_differencefunctionType B flanking paths from Dv,ij,n (Formula 17 / Part 2 Formula 14).
• element indices [dB], normalized_velocity_level_difference [dB]
• separating_area (airborne) or area_i (impact) [m²], coupling_length lij [m]
rij = building.flanking_reduction_index_from_normalized_difference(index_i=ri, index_j=rj, normalized_velocity_level_difference=dvn, separating_area=20.0, coupling_length=4.0)
flanking_reduction_index_from_flanking_levelfunctionRij from a measured Dn,f (Formula 16).
• flanking_level_difference Dn,f [dB]
• separating_area Ss [m²], coupling_length lij [m]
• laboratory_coupling_length llab [m] (4.5 ceilings, 2.5 façades)
• reference_absorption_area A0 [m²] (Default: 10)
rij = building.flanking_reduction_index_from_flanking_level(dnf, separating_area=10.44, coupling_length=2.41, laboratory_coupling_length=2.5)
flanking_impact_level_from_flanking_levelfunctionLn,ij from a measured Ln,f (ISO 12354-2 Formula 13).
• normalized_flanking_impact_level Ln,f,ij,situ [dB]
• area Si, laboratory_area Si,lab [m²]
• coupling_length lij, laboratory_coupling_length llab [m]
lnij = building.flanking_impact_level_from_flanking_level(lnf, area=20.0, laboratory_area=10.0, coupling_length=4.0, laboratory_coupling_length=4.5)
resonant_sound_reduction_indexfunction*R for resonant transmission only (Formula B.1/B.2).**
• sound_reduction_index [dB], frequencies [Hz]
• critical_frequency fc [Hz], correction [dB] (Default: 8, applied below fc)
rstar = building.resonant_sound_reduction_index(r, f, critical_frequency=2200.0)
floating_floor_improvementfunctionΔL of a floating floor (ISO 12354-2 Formulae C.1/C.3).
• frequencies [Hz], resonance_frequency fo = 160 √(s'/m') [Hz]
• slope: 30 (screed) or 40 (asphalt/dry)
dl = building.floating_floor_improvement(f, resonance_frequency=52.8)

• 30 lg(f/fo), 0 at and below fo
hammer_impact_velocityfunctionISO tapping-machine impact velocity vo = √(2 g h) (Hopkins Eq. 3.85).
• drop_height h [m] (Default: 0.04), gravity g [m/s²]
hammer_impact_velocity()

• 0.886 [m/s]
plate_contact_stiffnessfunctionHammer contact stiffness of a plate material K = 2 r E/(1 − ν²) (Hopkins Eq. 3.97).
• youngs_modulus E [Pa]
• poisson_ratio ν (Default: 0.2), radius r [m] (Default: 0.015)
k = building.plate_contact_stiffness(3.05e10)

• K [N/m]
covering_contact_stiffnessfunctionHammer contact stiffness of a soft covering K = E π r²/d (Hopkins Eq. 3.98).
• youngs_modulus E [Pa], thickness d [m]
• radius r [m] (Default: 0.015)
k = building.covering_contact_stiffness(1.4e6, 0.005)

• K [N/m]
tapping_cut_off_frequencyfunctionForce-spectrum cut-off fco (Hopkins Eqs. 3.101/3.102).
• contact_stiffness K [N/m], impedance Zdp [N.s/m]
• mass m [kg] (Default: 0.5)
fco = building.tapping_cut_off_frequency(k, z)

• fco [Hz], under- or over-critical branch
hammer_limiting_frequencyfunctionflimit = Zdp/(2 π m), above which the hammer mass limits the power input (Hopkins Eq. 3.106).
• impedance Zdp [N.s/m], mass m [kg]
hammer_limiting_frequency(1637.0)

• 521 [Hz]
force_pulsefunctionSingle-impact force pulse F1(t) (Hopkins Eqs. 3.95/3.96).
• time t [s], contact_stiffness K [N/m], impedance Zdp [N.s/m]
• mass m [kg], impact_velocity vo [m/s]
f = building.force_pulse(t, k, z)

• F1(t) [N]
short_pulse_mean_square_forcefunctionF²rms = 3.9 B for a short impact (Hopkins Eq. 3.92).
• frequencies [Hz], band: 'third'/'octave'
short_pulse_mean_square_force(500.0)
tapping_force_spectrumfunctionForce spectrum of the ISO tapping machine (Hopkins 3.6.3.1).
• frequencies [Hz], contact_stiffness K [N/m], impedance Zdp [N.s/m]
• mass, impact_rate fi, impact_velocity vo, band
res = building.tapping_force_spectrum(f, k, z)

• TappingForceResult
TappingForceResultdataclassTapping-machine force spectrum on one walking surface.
• peak_force |Fn| [N], mean_square_force [N²], power_input [W], power_input_level [dB]
• cut_off_frequency, limiting_frequency [Hz], over_critical, lower_limit/upper_limit [N]
• .plot()
res.cut_off_frequency, res.over_critical
covering_improvementfunctionPredicted ΔL of a soft floor covering, ΔL = 20 lg(|Fn|without/|Fn|with) (Hopkins Eq. 4.114).
• frequencies [Hz], covering_stiffness, plate_stiffness [N/m], impedance [N.s/m]
res = building.covering_improvement(f, kc, kp, z)

• CoveringImprovementResult
CoveringImprovementResultdataclassSoft-covering improvement prediction.
• improvement ΔL [dB], two_line (0 dB below fco, 12 dB/oct above)
• cut_off_frequency, bare_cut_off_frequency [Hz], bare/covered force spectra
• .plot()
res.improvement, res.two_line
floating_floor_resonance_frequencyfunctionfo = 160 √(s'/m') of a floating floor (ISO 12354-2 Formula C.2).
• dynamic_stiffness s' [N/m³], mass_per_area m' [kg/m²]
floating_floor_resonance_frequency(8e6, 73.5)

• 52.8 [Hz]
combined_dynamic_stiffnessfunctions'tot = (Σ 1/s'i)⁻¹ for stacked resilient layers (ISO 12354-2 Formula C.6).
• layers: s'i [N/m³]
combined_dynamic_stiffness([8e6, 8e6])

• 4e6 [N/m³]
double_floating_floor_resonancesfunctionThe two resonances of a double floating floor (Hopkins Eq. 4.125).
• lower_stiffness, lower_mass_per_area, upper_stiffness, upper_mass_per_area
double_floating_floor_resonances(7.25e6, 12.78, 7.25e6, 12.78)

• (74, 194) [Hz]
weighted_floating_floor_improvementfunctionΔLw of a floating floor (ISO 12354-2 Formulae C.4/C.5).
• mass_per_area m' [kg/m²], dynamic_stiffness s' [N/m³]
• floor: 'screed' (C.4) or 'asphalt' (C.5)
weighted_floating_floor_improvement(73.5, 8e6)

• 32.2 [dB]
floating_floor_improvement_spectrumfunctionΔL(f) of a floating floor above fo.
• frequencies [Hz], resonance_frequency fo [Hz]
• model: 'en12354' (30 lg), 'cremer' (40 lg) or 'cremer_hammer' (+10 lg[1 + (f/flimit)²])
• limiting_frequency, mass_per_area, dynamic_stiffness
res = building.floating_floor_improvement_spectrum(f, resonance_frequency=52.8)

• FloatingFloorImprovementResult
FloatingFloorImprovementResultdataclassFloating-floor improvement prediction.
• improvement ΔL [dB], resonance_frequency [Hz], model, slope [dB/decade]
• limiting_frequency [Hz] or None, delta_lw [dB] or None
• .plot()
res.improvement, res.delta_lw
resilient_mount_improvementfunctionΔL of a floating floor on discrete mounts, 30 dB/decade (Vér; Hopkins Eq. 4.118, Vigran Eq. 8.45).
• frequencies [Hz], impedance Zdp1 [N.s/m], mass_per_area ρs1 [kg/m²]
• loss_factor η1, mount_stiffness k [N/m], mount_density N' [1/m²]
dl = building.resilient_mount_improvement(f, impedance=3.8e5, mass_per_area=115.0, loss_factor=0.02, mount_stiffness=2e6, mount_density=4.0)
lining_resonance_frequencyfunctionfo of a lining on a basic element (ISO 12354-1 Formulae D.1/D.2).
• base_mass_per_area m'1, lining_mass_per_area m'2 [kg/m²]
• exactly one of dynamic_stiffness s' [N/m³] (D.1) or cavity_depth d [m] (D.2)
lining_resonance_frequency(51.0, 6.3, dynamic_stiffness=65e6)

• 542 [Hz]
weighted_lining_improvementfunctionΔRw of an interior lining (ISO 12354-1 Table D.1).
• resonance_frequency fo [Hz] (30-5000, rounded to the third-octave centre)
• base_rating Rw [dB]
weighted_lining_improvement(100.0, 40.0)

• 14.4 [dB]
lining_improvementfunctionSingle-number ratings of an additional layer (ISO 12354-1 Formulae D.3-D.7).
• resonance_frequency fo [Hz]
• system: 'mineral_wool' (D.3), 'foam' (D.4) or 'studs' (D.7)
• anchors (D.5), glued_area %So (D.6)
res = building.lining_improvement(100.0)

• LiningImprovementResult
LiningImprovementResultdataclassAnnex D single-number ratings of an additional layer.
• delta_rw, delta_ra, delta_ratr [dB], .ratings tuple
• resonance_frequency [Hz], system, anchors, glued_area
• .plot()
res.delta_rw, res.ratings
lining_improvement_in_situfunctionLaboratory → field transfer of a lining rating (ISO 12354-1 Formula D.8).
• laboratory_improvement ΔRlab [dB], resonance_frequency fo [Hz], base_rating_in_situ Rw,situ [dB]
lining_improvement_in_situ(10.0, 100.0, 60.0)
TAPPING_HAMMER_MASS / TAPPING_DROP_HEIGHT / TAPPING_IMPACT_RATE / TAPPING_HAMMER_RADIUSconstantISO tapping-machine constants: hammer mass 0.5 kg, drop height 0.04 m, impact rate 10 Hz, assumed contact radius 0.015 m.TAPPING_HAMMER_MASS # 0.5
airborne_flanking_path / impact_flanking_pathfunctionBuild one flanking path from two in-situ elements.
• label, kind ('Ff'/'Df'/'Fd', airborne only)
• element_i/element_j (or floor/element_j): InSituElementResult
• vibration_reduction_index Kij [dB], coupling_length lij [m]
• separating_area Ss [m²] (airborne), delta_r_* / delta_l [dB]
p = building.airborne_flanking_path(label='D1', kind='Df', element_i=el, element_j=wall, vibration_reduction_index=6.4, coupling_length=4.0, separating_area=20.0) (el, wall are InSituElementResult)

• BandPath
BandPathdataclassOne per-band transmission path of the detailed model.
• label, kind: 'Dd'/'Ff'/'Df'/'Fd'
• values: Rij or Ln,ij per band [dB]
p.values
detailed_airborne_prediction / detailed_impact_predictionfunctionCombine the paths into R' / L'n per band (ISO 12354-1 Formulae 1-4 / -2 Formula 1).
• frequencies [Hz]
• direct_index RDd or direct_level Ln,d [dB]
• flanking_paths: sequence of BandPath, direct_label, bands
res = building.detailed_airborne_prediction(f, direct_index=rdd, flanking_paths=paths) (rdd from direct_reduction_index, paths of BandPath)

• DetailedAirborneResult / DetailedImpactResult
DetailedAirborneResult / DetailedImpactResultdataclassPer-band detailed prediction (ISO 12354-1/-2:2017 Clause 4.2).
• r_prime or l_prime_n per band [dB]
• paths: tuple of BandPath (direct first), fractions: energy share per path and band
• dominant: the leading path in each band
• rating: WeightedRatingResult / ImpactRatingResult or None
• .plot(): per-band path-contribution bars
• .report(path, ...): one-page EN/ISO 12354 detailed prediction fiche → PDF
res.r_prime, res.dominant, res.rating.rating
PathContributiondataclassA path with its energy share.
• label, kind: 'Dd'/'Ff'/'Df'/'Fd'
• r_w: Path index [dB]
• fraction: share of transmitted energy (0–1)
c.r_w, c.fraction
vibration_reduction_indexfunctionMeasured vibration reduction index Kij (ISO 10848 Formula 13/14).
• velocity_level_difference: direction-averaged D̄v,ij [dB]
• junction_length lij [m], area_i/area_j [m²]
• frequencies [Hz], structural_reverberation_time_i/_j [s] (both → Formula 13; else simplified 14)
• speed_of_sound (Default: 343)
• modal_overlap: per-band M; M < 0.25 bands bracketed and excluded from K̄ij (ISO 10848-4 Clause 9)
res = building.vibration_reduction_index(dbar, 4.0, 12.0, 10.0, frequencies=f, structural_reverberation_time_i=0.35, structural_reverberation_time_j=0.40)

• VibrationReductionResult
direction_averaged_level_differencefunctionDirection average D̄v,ij = ½(Dv,ij+Dv,ji) (ISO 10848 Formula 11).
• dv_ij, dv_ji [dB]
dbar = building.direction_averaged_level_difference(dv_ij, dv_ji)
velocity_level_differencefunctionVelocity level difference Dv,ij = Lv,i−Lv,j (ISO 10848 Formula 8).
• source_level, receive_level [dB]
dv = building.velocity_level_difference(lv_i, lv_j)
equivalent_absorption_lengthfunctionEquivalent absorption length aj (ISO 10848 Formula 12).
• area Sj [m²], structural_reverberation_time Ts [s], frequencies [Hz]
• speed_of_sound (Default: 343)
a = building.equivalent_absorption_length(10.0, 0.5, f)
total_loss_factorfunctionTotal loss factor η = 2.2/(f·Ts) (ISO 10848 Clause 7.3.1).
• frequencies [Hz], structural_reverberation_time [s]
eta = building.total_loss_factor(f, ts)
normalized_flanking_level_differencefunctionAirborne Dn,f = L1−L2−10 lg(A/A0) (ISO 10848 Formula 4).
• source_level L1, receive_level L2 [dB]
• absorption_area A [m²]
• reference_area A0 (Default: 10)
res = building.normalized_flanking_level_difference(l1, l2, a)

• FlankingLevelDifferenceResult
normalized_flanking_impact_levelfunctionImpact Ln,f = L2+10 lg(A/A0) (ISO 10848 Formula 5).
• receive_level L2 [dB], absorption_area A [m²]
• reference_area A0 (Default: 10)
res = building.normalized_flanking_impact_level(l2, a)

• FlankingImpactLevelResult
vibration_reduction_index_from_flankingfunctionIndirect Kij from Dn,f (ISO 10848 Clause 4.3.1).
• normalized_flanking_level_difference Dn,f, reduction_index_i/_j Ri/Rj [dB]
• junction_length, area_i/area_j, absorption_length_i/_j
k = building.vibration_reduction_index_from_flanking(dnf, ri, rj, 2.0, 10.0, 12.0, ai, aj)

• Kij [dB]
critical_frequencyfunctionThin-plate critical frequency fc = c0²/(1.8·cL·h·π) (ISO 10848 Formula 20).
• longitudinal_wave_speed cL [m/s], thickness h [m]
• speed_of_sound (Default: 343)
fc = building.critical_frequency(5500.0, 0.2)
strong_coupling_satisfiedfunctionStrong-coupling validity check (ISO 10848 Formula 15).
• velocity_level_difference D̄v,ij [dB]
• mass_i/mass_j [kg/m²], critical_frequency_i/_j [Hz]
ok = building.strong_coupling_satisfied(dbar, 20, 20, 100, 100)

• bool per band
modal_densityfunctionModal density n = π·S·fc/c0² (ISO 10848-4 Formula 5).
• area S [m²], critical_frequency fc [Hz]
• speed_of_sound (Default: 343)
n = building.modal_density(10.0, 200.0)
modal_overlap_factorfunctionModal overlap M = 2.2·n/Ts (ISO 10848-4 Formula 6).
• area, critical_frequency, structural_reverberation_time [s]
m = building.modal_overlap_factor(10.0, 200.0, ts) # feed building.vibration_reduction_index(modal_overlap=m)
band_mode_countfunctionIn-band mode count N = 0.23·f·n (ISO 10848-4 Formula 4).
• frequencies [Hz], area, critical_frequency
n5 = building.band_mode_count(f, 10.0, 200.0) # N≥5 OK
VibrationReductionResultdataclassMeasured Kij (ISO 10848).
• frequencies [Hz] (or None), k_ij [dB]
• single_number: mean K̄ij 200–1250 Hz (thirds) / 125–1000 Hz (octaves), or None
• bracketed: M < 0.25 flags (or None)
• .octave_bands(), .plot()
res.k_ij, res.single_number
FlankingLevelDifferenceResultdataclassNormalized flanking level difference Dn,f (ISO 10848).
• d_n_f [dB], rating: Dn,f,w (or None)
• .plot()
res.d_n_f, res.rating
FlankingImpactLevelResultdataclassNormalized flanking impact level Ln,f (ISO 10848).
• l_n_f [dB], rating: Ln,f,w (or None)
• .plot()
res.l_n_f, res.rating
PUBLISHED_TRANSMISSION_LOSSmappingTwo hundred and fifty-five measured constructions from ten published tables, keyed '<table>/<row>'.
• Bies 5e Table 7.6, nine groups from sheet panels and sandwich panels through masonry, stud partitions, glazing and doors to floors
• ASHRAE Chapter 49 Table 40, nine machine equipment room walls, floors and ceilings with the Sound Transmission Class the page prints beside each one
• Rossing (2014) Table 11.4, twenty-three common partitions in six bands with an STC
• Harris 3e Tables 31.2, 31.3 and 31.5 to 31.9, a hundred and twenty-nine STC ratings with no band: stud walls, block walls, doors, sealed windows and floor-ceiling systems, one row per condition the page rates, the condition in variant
• each row carries the thickness_mm and the surface_density_kg_m2 the page prints beside the description, which is what tells apart six windows all called "Single glass in heavy frame"
• the book calls the values representative, says they come from tests published by manufacturers and laboratories, and names no standard, no mounting and no source per row; the qualifier it does give is field incidence
• what a formula does not give you: the same 280 mm brick wall is 40 dB at 500 Hz on strip ties and 55 dB on expanded metal ties
• the transcription was made twice, from the rendered pages, by readers who never saw each other's work
row = building.PUBLISHED_TRANSMISSION_LOSS['bies-2017-table-7-6/6_mm_steel_plate_6mm']
row.spectrum()[500] # 41 dB

• TransmissionLossSpectrum, transmission_loss_named
TransmissionLossSpectrumdataclassOne construction of a published table, with its transmission loss in each octave band.
• transmission_loss_63_db … transmission_loss_8000_db, in decibels, None where the page prints a dash
• thickness_mm, surface_density_kg_m2: the two columns Bies prints beside the description; two rows carry no weight and say so
• sound_transmission_class: the single-number rating a page prints where it prints one, kept because an STC is computed from third octaves and these seven or eight bands do not give it back; seven tables print nothing else
• block_mass_kg: the mass of one masonry block where a page prints it, which is not a surface density
• refers_to_row: the row a printed "Igual que 8" inherits from; resolve with PUBLISHED_TRANSMISSION_LOSS[f'{row.table}/{row.refers_to_row}']
• .bands(), .spectrum() → {band_hz: db}, .transmission_loss_db(band_hz) narrows or refuses, naming the row and the band
• a measurement of one construction in one laboratory, not a property of a material
row.transmission_loss_db(63) # ValueError: the page prints a dash there

• PUBLISHED_TRANSMISSION_LOSS
TRANSMISSION_LOSS_BANDS_HZconstantThe octave bands a published transmission loss table can print: 63 Hz to 8 kHz.
• (63, 125, 250, 500, 1000, 2000, 4000, 8000); Bies fills the six middle bands on every row and leaves the ends empty on about forty
building.TRANSMISSION_LOSS_BANDS_HZ
transmission_loss_namedfunctionEvery published construction whose printed description contains a fragment.
• name: matched without case against the description the page prints, and nothing else
• 'door' answers with the rows that carry the word, not with Bies's hollow flush panel described without it, nor with the Spanish 'puerta' of Harris
[r.thickness_mm for r in building.transmission_loss_named('Concrete, reinforced')] # [100, 200, 300]

• PUBLISHED_TRANSMISSION_LOSS
PUBLISHED_IMPACT_INSULATIONmappingSeventy-one rows of measured impact insulation, keyed '<table>/<row>'.
• Harris 3e Tables 32.1 to 32.8: forty-two floor-ceiling constructions with their IIC, and six elastic surface treatments with the improvement each adds over a hard massive floor
• Harris (1977) Tables 19.2 to 19.4: twenty-three floor finishes, floating screeds and timber floors on bare concrete, with the average improvement in impact sound insulation in decibels, keyed by a slug of the description
• Tables 32.1 to 32.7 are keyed by the row number the page prints in its own column, '1' to '38', with a lettered pair such as '34A'/'34B' where a construction is printed as two rows, each with its own description and rating; the six treatments of Table 32.8 and every 1977 row are keyed by a slug of the description
• single numbers and nothing per band: these pages print no impact sound pressure level, no octave, no third octave and no reference curve
• Chapter 32 is collected measurements from a 1967 report for the Federal Housing Administration, except Table 32.8, which credits a 1963 paper by Zeller; the 1977 tables credit nothing; no laboratory, no test standard and no uncertainty is named for any row
• what a formula does not give you: the same reinforced concrete slab is IIC 25 bare and 80 under a wool carpet on a rubber underlay
row = building.PUBLISHED_IMPACT_INSULATION['harris-1995-tables-32-1-to-32-8/4']
row.impact_insulation_class # 80

• ImpactInsulation, impact_insulation_named
ImpactInsulationdataclassOne floor-ceiling construction, or one surface treatment, as its page prints it.
• impact_insulation_class: the IIC of a whole assembly, dimensionless, from Tables 32.1 to 32.7
• impact_insulation_class_improvement: the delta-IIC a treatment adds, from Table 32.8 alone; no row carries both, because a difference between two ratings is not a rating
• impact_sound_improvement_db: the 1977 edition's average improvement in impact sound insulation, in decibels, a level difference and neither of the two above; added_load_pa is the load a floor of Table 19.4 was measured under, printed in kg/cm² and held in pascals
• refers_to_row: twelve descriptions are printed in full and refer to another row rather than repeating the structural floor; resolve with PUBLISHED_IMPACT_INSULATION[f'{row.table}/{row.refers_to_row}']
• has_section_drawing: the "Esquema" cell is a drawing with no textual equivalent, so that is all the row records of it
• layer_density_kg_m3: a mass density the running description buries, on the three rows that print one; it is one layer's, which is why it says layer, and row 35A serves none because the page prints that cell twice and the two printings disagree
• misprinted: seventeen rows carry a pair whose two halves are not each other, registered in docs/ERRATA.md; the printed description is kept whole beside the mark
• attributed_to: every row of Chapter 32 names the credit of its own table, because Tables 32.1 to 32.7 are a 1967 NBS survey and Table 32.8 a 1963 paper by Zeller; the 1977 rows credit nothing
row.why_missing('impact_insulation_class') # the page does not give it
impact_insulation_namedfunctionEvery published row whose printed description contains a fragment.
• name: matched without case against the description, which is the only thing these tables name a construction by
• the descriptions are in the language of the page, and a fragment crosses the two tables: 'linóleo' answers with four floors that carry a linoleum finish and the five treatments of Table 32.8
building.impact_insulation_named('baldosa de vinilo') # one row

• PUBLISHED_IMPACT_INSULATION
mass_law_transmission_loss / field_incidence_correctionfunctionPanel mass law TL (Bies Eq. 7.40/7.42).
• frequency [Hz], mass_per_area m'' [kg/m²]
• incidence: 'normal'/'field', band: 'third' (−5.5 dB) / 'octave' (−4.0 dB), or field_correction [dB] (Norton uses a flat 5 dB)
• +6 dB/octave and +6 dB/mass doubling
tl = building.mass_law_transmission_loss(500, 20)
single_panel_transmission_lossfunctionSingle-panel R, Sharp's method (Bies 7.2.4.1).
• frequency [Hz], mass_per_area [kg/m²]
• critical_frequency fc [Hz] or bending_stiffness B' [N·m]
• loss_factor η, band, coincidence_model: 'sharp' (Bies 7.44) / 'cremer' (Norton 3.110)
r = building.single_panel_transmission_loss(f, 15, critical_frequency=2100)

• SoundReductionResult
plateau_transmission_loss / PLATEAU_MATERIALSfunction / mappingPlateau (Watters) TL estimate (Norton & Karczub 3.9.1, Table 3.1).
• frequency [Hz]; material + thickness_mm, or mass_per_area + plateau_height + frequency_ratio
• field-incidence mass law → horizontal coincidence plateau (point A to B) → 10 dB/octave
• PLATEAU_MATERIALS: 8 materials as (kg/m² per mm, plateau dB, B/A)
r = building.plateau_transmission_loss(f, material='brick', thickness_mm=110)

• SoundReductionResult with plateau_height, plateau_start, plateau_end
orthotropic_transmission_lossfunctionOrthotropic (ribbed / corrugated) panel R (Vigran 6.5.3; Bies 7.2.4.5).
• frequency [Hz], mass_per_area m'' [kg/m²]
• critical_frequency_lower fc1 / critical_frequency_upper fc2 [Hz]
• method: 'integral' (Vigran Eq. 6.111 double integral, uses loss_factor η) / 'heckl' (Bies Fig. 7.9b design chart, needs fc2 > 4·fc1)
• area S [m²] (Bies Eq. 7.36 limit) or limiting_angle_deg θL [deg] (Default: 78)
r = building.orthotropic_transmission_loss(f, 7.5, critical_frequency_lower=400, critical_frequency_upper=4000)

• SoundReductionResult with critical_frequency_upper
orthotropic_critical_frequenciesfunctionCoincidence range (fc1, fc2) of an orthotropic panel (Vigran Eq. 6.107).
• mass_per_area m'' [kg/m²]
• bending_stiffness_1 / bending_stiffness_2 [N·m] (order irrelevant)
• speed_of_sound (Default: 343.0)
• the stiffest direction gives the lowest fc
fc1, fc2 = building.orthotropic_critical_frequencies(8.5, 17.5, 2202)

• (float, float) [Hz], sorted
corrugated_plate_stiffness / corrugated_plate_mass_factorfunctionEquivalent stiffnesses and developed length of a sinusoidal corrugation (Vigran Eq. 3.115, Timoshenko & Woinowsky-Krieger).
• thickness h, corrugation_amplitude H, corrugation_wavelength L [m]
• youngs_modulus E [Pa], poisson_ratio ν (Default: 0.3)
• the mass factor is the arc length of one period over the period
bx, bz, bxz = building.corrugated_plate_stiffness(1e-3, 0.01, 0.1, youngs_modulus=2.1e11)
m = 7.8 * building.corrugated_plate_mass_factor(0.01, 0.1)

• (Bx, Bz, Bxz) [N·m]; factor ≥ 1
orthotropic_plate_resonancefunctionEigenfrequency of a simply supported orthotropic plate (Vigran Eq. 3.113 = Bies Eq. 7.27, Hearmon 1959).
• mode_x i, mode_z n (≥ 1)
• length_x a, length_z b [m], mass_per_area m'' [kg/m²]
• bending_stiffness_x / _z / _xz [N·m]
• the panel TL models are valid above ≈ 1.5·f₁,₁
orthotropic_plate_resonance(1, 1, length_x=1.0, length_z=1.0, mass_per_area=7.8, bending_stiffness_x=b, bending_stiffness_z=b, bending_stiffness_xz=b)

• [Hz]
double_wall_transmission_loss / mass_spring_mass_resonancefunctionDouble-wall R (Bies 7.2.6, Eq. 7.62-7.64).
• mass1/mass2 [kg/m²], gap d [m]
• cavity_medium: porous fill (PorousMediumResult) lowers f0
• below f0 = total-mass law; f0 = mass-air-mass resonance
r = building.double_wall_transmission_loss(f, 12, 12, 0.1)

• SoundReductionResult
heavy_impact_source_specification / heavy_impact_source_limits / HeavyImpactSourceSpec / HEAVY_IMPACT_SOURCES / HEAVY_IMPACT_OCTAVE_BANDSfunction / dataclass / mapping / tupleStandard heavy and soft impact source (ISO 16283-2 Table A.1, JIS A 1418-2 Tables A.1/A.2).
• source: 'rubber_ball' / 'bang_machine'
• printed LFE per octave 31.5-500 Hz with tolerance, drop height, effective mass, restitution, 20 ± 2 ms contact time
spec = building.heavy_impact_source_specification('rubber_ball')
f, lo, hi = building.heavy_impact_source_limits('bang_machine')
check_heavy_impact_source / HeavyImpactSourceCheckfunction / dataclassSource conformance against the printed spectrum.
• force_exposure_level: five octave-band LFE [dB re 1 N]
• source: 'rubber_ball' / 'bang_machine'
• .plot()
chk = building.check_heavy_impact_source([39, 31, 23, 17, 12.5])

• HeavyImpactSourceCheck (passes, deviation, within_tolerance)
impact_force_exposure_levelfunctionImpact force exposure level LFE (ISO 16283-2 Formula (A.1)).
• force F(t) [N] (1-D record of one impact), fs [Hz]
• reference_force F0 (Default: 1 N), reference_time Tref (Default: 1 s)
lfe = building.impact_force_exposure_level(force, 200_000)

• [dB re 1 N]
standardized_maximum_impact_level / fast_reverberation_correction / StandardizedMaximumImpactResultfunction / dataclassStandardized maximum impact level L'i,Fmax,V,T (ISO 16283-2 Formulae (4)-(6)).
• level Li,Fmax [dB], volume V [m³], reverberation_time T [s]
• reference_time T0 (Default: 0.5 s), reference_volume V0 (Default: 50 m³)
• the Fast correction is exactly 0 dB at T = T0
• .plot()
res = building.standardized_maximum_impact_level(li, 41.4, t)

• StandardizedMaximumImpactResult
heavy_impact_octave_levelsfunctionOne-third-octave to octave synthesis (ISO 16283-2 Formula (20)).
• level: thirds in ascending order, length a multiple of 3
oct = building.heavy_impact_octave_levels(thirds)

• [dB]
a_weighted_maximum_impact_level / HEAVY_IMPACT_A_WEIGHTING / AWeightedMaximumImpactResultfunction / mapping / dataclassA-weighted maximum impact level XiA,Fmax (ISO 717-2 Annex D, Formula (D.1)).
• level: 12 thirds (50-630 Hz) or 4 octaves (63-500 Hz) [dB]
• band: 'third' / 'octave' (inferred from the length)
• Table D.3 corrections, rounded half-up
• .plot()
res = building.a_weighted_maximum_impact_level([65.3, 64.5, 58.0, 55.8])

• AWeightedMaximumImpactResult (rating = 55 dB)
normalized_ceiling_attenuationfunctionNormalized ceiling attenuation Dn,c (ISO 140-9 clause 3.3).
• level_source L1, level_receiving L2 [dB], absorption_area A [m²]
• reference_area A0 (Default: 10 m² ISO; ASTM E1414 uses 12 m²)
dnc = building.normalized_ceiling_attenuation(l1, l2, a)
ceiling_attenuation_class / CEILING_ATTENUATION_CONTOUR / CeilingAttenuationResultfunction / mapping / dataclassCeiling attenuation class CAC (ASTM E413-22 clause 5, via ASTM E1414).
• attenuation Dn,c: 16 thirds 125-4000 Hz [dB]
• data rounded to integers (5.2), Σ deficiencies ≤ 32 dB, max ≤ 8 dB
• .plot()
res = building.ceiling_attenuation_class(dnc)

• CeilingAttenuationResult (rating, deficiencies)
plenum_flanking_reduction_index / partition_referenced_reduction_index / PlenumFlankingResultfunction / dataclassSuspended-ceiling plenum flanking path Rcl (Vigran Eqs. (9.13), (9.18)-(9.20)).
• reduction_index_source RS / _receiving RR [dB]
• ceiling_length LR, plenum_height h [m]
• sidewalls: 'reflecting' (ε = 2) / 'absorbing' (ε = 1)
• attenuation_source / _receiving m [1/m] switch to Eq. (9.18)
• .plot()
res = building.plenum_flanking_reduction_index(rs, rr, ceiling_length=4.75, plenum_height=0.43)

• PlenumFlankingResult
wall_tie_stiffness / wall_tie_stiffness_per_area / WALL_TIE_STIFFNESSfunction / mappingDynamic stiffness of masonry wall ties (Hopkins Table A4).
• tie: 'butterfly' (1.7 MN/m) / 'double_triangle' (16.1) / 'vertical_twist' (94.0) at 50 mm, 'vertical_twist_100mm' (43.4)
• ties_per_area n [1/m²] → N·k/S [N/m³] for tie_stiffness_per_area
s = building.wall_tie_stiffness_per_area(2.5, 'vertical_twist_100mm')

• feeds mass_spring_mass_resonance / double_wall_transmission_loss
wall_tie_coupling_loss_factor / WallTieCouplingResultfunction / dataclassStructure-borne coupling of a tie array (Hopkins Eqs. 4.87/4.88).
• frequency [Hz], mass1/mass2 [kg/m²], bending_stiffness1/2 [N·m]
• ties_per_area n [1/m²], tie: name, k [N/m], or None (rigid, Yc = 0)
• .plot()
res = building.wall_tie_coupling_loss_factor(f, 150, 170, b1, b2, ties_per_area=2.5, tie='butterfly')

• WallTieCouplingResult
plot_double_wall_geometryfunctionMass-spring-mass cross-section to scale.
• mass1, mass2 [kg/m²], gap [m]
• resonance_frequency [Hz] (annotation)
• language
plot_double_wall_geometry(8.8, 8.8, 0.1)

• Also SoundReductionResult.plot_geometry() (double-wall results)
SoundReductionResultdataclassPredicted R(f) of a construction (Bies 7.2).
• transmission_loss R [dB], transmission_coefficient τ
• critical_frequency / critical_frequency_upper (orthotropic fc1/fc2) / resonance_frequency
• .rating() → Rw (ISO 717-1), .plot()
res.transmission_loss, res.rating().rating
slit_transmission_coefficient / slit_resonance_frequenciesfunctionStraight slit τ (Hopkins Eq. 4.99, Gomperts).
• frequency [Hz], width w [m], depth d [m]
• field: 'diffuse'/'normal', position: 'mid'/'edge'
• maxima at d+2e = zλ/2
res = building.slit_transmission_coefficient(f, 0.002, 0.1)

• ApertureTransmissionResult
circular_aperture_transmission_coefficientfunctionCircular hole τ (Hopkins Eq. 4.102, Wilson-Soroka).
• frequency [Hz], radius a [m], depth d [m]
• τ → 1 for a large hole
res = building.circular_aperture_transmission_coefficient(f, 0.01, 0.002)

• ApertureTransmissionResult
plot_aperture_geometryfunctionWall-aperture section to scale.
• depth d [m]
• Exactly one of width w / radius [m]
• language
plot_aperture_geometry(0.1, width=0.003)

• Also ApertureTransmissionResult.plot_geometry()
composite_transmission_loss / transmission_loss_from_coefficientfunctionComposite R of parallel elements (Hopkins Eq. 4.92).
• areas Sₙ [m²], reduction_indices Rₙ [dB] (1-D or (N, bands))
• a bare opening (Sₐ/S) caps R at 10 lg(S/Sₐ)
r = building.composite_transmission_loss([0.99, 0.01], [55, 0])
ApertureTransmissionResultdataclassSlit / hole transmission (Hopkins 4.3.10).
• transmission_coefficient τ, transmission_loss R = −10 lg(τ)
• kind: 'slit'/'circular', .plot()
res.transmission_loss
band_uncertaintyfunctionOne-third-octave standard uncertainty u (ISO 12999-1 Tables 2/4/6).
• measurand: 'airborne'/'impact'/'impact_reduction'
• situation: 'A'/'B'/'C'
• upper_limit: σR95 (airborne A, Annex D) (Default: False)
u = building.band_uncertainty('airborne', 'B')

• BandUncertainty
single_number_uncertaintyfunctionSingle-number standard uncertainty u (ISO 12999-1 Tables 3/5/7).
• quantity: 'r_w'/'ln_w'/'delta_lw' (+ aliases, +c/+ctr variants)
• situation: 'A'/'B'/'C'
• upper_limit (Default: False)
u = building.single_number_uncertainty('r_w', 'B')

• u [dB] (0.9)
single_number_uncertainty_uncorrelatedfunctionUncorrelated single-number u from bands (ISO 12999-1 Formula B.2).
• band_uncertainties: per-band u_i [dB]
• reference_differences: L_i − R_i [dB]
u = building.single_number_uncertainty_uncorrelated(u_i, d_i)

• Energy-weighted quadrature u [dB]
maximum_repeatability_standard_deviationfunctionMax repeatability σx per band (ISO 12999-1 Table 1).
• (no parameters)
b = building.maximum_repeatability_standard_deviation()

• BandUncertainty (lab self-verification)
insulation_coverage_factorfunctionCoverage factor k (ISO 12999-1 Table 8).
• confidence: fraction (Default: 0.95)
• one_sided (Default: False)
k = building.insulation_coverage_factor(0.95)

• 1.96 (two-sided) / 1.65 (one-sided)
insulation_expanded_uncertaintyfunctionExpanded uncertainty U = k·u (ISO 12999-1 Formula 2).
• u [dB]
• coverage: fraction (Default: 0.95)
• one_sided (Default: False); enforces k ≥ 1
U = building.insulation_expanded_uncertainty(0.9)

• 1.764 [dB]
uncertain_valuefunctionAttach U to a rating (ISO 12999-1 Clause 8).
• value [dB], quantity, situation
• coverage (Default: 0.95), one_sided (Default: False), upper_limit (Default: False)
uv = building.uncertain_value(52.0, 'rprime_w', 'B')

• UncertainValue (value ± U)
combine_uncertaintiesfunctionQuadrature combination (ISO 12999-1 Formula C.2).
• *components: non-negative u_i [dB]
uc = building.combine_uncertainties(1.0, 0.6)

• sqrt(Σ u_i²) = 1.166 [dB]
prediction_input_uncertaintyfunctionPrediction input uncertainty (ISO 12999-1 Formula A.1).
• sigma_reproducibility, sigma_product [dB]
• n: measurements (≥ 1)
u = building.prediction_input_uncertainty(1.8, 1.0, 3)

• sqrt((σR²+σp²)/n + σp²) [dB]
reduce_by_independent_measurementsfunctionReduce u by m measurements (ISO 12999-1 Formula A.7).
• u [dB]
• m: independent measurements (≥ 1)
ur = building.reduce_by_independent_measurements(1.0, 4)

• u/√m = 0.5 [dB]
satisfies_lower_requirementfunctionConformity to a minimum (ISO 12999-1 Formula 5).
• value, expanded_uncertainty_value, requirement [dB]
ok = building.satisfies_lower_requirement(52.0, 1.485, 50.0)

• True when value − U > requirement
satisfies_upper_requirementfunctionConformity to a maximum (ISO 12999-1 Formula 4).
• value, expanded_uncertainty_value, requirement [dB]
ok = building.satisfies_upper_requirement(45.0, 1.5, 50.0)

• True when value + U < requirement
BandUncertaintydataclassPer-band standard uncertainty (ISO 12999-1).
• measurand, situation
• frequencies [Hz], uncertainties [dB]
• upper_limit: σR95 flag
• .to_arrays()
b.frequencies, b.uncertainties
UncertainValuedataclassA value with its expanded uncertainty.
• value, standard_uncertainty, expanded_uncertainty [dB]
• coverage_factor, confidence, one_sided
• .lower = y − U, .upper = y + U
uv.lower, uv.upper
COVERAGE_FACTORSmappingTable 8 coverage factors (read-only).
Keyed by (confidence, one_sided) → k
COVERAGE_FACTORS[(0.95, False)] # 1.96
sound_absorption_coefficient_uncertaintyfunctionAbsorption-coefficient uncertainty αs (ISO 12999-2 Table 1, Formula 1).
• alpha, frequencies [Hz] (1/3-oct 63–5000)
• condition: 'reproducibility'/'repeatability'
• confidence (Default: 0.95)
r = materials.sound_absorption_coefficient_uncertainty(a_s, f)

• AbsorptionUncertaintyResult
equivalent_area_uncertaintyfunctionEquivalent-area uncertainty AT (ISO 12999-2 Formula 2, S = 10 m²).
• area, frequencies [Hz]
• condition, confidence (Default: 0.95)
r = materials.equivalent_area_uncertainty(a_t, f)

• AbsorptionUncertaintyResult
practical_coefficient_uncertaintyfunctionPractical-coefficient uncertainty αp (ISO 12999-2 Table 2, Formula 4).
• alpha_p, frequencies [Hz] (octave 250–4000)
• condition, confidence (Default: 0.95)
r = materials.practical_coefficient_uncertainty(a_p, f)

• AbsorptionUncertaintyResult
weighted_coefficient_uncertaintyfunctionWeighted-coefficient uncertainty αw (ISO 12999-2 Formulae 6/7).
• alpha_w (carried for the interval)
• condition, confidence
weighted_coefficient_uncertainty(0.70)

• σR = 0.035 / σr = 0.020
single_number_rating_uncertaintyfunctionDLα,NRD uncertainty (ISO 12999-2 Formulae 8/9, EN 1793-1).
• dl_alpha [dB] (≥ 0)
• condition, confidence
single_number_rating_uncertainty(8.1)

• σR = 0.10·DLα / σr = 0.02·DLα
absorption_coverage_factorfunctionCoverage factor k (ISO 12999-2 Table 3, rounded).
• confidence: 0.68/0.80/0.90/0.95/0.99/0.999
absorption_coverage_factor(0.95) # 2.0
AbsorptionUncertaintyResultdataclassAbsorption uncertainty (ISO 12999-2).
• standard_uncertainty u, expanded_uncertainty U = k·u
• reported_expanded_uncertainty (Clause 8 rounding)
• .lower, .upper, .plot()
r.reported_expanded_uncertainty
sound_power_pressurefunctionSound power from surface pressure (ISO 3744/3746).
• levels_positions: (NM, NB) SPL [dB]
• surface: 'hemisphere' / 'box'
• radius [m] or dimensions+distance [m]
• reflecting_planes: 1/2/3 (Default: 1)
• background_levels: for K1
• frequencies [Hz]: for LWA
• room: RoomEnvironment for K2 (Default: None → free field)
• grade: 'engineering' (Default) / 'survey'
• omc_uncertainty [dB] (Default: 0)
res = emission.sound_power_pressure(levels, 'hemisphere', radius=1.5, frequencies=f)

• SoundPowerResult
measurement_positionsfunctionHemisphere mic coordinates (ISO 3744 Annex B).
• surface: 'hemisphere'
• radius [m]
• reflecting_planes: 1/2/3
• tones: Table B.1 vs B.2 (Default: True)
• grade: 'engineering'/'survey'
xyz = emission.measurement_positions('hemisphere', radius=1.5)

• (N, 3) coordinates [m]
plot_microphone_positionsfunction3-D microphone array on its measurement surface.
• positions: (N, 3) [m] from measurement_positions/precision_positions
• radius [m] (Default: largest norm)
• language
plot_microphone_positions(emission.measurement_positions('hemisphere', radius=2.0), radius=2.0)

• Numbered points + hemisphere/sphere wireframe + reflecting plane
emission_sound_pressure_levelfunctionL_p at a work station: the reading less both corrections (ISO 11201 Eq. 7, ISO 11202 Eq. 10, ISO 11204 Eq. 9).
• measured_level_db [dB]
• background_correction_db K1 [dB], local_correction_db K3 [dB]
Never for a peak level: neither correction is permitted on one
emission.emission_sound_pressure_level(76.9, local_correction_db=3.7) # 73.2
background_noise_correction_at_workstationfunctionK1 with the ISO 11200 group's own thresholds.
• measured_level_db, background_level_db [dB]
• grade: 'engineering' (6 dB floor) / 'survey' (3 dB)
Past 15 dB of margin K1 is zero; below the floor it is held there and the level becomes an upper bound
k1, held = emission.background_noise_correction_at_workstation(79.0, 70.0)
local_environmental_correctionfunctionK3, the piecewise correction of ISO 11202 Eq. (A.5) and ISO 11204 Eqs. (A.2)/(A.5).
• ratio: the dimensionless z
7 dB for z ≤ 0,2, −10 lg z up to 1, then 0; continuous where the cap takes over
emission.local_environmental_correction(0.5) # 3.01
environmental_ratio_from_k2functionz from the environmental correction of the test room (ISO 11202 Eq. A.4, ISO 11204 Eq. A.3).
• environmental_correction_db K2 [dB]
• directivity_index_db [dB] (Default: 0)
With no directivity K3 comes out equal to K2
emission.environmental_ratio_from_k2(3.73)
environmental_ratio_from_absorptionfunctionThe same z from the equivalent absorption area (ISO 11204 Eq. A.6).
• absorption_area_m2 A, measurement_surface_m2 S_M
• directivity_index_db [dB] (Default: 0)
Identically equal to the K2 route under the ISO 3744 definition of K2
emission.environmental_ratio_from_absorption(47.0, 16.0)
grade_from_local_correctionfunctionThe accuracy grade K3 earns (ISO 11202 A.1.3).
• local_correction_db [dB]; the worst band decides
4 dB or less is grade 2, more is grade 3
emission.grade_from_local_correction(3.7) # 'engineering'
operating_standard_deviationfunctionsigma_omc of repeated readings, Equation (C.1).
• levels_db: at least two readings [dB]
Sample standard deviation, 1/(N−1), as printed; see docs/ERRATA.md on the two Annex B tables
emission.operating_standard_deviation([79.0, 80.2, 82.9]) # 2.0
total_standard_deviationfunctionsigma_tot = sqrt(sigma_R0² + sigma_omc²).
• reproducibility_db of the method, operating_db of the machine [dB]
emission.total_standard_deviation(1.5, 1.0) # 1.80
emission_expanded_uncertaintyfunctionU = k·sigma_tot for the ISO 11200 group.
• total_standard_deviation_db [dB]
• coverage_factor (Default: 1.6, what the worked examples print)
emission.emission_expanded_uncertainty(1.8) # 2.88
subinterval_levelfunctionOne level for a cycle of operating periods of different lengths.
• levels_db, durations_s
Energy average weighted by duration, not by count
emission.subinterval_level([80.0, 90.0], [10.0, 1.0])
EmissionPressureResultdataclassAn emission sound pressure level and the two corrections behind it.
• level_db, measured_level_db, background_correction_db, local_correction_db
• grade, upper_bound, standard
• .plot(): the reading, both corrections and what is left, as a waterfall
res.level_db, res.upper_bound
NEGLIGIBLE_BACKGROUND_MARGIN_DB / MINIMUM_BACKGROUND_MARGIN_DBconstant / mappingThe two background thresholds of the group: 15 dB above which K1 is zero, and the 6 dB (grade 2) / 3 dB (grade 3) floor a determination may be claimed from.emission.MINIMUM_BACKGROUND_MARGIN_DB['engineering'] # 6.0
MAX_K3_DB / GRADE_2_MAX_K3_DBconstantThe 7 dB cap on K3, and the 4 dB above which the result is grade 3 rather than grade 2.emission.GRADE_2_MAX_K3_DB # 4.0
DEFAULT_COVERAGE_FACTORconstantk = 1,6, the factor the ISO 11200 group's worked examples print.emission.DEFAULT_COVERAGE_FACTOR # 1.6
background_noise_correctionfunctionBackground correction K1 (ISO 3744 Eq. 16).
• source_levels [dB]
• background_levels [dB]
• grade: 'engineering'/'survey'
k1 = emission.background_noise_correction(src, bg)

• K1 per band [dB]
environmental_correctionfunctionEnvironmental correction K2 (ISO 3744 Eq. A.2).
• surface_area S [m²]
• absorption_area A, or reverberation_time+volume, or mean_absorption_coefficient+room_surface
k2 = emission.environmental_correction(14.1, reverberation_time=0.6, volume=300)

• K2 [dB]
SoundPowerResultdataclassSurface-pressure sound power.
• sound_power_level [dB]
• surface_pressure_level, mean_pressure_level [dB]
• background_correction, environmental_correction [dB]
• directivity_index [dB] (NM, NB)
• surface_area [m²]
• sound_power_level_a [dB]
• uncertainty [dB]
• grade
• declare(...) → NoiseEmissionDeclaration
res.sound_power_level, res.sound_power_level_a
RoomEnvironmentdataclassRoom data behind K2 (ISO 3744 Annex A), for sound_power_pressure.
• absorption_area A [m²]
• reverberation_time T [s] + volume V [m³] (Eq. A.3)
• mean_absorption_coefficient α + room_surface Sv [m²] (Eq. A.7)
All Default: None; the empty environment is a free field (K2 = 0)
RoomEnvironment(reverberation_time=0.6, volume=300)
sound_energy_pressurefunctionSound energy level LJ of a burst from surface single event levels (ISO 3744 8.3 / ISO 3746 8.4).
• levels_positions: (NM, NB) single event levels, or (Ne, NM, NB) per event [dB]
• surface, radius / dimensions+distance, reflecting_planes: as sound_power_pressure
• events: Ne encompassed by one reading (Eq. 20)
• background_levels [dB] + integration_time T [s] (required together): K1 over the same window
• frequencies [Hz]: for LJA
• room: RoomEnvironment for K2
• grade, omc_uncertainty
lj = emission.sound_energy_pressure(events, 'hemisphere', radius=2.0, frequencies=f)

• SoundEnergyResult
SoundEnergyResultdataclassSurface single-event sound energy.
• frequencies [Hz] (or None)
• sound_energy_level [dB re 1 pJ]
• surface_event_level, mean_event_level [dB]
• background_correction, environmental_correction [dB]
• directivity_index (NM, NB)
• surface_area [m²]
• sound_energy_level_a [dB]
• uncertainty [dB], grade
• events (a count)
• integration_time [s]
lj.sound_energy_level, lj.sound_energy_level_a
mean_single_event_levelfunctionLevel of one event from Ne events (ISO 3744 Eq. 19/20).
• levels: per-event levels on the first axis (Eq. 19), or one reading of events events (Eq. 20) [dB]
• events: Ne of one reading (Default: None)
emission.mean_single_event_level(per_event)
emission.mean_single_event_level(reading, events=5)
reference_atmosphere_correctionfunctionAnnex G corrections C1, C2 to 101.325 kPa and 23 °C (ISO 3744 Eq. G.1/G.3).
• temperature_c [°C]
• static_pressure_kpa [kPa], or altitude [m] via Eq. G.2
corr = emission.reference_atmosphere_correction(8.0, altitude=1200.0)

• ReferenceAtmosphereCorrection
ReferenceAtmosphereCorrectiondataclassThe two Annex G corrections.
• c1, c2, total [dB]
• static_pressure_kpa [kPa], temperature_c [°C]
lj_ref = lj.sound_energy_level + corr.total
OperatingModeDeclarationdataclassISO 4871 dual-number values for one operating mode.
• mode: column label
• sound_power_level L_WA [dB re 1 pW]
• sound_power_uncertainty K_WA [dB]
• emission_pressure_level L_pA, emission_pressure_uncertainty K_pA [dB] (optional)
• verification_level L_1 [dB] (optional)
• declared_sound_power_level: L_WAd = L_WA + K_WA (3.15)
• verified: L_1 ≤ L_WAd (6.2, combined form)
• verified_dual: L_1 ≤ round(L_WA) + round(K_WA) (6.2, dual-number form)
OperatingModeDeclaration('Mode 1', 88.0, 2.0)
DeclarationFormconstantThe form literal of NoiseEmissionDeclaration (ISO 4871 clause 6).
• 'dual-number': L_WA and K_WA declared as a pair (Default)
• 'single-number': the declared L_WAd alone
NoiseEmissionDeclaration(modes, form='single-number')
NoiseEmissionDeclarationdataclassISO 4871:1996 noise emission declaration (machinery).
• modes: OperatingModeDeclaration per mode
• machine, operating_conditions (clause 5)
• noise_test_code, basic_standards (clause 5 b)
• form: 'dual-number' (Default) / 'single-number'
• .report(path, ...): ISO 4871 fiche → PDF
NoiseEmissionDeclaration((m1, m2), machine='...').report('iso4871.pdf')
sound_power_reverberationfunctionReverberation-room LW, direct (ISO 3741).
• levels: mean room SPL [dB] (1D or (NM, NB))
• t60 [s]
• volume V [m³]
• surface_area S [m²]
• frequencies [Hz] (required)
• background_levels: for K1
• temperature_c [°C] (Default: 23)
• static_pressure_kpa [kPa] (Default: 101.325)
rev = emission.sound_power_reverberation(lp, t60, 200, 220, f)

• ReverberationSoundPowerResult
reverberation_background_correctionfunctionThe background-noise correction K1 of ISO 3741:2010 Eq. (14), on its own.
• levels, background_levels, frequencies, all per band [dB, dB, Hz]
• K1 = −10 lg(1 − 10^(−0.1 ΔL)), with the qualification of 9.1.2: the lower criterion is 6 dB at 200 Hz and below and at 6.3 kHz and above and 10 dB between them, below it the correction is held there and the answer is an upper bound, and at 15 dB and over there is nothing to correct
• the standards that ask for a correction in accordance with ISO 3741, ISO 11957 four times over, call this rather than repeat it
emission.reverberation_background_correction(lp, bg, f)

• K1 [dB]
sound_power_comparisonfunctionReverberation-room LW, comparison (ISO 3741).
• levels, levels_ref: room SPL [dB]
• lw_ref: reference-source LW [dB]
• frequencies [Hz]
• background_levels, background_levels_ref
• temperature_c, static_pressure_kpa
cmp = emission.sound_power_comparison(lp, lp_ref, lw_ref)

• ReverberationSoundPowerResult (method='comparison')
ReverberationSoundPowerResultdataclassReverberation-room sound power.
• frequencies [Hz] (or None)
• sound_power_level [dB]
• mean_pressure_level [dB]
• absorption_area [m²]
• waterhouse_correction [dB]
• background_correction, c1, c2 [dB]
• speed_of_sound [m/s]
• sound_power_level_a [dB]
• method
rev.sound_power_level, rev.waterhouse_correction
sound_power_in_situfunctionIn situ LW by comparison with a reference sound source (ISO 3747).
• levels: (n, bands) L'pi(ST) [dB]
• levels_ref: (n, bands) or (m, n, bands) L'pi(RSS) [dB]
• lw_ref: calibrated LW(RSS) [dB], per band or per location
• frequencies [Hz] (octaves 63 Hz–8 kHz, required; 63 Hz only where the environment and instrumentation suit it, Table D.1 footnote a)
• background_levels, background_levels_ref: for K1 (8.1 rules)
• temperature_c [°C] (Default: 23), static_pressure_kpa [kPa] (Default: 101.325)
• conditions: GradeConditions(excess_levels, directivity_range) for the Table 2 grade
• sigma_omc [dB], coverage_factor (Default: 2)
res = emission.sound_power_in_situ(lp, lp_ref, lw_ref, f, background_levels=lb)

• InSituSoundPowerResult
sound_energy_in_situfunctionIn situ LJ of an impulsive source (ISO 3747 clauses 8.4, 8.5).
• event_levels: (n, N, bands) events one at a time, or (n, bands) with events=N
• integration_time [s]: carries Lp(B) to the event interval (Eq. 14)
• the rest as sound_power_in_situ
res = emission.sound_energy_in_situ(le, lp_ref, lw_ref, f, background_levels=lb)

• InSituSoundPowerResult (quantity='energy')
GradeConditionsdataclassThe two conditions Table 2 reads for the accuracy grade (ISO 3747).
• excess_levels: ΔLfA at each microphone position [dB] (Annex A)
• directivity_range: half-width of the A-weighted directivity survey [dB] (7.2)
Either one left out leaves the determination at survey grade
emission.GradeConditions(excess_levels=[8.2, 7.6, 8.9, 8.0], directivity_range=4.0)
InSituSoundPowerResultdataclassIn situ comparison result (ISO 3747).
• frequencies [Hz]
• sound_power_level / sound_energy_level [dB] (the other NaN)
• mean_source_level, mean_reference_level, reference_levels, reference_power_level [dB]
• background_correction (n, bands), background_correction_ref (m, n, bands) [dB]
• background_requirement_met per band
• c2 [dB], grade, sigma_r0, sigma_omc, sigma_tot, expanded_uncertainty, coverage_factor
• sound_power_level_a / sound_energy_level_a [dB], quantity
• .sound_power_level_ref, .sound_energy_level_ref (Annex C)
• .plot()
res.sound_power_level, res.background_requirement_met
excess_sound_pressure_levelfunctionExcess of sound pressure level over the free field ΔLf (ISO 3747 Eq. A.1).
• level Lp(RSS),r [dB], lw_ref LW(RSS) [dB], distance r [m]; broadcast
emission.excess_sound_pressure_level(76.5, 92.5, 3.0) # 4.54 dB
static_pressure_from_altitudefunctionStatic pressure from the site altitude (ISO 3747 Eq. C.2).
• altitude Ha [m]
emission.static_pressure_from_altitude(640.0) # 93.87 kPa
sound_energy_reverberationfunctionReverberation-room LJ of a single event, direct (ISO 3741 9.2.4, Eq. 30).
• levels: single event levels, 1D, (NM, NB) or (Ne, NM, NB) [dB]
• t60 [s], volume V [m³], surface_area S [m²], frequencies [Hz]
• events: Ne of one reading (Eq. 23)
• background_levels [dB] + integration_time T [s]: per-position K1i over the same window
• temperature_c, static_pressure_kpa
lj = emission.sound_energy_reverberation(slams, t60, 200, 220, f)

• ReverberationSoundEnergyResult
sound_energy_comparisonfunctionReverberation-room LJ of a single event, comparison (ISO 3741 9.2.5, Eq. 31).
• levels: single event levels of the source under test
• levels_ref, lw_ref: the steady reference source
• frequencies, events, background_levels + integration_time, background_levels_ref
• temperature_c, static_pressure_kpa
lj = emission.sound_energy_comparison(slams, lp_ref, lw_ref, frequencies=f)

• ReverberationSoundEnergyResult (method='comparison')
ReverberationSoundEnergyResultdataclassReverberation-room sound energy of a single event.
• frequencies [Hz] (or None)
• sound_energy_level [dB re 1 pJ]
• mean_event_level [dB]
• absorption_area [m²], waterhouse_correction [dB]
• background_correction, c1, c2 [dB]
• speed_of_sound [m/s]
• sound_energy_level_a [dB]
• method, events (a count)
• integration_time [s]
lj.sound_energy_level, lj.method
octave_band_levelsfunctionOctave-band levels from one-third-octave bands (ISO 3741 Annex F, Eq. F.1/F.4).
• levels [dB], bands on the last axis
• frequencies [Hz]: nominal thirds 50 Hz to 10 kHz, complete triplets per octave
octaves, lj_oct = emission.octave_band_levels(lj.sound_energy_level, f)
sound_power_in_ductfunctionIn-duct sound power of a fan (ISO 5136).
• levels: SPL [dB], (positions, bands) or an averaged (bands,)
• frequencies [Hz]: nominal thirds 50 Hz-20 kHz (required)
• duct_diameter_m d [m], 0.15-2
• flow_velocity U [m/s], < 0 inlet, > 0 outlet
• shield: 'sampling-tube' (Default)/'nose-cone'/'foam-ball'
• microphone_correction C1, shield_correction C2 [dB]
• temperature_c [°C] (Default: 20), static_pressure_kpa [kPa] (Default: 101.325)
duct = emission.sound_power_in_duct(lp, f, 0.63, 12.0)

• InDuctSoundPowerResult
flow_modal_correctionfunctionMean-flow and modal correction C3,4 (ISO 5136 Eq. 7 / Eq. 8).
• frequencies [Hz]: nominal thirds
• flow_velocity U [m/s], signed
• duct_diameter_m [m]: selects the Annex A table
• shield: sampling tube polynomial (Annex A) or the omni-directional Eq. 8
• speed_of_sound [m/s] (Default: 340, Eq. 8 only)
c34 = emission.flow_modal_correction(f, 15.0, 0.5)

• C3,4 per band [dB]
in_duct_reproducibilityfunctionReproducibility σR per band (ISO 5136 Table 2 / Table 3).
• frequencies [Hz]: nominal thirds 50 Hz-20 kHz
• 12.5-20 kHz: the extrapolated Table 3 values
s = emission.in_duct_reproducibility(f)

• σR per band [dB]; U95 = 2 σR (clause 9.2)
InDuctSoundPowerResultdataclassIn-duct sound power.
• frequencies [Hz]
• sound_power_level [dB], sound_power_level_a [dB]
• mean_pressure_level, corrected_pressure_level [dB]
• microphone_correction, shield_correction, flow_modal_correction, combined_correction [dB]
• reproducibility_standard_deviation, expanded_uncertainty [dB]
• information_only_band: > 10 kHz or |U| > 40 m/s
• duct_diameter_m, duct_area, characteristic_impedance, speed_of_sound, flow_velocity, shield
duct.sound_power_level, duct.flow_modal_correction
high_frequency_sound_powerfunctionSound power in the 16 kHz octave band, direct method (ISO 9295 Formula (6), clauses 6 and 7).
• pressure_levels_db: Lp(ST) [dB], (bands,) or (N, bands) averaged by Formula (1)
• frequencies_hz [Hz]: one per band, 11.2-22.4 kHz
• room_constant_m2 R [m²], scalar or per band
• temperature_c [°C] (Default: 23), static_pressure_kpa [kPa] (Default: 101.325): C1 + C2 of ISO 3741 (clause 10.1)
• tonal (Default: False)
res = emission.high_frequency_sound_power(lp, frequencies_hz=f, room_constant_m2=r)

• HighFrequencySoundPowerResult (method='direct')
high_frequency_sound_power_comparisonfunctionSound power in the 16 kHz octave band against a reference sound source (ISO 9295 Formulae (8) and (9)).
• pressure_levels_db: Lp(ST) [dB]
• frequencies_hz [Hz]
• reference_pressure_levels_db: Lp(FAR) [dB]
• reference_sound_power_levels_db: LW(FAR) [dB re 1 pW], per band, or per hertz for tones
• noise_bandwidth_hz ΔF [Hz]: selects Formula (9); ≤ 112 Hz for an FFT
• temperature_c, static_pressure_kpa: C2 of ISO 3741
res = emission.high_frequency_sound_power_comparison(lp, frequencies_hz=f, reference_pressure_levels_db=lp_ref, reference_sound_power_levels_db=lw_ref, noise_bandwidth_hz=12.5)
room_constant_from_reverberation_timefunctionRoom constant from the measured reverberation time (ISO 9295 Formulae (4), (5)).
• reverberation_time_s T [s], scalar or per band
• volume_m3 V [m³], surface_area_m2 S [m²]
r = emission.room_constant_from_reverberation_time([0.70, 0.42, 0.26], volume_m3=200.0, surface_area_m2=210.0)

• R per band [m²]
room_absorption_coefficientfunctionRoom absorption coefficient from the reverberation time, Eyring (ISO 9295 Formula (5)).
• reverberation_time_s T [s]
• volume_m3 V [m³], surface_area_m2 S [m²]
• 1 - exp(-0.16 V/(S T))
emission.room_absorption_coefficient(0.42, volume_m3=200.0, surface_area_m2=210.0)
room_constant_from_air_absorptionfunctionRoom constant from the calculated air absorption (ISO 9295 Formula (7)).
• frequencies_hz [Hz]
• volume_m3 V [m³], surface_area_m2 S [m²]
• temperature_c [°C], relative_humidity_percent [%] (required), static_pressure_kpa [kPa] (Default: 101.325)
• 8αV/(1 - 8αV/S); warns below 10 kHz, refuses 8αV/S ≥ 1
r = emission.room_constant_from_air_absorption(f, volume_m3=200.0, surface_area_m2=210.0, temperature_c=23.0, relative_humidity_percent=50.0)
air_absorption_np_per_mfunctionAir absorption coefficient α in nepers per metre (ISO 9295 Annex A).
• frequencies_hz [Hz], 50 Hz-22.4 kHz without advisory
• temperature_c [°C], relative_humidity_percent [%] (required), static_pressure_kpa [kPa] (Default: 101.325)
• ISO 9613-1 without the 8.686
emission.air_absorption_np_per_m(16000.0, temperature_c=23.0, relative_humidity_percent=50.0) # 0.0383 Np/m
minimum_analyzer_bandwidth_hzfunctionNarrowest analyser bandwidth for a tone under a moving microphone (ISO 9295 Formula (2)).
• tone_frequency_hz f [Hz]
• microphone_speed_m_s v [m/s], speed_of_sound c [m/s]
• Δf = 2 f v / c
emission.minimum_analyzer_bandwidth_hz(15625.0, microphone_speed_m_s=0.196, speed_of_sound=345.5)
tone_level_from_sidebandsfunctionTotal level of a tone from its sidebands (ISO 9295 Formula (3)).
• sideband_levels_db [dB re 20 µPa]
• the energy sum
emission.tone_level_from_sidebands([42.9, 41.3, 38.0]) # 45.9 dB
free_field_absorption_correctionfunctionAir absorption correction K_α = r α of the free-field method (ISO 9295 Formula (10)).
• frequencies_hz [Hz]
• radius_m r [m]: zero at 2 m or less (clause 9.8)
• temperature_c [°C], relative_humidity_percent [%], static_pressure_kpa [kPa] (Default: 101.325)
k = emission.free_field_absorption_correction(f, radius_m=2.5, temperature_c=23.0, relative_humidity_percent=50.0)
high_frequency_levels_to_determinefunctionThe sound power levels to determine for a type of noise (ISO 9295 Table 3).
• noise_125_hz_to_8_khz: 'broadband', 'narrowband' or 'none'
• noise_16_khz_octave: 'none', 'broadband', 'discrete_tone' or 'multiple_tones'
• returns a tuple of 'a_weighted_sound_power_level', 'one_third_octave_band_levels', 'tone_level_and_frequency', 'tone_levels_within_10_db'
• ValueError for the two combinations the table has no row for
emission.high_frequency_levels_to_determine(noise_125_hz_to_8_khz='broadband', noise_16_khz_octave='multiple_tones')
HighFrequencySoundPowerResultdataclassSound power in the 16 kHz octave band (ISO 9295).
• frequencies [Hz]
• sound_power_level [dB re 1 pW], at the reference meteorological conditions
• mean_pressure_level [dB]
• room_constant [m²] (direct) or reference_sound_power_level, reference_pressure_level [dB] (comparison)
• noise_bandwidth_hz, c1, c2 [dB], method, tonal
• within_10_db_of_maximum: the tones clause 13 c) reports
• .plot()
res.sound_power_level, res.within_10_db_of_maximum
res.plot()
sound_power_intensityfunctionSound power by intensity scanning (ISO 9614-2).
• normal_intensity: (N_seg, N_bands) [W/m²]
• areas: segment Si [m²]
• normal_intensity_2: 2nd sweep (criterion 3)
• pressure_levels: for FpI
• pressure_residual_index: δpI0 [dB]
• frequencies [Hz]
• band_type: 'third' (Default)/'octave'
• grade: 'engineering'/'survey'
• repeatability_limit: override s
ir = emission.sound_power_intensity(scan1, areas, frequencies=f, band_type='octave')

• SoundPowerIntensityResult
SoundPowerIntensityResultdataclassScanning sound power.
• partial_power, partial_power_level
• sound_power [W], sound_power_level [dB] (NaN where negative_band)
• negative_band: per-band bool (True where P ≤ 0)
• surface_pressure_intensity_index (FpI)
• negative_partial_power_index (F+/-)
• repeatability, dynamic_capability_index (Ld)
• achieved_grade
• surface_area, sound_power_level_a, grade
ir.sound_power_level, ir.achieved_grade
sound_power_intensity_pointsfunctionSound power at discrete points (ISO 9614-1).
• normal_intensity: (N, N_bands) signed Ini [W/m²]
• areas: segment Si [m²]
• pressure_levels: Lpi for F2/F3
• pressure_residual_index: δpI0 [dB] (criterion 1)
• temporal_intensity: M short-time samples (F1)
• frequencies [Hz] (criterion 2, Table B.2)
• band_type: 'third' (Default)/'octave'
• grade: 'precision'/'engineering' (Default)/'survey'
dp = emission.sound_power_intensity_points(i_n, areas, frequencies=f, band_type='octave')

• DiscretePointIntensityResult
DiscretePointIntensityResultdataclassDiscrete-point sound power.
• partial_power Pi = Ini·Si (Eq. 11)
• sound_power [W], sound_power_level [dB] (NaN where not_applicable_band, clause 9.2)
• f1…f4: Annex A indicators
• dynamic_capability_index (Ld), criterion_1, negative_power_within_limit, criterion_2, minimum_positions (C·F4²)
• achieved_grade per band ('precision'/'engineering'/'none')
• confidence_interval (Eq. B.3), expanded_uncertainty (2s at the grade achieved, clause 10.6; NaN where none was)
• surface_area, positions, sound_power_level_a, a_weighting_omitted_bands
• field_nonuniformity_a, achieved_grade_a, grade
• .required_actions() → Table B.3 codes, .plot()
dp.achieved_grade, dp.required_actions()
ActionCodeenumISO 9614-1 Table B.3 corrective actions.
• .value: the printed letter a…e
• .criterion: the Table B.3 row
• .action: what to change
[a.value for a in dp.required_actions()[0]]
position_count_factorfunctionCriterion-2 factor C (ISO 9614-1 Table B.2).
• grade: 'precision'/'engineering'/'survey'
• frequency [Hz], or None for the A-weighted row (grade 3 only)
• band_type: 'third' (Default)/'octave'
C = emission.position_count_factor('engineering', 1000.0)

• per-band C for grades 1/2; grade 3 raises (A-weighted only)
determination_standard_deviationfunctionStandard deviation s (ISO 9614-1 Table 2).
• grade, frequency (or None for A-weighted), band_type
• footnote 1: the true LW lies within ±2s at 95 %
s = emission.determination_standard_deviation('precision', 1000.0)
error_factorfunctionError factor Δ (ISO 9614-1 Table B.1).
• grade
• a_weighted: read the A-weighted row (grade 3 only) (Default: False)
d = emission.error_factor('engineering')

• 0.20 / 0.29 / 0.60
normal_intensity_from_levelsfunctionSigned Ini from printed levels (ISO 9614-1 clause 9.1).
• levels: XX [dB]
• negative: the (-) of the print, broadcast per position
i_n = emission.normal_intensity_from_levels(lvl, negative=mask)

• Ini = ±I0·10^(XX/10) [W/m²]
partial_power_concentrationfunctionOptional procedure of ISO 9614-1 8.3.2/B.1.3.
• normal_intensity, areas: one band
• grade: selects Δ (Table B.1)
c = emission.partial_power_concentration(i_n, areas)

• PartialPowerConcentration
PartialPowerConcentrationdataclassConcentrated positive partial power.
• positions N, subset_positions Nα, subset_area Sα
• power_fraction α, subset_nonuniformity F4(α), remainder_nonuniformity F4(1−α)
• error_factor Δ, subset_error_factor Δα
• additional_positions N* (Eq. B.4)
c.additional_positions
absorption_areafunctionEquivalent absorption area (ISO 354 Eq. 5/7).
• t60: T [s]
• volume V [m³]
• temperature_c [°C] (Default: 20)
• speed_of_sound [m/s] (overrides temperature)
• m: air attenuation [1/m] (Default: 0)
A = materials.absorption_area(t60, volume=200)

• A [m²]
absorption_coefficientfunctionSound absorption coefficient (ISO 354 Eq. 9).
• t1, t2: empty / with-specimen T [s]
• volume V [m³]
• sample_area S [m²]
• temperature1_c/temperature2_c [°C]
• speed_of_sound1/2, m1/m2
a = materials.absorption_coefficient(t1, t2, 200, 10.8)

• α_s (unclamped, may exceed 1)
attenuation_from_alphafunctionISO 9613-1 α → m (ISO 354 8.1.2.1).
• alpha: attenuation [dB/m]
m = materials.attenuation_from_alpha(0.01)

• m = α/(10 lg e) [1/m]
measure_sound_absorptionfunctionReverberation-room absorption measurement (ISO 354 Eq. 5/7/8/9).
• frequencies [Hz], t_empty T1 [s], t_specimen T2 [s]
• volume V [m³], area S [m²]
• temperature_c [°C] (Default: 20), relative_humidity_percent [%]
• speed_of_sound [m/s], m [1/m] (Default: 0)
r = materials.measure_sound_absorption(f, t1, t2, volume=200, area=10.8)

• SoundAbsorptionMeasurement
SoundAbsorptionMeasurementdataclassReverberation-room sound absorption (ISO 354).
• frequencies [Hz], t_empty/t_specimen [s]
• volume, area, temperature_c, relative_humidity_percent, speed_of_sound
• air_attenuation m [1/m]
• absorption_area_empty A1, absorption_area_with_specimen A2 [m²]
• alpha_s (unclamped)
• .equivalent_absorption_area AT = A2−A1
• .plot() / .report()
r.alpha_s, r.equivalent_absorption_area
air_attenuationfunctionAtmospheric attenuation coefficient α (ISO 9613-1 Eq. 5).
• frequencies [Hz]
• temperature_c [°C] (Default: 20)
• relative_humidity_percent [%] (Default: 50)
• atmospheric_pressure_kpa [kPa] (Default: 101.325)
• exact_midband: snap to Table 1 midbands (Default: False)
a = environment.air_attenuation([1000, 4000], 20, 50)

• α [dB/m] (×1000 = dB/km); out-of-range warns
air_attenuation_mfunctionISO 354 power attenuation m from conditions (ISO 9613-1 + ISO 354).
• Same parameters as air_attenuation
m = environment.air_attenuation_m([1000, 4000], 20, 50)

• m = α/(10 lg e) [1/m]
AtmosphericAbsorptionWarningwarning classISO 9613-1 out-of-range advisory.
Emitted by air_attenuation when temperature/humidity/frequency leave the tabulated ranges or pressure exceeds 200 kPa, and by emission.air_absorption_np_per_m (so also by emission.room_constant_from_air_absorption and emission.free_field_absorption_correction) outside 50 Hz to 22.4 kHz, the ISO 9613-1 range as ISO 9295 Annex A extends it, or outside its temperature and humidity ranges; the result still returns
warnings.simplefilter('error', AtmosphericAbsorptionWarning)
atmospheric_attenuationfunctionPlottable ISO 9613-1 attenuation-coefficient curve.
• Same parameters as air_attenuation
• distance d [m] (optional; enables total attenuation)
res = environment.atmospheric_attenuation([1000, 4000], 20, 50)

• AtmosphericAttenuation; res.plot()
AtmosphericAttenuationdataclassAtmospheric attenuation result (ISO 9613-1).
• frequencies [Hz]
• attenuation_coefficient α [dB/m]
• temperature_c, relative_humidity_percent, atmospheric_pressure_kpa
• distance [m] or None
• .total_attenuation A = α·d [dB] (ISO 9613-2 Aatm) or None
• .plot(): α (dB/km) vs frequency
res.attenuation_coefficient, res.total_attenuation
geometric_divergencefunctionGeometrical divergence Adiv (ISO 9613-2 Eq. 7).
• distance d [m]
a = environment.geometric_divergence(100.0)

• 20 lg(d/d₀) + 11 = 51 dB at 100 m
atmospheric_absorptionfunctionAtmospheric absorption term Aatm (ISO 9613-2 Eq. 8), α at the exact base-10 midbands (the Table 2 convention).
• distance d [m]
• frequencies [Hz] (snapped to exact midbands)
• temperature_c/relative_humidity_percent/atmospheric_pressure_kpa
aatm = environment.atmospheric_absorption(200, bands)

• α·d per band [dB]
ground_attenuationfunctionGround effect Agr, general method (ISO 9613-2 7.3.1, Eq. 9).
• distance d, source_height hs, receiver_height hr [m]
• frequencies [Hz]
• ground_source/ground_middle/ground_receiver G ∈ [0,1]
• projected_distance dp [m]
agr = environment.ground_attenuation(200, 2, 2, bands, 1, 1, 1)

• As+Ar+Am per band [dB] (negative = gain)
ground_attenuation_alternativefunctionGround effect Agr, A-weighted method (ISO 9613-2 7.3.2, Eq. 10).
• distance d [m]
• mean_height hm [m]
agr = environment.ground_attenuation_alternative(200, 2)

• 4.8 − (2hm/d)·(17+300/d) ≥ 0 [dB]
directivity_omegafunctionSolid-angle directivity index DΩ (ISO 9613-2 Eq. 11).
• source_height hs, receiver_height hr, projected_distance dp [m]
dw = environment.directivity_omega(1.5, 1.5, 200)

• 0…~3 dB (add to Dc for the 7.3.2 method)
region_ground_factorsfunctionGround factors of the three regions of a path over mixed ground (ISO/TR 17534-3 6.2.5).
• segment_lengths [m], segment_ground_factors G, in order from the source
• source_height hs, receiver_height hr [m]
g = environment.region_ground_factors([40.9, 102.2, 51.1], [0.9, 0.5, 0.2], 1, 4)

• GroundFactors (Gs, Gm, Gr), each a length-weighted mean over its region
mean_path_heightfunctionMean path height hm above a ground profile (ISO 9613-2 Figure 3).
• profile_distances [m], strictly increasing, profile_heights [m]
• source_height hs, receiver_height hr [m]
• distance d [m] (Default: the slant distance the profile implies)
hm = environment.mean_path_height([0, 112.4, 178.8, 194.2], [0, 0, 10, 10], 1, 4)

• hm = F/d [m], for the 7.3.2 method
BarrierdataclassBarrier diffraction geometry (ISO 9613-2 7.4).
• source_to_edge dss, edge_to_receiver dsr [m]
• parallel_distance a [m] (Default: 0)
• edge_separation e [m] (Default: None → single diffraction)
• ground_reflections_by_image (Default: False → C₂=20)
• lateral (Default: False → top-edge)
• line_of_sight_clear (Default: False; True gives z the negative sign of Eq. 16 when the sight line passes above the edge)
b = environment.Barrier(source_to_edge=101, edge_to_receiver=101)

• .is_double when e is given
barrier_attenuationfunctionBarrier diffraction Dz (ISO 9613-2 Eq. 14).
• barrier: Barrier
• distance d [m]
• frequencies [Hz]
dz = environment.barrier_attenuation(b, 200, bands)

• 10 lg[3+(C₂/λ)C₃ z Kmet], capped 20/25 dB; 10 lg 3 at grazing (z = 0), decaying to ≥ 0 for negative z
measured_insertion_loss_direct / measured_insertion_loss_indirect / MeasuredBarrierInsertionLossfunction / function / dataclassWhat a barrier is worth once it is built, ISO 10847 8.2.1 and 8.2.2.
• direct: D_IL = (L_ref,A − L_ref,B) − (L_r,A − L_r,B), the reference microphone normalising whatever the source did differently between campaigns
• indirect: the "before" pair comes from an equivalent site, which makes it an estimate, and each campaign carries its receiver correction C_r
• receiver_type_before / receiver_type_after: 'hemi_free_field' (Default, 0 dB) or 'reflecting_surface' (6 dB)
• result: insertion_loss_db, method, the four spectra and the two corrections, .plot()
environment.measured_insertion_loss_direct(ref_b, ref_a, rec_b, rec_a, frequencies=f)
barrier_background_correction_db / ISO10847_BACKGROUND_CORRECTIONS_DB / ISO10847_MINIMUM_BACKGROUND_MARGIN_DB / ISO10847_PREFERRED_BACKGROUND_MARGIN_DBfunction / mapping / constantTable 3 of ISO 10847, in decibels to add.
• 2 dB comes off at a margin of 4 or 5 dB, 1 dB from 6 to 9 dB, nothing from 10 dB up, which is the margin 6.4 asks for in the first place
• the column reads "correction to be made to", so the values are negative and are added, where ISO 11820 prints the same physical thing positive and subtracts it
• under 4 dB the results "are not valid", which is a refusal
environment.barrier_background_correction_db([5.0, 7.0]) # -2.0, -1.0
wind_class / WIND_CLASSES / MAXIMUM_WIND_SPEED_M_S / WIND_VECTOR_TOLERANCE_M_S / TEMPERATURE_TOLERANCE_C / CLOUD_COVER_CLASSESfunction / mapping / constantThe weather the two campaigns have to share, ISO 10847 Table 1 and 6.2.
• the vector component of the wind on the source-to-receiver line: positive downwind, negative upwind
• downwind 1 m/s to 5 m/s and calm ± 1 m/s over any distance; the upwind class exists over short distances alone
• past 5 m/s no measurement is made, which is a refusal rather than a class
• the two campaigns must agree within 2 m/s on the component and 10 °C on the temperature, and the cloud cover is recorded in the four classes of Table 2
environment.wind_class(2.5) # 'downwind'
is_short_distance / SHORT_DISTANCE_RATIO / LONG_DISTANCE_M / CLOSE_SOURCE_DISTANCE_M / POINT_SOURCE_DIVERGENCE_DB / LINE_SOURCE_DIVERGENCE_DBfunction / constantShort distance or long? ISO 10847 6.3.1, and what hangs on it.
• (H_s + H_R)/(d₁ + d₂) > 0,1 for the "before" campaign, and both of (H_s + H)/d₁ and (H + H_R)/d₂ > 0,1 for the "after" one
• the inequalities are strict, so exactly 0,1 is not a short distance
• only a short distance may be measured into the wind; beyond 250 m the standard stops claiming the method at all
• 6 dB per doubling for a point source and 3 dB for a line one, the divergence the geometry is read against
environment.is_short_distance(source_height_m=1.0, receiver_height_m=1.5, barrier_height_m=4.0, source_to_barrier_m=10.0, barrier_to_receiver_m=20.0)
reference_microphone_height_m / REFERENCE_MICROPHONE_CLEARANCE_M / REFERENCE_ELEVATION_INCREMENT_DEG / MINIMUM_RECEIVER_HEIGHT_M / MINIMUM_REPETITIONSfunction / constantWhere the two microphones stand, ISO 10847 7.2.2 and 7.3.
• the reference microphone at least 1,5 m above the top edge of the barrier, measured from its highest point where the top is not a straight edge
• for a source region nearer than 15 m the NOTE raises it further, until the elevation angle exceeds the angle to the top by 10°; the NOTE never lowers it, so this returns the higher of H + 1,5 m and d tan(arctan(H/d) + 10°)
• where the top already stands 80° or more above the source region no height reaches the 10°: the clearance is returned and a BarrierInSituWarning emitted
• a receiver stands at 1,2 m or higher, and the measurement is repeated at least three times
environment.reference_microphone_height_m(4.0, source_to_barrier_m=8.0)
hemi_free_field_distance_m / HEMI_FREE_FIELD_DISTANCE_M / HEMI_FREE_FIELD_DISTANCE_FACTOR / RECEIVER_CORRECTIONS_DB / EQUIVALENT_SURROUNDINGS_RADIUS_M / EQUIVALENT_SECTOR_DEGfunction / constant / mappingWhat makes a receiver position a free field, and a site an equivalent one, ISO 10847 8.1.2 and 6.1.
• min(30 m, 2 d) to any vertical reflecting surface, so a receiver close behind the barrier needs less clearance rather than more, the two rules crossing at 15 m
• a microphone against a facade instead carries the 6 dB of RECEIVER_CORRECTIONS_DB
• an equivalent site matches over 30 m around the receiver and over a 60° sector towards the source
environment.hemi_free_field_distance_m(10.0) # 20.0
ISO10847_OCTAVE_BAND_RANGE_HZ / ISO10847_OCTAVE_BAND_EXTENDED_RANGE_HZ / ISO10847_THIRD_OCTAVE_BAND_RANGE_HZ / ISO10847_THIRD_OCTAVE_BAND_EXTENDED_RANGE_HZconstantThe bands ISO 10847 measures in, clause 5.
• 63 Hz to 4 kHz in octaves and 50 Hz to 5 kHz in one-third octaves
• the extended ranges reach 8 kHz and 10 kHz where the source or the barrier asks for them
environment.ISO10847_OCTAVE_BAND_RANGE_HZ # (63.0, 4000.0)
BarrierInSituWarningwarning classThe measurement is outside a condition ISO 10847 states.
• a distance past 250 m, a reference microphone with less clearance than 7.2.2 asks for, a receiver lower than 1,2 m, campaigns whose weather does not match
warnings.catch_warnings()
Emitted by environment.propagation.barrier_in_situ
meteorological_correctionfunctionMeteorological correction Cmet (ISO 9613-2 Eq. 21/22).
• projected_distance dp, source_height hs, receiver_height hr [m]
• c0: factor C₀ [dB]
c = environment.meteorological_correction(200, 1.5, 1.5, 2.0)

• C₀[1 − 10(hs+hr)/dp] ≥ 0 [dB]
outdoor_propagation_attenuationfunctionTotal octave-band attenuation A (ISO 9613-2 Eq. 4).
• distance d, source_height hs, receiver_height hr [m]
• frequencies [Hz]
• ground_source/ground_middle/ground_receiver G
• barrier: Barrier or None
• temperature_c/relative_humidity_percent/atmospheric_pressure_kpa (Default: 20 °C/70 %/101.325 kPa, a Table 2 reference atmosphere)
• projected_distance dp [m]
att = environment.outdoor_propagation_attenuation(200, 2, 2, bands, 1, 1, 1)

• OutdoorAttenuation term breakdown
predicted_receiver_levelfunctionPredicted octave-band receiver level (ISO 9613-2 Eq. 3/6).
• sound_power_level Lw [dB]
• geometry: PropagationGeometry
• frequencies [Hz]
• ground: GroundFactors, barrier: Barrier, atmosphere: AtmosphericConditions
• directivity: DirectivityCorrection
• c0: subtract Cmet (Default: None)
lp = environment.predicted_receiver_level(lw, environment.PropagationGeometry(200, 2, 2), frequencies=bands)

• LfT(DW) = Lw + Dc − A per band [dB]
OutdoorAttenuationdataclassPer-band ISO 9613-2 attenuation breakdown.
• frequencies [Hz]
• a_div, a_atm, a_gr, a_bar [dB]
• a_total = Adiv+Aatm+Agr+Abar [dB]
• d_omega [dB]
• .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
SourceEmissiondataclassSource emission for the receiver-level fiche (ISO 9613-2 Eq. 3), report-time only.
• sound_power_level Lw [dB]
• directivity_index Di [dB] (Default: 0)
• d_omega DΩ [dB] (Default: 0)
• cmet Cmet [dB] (Default: None)
att.report("f.pdf", source_emission=environment.SourceEmission(lw))
PropagationGeometrydataclassSource-to-receiver geometry of the ISO 9613-2 path.
• distance d [m]
• source_height hs, receiver_height hr [m]
• projected_distance dp [m] (Default: None → √(d²−(hs−hr)²))
PropagationGeometry(200.0, 1.5, 1.5)
GroundFactorsdataclassGround factors G of the three regions (ISO 9613-2 7.3.1).
• source Gs, middle Gm, receiver Gr ∈ [0,1] (Default: 0, hard ground)
GroundFactors(1.0, 1.0, 1.0) # porous
AtmosphericConditionsdataclassAir state behind Aatm (ISO 9613-2 Eq. 8).
• temperature_c [°C] (Default: 20)
• relative_humidity_percent [%] (Default: None → 70)
• atmospheric_pressure_kpa [kPa] (Default: 101.325)
AtmosphericConditions(temperature_c=15.0)
DirectivityCorrectiondataclassDirectivity correction Dc = Di + DΩ (ISO 9613-2 Eq. 3).
• index Di [dB] (Default: 0)
• d_omega DΩ [dB] (Default: 0)
DirectivityCorrection(index=3.0)
DEFAULT_FREQUENCIEStupleISO 9613-2 nominal octave bands.
(no parameters)
DEFAULT_FREQUENCIES # (63, …, 8000)
railway_source_powerfunctionCNOSSOS-EU railway source line power at the two source heights (Directive 2002/49/EC Annex II, 2.3.1).
• traffic: one RailwayVehicle or a sequence
• track: the RailwayTrack of the section
• psi/phi [deg]: receiver angles (Default: 0 / 90, broadside)
• reference_time Tref (Default: 12)
• minimum_speed [km/h] (Default: 50, or 30 for a tram; 0 switches the floor off)
• interpolation (RoughnessInterpolation), directivity_edition (DirectivityEdition)
res = environment.railway_source_power(environment.RailwayVehicle(stock, 96.0, 160.0), track)

• RailwayEmissionResult
RailwayEmissionResultdataclassCNOSSOS-EU railway source-line power per metre.
• third_octave_frequencies (50…10000 Hz), frequencies (63…8000 Hz)
• heights (0.5, 4.0) m
• third_octave_line_power (2, 24), line_power (2, 8) [dB re 1 pW/m]
• total_line_power (8,)
• components: rolling / traction / aerodynamic / bridge, per height
• .plot()
res.total_line_power, res.components["rolling"]
RailwayVehicledataclassOne vehicle of the traffic on a track section.
• stock: RollingStock
• flow_rate Q [veh/h], speed v [km/h]
• condition: RunningCondition
• idling_time Tidle
RailwayVehicle(stock, flow_rate=96.0, speed=160.0)
RollingStockdataclassAppendix G data of one vehicle type.
• axles Na
• wheel_roughness, contact_filter: (wavelengths [mm], levels [dB])
• wheel_transfer, superstructure_transfer: 24 bands [dB/axle]
• traction, aerodynamic: (source A, source B)
• aerodynamic_alpha (Default: 50)
• tram (Default: False)
RollingStock(axles=4, wheel_roughness=..., ...)
RailwayTrackdataclassAppendix G data of one track section.
• rail_roughness, impact_roughness: (wavelengths [mm], levels [dB])
• track_transfer, bridge_transfer: 24 bands [dB/axle]
• joint_density nl [1/m] (Default: 0.01)
• squeal_excess [dB], length L [m] (Default: 100)
RailwayTrack(rail_roughness=..., track_transfer=...)
roughness_to_frequencyfunctionResample a roughness spectrum from wavelength onto frequency, λ = v/f with v in m/s (Annex II 2.3.2 as corrected in 2018).
• levels [dB], wavelengths [mm], speed [km/h]
• frequencies [Hz], interpolation
lr = environment.roughness_to_frequency(levels, lam, 160.0)
total_effective_roughnessfunctionTotal effective roughness LR,TOT (Annex II 2.3.7).
• rail, wheel, filter_: 24 bands [dB]
ltot = environment.total_effective_roughness(rail, wheel, a3)

• 10 lg(10^(LrTR/10)+10^(LrVEH/10)) + A3
impact_roughnessfunctionImpact roughness at a joint density (Annex II 2.3.12).
• single: Table G-4 on the frequency grid [dB]
• joint_density nl [1/m]
li = environment.impact_roughness(single, 0.03)

• + 10 lg(nl/0.01)
rolling_sound_powerfunctionOne rolling-noise component (Annex II 2.3.8 to 2.3.10).
• roughness LR,TOT, transfer LH [dB]
• axles Na
lw = environment.rolling_sound_power(ltot, environment.track_transfer("M/M"), 4)

• LR,TOT + LH + 10 lg(Na)
curve_squeal_excessfunctionCurve-squeal excess added to rolling noise (as replaced by (EU) 2021/1226 pt (4)(b)).
• radius R [m]
• tram, turnout (Default: False)
• track_length ltrack [m] (Default: 50)
curve_squeal_excess(280.0) # 8.0 dB
horizontal_directivityfunctionHorizontal dipole directivity (Annex II 2.3.15).
• phi [deg]
• frequencies [Hz]
horizontal_directivity(90.0) # 0 dB broadside
vertical_directivityfunctionVertical directivity of source A or B (Annex II 2.3.16/2.3.17).
• psi [deg], frequencies [Hz]
• height 1 or 2
• aerodynamic (height 2 only)
• edition: DirectivityEdition
vertical_directivity(30.0)
aerodynamic_sound_powerfunctionAerodynamic sound power at a speed (Annex II 2.3.13/2.3.14 with Table G-6).
• speed v [km/h] (Default: 300)
• reference: (source A, source B) at v0
• alpha (Default: 50)
low, high = environment.aerodynamic_sound_power(320.0)
octave_bands_from_third_octavesfunctionEnergy-sum 24 1/3-octave levels into the 8 octave bands (Annex II 2.3.2).
• levels [dB]
octave_bands_from_third_octaves(res.third_octave_line_power[0])
wheel_roughnessfunctionWheel roughness Lr,VEH of Table G-1a.
• brake: BrakeType
lam, lr = environment.wheel_roughness(BrakeType.NON_TREAD)
rail_roughnessfunctionRail roughness Lr,TR of Table G-1b (as replaced by (EU) 2021/1226).
• roughness: RailRoughnessClass (only E and M are tabulated)
lam, lr = environment.rail_roughness(RailRoughnessClass.NORMAL)
contact_filterfunctionContact filter A3 of Table G-2 (as replaced by (EU) 2021/1226).
• filter_: ContactFilter or (wheel load [kN], wheel diameter [mm])
lam, a3 = environment.contact_filter(ContactFilter.LOAD_50_DIAMETER_920)
track_transferfunctionTrack transfer function LH,TR of Table G-3a (as replaced by (EU) 2021/1226).
• track: TrackTransferClass or its column code
track_transfer("M/M") # 24 bands [dB/axle]
wheel_transferfunctionWheel transfer function LH,VEH of Table G-3b.
• diameter_mm: WheelDiameter or the diameter_mm [mm]
wheel_transfer(920.0)
superstructure_transferfunctionSuperstructure transfer LH,VEH,SUP of Table G-3c (freight only; 0,0 dB everywhere).
(no parameters)
superstructure_transfer()
impact_roughness_singlefunctionSingle-impact roughness of Table G-4 (as replaced by (EU) 2021/1226), for nl = 0,01 per m.
(no parameters)
lam, li = environment.impact_roughness_single()
traction_sound_powerfunctionTraction sound power of Table G-5; constant speed and idling are equal.
• vehicle: TractionVehicle
low, high = environment.traction_sound_power(TractionVehicle.ELECTRIC_LOCO)
bridge_transferfunctionBridge transfer function LH,bridge of Table G-7 (as replaced by (EU) 2021/1226).
• bridge: BridgeType
bridge_transfer(BridgeType.PLUS_10_DBA)
VehicleDescriptordataclassFour-digit vehicle descriptor of Table [2.3.a].
• vehicle_type, axles, brake, measure
• .from_code(), .code
VehicleDescriptor.from_code("a4cn")
TrackDescriptordataclassSix-digit track descriptor of Table [2.3.b].
• base, roughness, pad, measure, joints, curvature
• .from_code(), .code
TrackDescriptor.from_code("BMSNNH")
VehicleTypeenumDigit 1 of the vehicle descriptor.
HIGH_SPEED (h), SELF_PROPELLED (m), HAULED (p), CITY_TRAM (c), DIESEL_LOCO (d), ELECTRIC_LOCO (e), FREIGHT (a), OTHER (o)
VehicleType.FREIGHT
BrakeTypeenumDigit 3 of the vehicle descriptor.
CAST_IRON (c), COMPOSITE (k), NON_TREAD (n)
BrakeType.CAST_IRON
WheelMeasureenumDigit 4 of the vehicle descriptor.
NONE (n), DAMPERS (d), SCREENS (s), OTHER (o)
WheelMeasure.DAMPERS
TrackBaseenumDigit 1 of the track descriptor.
BALLAST (B), SLAB (S), BALLASTED_BRIDGE (L), NON_BALLASTED_BRIDGE (N), EMBEDDED (T), OTHER (O)
TrackBase.BALLAST
RailRoughnessClassenumDigit 2 of the track descriptor.
WELL_MAINTAINED (E), NORMAL (M), NOT_WELL_MAINTAINED (N), BAD (B)
RailRoughnessClass.NORMAL
RailPadenumDigit 3 of the track descriptor, the rail-pad dynamic stiffness.
SOFT (S, 150-250 MN/m), MEDIUM (M, 250-800 MN/m), HARD (H, 800-1 000 MN/m)
RailPad.MEDIUM
TrackMeasureenumDigit 4 of the track descriptor.
NONE (N), RAIL_DAMPER (D), LOW_BARRIER (B), ABSORBER_PLATE (A), EMBEDDED_RAIL (E), OTHER (O)
TrackMeasure.RAIL_DAMPER
RailJointsenumDigit 5 of the track descriptor.
NONE (N), SINGLE (S), TWO (D), MORE (M)
RailJoints.SINGLE
TrackCurvatureenumDigit 6 of the track descriptor.
STRAIGHT (N), LOW (L), MEDIUM (M), HIGH (H)
TrackCurvature.HIGH
TrackTransferClassenumColumns of Table G-3a (track base / rail pad).
MONOBLOCK_SOFT, MONOBLOCK_MEDIUM, MONOBLOCK_HARD, BIBLOCK_SOFT, BIBLOCK_MEDIUM, BIBLOCK_HARD, WOODEN, DIRECT_FASTENING
TrackTransferClass.WOODEN
WheelDiameterenumColumns of Table G-3b, the wheel diameter [mm].
MM_920, MM_840, MM_680, MM_1200
WheelDiameter.MM_920
ContactFilterenumColumns of Table G-2, (wheel load [kN], wheel diameter [mm]).
LOAD_50_DIAMETER_360, LOAD_50_DIAMETER_680, LOAD_50_DIAMETER_920, LOAD_25_DIAMETER_920, LOAD_100_DIAMETER_920
ContactFilter.LOAD_25_DIAMETER_920
TractionVehicleenumColumns of Table G-5.
DIESEL_LOCO_800, DIESEL_LOCO_2200, DIESEL_MULTIPLE_UNIT, ELECTRIC_LOCO, ELECTRIC_MULTIPLE_UNIT
TractionVehicle.DIESEL_LOCO_2200
BridgeTypeenumColumns of Table G-7, labelled by the A-weighted bridge excess.
PLUS_10_DBA, PLUS_15_DBA
BridgeType.PLUS_15_DBA
RunningConditionenumRunning condition c of Annex II 2.3.2.
CONSTANT (1), IDLING (2)
RunningCondition.IDLING
DirectivityEditionenumWhich text of the vertical directivity (2.3.16) to evaluate.
CURRENT ((EU) 2021/1226: zero for ψ ≤ 0), ORIGINAL_2015 (absolute-value bars over the whole range)
DirectivityEdition.ORIGINAL_2015
RoughnessInterpolationenumHow a roughness spectrum is resampled from wavelength onto frequency (Annex II gives prose, not a formula).
PROPORTIONAL (levels, the Commission reference module's rule), ENERGY (energies)
RoughnessInterpolation.ENERGY
RAILWAY_THIRD_OCTAVE_BANDStupleThe 24 1/3-octave bands of the railway source (50 Hz…10 kHz).
(no parameters)
RAILWAY_THIRD_OCTAVE_BANDS
RAILWAY_OCTAVE_BANDStupleThe 8 octave bands handed to propagation (63 Hz…8 kHz).
(no parameters)
RAILWAY_OCTAVE_BANDS
RAILWAY_SOURCE_HEIGHTStupleHeights of the two equivalent source lines (Annex II 2.3.1).
(no parameters)
RAILWAY_SOURCE_HEIGHTS # (0.5, 4.0)
RAILWAY_MINIMUM_SPEEDfloatSpeed floor used to determine the total effective roughness [km/h].
(no parameters)
RAILWAY_MINIMUM_SPEED # 50.0
TRAM_MINIMUM_SPEEDfloatThe same floor for trams and light metro [km/h].
(no parameters)
TRAM_MINIMUM_SPEED # 30.0
AERODYNAMIC_THRESHOLD_SPEEDfloatSpeed above which aerodynamic noise is relevant [km/h].
(no parameters)
AERODYNAMIC_THRESHOLD_SPEED # 200.0
AERODYNAMIC_REFERENCE_SPEEDfloatReference speed v0 of Annex II 2.3.13/2.3.14 [km/h].
(no parameters)
AERODYNAMIC_REFERENCE_SPEED # 300.0
REFERENCE_JOINT_DENSITYfloatJoint density Table G-4 is given for [1/m].
(no parameters)
REFERENCE_JOINT_DENSITY # 0.01
road_source_powerfunctionCNOSSOS-EU road source line power (Directive 2002/49/EC Annex II, 2.2.1).
• traffic: one RoadTraffic or a sequence, at most one per category
• surface: RoadSurface, its description or a RoadSurfaceCoefficients (Default: reference surface)
• temperature_c tau [°C] (Default: 20)
• road_slope_percent s [%] (Default: 0, positive uphill)
• studded_months Ts (Default: 0)
• junction_distance x [m], junction_type (JunctionType)
• coefficients: Appendix F database (Default: ROAD_COEFFICIENTS)
res = environment.road_source_power([environment.RoadTraffic(RoadVehicleCategory.LIGHT, 1200, 50)])

• RoadEmissionResult
RoadTrafficdataclassTraffic of one vehicle category on a source line.
• category: RoadVehicleCategory
• flow_rate Qm [veh/h]
• speed vm [km/h] (powers frozen below 20 km/h)
• studded_fraction Qstud,ratio (Default: 0, category 1 only)
RoadTraffic(RoadVehicleCategory.HEAVY, 45.0, 50.0)
RoadEmissionResultdataclassCNOSSOS-EU road source-line power per metre.
• frequencies [Hz] (63…8000)
• categories
• rolling, propulsion, vehicle_power, line_power: (N_cat, 8) [dB]
• total_line_power [dB re 1 pW/m]
• source_height (0.05 m)
• .a_weighted_line_power [dB(A)]
• .plot()
res.total_line_power, res.a_weighted_line_power
road_vehicle_sound_powerfunctionSingle-vehicle sound power LW,i,m (Annex II 2.2.2/2.2.3).
• category, speed [km/h]
• same surface/temperature/gradient/studded/junction parameters as road_source_power
lw = environment.road_vehicle_sound_power("1", 90.0)

• 8 octave bands [dB]; category 4 takes propulsion alone
road_rolling_noisefunctionRolling-noise sound power LWR,i,m (Annex II 2.2.4/2.2.5).
• category, speed [km/h]
• surface, temperature_c, studded_fraction, studded_months, junction_distance, junction_type, coefficients
lwr = environment.road_rolling_noise("1", 90.0, temperature_c=5.0)

• AR + BR·lg(v/70) + ΔLWR per band
road_propulsion_noisefunctionPropulsion-noise sound power LWP,i,m (Annex II 2.2.11/2.2.12).
• category, speed [km/h]
• surface, road_slope_percent, junction_distance, junction_type, coefficients
lwp = environment.road_propulsion_noise("3", 80.0, road_slope_percent=-8.0)

• AP + BP·(v−70)/70 + ΔLWP per band
road_surface_coefficientsfunctionTable F-4 row of a road surface (as replaced by (EU) 2021/1226).
• surface: RoadSurface or its description
row = environment.road_surface_coefficients(RoadSurface.THIN_LAYER_A)

• RoadSurfaceCoefficients
RoadSurfaceCoefficientsdataclassOne Table F-4 row.
• name
• alpha: per category, 8 bands [dB]
• beta: per category
• speed_range (vmin, vmax) [km/h] or None
row.alpha["1"], row.beta["1"], row.speed_range
RoadEmissionCoefficientsdataclassAppendix F database (Tables F-1 to F-3 + Km).
• rolling_a/rolling_b/propulsion_a/propulsion_b: per category, 8 bands
• studded_a/studded_b (Table F-2)
• junction_c (Table F-3)
• temperature_k Km [dB/°C]
ROAD_COEFFICIENTS.rolling_a["1"]
ROAD_COEFFICIENTSdataclassThe consolidated Appendix F database.
Tables F-1/F-4 as replaced by (EU) 2021/1226, F-2/F-3 as published in (EU) 2015/996
ROAD_COEFFICIENTS.propulsion_a["3"]
RoadVehicleCategoryenumVehicle categories of Table [2.2.a].
LIGHT (1), MEDIUM_HEAVY (2), HEAVY (3), MOPEDS (4a), MOTORCYCLES (4b)
RoadVehicleCategory.HEAVY.value # '3'
RoadSurfaceenumThe fifteen road surfaces of Table F-4.
REFERENCE, ONE_LAYER_ZOAB, TWO_LAYER_ZOAB, TWO_LAYER_ZOAB_FINE, SMA_NL5, SMA_NL8, BRUSHED_DOWN_CONCRETE, OPTIMISED_BRUSHED_DOWN_CONCRETE, FINE_BROOMED_CONCRETE, WORKED_SURFACE, HARD_ELEMENTS_HERRINGBONE, HARD_ELEMENTS_NOT_HERRINGBONE, QUIET_HARD_ELEMENTS, THIN_LAYER_A, THIN_LAYER_B
RoadSurface.QUIET_HARD_ELEMENTS
JunctionTypeenumJunction types k of Table F-3.
NONE (0), CROSSING (1), ROUNDABOUT (2)
JunctionType.ROUNDABOUT
line_source_segment_powerfunctionPoint-source power of a segment of source line (arithmetic; the split is outside the scope of Annex II 2.5.3).
• line_power [dB re 1 pW/m]
• length dL [m]
lw = environment.line_source_segment_power(res.total_line_power, 20.0)

• L'W,eq,line + 10 lg(dL)
CNOSSOS_A_WEIGHTINGtupleOctave-band A-weighting AWCf,i printed by Annex II 2.5.5 as amended by (EU) 2021/1226.
(no parameters)
CNOSSOS_A_WEIGHTING # (-26.2, …, -1.1)
ROAD_OCTAVE_BANDStupleCNOSSOS-EU road source octave bands (63 Hz…8 kHz, per the 2018 corrigendum to 2.2.1).
(no parameters)
ROAD_OCTAVE_BANDS
ROAD_REFERENCE_SPEED / ROAD_REFERENCE_TEMPERATURE / ROAD_SOURCE_HEIGHTfloatReference conditions of Annex II 2.2.
vref = 70 km/h, tauref = 20 °C, source height 0,05 m
ROAD_REFERENCE_SPEED # 70.0
statistical_pass_byfunctionStatistical Pass-By method of a road surface (ISO 11819-1:1997, 9.1 to 9.5).
• vehicle_categories ("1" cars, "2a" dual-axle, "2b" multi-axle heavy) / speeds_kmh / max_levels_db (LAFmax): one row per pass-by
• road_speed_category: "low"|"medium"|"high" (Table 1 reference speeds and weights)
• corrected_vehicle_sound_levels_db: temperature-corrected L_veh (9.4 gives no method)
• reference_db: reference surface SPBI or its three L_veh (clause 10)
• weighting_factors: other proportions, summing to 1
• 7.3 counts and 9.3 speed windows emit StatisticalPassByWarning
res = environment.statistical_pass_by(cats, v, L, road_speed_category="medium")

• StatisticalPassByResult
StatisticalPassByResultdataclassVehicle sound levels and index of one surface.
• regressions (per category) / vehicle_sound_levels_db / index_db (unrounded)
• reported_vehicle_sound_levels_db / reported_index_db (one decimal, half up)
• corrected_index_db / reference_index_db / .difference_db / .corrected_difference_db
• .index_confidence_interval_db / .meets_minimum_counts / .reference_speeds_in_window
• .plot(): the three clouds, their lines and L_veh
res.reported_index_db
pass_by_regressionfunctionLeast-squares line of LAFmax on lg v for one category, read at the reference speed (9.1, 9.2).
• speeds_kmh / max_levels_db
• vehicle_category / road_speed_category
reg = environment.pass_by_regression(v, L, vehicle_category="1", road_speed_category="medium")

• PassByRegression
PassByRegressiondataclassOne category's line and the clause 13 item 29 statistics.
• intercept_db / slope_db_per_decade / correlation
• level_standard_deviation_db / residual_standard_deviation_db (n − 2) / lg_speed_standard_deviation
• .vehicle_sound_level_db / .reported_vehicle_sound_level_db / .mean_speed_kmh (10^mean lg v)
• .speed_window_kmh / .reference_speed_in_window (9.3) / .meets_minimum_count (7.3)
• .confidence_interval_db (95 %, Student t) / .plot()
reg.vehicle_sound_level_db
statistical_pass_by_indexfunctionSPBI of three vehicle sound levels (9.5).
• vehicle_sound_levels_db: keyed "1", "2a", "2b"
• road_speed_category / weighting_factors
environment.statistical_pass_by_index({"1": 78.5, "2a": 81.1, "2b": 83.8}, road_speed_category="medium") # 79.946…
normalized_reference_levelsfunctionL_veh of a normalized reference surface: the average of several surfaces (10.2, Annex D).
• surface_levels_db: surface label → the three L_veh
normalized_reference_levels(SPB_ANNEX_D_SURFACES_DB)
StatisticalPassByWarningwarning classISO 11819-1 advisory.
Emitted when a category falls short of the 7.3 minimum count or its reference speed leaves the 9.3 window
warnings.simplefilter('error', StatisticalPassByWarning)
SPB_REFERENCE_SPEEDS_KMH / SPB_WEIGHTING_FACTORSmappingTable 1: reference speeds [km/h] and weighting factors Wx, by road speed then vehicle category.SPB_REFERENCE_SPEEDS_KMH["medium"]["1"] # 80.0
SPB_VEHICLE_STANDARD_DEVIATIONS_DB / SPB_CONFIDENCE_INTERVALS_DBmappingTable 2: expected spread of individual vehicles about L_veh and the 95 % interval it leaves [dB].SPB_CONFIDENCE_INTERVALS_DB["1"] # 0.3
SPB_MINIMUM_VEHICLE_COUNTS / SPB_SPEED_WINDOW_STANDARD_DEVIATIONSmapping7.3 minimum vehicles for classification ("2" is 2a and 2b together) and the 9.3 window in standard deviations of speed.SPB_MINIMUM_VEHICLE_COUNTS["2"] # 80
SPB_ANNEX_D_SURFACES_DB / SPB_NORMALIZED_REFERENCE_DBmappingAnnex D: the seven surfaces of the example reference case and their average row [dB], medium speed range.SPB_NORMALIZED_REFERENCE_DB["2b"] # 84.0
SPB_VEHICLE_CATEGORIES / SPB_ROAD_SPEED_CATEGORIESconstantThe category labels the method uses: ("1", "2a", "2b") and ("low", "medium", "high").SPB_VEHICLE_CATEGORIES
SPB_REFERENCE_AIR_TEMPERATURE_Cfloat9.4: the air temperature L_veh should be corrected to [°C].SPB_REFERENCE_AIR_TEMPERATURE_C # 20.0
ground_effectfunctionSpherical-wave ground effect ΔL (Weyl-Van der Pol; Attenborough 2e Eq. 2.40, Salomons Eq. 3.4).
• frequencies [Hz], source_height hs, receiver_height hr, distance [m]
• impedance (normalized) or flow_resistivity σ [Pa·s/m²]
• model 'delany_bazley'/'miki'
r = environment.ground_effect(bands, 1, 1.5, 50, flow_resistivity=2e5)

• SphericalGroundResult (ΔL, Q, Rp, F)
GroundSurfacedataclassOne ground surface as one published table prints it.
• flow_resistivity_pa_s_m2 is an effective resistivity: the number that makes a rigid-framed ground model reproduce a measured attenuation, so it carries the fit it came from
• porosity (a fraction), water_content_percent, porosity_decay_rate_per_m: what Cox tabulates beside it; the six porosities Cox prints in per cent in a column of fractions are None, and .why_missing('porosity') quotes them
• iso_9613_ground_factor, nmpb_ground_factor, harmonoise_class: the class rows, where the two models disagree on two of the eight classes
• The hedges every catalogue row has: ranges, reported, unquantified, uncertainty, approximate, variant
g = environment.PUBLISHED_GROUND['bies-2017-table-5-1/sugar_snow']
g.printed('flow_resistivity_pa_s_m2')

• g.source prints the page
PUBLISHED_GROUNDmappingA hundred and five ground surfaces from three published tables, keyed '<table>/<row>'.
• Bies 5e Table 5.1, thirty-four measured surfaces, and Table 5.2, the eight classes A to H with the ISO 9613-2 and NMPB-2008 ground factors
• Cox & D'Antonio 3e Table 6.7, sixty-three rows: the same surface fitted with three different models is three rows, because the fit is part of the quantity
• Seven surfaces both books take from Embleton (1983) come out to the same digits through two different printed units
• One cell of Cox prints 1.7.3 × 10⁵, with two decimal points; it is kept as the page printed it and answers None
environment.PUBLISHED_GROUND['bies-2017-table-5-2/normal_uncompacted_ground']

• GroundSurface, ground_surfaces_named
ground_surfaces_namedfunctionEvery published row for a surface name, across the books.
• name as a table prints it, matched without regard to case
• Returns every reading rather than choosing one: the spread between books is the answer
environment.ground_surfaces_named('Sugar snow')

• (GroundSurface, ...)
spherical_reflection_coefficientfunctionSpherical-wave reflection coefficient Q = Rp + (1−Rp)F(w) (Attenborough Eq. 2.40c; Salomons Eq. D.58).
• frequencies, normalized_impedance, source_height, receiver_height, distance
q = environment.spherical_reflection_coefficient(bands, 12-6j, 1, 1.5, 50)
SphericalGroundResultdataclassSpherical-wave ground-effect result.
• excess_attenuation ΔL [dB re free field]
• reflection_coefficient Q, plane_reflection_coefficient Rp, boundary_loss F
• r_direct, r_reflected [m]
• .plot()
r.excess_attenuation, r.reflection_coefficient
fresnel_numberfunctionBarrier Fresnel number N = (2/λ)(A+B−d) (Bies 5e Eq. 5.134).
• source_to_edge A, edge_to_receiver B, direct_distance d [m]
• frequencies [Hz]
n = environment.fresnel_number(101, 101, 200, bands)
kurze_anderson_attenuationfunctionKurze-Anderson barrier attenuation (Bies Eq. 5.138).
• fresnel_number N
kurze_anderson_attenuation(0.0) # 5 dB
barrier_insertion_lossfunctionBarrier insertion loss: Kurze-Anderson / exact half-plane / coherent ground four-path (Attenborough Ch. 9, Bies 5.3.5-5.3.7).
• frequencies, source_height, barrier_distance, barrier_height, receiver_distance, receiver_height
• method 'exact'/'kurze_anderson'
• thickness e [m] (thick barrier)
• ground_impedance or ground_flow_resistivity
il = environment.barrier_insertion_loss(bands, 1, 50, 4, 100, 1.5, ground_flow_resistivity=2e5)

• BarrierInsertionLoss
TRAFFIC_NOISE_BANDS_HZ / NORMALISED_TRAFFIC_NOISE_SPECTRUM_DB / NORMALISED_RAILWAY_NOISE_SPECTRUM_DB / SPECTRAconstantThe eighteen one-third octave bands from 100 Hz to 5 kHz, and the two spectra a device is rated against: EN 1793-3 Table 1 for a road and EN 16272-3-1 Table 1 for a railway. SPECTRA maps 'road' and 'railway' to them.environment.NORMALISED_TRAFFIC_NOISE_SPECTRUM_DB[10] # -8.0 dB at 1 kHz
sound_absorption_rating / airborne_insulation_ratingfunctionEN 1793-1 Clause 5, EN 1793-2 Clause 5.2 and EN 16272-3-1 Clauses 5 and 6: what a noise reducing device is declared by.
• sound_absorption_rating(absorption_coefficients, spectrum='road'): DLα, the energy the device does not send back, capped by the 0,99 ratio limit both standards put on it
• airborne_insulation_rating(sound_reduction_index_db, spectrum='road'): DL_R, the energy it does not pass
• spectrum='railway' swaps in EN 16272-3-1 Clauses 5 and 6, which are the same formulas on the railway table and print no category ladder
• both return a RoadDeviceRating carrying the unrounded value, the reported integer and, for a road device, its Annex A category
environment.airborne_insulation_rating([32.0] * 18).category # 'B3'
RoadDeviceRatingdataclassOne declared rating: rating, reported, category (None for a railway device), quantity, spectrum, bands_hz, values, weights.
• .plot() draws the per-band input against the spectrum that weights it
rating.plot()
ABSORPTION_RATIO_LIMIT / ABSORPTION_CATEGORIES / INSULATION_CATEGORIESconstantThe 0,99 ceiling of EN 1793-1 Clause 5, and the two Annex A category ladders (A1 to A5, B1 to B4) read off the reported integer.environment.ABSORPTION_RATIO_LIMIT # 0.99
RoadDeviceWarningwarning classEmitted when the weighted absorption ratio reaches the 0,99 limit, so the rating is the limit rather than the measurement.warnings.catch_warnings()
plot_barrier_geometryfunctionSource-barrier-receiver section to scale.
• source_height, barrier_distance, barrier_height, receiver_distance, receiver_height [m]
• thickness [m] (Default: None → thin screen)
• language
plot_barrier_geometry(source_height=1.5, barrier_distance=5.0, barrier_height=3.0, receiver_distance=20.0, receiver_height=1.5)

• Direct + diffracted paths, path difference annotated; also BarrierInsertionLoss.plot_geometry()
BarrierInsertionLossdataclassPer-band barrier insertion loss.
• insertion_loss [dB], fresnel_number, method, ground
• .plot() (IL vs frequency)
il.insertion_loss
linear_sound_speed_profilefunctionLinear effective sound-speed profile c_eff(z) = c0 + g·z (Salomons Sec. 4.2).
• gradient_per_s g [s⁻¹]
• ground_speed c0 [m/s], max_height [m]
p = environment.linear_sound_speed_profile(0.1)

• EffectiveSoundSpeedProfile
log_linear_sound_speed_profilefunctionLogarithmic surface-layer profile c_eff(z) = c0 + b·ln(1+z/z0) (Salomons Eq. 4.5).
• b [m/s] (downward > 0)
• ground_speed c0, roughness_length z0, max_height [m], n_points
p = environment.log_linear_sound_speed_profile(1.0)

• EffectiveSoundSpeedProfile
EffectiveSoundSpeedProfiledataclassEffective sound-speed profile c_eff(z).
• heights z [m], sound_speeds [m/s], description
• .speed_at(z), .plot()
p.speed_at(10.0)
ray_curvature_radiusfunctionRadius of curvature of a ray in a linear gradient_per_s Rc = c0/(|g| cos θ0) (Salomons Sec. 4.4).
• gradient_per_s g [s⁻¹]
• ground_speed c0 [m/s], launch_angle_deg θ0
ray_curvature_radius(0.1) # 3430 m
shadow_zone_distancefunctionShadow-boundary distance in upward refraction √(2Rc)(√hs+√hr) (Salomons Sec. 4.4).
• gradient_per_s g < 0 [s⁻¹]
• source_height hs, receiver_height hr [m]
• ground_speed c0
shadow_zone_distance(-0.1, 2, 2)
atmospheric_ray_pathsfunctionRay tracing through a refracting atmosphere (Snell's law, Salomons Eq. 4.3).
• profile: EffectiveSoundSpeedProfile
• source_height [m], launch_angles_deg
• max_range [m], n_steps
r = environment.atmospheric_ray_paths(p, source_height=2, launch_angles_deg=[-2,0,2])

• AtmosphericRayResult
AtmosphericRayResultdataclassRay-tracing solution.
• ranges, heights, travel_times [s]
• turning_points, ground_reflections
• .plot() (ray paths)
r.heights, r.turning_points
atmospheric_parabolic_equationfunctionRelative-level field from the Green's Function PE (Salomons App. H).
• frequency_hz, profile, source_height [m]
• impedance or flow_resistivity σ, model
• max_range/max_height/range_step/height_step [m]
pe = environment.atmospheric_parabolic_equation(500, p, source_height=2, flow_resistivity=2e5)

• AtmosphericPEResult
AtmosphericPEResultdataclassGFPE relative-level field (dB re free field).
• ranges, heights, relative_level (z×r)
• normalized_impedance
• .level_at_height(z), .plot()
pe.level_at_height(2.0)
task_based_exposurefunctionTask-based daily exposure LEX,8h + U (ISO 9612 Clause 9).
• tasks: sequence of Task
• instrument: 'class1'/'class2'/'personal_exposimeter' (Default)
• u3 [dB] (Default: 1.0)
• include_duration_uncertainty (Default: True)
• warn (Default: True)
res = hearing.task_based_exposure(tasks)

• ExposureResult with per-task breakdown
job_based_exposurefunctionJob-based daily exposure LEX,8h + U (ISO 9612 Clause 10).
• samples Lp,A,eqT [dB]
• effective_duration_hours Te [h]
• instrument, u3
• n_workers/sample_duration_hours: Table 1 check
res = hearing.job_based_exposure(samples, 7.5)

• ExposureResult (Eq C.9 / Table C.4 budget)
full_day_exposurefunctionFull-day daily exposure LEX,8h + U (ISO 9612 Clause 11).
• samples whole-day Lp,A,eqT [dB]
• effective_duration_hours Te [h]
• instrument, u3, warn
res = hearing.full_day_exposure(samples, 9.25)

• ExposureResult; 3 samples spanning ≥3 dB advise
TaskdataclassOne task of a task-based measurement (ISO 9612 Clause 9).
• samples [dB], duration_hours [h]
• duration_samples/duration_range (for u1b)
• label, instrument
Task(samples=(80.1, 82.2), duration_hours=5.0)
ExposureResultdataclassDaily exposure and uncertainty (ISO 9612).
• lex_8h [dB]
• combined_standard_uncertainty u [dB]
• expanded_uncertainty U = 1.65 u [dB]
• upper_limit = LEX,8h + U [dB]
• strategy, sampling_advisory, instrument, tasks
• .report(path, ...): ISO 9612 Clause 15 measurement report with the Directive 2003/10/EC assessment → PDF
res.report("lex.pdf", metadata=ReportMetadata(client="..."))
TaskContributiondataclassPer-task breakdown inside ExposureResult.tasks (ISO 9612 Clause 9).
• label, lp_aeqt (Eq. 7), duration_hours
• lex_8h_contribution (Eq. 8) [dB]
• uncertainty terms u1a, u1b, c1a, c1b, u2, u3
res.tasks[0].lex_8h_contribution
table_c4_contributionfunctionSampling contribution c₁u₁ [dB] from Table C.4 (ISO 9612 job/full-day).
• n_samples: N (clamped to [3, 30])
• u1: sampling standard uncertainty [dB]
• bilinear interpolation, anchored at u₁ = 0
table_c4_contribution(6, 2.0) # 1.4
minimum_cumulative_duration_hoursfunctionMinimum cumulative measurement duration [h] (ISO 9612 Table 1).
• n_workers: group size n_G (> 40 → 17 h; the standard advises splitting the group)
minimum_cumulative_duration_hours(18) # 10.75
COVERAGE_FACTORfloatISO 9612 coverage factor k = 1.65 (Clause 14).
One-sided 95 % confidence: U = 1.65 u, upper limit LEX,8h + U
COVERAGE_FACTOR # 1.65
real_ear_attenuationfunctionThe attenuation of a protector on a panel of subjects, its spread and its uncertainty (ISO 4869-1 4.6 and Annex A).
• attenuation_db: (subjects, bands) individual attenuations [dB], or open_threshold_db with occluded_threshold_db (4.6.2: occluded minus open)
• frequencies [Hz] (Default: 125 Hz to 8 kHz for seven bands, from 63 Hz for eight)
• u = s/√N, U95 = 2u, at full precision
r = hearing.real_ear_attenuation(grid)

• RealEarAttenuationResult; r.attenuation_db feeds assumed_protection_value, hml_rating and snr_rating unchanged
RealEarAttenuationResultdataclassISO 4869-1 measurement.
• attenuation_db, mean_db, standard_deviation_db, standard_uncertainty_db, expanded_uncertainty_db [dB]
• frequencies [Hz], subjects
• .plot(): mean attenuation downwards on the IEC 60263 grid, Clause 6 l)
r.expanded_uncertainty_db
assess_attenuation_differencefunctionDo two attenuation measurements differ significantly? (ISO 4869-1 Annex B).
• first, second: a RealEarAttenuationResult or its means [dB]
• first_expanded_uncertainty_db, second_expanded_uncertainty_db: U95 for bare means [dB]
• significant when |m1 − m2| > √(U95,1² + U95,2²)
d = hearing.assess_attenuation_difference(r1, r2)

• AttenuationDifferenceResult (difference_db, criterion_db, significant, significant_frequencies, .plot())
AttenuationDifferenceResultdataclassAnnex B verdict per band.
• difference_db, criterion_db [dB], significant per band, any_significant
• no truth value: read significant
• .plot()
d.significant_frequencies
minimum_significant_differencefunction√2·U95, the minimum difference for two equal uncertainties (ISO 4869-1 B.1.1, B.2).
• expanded_uncertainty_db [dB], a number or an array
• B.1.1 feeds it the rounded 2,3 dB of Table A.2 and prints 3,3 dB
hearing.minimum_significant_difference(2.3) # 3.25
reat_expanded_uncertaintyfunctionTypical U95 per band from Table A.2 (within a laboratory) or B.2 (between laboratories).
• frequencies [Hz]
• protector: 'earplug' or 'earmuff'
• between_laboratories (Default: False)
hearing.reat_expanded_uncertainty([250, 8000], protector='earplug')
ProtectorUncertaintyBudgetdataclassThe three standard uncertainties of Table A.1: method_db, equipment_db, environment_db [dB].
• combined_db = root sum of squares, expanded_db = 2u, both derived
hearing.REAT_WITHIN_LABORATORY_UNCERTAINTY['earmuff']['250 Hz up to 4 kHz'].expanded_db
REAT_WITHIN_LABORATORY_UNCERTAINTY / REAT_BETWEEN_LABORATORY_UNCERTAINTYmappingTables A.2 and B.2 of ISO 4869-1: the typical budget by protector ('earplug', 'earmuff') and frequency range.hearing.REAT_BETWEEN_LABORATORY_UNCERTAINTY['earplug']
REAT_FREQUENCY_RANGESconstantThe three columns of Tables A.2 and B.2: 'below 250 Hz', '250 Hz up to 4 kHz', 'above 4 kHz'.hearing.REAT_FREQUENCY_RANGES
REAT_FIELD_VARIATION_LIMITSconstantTable 1 of ISO 4869-1: (lowest free-field rejection, allowable field variation) [dB].
25 → 20, 20 → 15, 15 → 10, 10 → 5; below 10 dB the microphone is not suitable
hearing.REAT_FIELD_VARIATION_LIMITS[0] # (25.0, 20.0)
allowable_field_variationfunctionTable 1 lookup.
• free_field_rejection_db [dB]; below 10 dB raises
hearing.allowable_field_variation(18.0) # 10.0
check_reat_sound_fieldfunctionIs the test site's sound field diffuse enough? (ISO 4869-1 4.2.2).
• position_levels_db: levels at 'front', 'back', 'left', 'right', 'up', 'down' [dB]
• reference_levels_db [dB]
• rotation_levels_db with free_field_rejection_db for b), from 500 Hz
c = hearing.check_reat_sound_field(levels, reference)

• ReatSoundFieldCheck
ReatSoundFieldCheckdataclass4.2.2 verdict.
• uniform (±2,5 dB), balanced (right-left 3 dB), diffuse (Table 1) per band
• directionality_judged: whether b) was measured
• passes needs a) and b); no truth value
• .plot()
c.passes
assumed_protection_valuefunctionAssumed protection value APVfx = mf − α·sf (ISO 4869-2 Clause 5, Formula (1)).
• attenuation: (subjects, bands) ISO 4869-1 grid [dB]
• performance: 50/75/80/84/90/95/98 % from Table 1 (Default: 84)
• frequencies: mid-band [Hz] (Default: the eight octaves from 63 Hz)
apv = hearing.assumed_protection_value(grid)

• AssumedProtectionResult (apv, mean_attenuation, standard_deviation, alpha, subjects)
octave_band_protected_levelfunctionEffective A-weighted level, octave-band method (ISO 4869-2 Formula (2)).
• noise_levels: unweighted octave-band levels [dB]
• apv: assumed protection values or the result carrying them
• a_weighting: [dB] (Default: IEC 61672-1 Table 3)
res = hearing.octave_band_protected_level(noise, apv)

• ProtectedLevelResult (effective_level, reported_level, noise_reduction, band_levels)
hml_rating / hml_protected_levelfunctionH, M and L values and their application (ISO 4869-2 Clause 7).
• hml_rating(attenuation, performance=84): Formulae (3)-(15) over the eight reference noises of Table 2
• hml_protected_level(l_p_a, l_p_c, rating): Formulae (16)-(18), consuming the rounded triple
res = hearing.hml_protected_level(104.0, 103.0, hearing.hml_rating(grid))

• HMLRatingResult (high, medium, low, reported, subject_h/m/l, predicted_reduction)
snr_rating / snr_protected_levelfunctionSingle number rating and its application (ISO 4869-2 Clause 8).
• snr_rating(attenuation, performance=84): Formulae (19)-(22) against the pink noise of Table 3
• snr_protected_level(rating, l_p_c=...): Formula (23); or l_p_a= with c_minus_a= for Formula (24)
res = hearing.snr_protected_level(hearing.snr_rating(grid), l_p_c=103.0)

• SNRRatingResult (snr, reported, subject_snr, mean, standard_deviation)
AssumedProtectionResult / HMLRatingResult / SNRRatingResult / ProtectedLevelResultdataclassISO 4869-2 protector results.
• Ratings expose the unrounded fit and reported, the integer the standard publishes
• ProtectedLevelResult.reported_level rounds halves away from zero, not to even
apv = hearing.assumed_protection_value(grid)
PROTECTION_PERFORMANCESdictTable 1: the constant α for each protection performance x (ISO 4869-2).
50 → 0.00, 75 → 0.67, 80 → 0.84, 84 → 1.00, 90 → 1.28, 95 → 1.64, 98 → 2.00
hearing.PROTECTION_PERFORMANCES[84]
PROTECTOR_OCTAVE_BANDS / PROTECTOR_A_WEIGHTINGtupleThe eight octave bands of Formula (2) and frequency weighting A at them.
63 Hz to 8 kHz; the weighting is IEC 61672-1:2013 Table 3, which ISO 4869-2 reprints as its Table B.1
hearing.PROTECTOR_OCTAVE_BANDS
HML_REFERENCE_NOISES / HML_REFERENCE_C_MINUS_A / HML_REFERENCE_DtupleTable 2: the eight reference noises the HML method is fitted on.
A-weighted octave-band levels 125 Hz to 8 kHz, their (LpC − LpA) and the empirical weights d
hearing.HML_REFERENCE_NOISES
active_insertion_lossfunctionThe active insertion loss of an ANR earmuff, its lower ear and its uncertainty (ISO 4869-6 5.4, 5.5 b) and Annex A).
• passive_levels_db, active_levels_db: MIRE levels, (subjects, 2, bands) [dB], left ear first
• or insertion_loss_db per ear, or already the lower ear
• frequencies [Hz] (Default: the one-third octaves 50 Hz or 100 Hz to 10 kHz, or the octaves 63 Hz or 125 Hz to 8 kHz, by count)
ail = hearing.active_insertion_loss(passive_levels_db=off, active_levels_db=on)

• ActiveInsertionLossResult
ActiveInsertionLossResultdataclassISO 4869-6 active insertion loss.
• insertion_loss_db (lower ear), per_ear_db
• mean_db, standard_deviation_db, standard_uncertainty_db, expanded_uncertainty_db [dB]
• .plot()
ail.expanded_uncertainty_db
anr_total_attenuationfunctionTotal attenuation of an ANR earmuff and its ISO 4869-2 ratings at 84 % (ISO 4869-6 5.5).
• reat: ISO 4869-1 result or (subjects, octaves) grid, 63 Hz or 125 Hz to 8 kHz
• insertion_loss: ActiveInsertionLossResult or a grid on the one-third octaves
• passive side interpolated linearly in hertz, as ISO's calculation example does
anr = hearing.anr_total_attenuation(reat, ail)

• AnrTotalAttenuationResult (total_octave_db, assumed_protection, hml, snr)
AnrTotalAttenuationResultdataclassISO 4869-6 total attenuation.
• total_octave_db (Formula (1)), total_third_octave_db, reat_third_octave_db, insertion_loss_db [dB]
• assumed_protection, hml, snr at 84 %
• .plot()
anr.hml.reported
assess_anr_linearityfunctionUp to what external level does an ANR earmuff stay linear? (ISO 4869-6 5.4.4).
• external_levels_db: 5 dB steps up to 110 dB
• ear_levels_db: 125 Hz octave level at the ear, external levels on the last axis
• or ear_third_octave_levels_db (100, 125, 160 Hz on the last axis)
hearing.assess_anr_linearity([90, 95, 100], ears).maximum_linear_level_db

• AnrLinearityResult
AnrLinearityResultdataclass5.4.4 verdict.
• maximum_linear_level_db, increments_db, linear per ear and step
• passes, linear_to_110_db; no truth value
• .plot()
lin.maximum_linear_level_db
ANR_WITHIN_LABORATORY_UNCERTAINTYconstantTable A.2 of ISO 4869-6: the typical budget of the mean active insertion loss (0.6, 0.3, 0.4 dB) as a ProtectorUncertaintyBudget.hearing.ANR_WITHIN_LABORATORY_UNCERTAINTY.expanded_db # 1.56
PINK_NOISE_A_WEIGHTEDtupleTable 3: the pink noise the SNR method is defined against.
A-weighted octave-band levels 125 Hz to 8 kHz of a pink noise whose C-weighted level is 100 dB
hearing.PINK_NOISE_A_WEIGHTED
INSTRUMENT_U2mappingInstrument standard uncertainty u2 [dB] (ISO 9612 Table C.5).
Keyed by 'class1' (0.7), 'class2' (1.5), 'personal_exposimeter' (1.5)
INSTRUMENT_U2['class1'] # 0.7
OccupationalExposureWarningwarning classISO 9612 sampling advisory.
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)
SoundPowerWarningwarning classISO 3744/3746/3741/9614-2/9295 qualification issue.
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. Under ISO 9295 it is also emitted for a band outside the 16 kHz octave (11.2 kHz to 22.4 kHz), for a room constant taken from the air absorption below 10 kHz (clause 7.2), and for an FFT noise bandwidth wider than 112 Hz (clause 8.5.2)
warnings.simplefilter('error', SoundPowerWarning)
AbsorptionWarningwarning classISO 354 advisory.
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_indexfunctionSpeech Intelligibility Index (ANSI S3.5-1997, any of its four band procedures).
• speech_spectrum: equivalent speech spectrum levels [dB SPL] on the procedure's bands, or a vocal-effort name 'normal'/'raised'/'loud'/'shout' ('normal' only outside the one-third-octave procedure)
• noise_spectrum: equivalent noise spectrum levels [dB SPL] (Default: None → quiet, −80 dB)
• threshold: equivalent hearing threshold [dB HL] (Default: None → 0)
• method: one of SII_METHODS (Default: 'one-third-octave')
• band_importance: alternative Ii per band (Default: None → the procedure's table)
res = speech.speech_intelligibility_index("normal", noise_spectrum=[40.0]*18)

• SIIResult; res.sii = 0.066
standard_speech_spectrumfunctionStandard speech spectrum level by vocal effort (ANSI S3.5-1997 Table 3).
• vocal_effort: 'normal', 'raised', 'loud' or 'shout' (Default: 'normal')
u = speech.standard_speech_spectrum('raised')

• 18 band levels [dB SPL]
standard_speech_spectrafunctionPlottable standard speech spectra by vocal effort (ANSI S3.5-1997 Table 3).
• vocal_efforts: a name or sequence of 'normal'/'raised'/'loud'/'shout' (Default: the full family)
res = speech.standard_speech_spectra()

• StandardSpeechSpectrum; res.plot()
StandardSpeechSpectrumdataclassStandard speech spectrum result.
• frequencies: the 18 band centres [Hz]
• vocal_efforts: the efforts carried
• levels: Ui per effort, (len(vocal_efforts), 18) [dB SPL]
• .plot(): the speech spectrum level vs one-third-octave band, one line per effort
res.levels, res.vocal_efforts
SIIResultdataclassSII result.
• sii: index in [0, 1]
• band_audibility: Ai per band (§5.8)
• band_importance: Ii used
• frequencies [Hz]
• speech_spectrum / disturbance / masking: Ei′ / Di / Zi per band [dB]
• level_distortion: Li per band (§5.7)
• method: the band procedure used
• .plot()
res.sii, res.band_audibility
SII_METHODSconstantThe four ANSI S3.5-1997 band procedures, in the order of its Tables 1 to 4.
('critical-band', 'equally-contributing', 'one-third-octave', 'octave'), i.e. 21, 17, 18 and 6 bands
for m in SII_METHODS: ...
sii_procedurefunctionTabulated band table of one ANSI S3.5-1997 band procedure (Tables 1–4).
• method: one of SII_METHODS (Default: 'one-third-octave')
proc = speech.sii_procedure('octave')

• SIIProcedure; proc.plot()
SIIProceduredataclassANSI S3.5-1997 band-procedure constants.
• method: the procedure name
• frequencies: nominal band centres [Hz]
• band_edges: band limits [Hz], one more than the band count
• band_importance: Ii
• internal_noise: Xi [dB SPL]
• speech_spectrum: Ui, normal vocal effort [dB SPL]
• .plot(): Ii stepped over the band limits
proc.band_importance, proc.band_edges
stoifunctionShort-time objective intelligibility STOI / ESTOI (Taal et al. 2011; Jensen & Taal 2016).
• clean: clean reference (1D)
• degraded: degraded/processed signal (1D, same length)
• fs [Hz] (resampled to 10 kHz internally)
• extended: use ESTOI (Default: False)
d = speech.stoi(clean, degraded, fs)

• STOIResult; d.value in ~[0, 1] (1 if identical)
STOIResultdataclassSTOI / ESTOI result.
• value: the intelligibility index
• extended: True for ESTOI
• segment_scores: per-segment intermediate
• band_scores: per-band mean correlation (STOI; None for ESTOI)
• band_frequencies [Hz]
• fs (10 kHz)
• .plot()
res.value, res.band_scores
thdfunctionTotal harmonic distortion (IEC 60268-3 14.12.2–3).
• signal (1D), fs [Hz]
• fundamental [Hz] (Default: None → largest peak)
• kind: 'F' rel. fundamental or 'R' rel. total RMS (Default: 'F')
• n_harmonics (Default: 10)
• window (Default: 'hann')
thd(sig, fs, 1000.0, kind="F")

• ratio (0..)
harmonic_distortionfunctionnth-order harmonic distortion dₙ (IEC 60268-3 14.12.5).
• signal, fs, fundamental [Hz], order n (≥ 2)
harmonic_distortion(sig, fs, fundamental=1000.0, order=2)

• ratio (aₙ rel. total RMS)
thd_plus_noisefunctionTHD+N ratio (AES17-2015 6.3.1).
• signal, fs, fundamental (Default: None)
• notch_q: effective Q of the applied notch, 1.2–3 (Default: 2.0)
• bandwidth: AES17 chain upper edge [Hz] (Default: 20000; None = full Nyquist); 20 Hz high-pass included
• as_db: 20·lg(ratio) dB (Default: False)
• window: FFT window for auto-detection (Default: 'hann')
thd_plus_noise(sig, fs, 1000.0)

• ratio, or dB if as_db
sinadfunctionSignal-to-noise-and-distortion ratio, dB (derived from AES17 THD+N).
• signal, fs, fundamental (Default: None), notch_q (Default: 2.0), bandwidth (Default: 20000)
= −(THD+N in dB)
sinad(sig, fs, 1000.0)

• SINAD [dB]
dynamic_rangefunctionDynamic range (AES17-2015 6.4.1), dB CCIR-RMS.
• signal, fs, fundamental (Default: None → 997 Hz)
• notch_q (Default: 2.0), bandwidth (Default: 20000)
• full_scale: digital full-scale peak amplitude (Default: 1.0)
= full-scale sine / CCIR-RMS-weighted notched residual
dynamic_range(out, fs, 997.0)

• dB CCIR-RMS
idle_channel_noisefunctionIdle channel noise level (AES17-2015 6.4.2), dBFS CCIR-RMS.
• signal (idle output, 1D), fs
• bandwidth (Default: 20000)
• full_scale (Default: 1.0)
= CCIR-RMS-weighted RMS re full scale
idle_channel_noise(idle, fs)

• dBFS CCIR-RMS (−inf for digital zero)
weighted_thdfunctionWeighted THD (IEC 60268-3 14.12.11).
• signal, fs, fundamental (Default: None)
• weighting: '468' (ITU-R BS.468-4 / IEC 60268-1, the 14.12.11 network), 'A' or 'C' (Default: '468')
• notch_q (Default: 2.0)
• valid for fundamentals 31.5–400 Hz
weighted_thd(sig, fs, 100.0)

• ratio
itu_r_468_weightingfunctionITU-R BS.468-4 weighting response (clause 1, Fig. 1a).
• frequencies [Hz] (≥ 0)
• the Fig. 1a network evaluated in closed form, which Table 1 samples to 0.1 dB; DC → −inf
itu_r_468_weighting([6300.0]) # +12.2167

• dB re 1 kHz
modulation_distortionfunctionModulation distortion d_m,2 / d_m,3 (IEC 60268-3 14.12.7).
• signal, fs, f_low [Hz], f_high [Hz]
• arithmetic sideband sums over the f₂ amplitude (14.12.7.2 g–h)
modulation_distortion(sig, fs, f_low=60.0, f_high=7000.0).d2

• ModulationDistortionResult
ModulationDistortionResultdataclassModulation distortion result.
• d2 / d3: the IEC per-order values
• smpte: combined-RMS analyzer convention (not an IEC quantity)
res.d2, res.d3, res.smpte
difference_frequency_distortionfunctionDifference-frequency distortion d_d,n (IEC 60268-3 14.12.8).
• signal, fs, f1 < f2 [Hz]
• order: 2 or 3 (Default: 2)
• ref. U₂,ref = 2·U₂,f₂; 3rd order sums arithmetically
difference_frequency_distortion(sig, fs, f1=13e3, f2=14e3, order=2)

• ratio
total_difference_frequency_distortionfunctionTotal difference-frequency distortion (IEC 60268-3 14.12.10).
• signal, fs
• f1 (Default: 8000), f2 (Default: 11950) [Hz]
= √(a²_{f₂−f₁} + a²_{2f₁−f₂}) / (a_{f₁} + a_{f₂})
total_difference_frequency_distortion(sig, fs)

• ratio
dynamic_intermodulation_distortionfunctionDynamic intermodulation DIM (IEC 60268-3 14.12.9).
• signal, fs
• f_sine [Hz] (Default: 15000)
• f_square [Hz] (Default: 3150)
dynamic_intermodulation_distortion(sig, fs)

• ratio (products rel. 15 kHz sine)
harmonic_analysisfunctionFull harmonic analysis (THD, THD+N, SINAD).
• signal, fs, fundamental (Default: None)
• n_harmonics (Default: 10), notch_q (Default: 2.0), bandwidth (Default: 20000)
• window: FFT window (Default: 'hann')
res = electroacoustics.harmonic_analysis(sig, fs, 1000.0)

• HarmonicDistortionResult
HarmonicDistortionResultdataclassHarmonic analysis result.
• fundamental [Hz]
• harmonic_frequencies / harmonic_amplitudes
• thd_f / thd_r / thd_plus_noise: ratios
• sinad_db [dB]
• .plot(): annotated harmonic spectrum
res.thd_f, res.sinad_db
transfer_functionfunctionFrequency-response estimate H1/H2 (Bendat & Piersol).
• x (input), y (output), fs [Hz]
• estimator: 'H1' or 'H2' (Default: 'H1')
• nperseg (Default: None), overlap (Default: 0.5)
res = electroacoustics.transfer_function(x, y, fs)

• FrequencyResponseResult
coherencefunctionOrdinary coherence γ² (Bendat & Piersol).
• x, y, fs [Hz]
• nperseg (Default: None), overlap (Default: 0.5)
= |Gxy|²/(Gxx·Gyy) ∈ [0, 1]
f, g = electroacoustics.coherence(x, y, fs)
FrequencyResponseResultdataclassFrequency-response result.
• frequencies [Hz]
• response: complex H(f)
• magnitude_db / phase [rad]
• coherence: γ²(f)
• estimator
• .plot(): Bode + coherence
res.magnitude_db, res.coherence
synchronized_sweep_signalfunctionSynchronized exponential sweep (Novak et al. 2015, Eqs. 47/49).
• fs, f1 < f2 [Hz], seconds (quantized by the rounding)
• amplitude (Default: 1.0), fade (Default: 0.0)
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 = electroacoustics.synchronized_sweep_signal(48000, 20.0, 6000.0, 4.0)

• sweep samples (duration L·ln(f2/f1))
swept_sine_distortionfunctionHarmonic separation and THD(f) from one sweep (Farina 2000 / Novak et al. 2015).
• recorded, fs, plus the generator parameters f1, f2, seconds
• method: 'synchronized' (Default; analytic deconvolution, meaningful phases) / 'farina' (classical ESS, magnitudes only)
• n_harmonics (Default: 5), ir_length (Default: largest power of two fitting the closest arrivals)
• amplitude (Default: 1.0), fade (Default: generator default), remove_dc (Default: True)
res = electroacoustics.swept_sine_distortion(y, fs, 20.0, 6000.0, 4.0)

• SweptSineDistortionResult
SweptSineDistortionResultdataclassSwept-sine harmonic separation.
• frequencies [Hz], harmonic_responses: complex H₁..H_N, harmonic_irs (windowed, centred), delays L·ln(n) [s]
• thd_frequencies [Hz], thd, distortion_ratios: |Hₙ(n·f)|/|H₁(f)| per order
• fs, f1, f2, duration, rate L, method, n_harmonics
• .plot(): |Hₙ| magnitudes + THD(f)
res.thd, res.harmonic_responses
radiating_pistonfunctionRadiation of a rigid baffled circular piston (Beranek & Mellow §4.19/§13.7).
• radius a [m], frequencies [Hz]
• speed_of_sound (Default: 343), density (Default: 1.206)
• angles_rad: directivity polar angles_rad [rad] (Default: None)
res = electroacoustics.radiating_piston(0.1, freqs)

• RadiatingPistonResult
plot_piston_geometryfunctionBaffled piston to scale, optional far-field lobe.
• radius a [m]
• angles_rad [rad] + directivity (linear), together
• lobe_label, language
plot_piston_geometry(0.1, angles_rad=ang, directivity=d)

• Also RadiatingPistonResult.plot_geometry(frequency_index=...)
piston_resistance / piston_reactancefunctionNormalized 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_directivityfunctionFar-field piston directivity 2·J1(ka·sinθ)/(ka·sinθ).
• ka, theta [rad]
piston_directivity(5.0, 0.3)
piston_directivity_patternfunctionFar-field directivity (beam) pattern of one or more baffled pistons.
• ka (scalar or 1-D)
• angles_rad [rad] (Default: front hemisphere −90°…+90°)
p = electroacoustics.piston_directivity_pattern([3, 8, 16])

• PistonDirectivity
RadiatingPistonResultdataclassPiston radiation result.
• ka, resistance/reactance, radiation_resistance/radiation_reactance [N·s/m], radiation_mass = 8ρa³/3 [kg], directivity_index [dB], directivity
• .plot(): R1/X1 vs ka
res.radiation_mass
PistonDirectivitydataclassPiston directivity-pattern result.
• angles_rad [rad], ka, directivity (linear), directivity_db
• .plot(): polar beam pattern in dB (family over ka)
p.plot()
loudspeaker_characteristicsfunctionRated loudspeaker characteristics for an IEC 60268-5 report.
• frequencies, spl_db (on-axis SPL), rated_impedance R [Ω]
• input_voltage (Default: √R → 1 W), distance (Default: 1 m), sensitivity_band, tolerance_db
• impedance, distortion panels
• directivity: LoudspeakerDirectivity (23), ratings: LoudspeakerRatings (18/19)
res = electroacoustics.loudspeaker_characteristics(f, spl, 8.0)

• LoudspeakerCharacteristics
LoudspeakerDirectivitydataclassDirectional characteristics of the loudspeaker (IEC 60268-5 Clause 23).
• piston: a RadiatingPistonResult computed with angles_rad, or polar = (angles_deg, relative_db)
• frequency [Hz], index_db (directivity index, 23.3)
LoudspeakerDirectivity(piston=res, frequency=2000.0)
LoudspeakerRatingsdataclassManufacturer-stated ratings (IEC 60268-5 Clauses 18 and 19).
• frequency_range (lo, hi) [Hz] (19.1), also the band the 16.1 minimum impedance is scanned over
• noise_power [W] (18.1), sinusoidal_power [W] (18.4), resonance_frequency [Hz] (19.2)
LoudspeakerRatings(frequency_range=(45.0, 22000.0))
LoudspeakerCharacteristicsdataclassLoudspeaker rated-characteristics result (IEC 60268-5).
• sensitivity_level_db (1 W/1 m, 20.3/20.4), effective_range (21.2), reference_level_db, characteristic_sensitivity_pa, minimum_impedance
• .report(): IEC 60268-5 fiche (graphs to IEC 60263)
res.effective_range
feedback_stabilityfunctionGain before feedback of a reinforcement loop (Long, Architectural Acoustics 2e, Eqs. 18.16–18.24).
• open_loop_gain Zs [dB] (≈ −6 in an auditorium)
• level_loudspeaker_at_microphone L(H-M) [dB]
• level_loudspeaker_at_listener L(H-L) [dB]
• microphone_directivity DM(θ) [dB] (Default: 0)
• open_microphones Nm (Default: 1), stability_margin [dB] (Default: 10)
res = electroacoustics.feedback_stability(-6.0, 76.0, 80.0)

• FeedbackStabilityResult
FeedbackStabilityResultdataclassGain structure and stability verdict.
• open_loop_gain, feedback_loop_gain, nom_correction, loop_gain [dB]
• margin, headroom, stability_margin [dB], is_stable
• maximum_open_loop_gain, maximum_level_at_microphone [dB]
• .plot(): gain bars against the oscillation and margin lines
res.is_stable, res.headroom
res.plot()
feedback_loop_gain / open_microphone_correctionfunctionFeedback building blocks (Long Eqs. 18.18, 18.23).
• feedback_loop_gain(L_HM, L_HL, microphone_directivity=0) = L(H-M) − L(H-L) + DM(θ) [dB]
• open_microphone_correction(Nm) = 10 lg Nm [dB]
open_microphone_correction(4) # 6.02
plot_sound_reinforcement_geometryfunctionSchematic of the feedback loop with each path length annotated.
• talker_distance, microphone_distance, listener_distance [m]
• language
plot_sound_reinforcement_geometry(0.3, 4.0, 12.0)
DEFAULT_STABILITY_MARGIN / CARDIOID_RELATIVE_DIRECTIVITYconstantReinforcement defaults (Long Ch. 18).
• 10 dB feedback stability margin for an equalised system
• −2 dB cardioid directivity toward the loudspeaker relative to the talker
feedback_stability(-6.0, 78.0, 80.0, microphone_directivity=CARDIOID_RELATIVE_DIRECTIVITY)
microphone_characteristicsfunctionRated microphone characteristics for an IEC 60268-4 report.
• frequencies, response_db (free-field, re the reference frequency), sensitivity_mv_per_pa M [mV/Pa]
• reference_frequency (Default: 1 kHz), tolerance_db (Default: 2)
• directivity: MicrophoneDirectivity (13), noise: MicrophoneNoise (17), overload: MicrophoneOverload (14.2/15.2), electrical: MicrophoneElectrical (9/10)
res = electroacoustics.microphone_characteristics(f, resp, 12.5)

• MicrophoneCharacteristics
MicrophoneDirectivitydataclassDirectional characteristics of the microphone (IEC 60268-4 Clause 13).
• polar = (angles_deg, relative_db) (13.1)
• frequency [Hz], index_db (directivity index, 13.2; computed from polar when omitted)
MicrophoneDirectivity(polar=(ang, cardioid), frequency=1000.0)
MicrophoneNoisedataclassInherent noise of the microphone (IEC 60268-4 Clause 17).
• voltage U_N [V] (17.2 b) or equivalent_level_db [dB SPL] (17.1), not both
• weighting: "A" (Default) or "468", the ITU-R BS.468-4 quasi-peak figure; spectrum = (frequencies, band_levels_db)
MicrophoneNoise(voltage=1.25e-6)
MicrophoneOverloaddataclassOverload sound pressure and the distortion it is read from (IEC 60268-4 14.2/15.2).
• distortion = (spl_db, thd_percent) (14.2)
• thd_percent limit (Default: 1), spl_db (stated overload level; read off the curve when omitted)
MicrophoneOverload(distortion=(spl, thd), thd_percent=0.5)
MicrophoneElectricaldataclassElectrical impedance and rated power supply (IEC 60268-4 Clauses 10/9).
• rated_impedance [Ω] (10.2), minimum_load_impedance [Ω] (10.3)
• powering (9.1), supply_current_ma [mA] (9.1)
MicrophoneElectrical(rated_impedance=150.0, powering="Phantom P48 (IEC 61938)")
MicrophoneCharacteristicsdataclassMicrophone rated-characteristics result (IEC 60268-4).
• 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
• .report(): IEC 60268-4 fiche (graphs to IEC 60263)
res.sensitivity_level_db
expansion_chamberfunctionExpansion-chamber silencer TL/IL (Bies Eq. 8.111, four-pole).
• frequencies, length L, chamber_area, pipe_area
• source_impedance/radiation_impedance (Default: None → no IL)
res = noise_control.expansion_chamber(f, 0.3, 0.04, 0.01)

• ReactiveSilencerResult
plot_silencer_geometryfunctionTo-scale silencer cross-section.
• kind: the ReactiveSilencerResult.kind strings
• Chamber: length, chamber_area, pipe_area (+ inlet_extension/outlet_extension)
• Branch: duct_area + Helmholtz (neck_area, neck_length, cavity_volume) or quarter-wave (length, branch_area)
• language
plot_silencer_geometry('expansion chamber', length=0.3, chamber_area=0.03, pipe_area=0.005)

• Equivalent circular diameters 2·√(S/π); also ReactiveSilencerResult.plot_geometry()
helmholtz_resonator / quarter_wave_resonatorfunctionSide-branch resonator silencers (Bies Eqs. 8.46/8.44).
• Helmholtz: duct_area, neck_area, neck_length, cavity_volume
• Quarter-wave: duct_area, length, branch_area
quarter_wave_resonator(f, 0.01, 1.5, 2e-3)
extended_tube_chamberfunctionExtended-inlet/outlet expansion chamber (Bies §8.9.7); reduces to expansion_chamber at zero extension.
• length, chamber_area, pipe_area, inlet_extension, outlet_extension
extended_tube_chamber(f, 0.4, 0.04, 0.01, inlet_extension=0.1)
transmission_lossfunctionTransmission loss of a four-pole element (Munjal Eq. (3.27), no flow).
• transfer_matrix T, shape (n_freq, 2, 2)
• inlet_area S_in / outlet_area S_out [m²]
• speed_of_sound / density
• The anechoic termination is part of the definition, so this describes the element alone
transmission_loss(t, inlet_area=0.01, outlet_area=0.01)
insertion_lossfunctionInsertion loss of a four-pole element for stated end impedances.
• transfer_matrix T
• source_impedance Z_s, radiation_impedance Z_r [Pa·s/m³]
• Unlike the transmission loss it depends on the source and the termination, which is what makes it the number a client hears
insertion_loss(t, source_impedance=zs, radiation_impedance=zr)
duct_matrix / shunt_matrix / cascadefunctionThe four-pole primitives the silencers are assembled from (Bies Eqs. 8.143/8.144).
• duct_matrix(frequencies, length, area, ...): a straight duct
• shunt_matrix(branch_impedance): a side branch of impedance Z_b
• cascade(*matrices): multiplies elements inlet to outlet
t = noise_control.cascade(noise_control.duct_matrix(f, 0.1, s), noise_control.shunt_matrix(z))
helmholtz_impedance / quarter_wave_impedancefunctionSide-branch impedances to feed shunt_matrix (Bies Eqs. 8.152/8.146).
• Helmholtz: neck_area, neck_length, cavity_volume, resistance
• Quarter-wave: length, area
• speed_of_sound / density
shunt_matrix(noise_control.helmholtz_impedance(f, 1e-3, 0.05, 2e-3))
ReactiveSilencerResultdataclassReactive-silencer result.
• frequencies, transmission_loss, insertion_loss (or None), transfer_matrix, kind, resonances
• .plot(): TL/IL vs frequency
res.transmission_loss
SilencerChainclassHand-built four-pole chain that keeps the geometry it was given.
• SilencerChain(frequencies, speed_of_sound=…, density=…)
• .duct(length, area) and .shunt(branch_impedance, label=…) in order, each returning the chain
• .transfer_matrix, .result(inlet_area=…, outlet_area=…), .plot_geometry()
SilencerChain(f).duct(0.3, 0.031).shunt(zb).duct(0.6, 0.126)

• Ducts drawn to scale, shunts marked as branch points
SilencerChainElementdataclassOne recorded element of a SilencerChain.
• matrix, plus whatever geometry the call was handed: length and area for a duct, neither for a shunt
• label, shorting_frequency (where the branch impedance is least), .is_duct
chain.elements[0].area
substitution_insertion_lossfunctionThe measured insertion loss of ISO 7235 Eq. (1) and ISO 11691 Eq. (1): the level without the silencer minus the level with it.
• substitution_level (the series run with the substitution duct), object_level (the series run with the test object) [dB]
• reverberation_times: optionally (T_1, T_2) [s], adding the 10 lg(T_2/T_1) of ISO 7235 6.3; one value stands for every band
• the two standards number the series the opposite way round; the argument names are neither numbering
noise_control.substitution_insertion_loss(sub, obj)
octave_insertion_lossfunctionISO 11691 Eq. (2): three one-third octaves folded into their octave on the transmitted energy.
• insertion_loss [dB], a multiple of three bands in ascending order
• -10 lg[(10^-D1/10 + 10^-D2/10 + 10^-D3/10)/3], so the leakiest third decides the octave: 30, 30 and 5 dB give 9.7 dB, not 21.7
noise_control.octave_insertion_loss([30.0, 30.0, 5.0]) # 9.744
microphone_spread_limit / microphone_positions_required / ISO7235_SPREAD_LIMITSfunction / function / constantISO 7235 Table 6 and the rule of 6.2.1 it serves: when three microphone positions in a test duct are not enough.
• microphone_spread_limit(frequency): 10 dB at 50 and 63 Hz, 8 at 80 and 100, 7 at 125, 6 from 160 up
• microphone_positions_required(levels, frequency): 3 or 5, from the spread of exactly three levels
• the printed last row says > 160, leaving the 160 Hz band with no limit; read here as 160 and above (see the errata)
noise_control.microphone_positions_required([70.0, 74.0, 79.0], 125.0) # 5
measurement_reproducibility / measurement_expanded_uncertainty / ISO7235_REPRODUCIBILITY / ISO7235_COVERAGE_FACTORfunction / function / table / constantISO 7235 Table 7 and 7.9: how repeatable the measurement is, and the uncertainty that goes on the report.
• frequency [Hz], quantity: 'insertion_loss' (Default), 'transmission_loss' or 'intensity'
• insertion loss 1.5/1/2/3 dB by band range, transmission loss a flat 3, intensity 3/1.5/1/1 and stopping at 5 kHz
• the expanded uncertainty is ISO7235_COVERAGE_FACTOR = 2 times the deviation, for 95 % coverage
noise_control.measurement_expanded_uncertainty(4000.0) # 6.0 dB
survey_reproducibility / ISO11691_REPRODUCIBILITYfunction / constantISO 11691 Table 1: 2 dB up to the 1.25 kHz one-third octave and 3 dB above it.
• frequency [Hz]
• the standard offers no interlaboratory result of its own and says this estimate is what makes it a survey method
noise_control.survey_reproducibility(1000.0) # 2.0 dB
substitution_area_ratio / SURVEY_AREA_RATIO_RANGE / SURVEY_MAX_VELOCITY_M_S / SURVEY_DIAMETER_RANGE_M / SURVEY_BAND_RANGE_HZ / SilencerMeasurementWarningfunction / range / constant / range / range / warning classThe scope ISO 11691 writes for its own survey method.
• substitution_area_ratio(duct_area, element_area) [m²], warning outside the 0.6 to 1.7 of 4.5
• design velocity up to 15 m/s (1.1), circular diameters 80 mm to 2 m, one-third octaves from 50 Hz to 10 kHz
noise_control.substitution_area_ratio(0.09, 0.09) # 1.0
Emitted by noise_control.silencer_measurement
open_end_transmission_loss / open_end_reflection_coefficient / RADIATION_SOLID_ANGLESfunction / function / mappingISO 7235 Eqs. (B.3) and (B.4): what the open end of a duct keeps in, and the reflection that is the same fact said the other way.
• frequency [Hz], area S [m²], solid_angle_sr Ω [sr] (Default: 2π), speed_of_sound [m/s]
• D_td = 10 lg[1 + Ω/(4πf√S/c)²], r = [(1/Ω)(4πf√S/c)² + 1]^(−1/2), and the two close through D_td = −10 lg(1 − r²)
• RADIATION_SOLID_ANGLES is Table B.1, the same five values as ISO 5135 Table 1: A 2π, B π, C 4π, D 2π, E 4π
• the same physics as end_reflection_loss_closed_form, which raises the same argument to 1.88 rather than to 2
noise_control.open_end_transmission_loss(bands, 0.0962)
measured_transmission_loss / flow_noise_power_levelfunctionISO 7235 Eqs. (6) and (7): the two quantities the open-end loss is needed for.
• measured_transmission_loss(insertion_loss, open_end_loss): D_t = D_i + D_td, the transmission loss of an air-terminal unit
• flow_noise_power_level(pressure_level, open_end_loss, room_correction): L_W = L_p + D_td + C, with L_p uncorrected for background as 6.4 requires and C from ISO 3741
noise_control.measured_transmission_loss(d_i, d_td)
modal_filter_cut_on / CIRCULAR_CUT_ON_COEFFICIENT / RECTANGULAR_CUT_ON_COEFFICIENT / MODAL_FILTER_ATTENUATION_DBfunction / constant / constant / constantISO 7235 Eqs. (4) and (5): where higher-order modes start in the duct the modal filter is connected to.
• exactly one of diameter_m d or larger_dimension H [m], plus speed_of_sound
• 0.59 c/d and 0.5 c/H; the rectangular constant is exact, the circular one sits 0.67 % above the Bessel eigenvalue that circular_duct_cut_on uses
• MODAL_FILTER_ATTENUATION_DB = (3.0, 5.0), the minimum longitudinal attenuation of 5.2.2.3 below and above it
noise_control.modal_filter_cut_on(diameter_m=0.4) # 506 Hz
normal_air_density / ISO7235_GAS_CONSTANT / ISO7235_ABSOLUTE_ZERO_OFFSETfunction / constant / constantISO 7235 Eqs. (10), (21) and (22): the gas law with the standard's own two constants.
• static_gauge_pressure_pa p_s1 [Pa, relative to ambient], ambient_pressure_pa p_a [Pa absolute], temperature_c θ [°C]
• R = 287 and θ + 273, both as printed rather than 287.05 and 273.15; together 0.069 % high at 20 °C, and both cancel in the pressure loss coefficient
noise_control.normal_air_density(200.0, 101325.0, 20.0) # 1.2073
volume_flow_rate / dynamic_pressure / total_pressure / DENSITY_RATIO_RANGEfunction / function / function / constantISO 7235 Eqs. (8), (9), (11), (13), (16), (19) and (20): the flow quantities the pressure loss coefficient is built from.
• volume_flow_rate(mass_flow, density): q_V = q_m/ρ, with ρ the normalised density of Eq. (10) when the meter and the object leave DENSITY_RATIO_RANGE (0.98 to 1.02)
• dynamic_pressure(volume_flow, area, density): (ρ/2)(q_V/S)², the velocity head
• total_pressure(static_pressure, volume_flow, area, density): static plus dynamic in one plane
noise_control.dynamic_pressure(1.0, 0.0962, 1.2) # 64.8 Pa
total_pressure_loss / pressure_loss_coefficient / average_pressure_loss_coefficientfunctionISO 7235 Eqs. (12), (14), (17) and (18): what an object costs to push air through, in velocity heads.
• total_pressure_loss(static_pressure_loss_pa, inlet_dynamic_pressure_pa, inlet_area, outlet_area): adds p_d1[1 − (S_1/S_2)²], which vanishes when the two ducts match
• pressure_loss_coefficient(total_loss, inlet_dynamic_pressure_pa): ζ, the same number at every flow rate the object sees the same flow pattern at, warning at 10 Pa and below
• average_pressure_loss_coefficient(object_static, object_dynamic, substitution_static, substitution_dynamic): Eq. (18), a substitution average over each series' own flow rates, warning below five points
noise_control.pressure_loss_coefficient(45.0, 64.8) # 0.694
upstream_straight_length / MINIMUM_FLOW_RATES / MINIMUM_PRESSURE_DIFFERENCE_PA / UPSTREAM_STRAIGHT_DIAMETERS / UPSTREAM_STRAIGHT_MIN_M / VELOCITY_PROFILE_TOLERANCE_PERCENTfunction / constantISO 7235 6.5.2.1 and 6.5.2.2.1: what a flow measurement needs before it counts.
• upstream_straight_length(area): max(5 d_e, 2 m) with d_e = √(4S/π), the two rules crossing at a 0.4 m equivalent diameter
• five airflow rates per series, the lowest above 10 Pa, and a velocity profile uniform to ±10 % excluding 15 mm from the walls
noise_control.upstream_straight_length(0.5) # 3.99 m
duct_sound_power_levelfunctionISO 5135 Eq. (1): from what the room heard back to what the duct carries.
• room_sound_power_level L_W [dB] from ISO 3741, end_reflection_loss ΔL_r [dB]
• ISO 5135 Eq. (2) is ISO 7235 Eq. (B.3) written out, so open_end_transmission_loss supplies both, and their two solid-angle tables agree entry for entry
• the NOTE to Table 1 offers a transmission element to ISO 7235 as an alternative to correcting at all
noise_control.duct_sound_power_level(lw, d_td)
fit_operating_line / OperatingLine / EXTRAPOLATION_MAX_DEVIATION_DB / EXTRAPOLATION_RANGE_FACTORS / REPORTING_RESOLUTION_DBfunction / dataclass / constantISO 5135 5.5.2: the least-squares line a level is read off at a duty the laboratory did not measure at.
• duty q_V [m³/s] or Δp_t [Pa], levels [dB], at least two points at more than one duty
• result: slope [dB/decade], intercept, maximum_deviation, smallest_duty, largest_duty, valid_range (half to twice), .level_at(duty), .plot()
• warns past the 3 dB of 5.5.2, and again when a duty is read outside the range the clause allows; 8 k) reports to half a decibel
noise_control.fit_operating_line(q, lwa).level_at(0.3)
end_reflection_loss / elbow_insertion_lossfunctionHVAC duct end reflection & bend insertion loss (Bies Tables 8.14/8.11, ASHRAE).
• end: frequencies, diameter_m, termination 'flush'/'free'
• elbow: frequencies, width, bend_type, vanes, lined
end_reflection_loss(bands, 0.3)

• HvacSpectrumResult
plenum_attenuationfunctionPlenum-chamber TL by Wells' method (Bies Eq. 8.275).
• exit_area, line_of_sight, wall_area, mean_absorption, angle_rad
plenum_attenuation(0.1, 1.0, 20.0, 0.2) # dB
plot_plenum_geometryfunctionPlenum section honouring r and θ exactly.
• exit_area S_out [m²], line_of_sight r [m], wall_area S_w [m²]
• angle_rad θ [rad] (Default: 0)
• language
plot_plenum_geometry(0.09, 1.2, 6.0, angle_rad=0.35)

• Box fixed by r/θ, S_out mouth to scale, S_w annotated
flow_noise_straight_duct / flow_noise_bendfunctionHVAC flow-generated (self) noise sound power (VDI 2081, Bies Eqs. 8.251/8.254).
• frequencies, flow_velocity, area (+ height for the bend)
flow_noise_straight_duct(bands, 10.0, 0.04)

• HvacSpectrumResult
flow_noise_straight_duct_overallfunctionOverall flow noise of a straight run (VDI 2081 Equations (16) and (17)).
• flow_velocity v, area S
• weighting='Z' gives 7 + 50 lg v + 10 lg S, 'A' gives -25 + 70 lg v + 10 lg S
• the octave levels of flow_noise_straight_duct do not sum back to it: Figure 16 is a shape, not a partition
flow_noise_straight_duct_overall(5.83, 0.2)

• 38.3
HvacSpectrumResultdataclassPer-frequency HVAC attenuation or regenerated Lw.
• frequencies, values, quantity, label
• .plot()
res.values
fan_sound_powerfunctionOctave-band fan sound power from the operating point, by either method (Long Eq. 13.1 / ASHRAE 1987, or VDI 2081 Blatt 1 Eqs. (13)/(15)).
• model: 'ashrae' (Default) or 'vdi2081'; each takes its own arguments, and the two pressures are different quantities
• volume_flow Q [m³/s]
• ASHRAE: fan_static_pressure_pa P [Pa gauge]
• fan_type (Table 13.5 rows: 'forward_curved', 'airfoil_large', 'radial_high', 'vaneaxial_hub_low', 'tubeaxial_small', 'propeller' …)
• relative_efficiency_percent [% of peak] (Default: 80 → C_EFF 6 dB), blade_frequency
• VDI 2081: fan_total_pressure_pa Δp_t [Pa], assembly ('rr'/'t'/'am'), fan_speed_rpm n [min⁻¹], specific_sound_power_level L_WSM (Default: 34/36/42 dB by assembly), blade_count z, relative_flow V̇/V̇_opt (Default: 1)
• frequencies
fan_sound_power(2.36, fan_static_pressure_pa=498.0)

• HvacSpectrumResult; prefer AMCA 300 manufacturer data
octave_band_limits / VDI2081_SPECTRAL_CORRECTIONfunction / arrayOctave limits from an A-weighted room requirement (VDI 2081 Blatt 2 Eq. (1)).
• a_weighted_limit_db L_A [dB], frequencies
• L_Okt,max = L_A + K_A, with K_A the inverse A-weighting less the 5 dB the guideline allows for the sum of eight octaves
• VDI2081_SPECTRAL_CORRECTION: K_A = 21, 11, 4, −2, −5, −6, −6, −4 dB
noise_control.octave_band_limits(25.0)

• HvacSpectrumResult (46, 36, 29, 23, 20, 19, 19, 21 dB)
fan_efficiency_correction / blade_passing_frequency / fan_casing_attenuationfunctionThe three side terms of the fan model (Long Tables 13.6/13.7/13.8, Eq. 13.4).
• fan_efficiency_correction(relative_efficiency_percent=80.0) → C_EFF [dB] (6,0 at 80 %)
• blade_passing_frequency(rotational_speed, blades) = rpm·N/60 [Hz]
• fan_casing_attenuation(frequencies) → casing-radiated attenuation
blade_passing_frequency(1200.0, 12) # 240 Hz
HvacWarningwarning classA relative efficiency below the 50 % floor Long Table 13.6 is tabulated from.
The table's worst-case row is returned, which is where a caller who passed a fraction such as 0,8 instead of 80 also lands; the two are indistinguishable from the value alone
warnings.simplefilter("error", noise_control.HvacWarning)
Emitted by noise_control.hvac
unlined_rectangular_duct_attenuation / unlined_circular_duct_attenuationfunctionStraight unlined sheet-metal duct attenuation (Long Eqs. 14.9-14.11, Table 14.1).
• rectangular: frequencies, width, height, length, wrapped (fibreglass blanket doubles 63-250 Hz)
• circular: frequencies, length (about a tenth of the rectangular loss)
unlined_rectangular_duct_attenuation(bands, 0.9, 0.6, 1.5)

• HvacSpectrumResult
lined_rectangular_duct_attenuation / lined_circular_duct_attenuationfunctionLined-duct insertion loss, Reynolds (1990) regressions (Long Eqs. 14.12/14.13, Tables 14.2/14.3).
• rectangular: frequencies, width, height, length, lining_thickness, include_unlined
• circular: frequencies, diameter_m, length, lining_thickness
• Flanking caps a run at 40 dB
lined_rectangular_duct_attenuation(None, 0.46, 0.30, 1.8, 0.025)
flexible_duct_insertion_lossfunctionLined round flexible duct IL (Long Table 14.4, ASHRAE 1995), 63 Hz-4 kHz.
• frequencies, diameter_m (100-406 mm), length (0.9-3.7 m)
• Interpolated over length and log diameter_m
flexible_duct_insertion_loss(None, 0.305, 1.8)
splitter_silencer_insertion_lossfunctionParallel-splitter (dissipative) silencer IL: each airway a lined duct of half the splitter thickness, combined by Bies Eq. (8.241).
• frequencies, height, length, airway_widths (scalar or per airway), splitter_thickness
• Prefer the manufacturer's dynamic insertion loss
splitter_silencer_insertion_loss(None, 0.6, 1.5, [0.1]*3, 0.2)
silencer_self_noisefunctionRegenerated (self) noise of a splitter silencer (Long Eq. 14.31 + Table 14.8, Fry 1988).
• frequencies, airway_velocity V [m/s], passages N, height H [m]
L_W = 55·lg V + 10·lg N + 10·lg(H/1 mm) − 45
silencer_self_noise(None, 10.0, 4, 0.9)
section_change_lossfunctionReflection at a sudden change of duct section (VDI 2081 6.3, Figure 26).
• upstream_area S1, downstream_area S2; the loss is 10 lg (r+1)²/(4r) in r = S1/S2
• a sudden reduction reflects in every band; a sudden increase only below the limit frequency of the upstream duct, so shape and upstream_size are needed for it
• cap (Default: 5 dB, VDI 3733's recommendation)
noise_control.section_change_loss(bands, 0.5, 0.2, shape='round')

• 0.88 dB
split_lossfunctionBranch power-division loss at a duct split (Long Eq. 14.17), returned as a positive attenuation.
• main_area S_m [m²], branch_areas [m²], branch index
split_loss(0.6, [0.15]*4) # 6.02 dB
end_reflection_loss_closed_form / equivalent_diameterfunctionReynolds' closed-form duct end reflection (Long Eqs. 14.14-14.16); the alternative to the end_reflection_loss table look-up (method='long').
• frequencies, diameter_m, termination 'flush'/'free'
• equivalent_diameter(area) = √(4S/π) for a rectangular duct
end_reflection_loss(bands, 0.3, method='long')
diffuser_sound_powerfunctionRegenerated (self) noise of a grille, register or diffuser (Long Eqs. 13.27-13.33, Reynolds 1990).
• frequencies, face_area S_G [m²], volume_flow Q [m³/s], pressure_drop_pa ΔP [Pa]
• shape 'rectangular'/'round', count n (adds 10·lg n)
• 18 dB per doubling of approach velocity; peak band at f_P = 48.8·U_G
diffuser_sound_power(None, 0.372, 0.147, 12.4)
air_terminal_velocity_limit / air_terminal_damper_correctionfunctionScreening checks for grilles, registers and diffusers (ASHRAE 2019 Ch. 49 Tables 9/10); a measured device spectrum to ASHRAE Standard 70 beats both.
• air_terminal_velocity_limit(design_criterion, opening='supply'/'return') [m/s]
• air_terminal_damper_correction(pressure_ratio, location='diffuser_neck'/'plenum_inlet'/'supply_duct') [dB]
air_terminal_velocity_limit(30) # 2.2 m/s
room_effectfunctionRoom effect: the drop from the sound power at the terminal device to the level in the room (Long Eq. 14.40, VDI 2081-1 Eq. 36), as a positive attenuation.
• distance r [m]
• room_constant R [m²] or absorption_area A [m²], exactly one, scalar or per band
• directivity Q (Default: 2, flush in a ceiling), scalar or per band
room_effect(3.0, room.room_constant(S, alpha))
room_effect(1.5, absorption_area=20.0, directivity=q_per_band)
duct_pathfunctionEnd-to-end duct-borne cascade, fan to room (Long Table 14.9; AHRI 885 Table 8).
• frequencies, source_level L_W, elements (DuctElement list)
• room_effect, criterion 'NC'/'RC', target, self_noise_floor (Default: 0 dB)
• section/flow_velocity → plane-wave validity warning
duct_path(bands, lw, elements, room_effect=6.0, target=30)

• DuctPathResult
DuctElement / DuctPathStagedataclassOne path element and its computed rows.
• DuctElement: label, attenuation (positive loss; scalar, array or HvacSpectrumResult), self_noise L_W, code
• DuctPathStage: attenuation, attenuated (the Sum row), self_noise, levels (the Combined row)
DuctElement('Silencer', il, sn, code='3')
DuctPathResultdataclassDuct-borne noise path result.
• received_level, stages, room_effect, criterion, target, contributions
• .rating (NC/RC), .criterion_curve, .exceedance, .meets_target
• .table(): the printed sheet, row by row
• .plot(): the cascade vs the criterion curve; .report(): one-page sheet
res.meets_target
combine_duct_pathsfunctionEnergy sum of the received spectra of several paths (supply + return).
• paths, criterion, target, label
combine_duct_paths([supply, ret])

• DuctPathResult with contributions
room_to_room_transmissionfunctionRoom-to-room chain: source-room level → partition TL → receiving-room absorption → criterion (Norton Eq. 4.101, NR = TL − 10 lg[S_w/(S₂α₂ + τS_w)]).
• frequencies, transmission_loss, partition_area S_w [m²], receiving_absorption S₂α₂ [m²]
• source: SourceRoom
• include_partition_transmission (the τS_w term)
• criterion: DesignCriterion, label
• receiver_distance_m [m]: adds the direct field of the partition at that distance, Barron (2003) Eqs. (7-71) and (7-72), g = 1/4 inside r* = (S_w/2π)^½ and S_w/(8πr₂²) beyond it; None (Default) is the reverberant field alone
room_to_room_transmission(bands, tl, 24.0, a2, source=noise_control.SourceRoom(level=lp1), criterion=noise_control.DesignCriterion(target=45))

• RoomToRoomResult
RoomToRoomResultdataclassRoom-to-room chain result.
• source_level, transmission_loss, receiving_absorption, noise_reduction, received_level
• .rating (NC/RC), .criterion_curve, .exceedance, .meets_target
• .required_transmission_loss: the partition TL that just meets the criterion, at receiver_distance_m when one was given
• .table(): the rows of the hand calculation; .plot(): both spectra, the curve and NR
res.required_transmission_loss
SourceRoomdataclassThe source room of the room-to-room chain (Norton 4.7, Table 4.5).
• level L_p1 [dB], or power_level L_W [dB] + room_constant R₁ [m²]
• directivity Q (Default: 1)
• model: 'constant_power' (Default) / 'constant_volume' / 'constant_pressure'
SourceRoom(power_level=lw, room_constant=r1, directivity=4.0, model='constant_volume')
DesignCriteriondataclassThe design criterion of a composed chain.
• family: 'NC' (Default) / 'RC'
• target (Default: None → no verdict)
• flanking_penalty [dB] (Default: 0)
DesignCriterion(target=45.0, flanking_penalty=3.0)
circular_duct_cut_on / rectangular_duct_cut_onfunctionHigher-order acoustic mode cut-on with mean flow (Norton & Karczub Eqs. 7.6-7.10, Table 7.1).
• circular: diameter_m, flow_velocity, speed_of_sound, count (≤ 12)
• rectangular: width, height, …
• Flow lowers every cut-on by √(1 − M²) and shifts it to k_x = −Mκ/√(1 − M²)
circular_duct_cut_on(0.254, flow_velocity=200.0)

• DuctModeResult
DuctModeResultdataclassDuct cut-on result.
• modes (p, q), cut_on, cut_on_no_flow, axial_wavenumber, mach
• .plane_wave_limit: the lowest cut-on
• .plot(): the cut-on ladder with and without flow
res.plane_wave_limit
plane_wave_limit / PlaneWaveWarningfunction / warning classThe frequency above which a duct stops carrying plane waves only, and the warning the plane-wave results raise past it.
• plane_wave_limit(diameter_m=…), or width/height, or area
• flow_velocity, speed_of_sound
• Emitted by duct_path(section=…) and by every ReactiveSilencerResult
plane_wave_limit(width=0.65, height=0.4) # 264 Hz
DuctWallSpectrumdataclassOne duct wall of one printed table, in one of the two directions.
• transmission_loss_63_db … transmission_loss_8000_db, in decibels, and direction says whether they are the sound leaving the duct or the sound entering it
• shape: what the table's own title calls the duct, 'rectangular', 'round', 'flat oval' or 'circular'; the chapter uses two words for one geometry
• first_side_mm / second_side_mm in the order the page prints them, or diameter_mm, and duct_length_m for the two tables that print a length per row
• sheet_metal_gauge: the US gauge exactly as printed, asterisk and all; the chapter converts one of the six these tables use, '16 ga (1.6 mm thickness)' on folio 49.37, and none of the other five, so no thickness is offered
• .is_breakout, .is_break_in, .bands(), .spectrum() → {band_hz: db}, .transmission_loss_db(band_hz) narrows or refuses
• ranges + bounded_below for a cell written >45, whose open end is empty because a transmission loss has no ceiling, and unquantified for one printed as a rule the chapter never explains; a value the page puts in parentheses is held as printed and the mark is recorded in note
row = noise_control.duct_wall_named('305 × 305 mm')[0]
row.direction # 'breakout'
row.transmission_loss_db(63) # 21 dB

• PUBLISHED_DUCT_TRANSMISSION_LOSS, duct_wall_named
PUBLISHED_DUCT_TRANSMISSION_LOSSmappingForty-six duct walls over six published tables, keyed '<table>/<row>'.
• ASHRAE Chapter 49 Tables 29 to 34 (PDF pages 914-916): breakout for rectangular, round and flat oval ducts, then break-in for the same three
• one row per printed row and one quantity per row: the round tables measure 200, 350, 560 and 810 mm at 4.6 m for breakout and 203, 356, 559 and 813 mm at 4.57 m for break-in, so there is no construction that carries both
• only the two measured tables say so in their titles, and they are the two that carry the bounds and the parenthesised values the background sound left; the other four say nothing about how they were obtained
• no table carries a source line, and every row credits the sentence of running text that credits it, in attributed_to['table']
• machine equipment room walls are not here: Table 40 of the same chapter is an ordinary partition and is published from building.PUBLISHED_TRANSMISSION_LOSS
noise_control.PUBLISHED_DUCT_TRANSMISSION_LOSS['ashrae-2019-tables-29-to-34/t30_long_seam_200_gage_26']

• DuctWallSpectrum, duct_wall_named
duct_wall_namedfunctionEvery duct wall whose printed label contains the text.
• name: part of a row label with the unit its column heading carries, '610 mm', '305 × 1220', matched without case
• one size is printed by a breakout table and by a break-in table, so the plain answer is two rows that are two different quantities; read direction to tell them apart
noise_control.duct_wall_named('305 × 305 mm') # two rows, two quantities

• PUBLISHED_DUCT_TRANSMISSION_LOSS
DUCT_WALL_BANDS_HZconstantThe octave bands a duct-wall table can print: 63 Hz to 8 kHz.
• (63, 125, 250, 500, 1000, 2000, 4000, 8000); the two rectangular tables print all eight, and the round, circular and flat oval ones stop at 4 kHz and leave the last field empty on every row
noise_control.DUCT_WALL_BANDS_HZ[-1] # 8000
enclosure_insertion_loss / ENCLOSURE_MODELSfunction / mappingMachine-enclosure insertion loss IL = R − C (Bies Eqs. 7.103/7.111); panel R supplied by the caller, never predicted.
• panel_transmission_loss (per-band array or callable of f)
• external_area, internal_area, internal_absorption
• frequencies (required for a callable R)
• model: ENCLOSURE_MODELS ('bies' keeps the 0.3 floor of Eq. 7.111, 'norton' the bare C = 10 lg(S_E/R_i) of Eq. 4.115)
enclosure_insertion_loss(R, 6.0, 5.0, 0.3)

• EnclosureResult
enclosure_required_transmission_lossfunctionThe same equation solved for the panel R: R = IL + C (Norton Eq. 4.115 design use).
• insertion_loss (required IL per band, e.g. the room level minus an NC curve)
• external_area, internal_area, internal_absorption, frequencies, model
enclosure_required_transmission_loss(lp1 - nc45, 38.75, 59.5, alpha)

• EnclosureResult whose panel_transmission_loss is the required R
sound_power_insulation / sound_pressure_insulation / reciprocity_insulation / artificial_source_insulationfunctionWhat an enclosure is worth once it is built, ISO 11546-1 and -2 Eqs. (1) to (5).
• sound_power_insulation(level_without, level_with, frequencies=…): D_W band by band, and D_WA from the A-weighted totals or from an explicit pair
• sound_pressure_insulation(…): the same subtraction on a level at a stated position, D_p and D_pA
• reciprocity_insulation(external_levels, internal_levels, …): D_pr of part 1 clause 7.2, for an enclosure that cannot be measured with its machine
• artificial_source_insulation(without_by_position, with_by_position, …): the tapping plate of Annex A, averaged over source positions arithmetically, which is the standard's own word and not the energy mean used elsewhere
• condition: 'laboratory' (part 1, for declaration) or 'in-situ' (part 2, for acceptance); base_standard: the row of Table 1 the levels came from
noise_control.sound_power_insulation(lw_off, lw_on, frequencies=f)

• EnclosureInsulationResult
EnclosureInsulationResultdataclassThe insertion loss of an enclosure, band by band.
• frequencies [Hz], level_without, level_with, insulation [dB]
• quantity: 'sound_power', 'sound_pressure' or 'reciprocity'; a_weighted_insulation [dB]
• condition, source_kind, base_standard, band_fraction
• .rounded(): the integers clause 9.4 reports; .plot(): the two runs, the area between them and the difference
res.rounded(), res.a_weighted_insulation
weighted_insulation / WeightedEnclosureInsulationfunction / dataclassThe single-number rating of an insertion loss, 7.4 of part 1 and 7.3 of part 2.
• insulation over the 16 one-third-octave rating bands or the 5 octave ones [dB], quantity, band_fraction
• ISO 717-1 with D_W or D_pr written where that standard writes R, delegated to building.weighted_rating rather than re-derived
• result: rating, c, ctr, unfavourable_sum, band_centres_hz, quantity
noise_control.weighted_insulation(d_w[:16]).rating
estimated_a_weighted_insulationfunctionWhat an enclosure would be worth against a stated spectrum, Annex C of part 1 and Annex D of part 2.
• spectrum_levels L_i [dB], insulation D_i [dB], frequencies [Hz]
• D_WA,e = L_A − 10 lg Σ 10^(0.1 (L_i − A_i − D_i)), with A_i the printed attenuation, so A_i = −C_k against this library's band corrections
• both terms are built from the same table, so the answer cannot disagree with its own inputs and an insulation of zero returns exactly zero
noise_control.estimated_a_weighted_insulation(spectrum, d_w, frequencies=f)
applicable_methods / MethodEntryfunction / dataclassTable 1 of ISO 11546 as data: which base standard may be used, and what it can give.
• condition: 'laboratory' (Default) or 'in-situ'; source_kind: 'actual' (Default), 'reciprocity' or 'artificial'
• each row carries base_standard, quantities, subclause and band_values: a survey-grade determination hands back an A-weighted number and nothing per band, so D_W cannot be declared from it
• the reciprocity method exists in part 1 only, and asking for it in situ is refused
noise_control.applicable_methods(condition='in-situ')
test_environment_applicability / TestEnvironmentApplicability / TEST_ENVIRONMENT_REQUIREMENTS / ROOM_ABSORPTION_ESTIMATESfunction / dataclass / mapping / mappingIs this room good enough for that base standard? Annex C of ISO 11546-2.
• base_standard, mean_absorption_coefficient α, room_surface_area_m2 S_V, measurement_surface_area_m2 S
• S_V/S = 4/((10^(K2/10) − 1) α), which is Figure C.1 in closed form, cross-checked against emission.environmental_correction
• TEST_ENVIRONMENT_REQUIREMENTS is Table C.1, the K2 ceiling and the background margin of each standard; ISO 3743-1 and ISO 3747 state no K2 at all
• ROOM_ABSORPTION_ESTIMATES is Table C.2, the seven room descriptions and their α, for when nobody measured it
noise_control.test_environment_applicability(base_standard='ISO 3744', mean_absorption_coefficient=0.15, room_surface_area_m2=520.0, measurement_surface_area_m2=14.1)
leak_ratio / seal_ratio / fill_ratio / source_position_clearance_mfunctionThe four ratios and distances the two standards define in words.
• leak_ratio(opening_area_m2, interior_surface_area_m2): θ, the openings over the interior surface; an opening with an effective silencer is not one
• seal_ratio(leak): ψ = 1/θ, the same fact for a catalogue that prefers it
• fill_ratio(source_volume_m3, interior_volume_m3): φ, how much of the enclosure the source fills
• source_position_clearance_m(shortest_inner_dimension_m): 0,2 d, so the tapping plate is never against the panel it excites
noise_control.seal_ratio(noise_control.leak_ratio(0.02, 6.0)) # 300
UNRESTRICTED_ENCLOSURE_VOLUME_M3 / ARTIFICIAL_SOURCE_MAX_FILL_RATIO / ARTIFICIAL_SOURCE_LEAK_RATIO_ADVISORY / ARTIFICIAL_SOURCE_PLATE_MM / ARTIFICIAL_SOURCE_DROP_MM / ARTIFICIAL_SOURCE_STANDOFF_MM / ARTIFICIAL_SOURCE_EXAMPLE_LWA_DB / SOURCE_WALL_CLEARANCE_FACTORconstantThe numbers of clause 1, clause 4 and Annex A of ISO 11546.
• clause 1 applies the part without restriction to a free-standing enclosure smaller than 2 m³, and lets a larger one be measured with its actual source while the base standard's own volume limit is met; the artificial source fills at most a quarter of the interior, and clause 4 would rather keep the leak ratio under 2 %
• the Annex A source is a 4 mm steel plate of 800 mm by 300 mm, dropped 40 mm onto a 60 mm standoff
• the spectrum Annex B prints as an illustration totals 110 dB(A), and it was measured on a 600 mm plate rather than on the Annex A one (see the errata)
• the plate stands 0,2 d from any wall
noise_control.ARTIFICIAL_SOURCE_PLATE_MM
MANDATORY_BAND_RANGE_HZ / PREFERRED_BAND_RANGE_HZmappingThe band range ISO 11546 and ISO 11957 require, and the one they would rather have, keyed by band fraction.
• required: 100 Hz to 5 kHz in one-third octaves, 125 Hz to 4 kHz in octaves
• preferred: 50 Hz to 10 kHz and 63 Hz to 8 kHz
• a spectrum that does not cover the required range raises the warning of its own standard
noise_control.MANDATORY_BAND_RANGE_HZ[3] # (100.0, 5000.0)
EnclosureInsulationWarning / CabinInsulationWarningwarning classThe measurement is outside a condition ISO 11546 or ISO 11957 states.
• a band range short of the required one, a base standard that gives only an A-weighted value, a margin under 6 dB over the background
• a room-to-cabin volume ratio under 20, a lowest band outside the range clause 6.2 covers
warnings.simplefilter('error', CabinInsulationWarning)
Emitted by noise_control.enclosure_insulation
cabin_insulation / CabinInsulationResultfunction / dataclassWhat a cabin keeps out, ISO 11957 Eqs. (1), (2) and (3).
• room_levels, cabin_levels [dB], frequencies [Hz], band_fraction
• method: 'laboratory' (Default), 'in-situ-loudspeaker' or 'in-situ-actual-noise'; the in-situ pair carries the prime of definition 3.6
• room_background_levels / cabin_background_levels: taken off by the ISO 3741 correction 6.4 asks for
• a_weighted_room_level / a_weighted_cabin_level: Eq. (3), defined for the actual-noise method alone, and refused under any other
• result: insulation, apparent, symbol, a_weighted_insulation, internal_noise_level, .rounded(), .plot()
noise_control.cabin_insulation(room, cabin, frequencies=f)
weighted_cabin_insulation / WeightedCabinInsulationfunction / dataclassThe single-number rating of a cabin, ISO 11957 clause 8.
• insulation over the rating bands [dB], apparent, band_fraction
• ISO 717-1 with D_p or D'_p written where that standard writes R
• clause 4 calls this the preferred single number and then warns against reading too much into it, because what a cabin is worth depends on the spectrum it stands in
noise_control.weighted_cabin_insulation(d_p[:16]).rating
estimated_cabin_noise_insulation / internal_noise_levelfunctionAnnex A and 6.7 of ISO 11957: the cabin against a stated spectrum, and the noise it makes on its own.
• estimated_cabin_noise_insulation(spectrum_levels, insulation, frequencies=…): D_pA,e = L_A − 10 lg Σ 10^(0.1 (L_i − A_i − D_pi)), the same identity and the same A_i sign as the enclosure annexes
• internal_noise_level(levels, background_level=…): L_pA, the energy mean over the 0,3 m sphere with the external sources off
• the background rule of 6.7 is not the one of 6.4: the correction is made only while the margin stays between 6 dB and 10 dB, and below 6 dB the answer is an upper bound
noise_control.internal_noise_level([58.2, 59.1, 58.7], background_level=51.0)
check_source_positions / SourcePositionCheck / MIN_SOURCE_POSITIONS_IN_SITU / MAX_SOURCE_POSITIONS_IN_SITUfunction / dataclass / constantWere there enough loudspeaker positions? ISO 11957 7.2.1.
• insulation_by_position: D'_p in octave bands, one row per source position
• the number of positions shall be at least the largest difference in decibels between any two of them, three to begin with and six at most
• result: positions_used, max_octave_spread_db, required_positions, satisfied, exceeds_maximum, the last of which 7.2.1 says shall be stated in the report
• the clause says octave bands, so one-third-octave data is folded at the level and not at the difference
noise_control.check_source_positions(d_p_by_position).satisfied
check_band_flatness / BandFlatnessCheck / BAND_FLATNESS_LIMIT_DB / DEFAULT_BAND_FLATNESS_LIMIT_DBfunction / dataclass / mapping / constantIs the driving spectrum flat enough inside each octave? ISO 11957 6.4 and 7.2.1.
• third_octave_levels [dB], frequencies [Hz], read three bands to an octave
• 6 dB in the octave of 125 Hz, 5 dB in the one of 250 Hz, 4 dB above; nothing is printed below 125 Hz, so limit_db is nan there and the octave counts as satisfied
• result: octave_centres_hz, spread_db, limit_db, satisfied, .all_satisfied
noise_control.check_band_flatness(lp, frequencies=f).all_satisfied
minimum_cabin_clearance_m / WALL_CLEARANCE_FACTOR / LOW_BAND_CLEARANCE_M / LOW_BAND_CLEARANCE_RANGE_HZfunction / constantHow far the cabin stands from the room, ISO 11957 6.2.
• lowest_band_frequency_hz, speed_of_sound [m/s] (Default: 343)
• half a wavelength at the lowest band of interest, from the walls, the ceiling and any diffusing element alike
• from 50 Hz to 80 Hz the clause fixes a flat 2 m instead, which at 50 Hz is less than the half wavelength above it would have asked for: the low-frequency sentence relaxes the rule rather than tightening it, and it is written as printed (see the errata)
noise_control.minimum_cabin_clearance_m(100.0) # 1.715 m
uncertainty_conditions / CabinUncertainty / MIN_ROOM_TO_CABIN_VOLUME_RATIO / STATED_UNCERTAINTY_BAND_RANGE_HZ / INCREASED_UNCERTAINTY_BAND_RANGE_HZ / IN_SITU_EXCESS_STANDARD_DEVIATION_DBfunction / dataclass / constantWhat ISO 11957 clause 10 is willing to say about a measurement.
• room_volume_m3, cabin_volume_m3, method
• in the laboratory the uncertainty of ISO 3741 carries over from 250 Hz to 10 kHz, while the room is at least 20 times the volume of the cabin; from 50 Hz to 200 Hz, and below that ratio, a larger uncertainty is expected
• the loudspeaker method in situ adds about 2 dB to the standard deviation
• for the actual-noise method the clause states nothing and sends a declared value to ISO 4871, so stateable is False
noise_control.uncertainty_conditions(room_volume_m3=300.0, cabin_volume_m3=12.0)
MIN_LOUDSPEAKER_SEPARATION_M / MIN_SOURCE_TO_CABIN_M / MIN_SOURCE_TO_MICROPHONE_M / MIN_SOURCE_TO_MICROPHONE_IN_SITU_M / MAX_MICROPHONE_TO_CABIN_M / MIN_MICROPHONE_HEIGHT_M / OPERATOR_SPHERE_RADIUS_M / OPERATOR_PATH_INCLINATION_DEG / INTERNAL_NOISE_CENTRE_HEIGHT_M / INTERNAL_NOISE_CENTRE_TOLERANCE_M / MIN_FIXED_MICROPHONE_POSITIONS / MIN_LOUDSPEAKER_POSITIONSconstantThe geometry of ISO 11957 6.4, 6.5 and 7.4, as numbers rather than as prose.
• loudspeakers at least 3 m apart and 2 m from the cabin; 2 m from a microphone in the laboratory and 3 m in situ, which is a deliberate difference
• in a large room with a short reverberation time, no microphone further than 5 m from the outside of the cabin
• inside, no position closer than 0,2 d to a surface and none below 1 m; with a defined operator position, three points on a sphere of radius 0,3 m, or a path inclined 45°
• for the internal noise level the centre of that sphere is 1,55 m ± 0,075 m above the floor
• at least six fixed microphone positions and two loudspeaker positions in the laboratory; 7.4 fixes the microphones at exactly six
noise_control.OPERATOR_SPHERE_RADIUS_M # 0.3
MAX_LEAK_RATIO / MIN_SIGNAL_TO_BACKGROUND_DB / PREFERRED_SIGNAL_TO_BACKGROUND_DB / INTERNAL_NOISE_CORRECTION_WINDOW_DBconstantThe four thresholds ISO 11957 states as conditions rather than as advice.
• clause 1 applies the standard to a cabin of leak ratio 2 % or less, where ISO 11546 only prefers the same figure
• 6 dB over the background, and preferably more than 12 dB, in every band of interest
• 6.7 corrects the internal noise level only while the margin is between 6 dB and 10 dB
noise_control.MAX_LEAK_RATIO # 0.02
in_situ_transmission_loss / in_situ_insertion_loss / SilencerInSituResultfunction / function / dataclassWhat a silencer is worth where it stands, ISO 11820 Eqs. (19) and (21).
• in_situ_transmission_loss(source_levels_db, receiver_levels_db, source_area_m2=, receiver_area_m2=): D_ts = D_tps + 10 lg(S₂/S₁) + K₂ − K₁
• in_situ_insertion_loss(levels_without_db, levels_with_db, area_without_m2=, area_with_m2=): the same form with the two runs of Eq. (3) in place of the two sides
• each area and field_correction_difference_db [dB] take one value or one per band: the area of a diffuse room is a quarter of its absorption and moves with T, so pass what reverberant_surface_area_m2 returns
• case: which installation of Figure 1 the numbers came from, checked against the quantity
• result: loss_db, level_difference_db, area_term_db and field_correction_difference_db (always per band), quantity, .plot()
noise_control.in_situ_transmission_loss(l2, l1, source_area_m2=0.9, receiver_area_m2=18.0)
installation_case / InstallationCase / INSTALLATION_CASESfunction / dataclass / mappingThe twenty installations of Figure 1 as data, with the area rules clause 9 gives each.
• number 1 to 20, source_side / receiver_side: 'duct', 'room' or 'outdoors'
• quantity: 'transmission' for 1 to 16, 'insertion' for 17 to 20
• source_area_rule / receiver_area_rule: the duct cross-section, a quarter of the room absorption, a hemisphere or the aperture in the wall
noise_control.installation_case(7).receiver_area_rule
transmission_level_difference_db / insertion_level_difference_db / mean_sound_pressure_level_dbfunctionThe level differences ISO 11820 builds everything else from, Eqs. (1), (3) and (2).
• transmission_level_difference_db(source_levels_db, receiver_levels_db): across the silencer
• insertion_level_difference_db(levels_without_db, levels_with_db): between the run without it and the run with it
• mean_sound_pressure_level_db(levels_db): the energy mean over the measuring points
noise_control.mean_sound_pressure_level_db([71.2, 73.4, 72.0])
sound_power_level_db / reverberant_surface_area_m2 / SABINE_AREA_COEFFICIENTfunction / function / constantFrom a mean level to a sound power, Eqs. (5), (7), (9) and (11), and the area a reverberant room stands in for, Eqs. (6), (10) and (12).
• L_W = L̄_p + 10 lg(S/S₀) + K, with S₀ = 1 m² and S whichever area the case calls for
• reverberant_surface_area_m2(volume_m3, reverberation_time_s, speed_of_sound=340.0): S = 6 ln10 V / (c T), a quarter of the Sabine absorption area
• SABINE_AREA_COEFFICIENT is that 6 ln10, the 13,8 the three equations share
noise_control.reverberant_surface_area_m2(320.0, t20)
extraneous_corrected_mean_level_db / silencer_background_correction_db / ISO11820_BACKGROUND_CORRECTIONS_DB / MAXIMUM_EXTRANEOUS_CORRECTION_DB / ISO11820_MINIMUM_BACKGROUND_MARGIN_DB / ISO11820_NEGLIGIBLE_BACKGROUND_MARGIN_DBfunction / function / mapping / constantThe two routes ISO 11820 offers around extraneous sound, 9.1.1 to 9.1.3.
• extraneous_corrected_mean_level_db(levels_db, extraneous_levels_db): the energy subtraction of Eqs. (17) and (18), and whether it hit the 3 dB cap past which the quantity is not determined, judged on the margin of the two energy means as Table 1 draws it: a 3 dB margin, a 3,02 dB correction, is still determined
• silencer_background_correction_db(level_difference_db): Table 1, in decibels to take off, stepped from 3 dB at a margin of 3 dB to 0,5 dB at 9 or 10
• a margin under 3 dB is refused; above 10 dB nothing is corrected, and 10 dB itself still takes off 0,5 dB
noise_control.silencer_background_correction_db([4.0, 9.0]) # 2.0, 0.5
temperature_field_correction_db / TYPICAL_FIELD_CORRECTION_LIMIT_DB / ISO11820_SOUND_SPEED_M_Sfunction / constantWhat a difference of temperature does to the field correction, Eqs. (20) and (22).
• K₂ − K₁ = 5 lg[(273 + θ₁)/(273 + θ₂)], the standard's own 273 rather than 273,15
• the same expression serves the insertion measurement, with the with-silencer run as the receiver side
• NOTE 4 expects K to stay under 3 dB in absolute value once the areas are the ones 3.3 and 3.4 define
noise_control.temperature_field_correction_db(receiver_temperature_c=20.0, source_temperature_c=120.0)
octave_levels_from_third_octave_db / ISO11820_OCTAVE_BAND_RANGE_HZ / ISO11820_OCTAVE_BAND_EXTENDED_RANGE_HZ / ISO11820_THIRD_OCTAVE_BAND_RANGE_HZ / ISO11820_THIRD_OCTAVE_BAND_EXTENDED_RANGE_HZfunction / constantThe bands ISO 11820 measures in, 9.1.5 and 8.1.
• octave_levels_from_third_octave_db(levels_db): threes folded into octaves, the route the clause allows when the narrower bands were measured
• 63 Hz to 4 kHz in octaves, 50 Hz to 5 kHz in one-third octaves, with the extended ranges the clause names for a silencer that works outside them
noise_control.octave_levels_from_third_octave_db(third_octave_levels)
total_pressure_loss_pa / static_pressure_difference_pa / velocity_pressure_pa / flow_velocity_m_s / gas_density_kg_m3 / silencer_flow_velocity_m_s / ISO11820_GAS_CONSTANT / ISO11820_AIR_GAS_CONSTANT / ISO11820_AMBIENT_PRESSURE_PA / VELOCITY_UNIFORMITY_TOLERANCE_PERCENTfunction / constantThe flow side of the measurement, Eqs. (13) to (16) and (27) to (31).
• pressure loss Δp_T, the static difference Δp_S behind a change of area, the velocity pressure and the velocity it stands for
• gas_density_kg_m3(temperature_c=, molar_mass_kg_kmol=None): ρ = M p_amb / [R (273 + θ)], with R/M = 287 N m per kg K for air
• silencer_flow_velocity_m_s: the upstream mean velocity scaled by S_u/S_f, which is the velocity the regenerated noise answers to
• 9.2 asks the velocity profile to be uniform within 10 %
noise_control.gas_density_kg_m3(temperature_c=120.0)
measurement_distance_upstream_m / measurement_distance_downstream_m / UPSTREAM_DISTANCE_DIAMETERS / DOWNSTREAM_DISTANCE_COEFFICIENTSfunction / constantWhere the measurement surfaces stand along the duct, Eqs. (15) and (16).
• upstream: one and a half equivalent diameters of the measurement cross-section
• downstream: 12 √S_d − 10 √S_f, which can fall to zero for a silencer whose free area is most of the duct, and 8.3.1 then sends the parties to agree
• S_f is the free cross-section, which NOTE 18 warns is not the intake one
noise_control.measurement_distance_downstream_m(0.9, 0.45)
SilencerInSituWarningwarning classThe measurement is outside a condition ISO 11820 states.
• a downstream distance the geometry cannot give, a field correction past what NOTE 4 expects, a velocity profile outside the 10 % the standard asks for
warnings.catch_warnings()
Emitted by noise_control.silencer_in_situ
screen_attenuation / ScreenInSituResultfunction / dataclassWhat a removable screen is worth where it stands, ISO 11821 clauses 5.8 and 5.9.
• unscreened_levels_db, screened_levels_db [dB], frequencies [Hz], distance_m
• source_kind: 'actual' (Default) or 'artificial'
• a_weighted_unscreened_level_db / a_weighted_screened_level_db: the pair of 5.9, refused with an artificial source because the spectrum would be the loudspeaker's
• result: attenuation_db, a_weighted_attenuation_db, .plot()
• .rounded() and .rounded_a_weighted(): the whole decibels 7.4 c) reports, an exact half to the even one
noise_control.screen_attenuation(without, with_screen, frequencies=f)
background_corrected_level_db / BACKGROUND_CORRECTION_WINDOW_DB / ISO11821_MINIMUM_BACKGROUND_MARGIN_DB / ISO11821_PREFERRED_BACKGROUND_MARGIN_DBfunction / constantThe background correction ISO 11821 boxes, clause 5.7.
• L_p = 10 lg(10^(L_ps/10) − 10^(L_pb/10)), the plain energy subtraction, band by band and position by position
• over 10 dB of margin nothing is corrected; under 6 dB the conditions are "not acceptable", which is a refusal, because the background it names includes wind noise
• where ISO 11820 corrects from a stepped table, this standard prints the formula
noise_control.background_corrected_level_db(levels, background)
directivity_index_db / DIRECTIVITY_POSITIONS / DIRECTIVITY_INDEX_LIMIT_DB / DIRECTIVITY_CIRCLE_RADIUS_Mfunction / constantIs this loudspeaker omnidirectional enough? ISO 11821 definition 3.10 and 5.2.2.
• twelve positions evenly spaced on a horizontal circle of about 1,5 m radius
• DI_i = L₃₆₀ − L₃₀,i, the logarithmic mean less the position, so the index is positive where the position is quieter than the mean
• the source qualifies while no position falls more than 8 dB below the mean
noise_control.directivity_index_db(levels_at_twelve)
microphone_distances_m / SCREEN_DISTANCE_FACTORS / MINIMUM_MICROPHONE_DISTANCE_M / MINIMUM_SCREEN_DIMENSION_Mfunction / constantWhere the microphones stand in front of a screen, ISO 11821 5.5.2.
• a quarter, a half, once and twice the screen height, never closer than 1 m, so for a low screen the two nearest positions coincide
• NOTE 2 reads the spread: the smallest attenuation at the most remote position, the largest at the nearest
• a screen under 1,5 m in either dimension is outside the standard, and that is reported
noise_control.microphone_distances_m(3.0)
impulse_mean_level_db / IMPULSE_REPEATS / IMPULSE_REPEAT_DEVIATION_DB / IMPULSE_INVALID_DEVIATION_DBfunction / constantA single-impulse source, ISO 11821 5.6.2.1.
• at least three repeats with the S time weighting, and the arithmetic mean of them, which is what the clause asks for
• a spread past 3 dB asks for three more repeats, which is reported
• a spread past 5 dB makes the measurement invalid, which is refused
noise_control.impulse_mean_level_db([88.1, 89.4, 87.9])
ISO11821_BAND_RANGE_HZ / OPERATOR_HEIGHT_M / OPERATOR_HEIGHT_TOLERANCE_M / OUTDOOR_RANGE_M / ENGINEERING_STANDARD_DEVIATION_DBmapping / constantThe conditions ISO 11821 states as numbers.
• 100 Hz to 5 kHz in one-third octaves, 125 Hz to 4 kHz in octaves
• a microphone stands at 1,55 m ± 0,075 m where no operator height is given, in the sphere of 0,3 m radius the cabin standard also prints
• outdoors the method reaches 25 m from the screen, and its standard deviation of reproducibility is 2 dB, which is engineering grade
noise_control.ISO11821_BAND_RANGE_HZ[3] # (100.0, 5000.0)
ScreenInSituWarningwarning classThe measurement is outside a condition ISO 11821 states.
• a screen smaller than 1,5 m, a spread of repeats past 3 dB, a distance past the 25 m the outdoor method reaches
warnings.catch_warnings()
Emitted by noise_control.screen_in_situ
valve_aerodynamic_noisefunctionControl valve aerodynamic noise, the whole of IEC 60534-8-3 Clause 5.
• stream: a GasStream, valve: a ValveTrim, pipe: a DownstreamPipe
• the three groups are the standard's own reading order: the operating point, the valve at that travel, and the pipe the noise comes out of
res = noise_control.valve_aerodynamic_noise(stream, valve, pipe)

• AerodynamicValveNoise
AerodynamicValveNoisedataclassWhat Clause 5 says about one operating point.
• regime (1 to 5), boundaries, pressure_ratio x, vena_contracta_pressure_pa [Pa]
• jet_diameter_m [m], mach, acoustical_efficiency, stream_power / sound_power [W], sound_power_level [dB]
• peak_frequency [Hz], outlet_mach, pipe_mach, velocity_correction [dB], internal_level [dB]
• frequencies and the three band arrays, plus external_level, the A-weighted single number of Eq. (25) [dB(A)] at 1 m
res.regime, res.external_level
GasStream / ValveTrim / DownstreamPipedataclassThe three groups of input IEC 60534-8-3 reads.
• GasStream: mass_flow [kg/s], inlet_pressure_pa / outlet_pressure_pa [Pa], inlet_density [kg/m3], inlet_temperature_k [K], specific_heat_ratio, molecular_mass [kg/kmol]
• ValveTrim: flow_coefficient C, style_modifier F_d, pressure_recovery F_L or F_LP/F_p, outlet_diameter_m D [m], efficiency_correction A_eta and strouhal_number St_p from Table 4, coefficient 'Cv' (Default) or 'Kv'
• DownstreamPipe: internal_diameter_m D_i [m], wall_thickness t_S [m], density [kg/m3], and the printed defaults speed_of_sound, air_sound_speed, atmospheric_pressure_pa, standard_pressure_pa
noise_control.ValveTrim(flow_coefficient=90.0, ...)
pressure_ratio_boundaries / RegimeBoundariesfunction / dataclassThe four pressure ratios of Eqs. (3) to (7) that cut Clause 5.2 into five regimes.
• specific_heat_ratio, pressure_recovery
• vena_contracta x_vcc, critical x_C, break_point x_B, constant_efficiency x_CE, recovery alpha
noise_control.pressure_ratio_boundaries(1.22, 0.8)
flow_regimefunctionWhich of the five regimes a pressure ratio falls in (Clause 5.2).
• pressure_ratio x, boundaries
• Each interval closed at the top; regime V starts strictly above x_CE, as the clause prints it and not as Table 3 does
noise_control.flow_regime(0.52, bounds) # 3
valve_style_modifierfunctionF_d of Eqs. (8a) to (8c): the hydraulic diameter of one passage over the diameter of the equivalent single orifice.
• passage_area A [m2], wetted_perimeter l_w [m], passages N_o
noise_control.valve_style_modifier(0.00137, 0.181, 6) # 0.30
jet_diameter_mfunctionD_j of Eq. (9), the length scale the peak frequency is set by.
• flow_coefficient C, style_modifier F_d, pressure_recovery
• coefficient: 'Cv' (Default) or 'Kv'
noise_control.jet_diameter_m(90.0, 0.30, 0.805) # m
internal_spectrumfunctionEq. (19): the internal level spread over the third-octave bands around the peak.
• internal_level [dB], peak_frequency [Hz], frequencies [Hz]
• Falls as f^-2.5 above the peak and f^1.7 below it
noise_control.internal_spectrum(155.3, 7778.0, bands)
pipe_transmission_lossfunctionEq. (20a): what the pipe wall keeps in, band by band (negative).
• frequencies [Hz]
• internal_diameter_m, wall_thickness, valve_outlet_diameter_m [m]
• downstream_density [kg/m3], downstream_sound_speed [m/s], pipe_density [kg/m3]
• pipe_sound_speed, air_sound_speed, atmospheric_pressure_pa, standard_pressure_pa
noise_control.pipe_transmission_loss(bands, internal_diameter_m=0.2, ...)
coincidence_frequencies / PipeFrequenciesfunction / dataclassThe ring and two coincidence frequencies of Eqs. (21) to (23) that shape the transmission loss.
• internal_diameter_m, wall_thickness, downstream_sound_speed
• ring f_r, internal_coincidence f_o, external_coincidence f_g
noise_control.coincidence_frequencies(0.2, 0.008, 408.0)
multistage_trim_conditions / MultistageConditionsfunction / dataclassClause 6.3: what a multistage trim hands Clause 5 in place of the valve inlet (Eqs. (27) to (29)).
• inlet_pressure_pa, outlet_pressure_pa [Pa], inlet_density [kg/m3]
• flow_coefficient C of the valve, last_stage_coefficient C_n
• result: flow_coefficient, stagnation_pressure_pa p_n, stagnation_density rho_n, and equation: which of '28a', '28b', '28c' NOTE 3 selected
noise_control.multistage_trim_conditions(inlet_pressure_pa=7e6, ...)
last_stage_flow_coefficient / LAST_STAGE_AREA_CONSTANTSfunction / constantEq. (27): C_n = N_16 A_n, the flow coefficient of the last stage from its total flow area.
• total_area A_n [m2]
• coefficient: 'Cv' (Default) or 'Kv', selecting N_16 from Table 1
6.3 asks for this only when the manufacturer states no C_n
noise_control.last_stage_flow_coefficient(6.44e-3) → 315
multiple_passage_jet_diameter / MAXIMUM_PASSAGE_ASPECTfunction / constantEq. (26): the jet diameter of a single-stage, many-passage trim, where [0.9 - 0.06 l/d] replaces the pressure recovery factor.
• flow_coefficient, style_modifier, passage_length l [m], passage_diameter_m d [m]
• coefficient: 'Cv' (Default) or 'Kv'
• l/d capped at 4 by NOTE 1, since the bracket would reach zero at 15
noise_control.multiple_passage_jet_diameter(90.0, 0.094, 0.02, 0.01)
stage_level_correctionfunctionEq. (31): what the stages before the last one add back.
• last_stage_level L_pi,n [dB], stages n (≥ 2), inlet_pressure_pa p_1, stagnation_pressure_pa p_n [Pa]
L_pi = L_pi,n + 10 lg(p_1/p_n)/(n-1)^0.125, so the stage count barely moves it
noise_control.stage_level_correction(150.0, 3, 7e6, 2.1e6)
expander_noise / ExpanderNoisefunction / dataclassClause 7: what the flow leaving the valve outlet makes (Eqs. (34) to (42)).
• frequencies [Hz]
• mass_flow, downstream_density, downstream_sound_speed
• internal_diameter_m D_i, throat_diameter_m d_i (the smaller of valve outlet and expander inlet) [m]
• velocity_correction L_g [dB], expander
• result: pipe_velocity (capped at Mach 0.8), inlet_velocity (capped at c_2), mach, stream_power, acoustical_efficiency, sound_power, peak_frequency, internal_level, band_internal_level
noise_control.expander_noise(bands, mass_flow=0.89, ...)
Expander / DEFAULT_EXPANDERdataclass / constantThe transition piece downstream of the valve, limited by 7.1 to 30 degrees of total included angle.
• contraction beta (Default: 0.93, the NOTE 1 figure for straight pattern globe valves; some rotary valves reach 0.7)
• efficiency_correction A_eta (Default: -3.0, Table 4's own expander row)
• strouhal_number St_p (Default: 0.2)
noise_control.Expander(contraction=0.7)
combine_internal_levelsfunctionEq. (43): two spectra at the same pipe wall, added in energy.
• *levels: two or more band level arrays of one shape [dB]
The valve trim and the outlet flow are two sources inside one pipe, and only the sum crosses the wall
noise_control.combine_internal_levels(trim, outlet)
ValveNoiseWarningwarning classA valve read outside the conditions IEC 60534-8-3 prints for it.
• emitted when the valve outlet passes the Mach 0.3 of NOTE 1 to Eq. (15) and no expander was given, so the second source is missing from the answer
warnings.simplefilter('error', noise_control.ValveNoiseWarning)
EXPANDER_PIPE_MACH_LIMIT / GLOBE_CONTRACTION_COEFFICIENTconstant0.8, the Mach number Eq. (34) caps the downstream pipe velocity at, and 0.93, the contraction coefficient NOTE 1 to Eq. (35) gives for straight pattern globe valves.noise_control.EXPANDER_PIPE_MACH_LIMIT
VALVE_ACOUSTIC_STYLESconstantTable 4: (A_eta, St_p) for the thirteen valve styles the table prints, from the globe parabolic plug to the expander.noise_control.VALVE_ACOUSTIC_STYLES['globe ported cage'] → (-3.8, 0.2)
FLOW_COEFFICIENT_CONSTANTSconstantTable 1: N_14 for the two flow coefficients, {'Cv': 4.6e-3, 'Kv': 4.9e-3}. Both are rounded to two digits, so the same valve rated either way differs by 1 %.noise_control.FLOW_COEFFICIENT_CONSTANTS
AERODYNAMIC_A_WEIGHTING_DBconstantTable 7: the A weighting the standard prints for its own 33 bands, which Eq. (25) sums with.noise_control.AERODYNAMIC_A_WEIGHTING_DB[19] → 0.0
MACH_LIMIT_STANDARD_TRIM / PIPE_WALL_MACH_LIMITconstant0.3 in both cases: the valve outlet Mach number above which Clause 5 gives way to Clause 7 (NOTE 1 to Eq. (15)), and the ceiling NOTE 2 puts on the pipe Mach number before Eq. (16).noise_control.MACH_LIMIT_STANDARD_TRIM
AIR_SOUND_SPEED_M_S / PIPE_SOUND_SPEED_M_Sconstant343 m/s and 5000 m/s, the values NOTES 3 and 4 print for the coincidence frequencies; the second is why Clause 1 restricts the method to steel pipe.noise_control.PIPE_SOUND_SPEED_M_S
STANDARD_ATMOSPHERE_PAconstant101325 Pa, the atmosphere Eqs. (20a) and (20c) are printed for. It is p_a and p_s both, which the standard keeps apart because a pipe can run at one and be rated at the other.noise_control.STANDARD_ATMOSPHERE_PA
STRUCTURAL_LOSS_REFERENCE_HZ / UNIVERSAL_GAS_CONSTANTconstant1.0 Hz, the f_s of Eq. (20c) that the equation never names again, and 8314 J/(kmol K), paired with a molecular mass in kg/kmol as Eqs. (10) and (14) are written for.noise_control.UNIVERSAL_GAS_CONSTANT
REGIME_SUBSONIC / REGIME_CHOKED / REGIME_SUPERSONIC / REGIME_SHOCK / REGIME_CONSTANT_EFFICIENCY / REGIME_COUNTconstant1 to 5, the five regimes of Clause 5.2 by the number it prints, and their count.res.regime == noise_control.REGIME_SHOCK
valve_hydrodynamic_noisefunctionControl valve hydrodynamic noise, the whole of IEC 60534-8-4 Clauses 4 and 5.
• stream: a LiquidStream, valve: a LiquidTrim, pipe: a LiquidPipe
• strouhal_form: 'annex' (Default) or 'clause', the two printings of Eq. (12)
• frequency (Default: the 50 Hz to 20 kHz thirds of 5.4.1)
res = noise_control.valve_hydrodynamic_noise(stream, valve, pipe)

• HydrodynamicValveNoise
LiquidStream / LiquidTrim / LiquidPipedataclassThe three groups of input IEC 60534-8-4 reads.
• LiquidStream: mass_flow [kg/s], inlet_pressure_pa / outlet_pressure_pa / vapour_pressure_pa [Pa], density [kg/m3], speed_of_sound [m/s]
• LiquidTrim: flow_coefficient C, style_modifier F_d, pressure_recovery F_L, incipient_ratio x_Fz, power_ratio r_W (Table 2), valve_diameter_m d and seat_diameter_m d_o [m], coefficient 'Cv' (Default) or 'Kv'
• LiquidPipe: internal_diameter_m D_i [m], wall_thickness t_p [m], density [kg/m3], and the printed defaults speed_of_sound, air_density, air_sound_speed
noise_control.LiquidTrim(flow_coefficient=90.0, ...)
HydrodynamicValveNoisedataclassWhat IEC 60534-8-4 says about one operating point on a liquid line.
• regime ('turbulent' / 'cavitating'), pressure_ratio x_F, differential and cavitation_differential [Pa], incipient_ratio / corrected_ratio
• jet_diameter_m [m], velocity U_vc [m/s], stream_power / sound_power [W], turbulent_efficiency / cavitation_efficiency
• internal_level [dB], strouhal_number, turbulent_peak / cavitation_peak [Hz]
• pipe_ring_frequency [Hz], reference_transmission_loss, turbulent_transmission_loss, cavitation_transmission_loss, transmission_loss [dB]
• frequencies and the three band arrays, plus external_level at 1 m, which the standard labels A-weighted although neither Eq. (18a) nor (18b) applies a weighting
res.regime, res.external_level
differential_pressure_ratio / cavitation_differentialfunctionEqs. (1) and (2): how far towards flashing the operating point is, and the differential the jet velocity is computed from.
• keyword-only: inlet_pressure_pa, outlet_pressure_pa, vapour_pressure_pa [Pa]; the second also takes pressure_recovery
• x_F = (p1 - p2)/(p1 - p_v); Delta p_c is the lesser of p1 - p2 and F_L^2 (p1 - p_v)
noise_control.differential_pressure_ratio(inlet_pressure_pa=1e6, outlet_pressure_pa=8e5, vapour_pressure_pa=2320.0) # 0.2005
incipient_cavitation_ratio / multihole_incipient_cavitation_ratio / corrected_incipient_ratiofunctionEqs. (3a), (3b) and (3c): where cavitation becomes audible.
• (3a): flow_coefficient, style_modifier, pressure_recovery, coefficient 'Cv' (Default) / 'Kv'
• (3b): passages N_o, hole_diameter_m d_H [m], pressure_recovery
• (3c) moves x_Fz from the 6e5 Pa the charts are drawn at to the working inlet_pressure_pa
4.2 asks for a value measured to IEC 60534-8-2; these are the estimates it offers instead
noise_control.incipient_cavitation_ratio(90.0, 0.42, 0.92) # 0.2543
vena_contracta_velocity / mechanical_stream_powerfunctionEqs. (5) and (6): the jet velocity and the stream power it carries.
• differential Delta p_c [Pa], density [kg/m3], pressure_recovery
• mass_flow [kg/s], velocity [m/s], pressure_recovery
noise_control.vena_contracta_velocity(2e5, 997.0, 0.92) # 21.77 m/s
turbulent_efficiency / cavitation_efficiencyfunctionEqs. (8) and (9): the two acoustical efficiencies the sound power is a fraction of.
• turbulent: velocity, speed_of_sound; 1e-4 at U_vc = c_L and linear below it
• cavitating (keyword-only): turbulent, differential, choked_differential, pressure_ratio, corrected_ratio
Exactly zero on the threshold, so the two regimes meet without a step
noise_control.turbulent_efficiency(21.77, 1400.0) # 1.555e-6
internal_sound_pressure_levelfunctionEq. (10): the level inside, at the pipe wall.
• keyword-only: sound_power W_a [W], density and speed_of_sound of the liquid, internal_diameter_m D_i [m]
The liquid's impedance is in the numerator, which is why a water line runs 150 dB inside
noise_control.internal_sound_pressure_level(sound_power=0.00234, density=997.0, speed_of_sound=1400.0, internal_diameter_m=0.1071)
jet_strouhal_number / turbulent_peak_frequency / cavitation_peak_frequencyfunctionEqs. (12), (11) and (13): where the noise sits in frequency.
• jet_strouhal_number (keyword-only): flow_coefficient, style_modifier, pressure_recovery, corrected_ratio, valve_diameter_m, seat_diameter_m, inlet_pressure_pa, vapour_pressure_pa, coefficient, form 'annex' (Default) / 'clause'
• turbulent_peak_frequency(strouhal_number, velocity, jet)
• cavitation_peak_frequency(turbulent_peak, pressure_ratio, corrected_ratio): six times the turbulent peak on the threshold, falling from there
noise_control.cavitation_peak_frequency(654.35, 0.3508, 0.2386)
pipe_ring_frequency / reference_transmission_loss / transmission_loss_correctionfunctionEqs. (14), (15), (16b) and (22b): the pipe wall.
• pipe_ring_frequency(internal_diameter_m, pipe_sound_speed=5000)
• reference_transmission_loss(internal_diameter_m, wall_thickness, pipe_density=…, air_density=…, …), negative by construction and therefore added downstream
• transmission_loss_correction(frequency, ring): one expression for both printed equations, scalar or per band
noise_control.reference_transmission_loss(0.1071, 0.0036, pipe_density=7800.0) # -44.7 dB
cavitation_transmission_lossfunctionEq. (17): what cavitation does to the wall.
• turbulent_loss [dB]; keyword-only turbulent_peak, cavitation_peak [Hz], efficiency_ratio
• pressure_ratio and corrected_ratio apply the NOTE's floor, which keeps the cavitating loss from falling below the turbulent one within 0.1 of the threshold
noise_control.cavitation_transmission_loss(-71.84, turbulent_peak=654.35, cavitation_peak=1088.94, efficiency_ratio=0.377)
turbulent_distribution / cavitation_distribution / band_internal_levelsfunctionEqs. (20a), (20b), (19a) and (19b): the internal level, band by band.
• the two distributions take frequency and their own peak, and return a dB correction
• band_internal_levels(frequency, internal_level, *, turbulent_peak, cavitation_peak=None, cavitation_fraction=0.0) weights the two by their share of the sound power
Turbulent: 3 dB per octave up, 9 dB down. Cavitating: 4.5 dB both ways
noise_control.band_internal_levels(bands, 156.5, turbulent_peak=654.4, cavitation_peak=1088.9, cavitation_fraction=0.377)
stage_conditions / StageConditions / combine_stage_levelsfunction / dataclass / functionClause 6: Eqs. (23a) to (24b), (26) and (27) for a multistage trim.
• stage_conditions (keyword-only): inlet_pressure_pa, outlet_pressure_pa, vapour_pressure_pa, stage_coefficients C_i, flow_coefficient C
• each stage takes a share of the differential in inverse proportion to its own C_i squared, the series law 1/C^2 = sum(1/C_i^2)
• StageConditions: inlet_pressure_pa, outlet_pressure_pa, pressure_ratio
• combine_stage_levels(*levels): the energy sum of Eq. (27)
noise_control.stage_conditions(inlet_pressure_pa=1e6, outlet_pressure_pa=4e5, vapour_pressure_pa=2320.0, stage_coefficients=[156.0]*3, flow_coefficient=90.0)
last_stage_differential / uniform_passage_style_modifier / last_stage_seat_diameter_mmfunction6.3.2: the fixed multistage device, where only the last stage is calculated.
• last_stage_differential (keyword-only, Eq. (28)) caps the differential at the cavitation threshold of the last stage, not at F_L^2 as Eq. (2) does
• uniform_passage_style_modifier(passages) = 1/sqrt(N_o), Eq. (29)
• last_stage_seat_diameter_mm(flow_coefficient, coefficient='Cv'): the unnumbered 5.2 sqrt(N_34 C_n), which returns millimetres for a symbol Clause 3 declares in metres (see docs/ERRATA.md)
noise_control.uniform_passage_style_modifier(16) # 0.25
ACOUSTIC_POWER_RATIOS / CAPACITY_SCALE_CONSTANTSconstantTable 2: r_W for the twelve valves and fittings the table prints, a quarter for the globes and rotaries, a half for the butterflies, one for an expander. Table 1: N_34, {'Cv': 1.17, 'Kv': 1.0}noise_control.ACOUSTIC_POWER_RATIOS['globe parabolic plug'] # 0.25
STROUHAL_CONSTANTS / REFERENCE_INLET_PRESSURE_PA / CAVITATION_FLOOR_WIDTH / AIR_DENSITY_KG_M3constantThe two printings of Eq. (12), {'annex': 0.036, 'clause': 0.02}; 6e5 Pa, the inlet pressure x_Fz is drawn at; 0.1, the width in x_F of the band the NOTE to Eq. (17) floors the efficiency ratio in; 1.293 kg/m3 for the air outside the pipenoise_control.STROUHAL_CONSTANTS['annex']
EnclosureResultdataclassEnclosure insertion-loss result.
• panel_transmission_loss, correction C, insertion_loss, room_constant, external_area, internal_area
• .plot()
res.insertion_loss
program_loudnessfunctionEBU R 128 measurement set of a programme (BS.1770-5 + Tech 3341/3342).
• x: signal (1D mono or 2D [channels, samples], 1.0 = 0 dBFS)
• fs [Hz]
• weights: per-channel Gi (Default: Table 3 by channel count)
• momentary_step [s] (Default: 0.01), short_term_step [s] (Default: 0.1)
• oversample: true-peak factor (Default: None → reaches 192 kHz)
res = broadcast.program_loudness(x, fs)

• ProgramLoudnessResult
integrated_loudnessfunctionProgramme (integrated) loudness with the two-stage gate (BS.1770-5 Annex 1).
• x, fs [Hz]
• weights (Default: Table 3 by channel count)
Absolute gate −70 LKFS, relative −10 LU
integrated_loudness(x, fs) # LUFS
loudness_rangefunctionLoudness range LRA (EBU Tech 3342).
• short_term_loudness: S readings [LUFS] at ≥ 10 Hz
Cascaded gate (−70 LUFS abs, −20 LU rel), 10th-95th percentile spread
loudness_range(res.short_term) # LU
true_peak_levelfunctionTrue-peak level (BS.1770-5 Annex 2).
• x (1.0 = 0 dBFS), fs [Hz]
• oversample: factor ≥ 1 (Default: None → smallest reaching 192 kHz, 4 at 48 kHz)
true_peak_level(x, fs) # dBTP
Scalar for 1D, per-channel array for 2D
k_weightingfunctionApply the two-stage K-weighting pre-filter (BS.1770-5 Annex 1).
• x, fs [Hz]
Spherical-head shelf + RLB high-pass
y = broadcast.k_weighting(x, fs)
k_weighting_coefficientsfunctionK-weighting biquads (Tables 1-2).
• fs [Hz] (≥ 16 kHz)
Verbatim tables at 48 kHz; analog-prototype redesign elsewhere
(b1, a1), (b2, a2) = broadcast.k_weighting_coefficients(fs)
k_weighting_responsefunctionK-weighting magnitude frequency response (BS.1770-5 Annex 1).
• fs [Hz] (≥ 16 kHz, Default: 48000)
• frequencies [Hz] (Default: None → n log points 10 Hz→Nyquist), n (Default: 512)
Evaluates the Table 1-2 biquads with freqz
k_weighting_response().plot()

• KWeightingResponse
channel_weightfunctionPosition-dependent channel weight Gi (BS.1770-5 Annex 3, Table 4).
• azimuth [deg], elevation [deg] (Default: 0)
1.41 for mid-layer side positions, 1.0 elsewhere
channel_weight(110, 0) # 1.41
DEFAULT_CHANNEL_WEIGHTSdictTable 3 weights by channel count.
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]
ProgramLoudnessResultdataclassEBU Mode measurement result.
• integrated [LUFS], loudness_range [LU], true_peak [dBTP]
• momentary / short_term series with momentary_time / short_term_time [s]
• max_momentary / max_short_term [LUFS]
• relative_threshold, lra_low / lra_high [LUFS]
• true_peak_per_channel [dBTP], channel_weights, fs
• .plot(): M/S over time with I and LRA annotated
• .report(path, *, tolerance='qc'/'live'): R 128 fiche (±0.2 LU item i / ±1.0 LU item h)
res.integrated, res.loudness_range
KWeightingResponsedataclassK-weighting magnitude frequency response (BS.1770-5 Annex 1).
• frequencies [Hz], magnitude_db (combined) [dB]
• shelf_db (stage 1, +4 dB shelf), highpass_db (stage 2, RLB) [dB]
• fs [Hz]
• .plot(): magnitude vs frequency (log axis) with the two stages
k_weighting_response().magnitude_db
quasi_peak_meterfunctionITU-R BS.468-4 clause 2 quasi-peak reading of a record, in dBqps.
• x: 1-D record, or a Signal
• fs [Hz]
• weighted: run the clause 1 network first (Default: True; False is the clause 2.4 mode)
• reference: level reference in the record's own unit (Default: None → 0.775 V; required for a calibrated Signal, whose samples are pascals)
Reading = the maximum of the needle over the record, so the record must include the decay
res = broadcast.quasi_peak_meter(x, fs)

• QuasiPeakResult
QuasiPeakResultdataclassQuasi-peak reading of one record (BS.468-4 clause 2).
• reading (record's unit), level_db, reference
• trace: the needle, sample for sample with the record
• fs [Hz], weighted
• .times [s], .level_unit: 'dBqps' only against the 0.775 V of clause 2.6
• .plot(): the trace with the reading marked
• no .report(): BS.468-4 prescribes no report format
res.reading, res.level_unit
verify_quasi_peak_dynamicsfunctionCheck the detector against the eleven acceptance windows of Tables 2 and 3.
• fs [Hz] (Default: 48000)
• keyword-only: ballistics, the chain to check (Default: BS468_BALLISTICS)
Builds the clause 2.1 and 2.2 stimuli (5 kHz, integral periods, through the network) and reads each against the steady tone
rep = broadcast.verify_quasi_peak_dynamics()

• QuasiPeakDynamicsResult
QuasiPeakDynamicsResultdataclassThe eleven acceptance windows of clause 2, read on one chain.
• fs [Hz], passes
• worst_margin_db: smallest of the eleven margins [dB]
• worst_deviation_db: largest departure from a printed reference [dB]
• stimuli: eleven rows of stimulus, table, reading_percent, lower_percent, reference_percent, upper_percent, deviation_db, margin_db
• no .report(): BS.468-4 prescribes no report format
rep.passes, rep.worst_margin_db
BS468_BALLISTICS / QuasiPeakBallisticsconstant / dataclassThe three time constants of the quasi-peak chain, in seconds (a fit to the eleven reference readings, printed nowhere in BS.468-4).
• charge 1.4096 ms, discharge 293.20 ms (the peak rectifier)
• reading_device 139.99 ms (clause 2.5's symmetric indicator)
The tables identify them only to within a factor of 1.88, 1.61 and 2.09 -- marginal ranges, not a box
BS468_BALLISTICS.discharge
DBQPS_REFERENCEfloatThe 0.775 V r.m.s. of clause 2.6, the steady 1 kHz sine that reads 0 dBqps and fixes the scale of the whole instrumentDBQPS_REFERENCE # 0.775
sound_pressure_levelfunctionUnderwater SPL (ISO 18405), dB re 1 µPa.
• pressure: signal (1D) [Pa]
• reference: p₀ (Default: 1e-6)
sound_pressure_level(p)
sound_exposure_levelfunctionUnderwater SEL (ISO 18405/18406), dB re 1 µPa²·s.
• pressure (1D) [Pa]
• fs [Hz]
• reference: E₀ (Default: 1e-12)
sound_exposure_level(p, fs)
peak_sound_pressure_levelfunctionZero-to-peak level (ISO 18406), dB re 1 µPa.
• pressure (1D) [Pa]
• reference (Default: 1e-6)
peak_sound_pressure_level(p)
UNDERWATER_REFERENCE_PRESSURE / UNDERWATER_REFERENCE_EXPOSUREfloatISO 18405 reference quantities.
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_splfunctionRe-reference a level between 1 µPa and 20 µPa (∓26.02 dB).
• level [dB]
Reference change only, not an energy equivalence.
underwater_to_in_air_spl(120.0)
radiated_noise_levelfunctionShip radiated noise level (ISO 17208-1), dB re 1 µPa·m.
• rms_pressure_pa [Pa]
• distance [m]
= 20·lg(p/p₀)+20·lg(r/r₀)
radiated_noise_level(2e-6, 100.0)
hydrophone_depthsfunctionISO 17208-1 hydrophone depths from depression angles_deg.
• cpa_distance [m]
• angles_deg (Default: (15,30,45)) [deg]
= cpa·tan(angle_deg)
hydrophone_depths(100.0)
source_level_uncertaintyfunctionTabulated source-level uncertainty (ISO 17208-2).
• frequency [Hz]
5 dB ≤100 Hz / 3 dB 125 Hz–16 kHz / 4 dB >16 kHz
source_level_uncertainty(1000.0) # 3.0
monopole_source_levelfunctionEquivalent monopole source level (ISO 17208-2).
• rnl: RNL [dB re 1 µPa·m] (scalar/array)
• frequency [Hz]
• draught D [m]
• speed_of_sound (Default: 1500) [m/s]
Ls = LRN + ΔL, d_s = 0.7·D
res = underwater.monopole_source_level(rnl, f, 6.0)

• ShipSourceLevelResult
ShipSourceLevelResultdataclassShip source-level result.
• frequencies [Hz]
• radiated_noise_level / surface_correction / source_level [dB]
• source_depth [m] / speed_of_sound [m/s]
• .plot(): RNL/Ls/ΔL vs frequency
res.source_level, res.surface_correction
single_strike_selfunctionSingle-strike SEL (ISO 18406), dB re 1 µPa²·s.
• pressure: one strike (1D) [Pa]
• fs [Hz]
single_strike_sel(p, fs)
cumulative_selfunctionCumulative SEL over strikes (ISO 18406).
• single_sels: per-strike SELs [dB]
= 10·lg(Σ 10^(SELₙ/10))
cumulative_sel([170, 176, 173])
cumulative_sel_identicalfunctionCumulative SEL of N identical strikes.
• sel_ss [dB]
• n_strikes N (≥ 1)
= sel_ss + 10·lg(N)
cumulative_sel_identical(180.0, 50)
pile_strike_metricsfunctionPer-strike pile-driving metrics (ISO 18406).
• pressure: one strike (1D) [Pa]
• fs [Hz]
res = underwater.pile_strike_metrics(p, fs)

• PileStrikeResult
sound_speed_profilefunctionSound-speed profile over a depth column.
• depths (1D, increasing) [m]
• temperatures_c / salinities: array or scalar
• model / latitude
sound_speed_profile(z, T, S)

• SoundSpeedProfile
SoundSpeedProfiledataclassSound-speed profile.
• depth [m] / speed_of_sound [m/s] / gradient_per_s [(m/s)/m]
• model
• .plot(): speed vs depth (depth down)
prof.speed_of_sound, prof.gradient_per_s
spreading_lossfunctionGeometrical spreading loss, dB.
• range_m [m] (scalar/array)
• law: "spherical" / "cylindrical" / "practical"
• transition_range [m] (for "practical")
spreading_loss(1000.0)
seawater_absorptionfunctionVolume absorption α, dB/km.
• frequency_hz [Hz] (scalar/array)
• temperature_c [°C] / salinity [ppt] / depth [m] / ph
• model: "francois-garrison" (default) / "ainslie-mccolm" / "thorp"
seawater_absorption(10e3)
propagation_lossfunctionPropagation loss PL = spreading + α·R, α in dB/km and R in km.
• range_m [m] / frequency_hz [Hz]
• law / temperature_c / salinity / depth / ph / model / transition_range
propagation_loss(r, 10e3)

• PropagationLossResult
PropagationLossResultdataclassPropagation-loss result.
• range_m [m] / pl / spreading / absorption [dB]
• frequency [Hz] / absorption_coefficient [dB/km]
• law / model
• .plot(): PL vs range
res.pl, res.absorption_coefficient
array_directivity_indexfunctionDirectivity index of an unshaded line array (Ainslie 2010 Eqs. 6.49–6.57).
• array_length_m L, wavelength_m λ
• steer_angle_rad ψ from broadside (Default: 0)
• DI = 10 log₁₀(4π/δΩ); also the array gain in isotropic noise, which is the case the sonar equation assumes
• 10 log₁₀(2L/λ) at broadside, 3 dB more at endfire, → 0 dB as L/λ → 0
underwater.array_directivity_index(50.0, 1.5) # 18.3
detection_thresholdfunctionDetection threshold at 50 % detection probability (Ainslie 2010 Eq. 11.22).
• false_alarm_probability p_fa, in (0, ½)
• DT = 10 log₁₀(log₂[1/(2 p_fa)]) − 0,8 dB, base two
• ±0,1 dB for p_fa < 10⁻² with one-dominant-plus-Rayleigh statistics; diverges at ½
underwater.detection_threshold(1e-4) # 10.09
passive_sonar_equationfunctionPassive sonar equation.
• source_level / propagation_loss / noise_level [dB]
• directivity_index / detection_threshold (Default: 0)
SE = SL − PL − (NL − DI) − DT
passive_sonar_equation(140, 80, 60)

• SonarEquationResult
active_sonar_equationfunctionActive (monostatic) sonar equation.
• source_level / propagation_loss / target_strength / noise_level [dB]
• directivity_index / detection_threshold / reverberation_level
noise-limited SE = SL − 2·PL + TS − (NL − DI) − DT; with reverberation_level → SE = SL − 2·PL + TS − RL − DT
active_sonar_equation(220, 70, 15, 60)

• SonarEquationResult
SonarEquationResultdataclassSonar-equation result.
• mode / signal_excess / snr [dB] / figure_of_merit [dB]
• propagation_loss / source_level / noise_level / directivity_index / detection_threshold [dB]
• target_strength [dB or None] / reverberation_limited
• .plot(): signal excess vs PL
res.signal_excess, res.figure_of_merit
critical_anglefunctionCritical grazing angle φc = arccos(c1/c2), degrees.
• c1 / c2 [m/s] (needs c2 > c1)
critical_angle(1500, 1650)
reflection_coefficientfunctionComplex seabed Rayleigh reflection coefficient.
• grazing_angle_deg [°] (scalar/array)
• rho1 / c1 / rho2 / c2
reflection_coefficient(30, rho1=1000, c1=1500, rho2=1900, c2=1650)
bottom_reflection_lossfunctionSeabed reflection loss BL = −20·lg|R|, dB.
• grazing_angle_deg [°]
• rho1 (Default: 1000) / c1 (Default: 1500) / rho2 / c2
bottom_reflection_loss(phi, rho2=1900, c2=1650)

• BottomLossResult
BottomLossResultdataclassSeabed reflection result.
• grazing_angle_deg [°] / reflection_loss [dB]
• reflection_coefficient [complex] / critical_angle_deg [° or None]
• .plot(): bottom loss vs grazing angle
res.reflection_loss, res.critical_angle_deg
seabed_reflectionfunctionPlottable seabed reflection coefficient (Rayleigh).
• grazing_angle_deg [°]
• rho1 (Default: 1000) / c1 (Default: 1500) / rho2 / c2
seabed_reflection(phi, rho2=1900, c2=1650)

• SeabedReflection
SeabedReflectiondataclassSeabed reflection-coefficient result.
• grazing_angle_deg [°] / reflection_coefficient [complex]
• magnitude |R| / bottom_loss [dB] / critical_angle_deg [° or None]
• rho1 / c1 / rho2 / c2
• .plot(): |R| vs grazing angle
res.magnitude, res.critical_angle_deg
wind_noise_spectrumfunctionWenz wind noise (rule of fives), dB re 1 µPa²/Hz.
• frequency_hz [Hz] / wind_speed_knots [kn]
wind_noise_spectrum(1000, 5)
thermal_noise_spectrumfunctionMellen thermal noise, dB re 1 µPa²/Hz.
• frequency_hz [Hz]
• temperature_c (Default: 16.85) / density (Default: 1025) / speed_of_sound (Default: 1500)
thermal_noise_spectrum(5e4)
ocean_ambient_noisefunctionComposite ambient-noise spectrum (wind + thermal [+ shipping]).
• frequency_hz [Hz] / wind_speed_knots [kn]
• shipping [dB or None] / temperature_c / density / speed_of_sound
ocean_ambient_noise(f, wind_speed_knots=10)

• AmbientNoiseResult
AmbientNoiseResultdataclassAmbient-noise result.
• frequencies [Hz] / spectrum_level [dB re 1 µPa²/Hz]
• wind / thermal / shipping [dB or None]
• wind_speed_knots [kn]
• .plot(): composite + components vs frequency
res.spectrum_level
ship_source_spectrumfunctionPredicted ship source-level spectrum.
• speed_knots (Default: 12) / length_m (Default: 100)
• vessel_class (Default: "containership") / model: "jomopans-echo" (default) / "randi" / "wales-heitmeyer"
• frequency_hz (Default: decidecade 10 Hz–31.5 kHz)
ship_source_spectrum(18, 300, vessel_class="containership")

• ShipTrafficSpectrum
ShipTrafficSpectrumdataclassShip source-spectrum result.
• frequencies [Hz] / source_psd [dB re 1 µPa²/Hz at 1 m] / band_level [dB re 1 µPa m]
• model / vessel_class / speed_knots / length_m
• .plot(): source PSD vs frequency
res.source_psd, res.band_level
VESSEL_CLASSEStupleThe 13 JOMOPANS-ECHO vessel classes."bulker" in VESSEL_CLASSES
normal_modesfunctionNormal-mode propagation loss (range-independent).
• frequency_hz / depths [m] / sound_speeds [m/s]
• 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)

• NormalModeResult
ray_tracefunctionRay tracing and travel times through a sound-speed profile (vectorised).
• depths [m] / sound_speeds [m/s]
• source_depth [m] / launch_angles_deg / max_range [m] / n_steps
• bathymetry: a (ranges_m, depths_m) polyline pair, or None for a level bottom
ray_trace(z, c, source_depth=1000, launch_angles_deg=[-10,0,10])

• RayTraceResult
eigenraysfunctionEigenrays connecting a traced fan's source to one receiver.
• trace: a RayTraceResult / receiver_range [m] / receiver_depth [m]
• bottom: "pressure-release"|"rigid"|FluidSeabed
• max_arrivals (earliest kept) / n_steps
eigenrays(fan, receiver_range=5e3, receiver_depth=60)

• EigenrayResult
gaussian_beamsfunctionGaussian beam PL field: finite at caustics, graded into shadow zones.
• frequency_hz / depths [m] / sound_speeds [m/s]
• source_depth [m] / max_range [m] / range_step [m] / ranges_m / receiver_depths_m
• fan: a BeamFan / bottom: "pressure-release"|"rigid"|FluidSeabed
• absorption: model name|VolumeAbsorption|None / bathymetry: (ranges_m, depths_m)|None
gaussian_beams(300, [0,1000], [1500,1500], source_depth=300)

• GaussianBeamResult
BeamFandataclassThe launch fan of gaussian_beams.
• max_angle_deg (Default: 80) / n_beams (Default: overlap condition) / beam_width W₀ [m] (Default: per launch angle)
BeamFan(max_angle_deg=45.0)
FluidSeabeddataclassA lossy fluid seabed, passed as the bottom of eigenrays/gaussian_beams.
• density ρ₂ [kg/m³] / speed_of_sound c₂ [m/s] / water_density ρ₁ (Default: 1000)
FluidSeabed(density=1800, speed_of_sound=1700)
VolumeAbsorptiondataclassSeawater volume absorption: a model and its water.
• model: "francois-garrison"|"ainslie-mccolm"|"thorp"
• temperature_c [°C] / salinity [ppt] / ph
VolumeAbsorption("thorp")
parabolic_equationfunctionSplit-step Fourier parabolic-equation PL field.
• frequency_hz / depths [m] / sound_speeds [m/s]
• source_depth [m] / max_range [m] / range_step [m] / n_depth_points
parabolic_equation(50, [0,200], [1500,1500], source_depth=50)

• ParabolicEquationResult
NormalModeResultdataclassNormal-mode result.
• frequency / wavenumbers [rad/m] / mode_depths [m] / mode_functions
• ranges [m] / propagation_loss [dB] / receiver_depth / source_depth
• .plot(): PL vs range
res.wavenumbers, res.propagation_loss
RayTraceResultdataclassRay-tracing result.
• launch_angles_deg [°] (n_rays,)
• ranges [m] / depths [m] / travel_times [s] (all (n_rays, n_steps))
• source_depth / water_depth [m]
• .plot(): ray paths
res.ranges, res.depths, res.travel_times
EigenrayResultdataclassEigenray arrival list, earliest first.
• launch_angles_deg / arrival_angles_deg [°] / travel_times [s] / amplitudes (complex, re 1 m)
• surface_reflections / bottom_reflections / caustic_crossings (per arrival)
• receiver_range / receiver_depth / source_depth / water_depth [m]
• .plot(): per-path loss stems vs delay
res.travel_times, res.amplitudes
GaussianBeamResultdataclassGaussian beam result.
• frequency / ranges [m] / depths [m]
• propagation_loss [dB] and pressure (both (n_depths, n_ranges))
• launch_angles_deg [°] / ray_ranges / ray_depths [m] / beam_widths [m] / wavefront_curvatures [1/m] (all (n_beams, n_steps))
• initial_beam_widths [m] (n_beams,) / source_depth / water_depth [m]
• .plot(): PL field
res.propagation_loss, res.beam_widths
ParabolicEquationResultdataclassParabolic-equation result.
• frequency / ranges [m] / depths [m]
• propagation_loss [dB] (n_depths, n_ranges) / source_depth
• .plot(): PL field
res.propagation_loss
PileStrikeResultdataclassPile-strike result.
• single_strike_sel [dB re 1 µPa²·s]
• peak_spl / spl [dB re 1 µPa]
• pulse_duration [s]
• pressure [Pa] / fs [Hz]
• .plot(): waveform + cumulative energy
res.single_strike_sel, res.peak_spl
strike_sel_spectrumfunctionBand-resolved single-strike SEL (ISO 18406).
• pressure: one strike (1D) [Pa] / fs [Hz]
• fraction: 1 or 3 (Default: 3) / limits [Hz] (Default: (10, 20000))
Parseval band split of ∫p²dt
strike_sel_spectrum(p, fs)

• StrikeSelSpectrum
StrikeSelSpectrumdataclassBand-resolved strike SEL.
• frequencies [Hz] / band_sel [dB re 1 µPa²·s]
• total_sel / broadband_sel [dB] / fraction / fs [Hz]
• .plot(): band SEL vs frequency
spec.frequencies, spec.band_sel
weston_propagation_lossfunctionWeston shallow-water regimes: PL = −10·lg F (Ainslie §9.1.1.2).
• range_m [m] / frequency_hz [Hz] / water_depth H [m]
• seabed: "sand" (default) / "mud" / WestonSeabed
• speed_of_sound (Default: 1500) / source_depth / receiver_depth [m]
• critical_angle_deg [°] / reflection_loss_gradient_value_np_per_rad [Np/rad] overrides
weston_propagation_loss(r, 250, 50)

• WestonPropagationResult
WestonPropagationResultdataclassWeston regime result.
• range_m [m] / propagation_loss [dB re 1 m²] / propagation_factor [m⁻²] / regime
• spherical / cylindrical / mode_stripping / single_mode / multipath [dB]
• boundaries / frequency / water_depth / source_depth / receiver_depth / seabed
• .plot(): composite loss + each regime law
res.propagation_loss, res.regime
weston_regime_boundariesfunctionRange boundaries of the four Weston regimes.
• frequency_hz [Hz] / water_depth [m]
• seabed / speed_of_sound / critical_angle_deg / reflection_loss_gradient_value_np_per_rad
weston_regime_boundaries(250, 50)

• WestonRegimeBoundaries
WestonRegimeBoundariesdataclassWeston regime boundaries.
• spherical_to_cylindrical / cylindrical_to_mode_stripping / mode_stripping_to_single_mode [m]
• critical_angle_deg [rad] / reflection_loss_gradient [Np/rad] / effective_depth [m]
• cutoff_frequency [Hz] / mode_count
b.cylindrical_to_mode_stripping
reflection_loss_gradientfunctionSeabed reflection loss gradient η (Ainslie Eqs. 9.51/9.53), Np/rad.
• seabed: "sand" (default) / "mud" / WestonSeabed
• frequency_hz [Hz] (refracting seabeds only)
reflection_loss_gradient("sand") # 0.278
critical_grazing_anglefunctionψc = arccos(c_w/c_sed), radians (0 when none exists).
• sound_speed_ratio c_sed/c_w
critical_grazing_angle(1.20)
effective_depthfunctionWeston effective water depth He (Ainslie Eq. 9.55), m.
• water_depth [m] / frequency_hz [Hz]
• seabed / speed_of_sound
effective_depth(50, 250)
waveguide_cutoff_frequencyfunctionShallow-water cut-off frequency fc (Ainslie Eq. 9.60), Hz.
• water_depth [m]
• seabed / speed_of_sound
waveguide_cutoff_frequency(50)
loss_parameterfunctionSediment loss parameter ε = β/(40·π·lg e) (Ainslie Eq. 9.23).
• attenuation_db_per_wavelength β [dB/λ]
loss_parameter(0.88) # 0.0161
WestonSeabeddataclassCharacteristic seabed (Ainslie Table 9.1).
• name / grain_size Mz / sound_speed_ratio / density_ratio
• attenuation_db_per_wavelength [dB/λ] / loss_parameter ε / sound_speed_gradient_per_s c′ [s⁻¹]
WESTON_SEABEDS["sand"].density_ratio
WESTON_SEABEDSdictAinslie Table 9.1 seabeds: "sand" (Mz 1.5) and "mud" (Mz 8).WESTON_SEABEDS["mud"]
WESTON_REGIMEStupleRegime labels in range order.
"spherical", "cylindrical", "mode-stripping", "single-mode"
WESTON_REGIMES[2]
detection_rangefunctionRange where the closed-form PL equals the figure of merit, m.
• figure_of_merit [dB] / frequency_hz [Hz]
• law / transition_range / temperature_c / salinity / depth / ph / model
• max_range (Default: 500000) [m] / n_points (Default: 400)
detection_range(82.7, 50e3)

• DetectionRangeResult
DetectionRangeResultdataclassDetection-range result.
• detection_range [m] / figure_of_merit [dB] / frequency [Hz]
• range_m [m] / propagation_loss [dB] / absorption_coefficient [dB/km]
• law / model
• .plot(): PL vs FOM with the crossing
res.detection_range
detection_range_from_curvefunctionDetection range read off any computed PL curve, m.
• figure_of_merit [dB] / range_m [m] / propagation_loss [dB]
• crossing: "first" (default) / "last"
detection_range_from_curve(60, nm.ranges, nm.propagation_loss)
auditory_weightingfunctionMarine-mammal auditory weighting W(f), dB.
• frequency_hz [Hz] / group: hearing-group code
• guidance: "nmfs-2024" (default) / "nmfs-2018" / "southall-2019"
auditory_weighting(1000, "LF")

• AuditoryWeightingResult
AuditoryWeightingResultdataclassAuditory weighting result.
• frequencies [Hz] / weighting W(f) [dB] / exposure_function E(f) [dB]
• parameters / guidance / group / weighted_tts_onset Tw = K + C [dB]
• .plot(): W(f) vs frequency
res.weighting, res.weighted_tts_onset
weighting_parametersfunctionWeighting/exposure parameters of one hearing group.
• group / guidance
weighting_parameters("OW", guidance="nmfs-2024")

• WeightingParameters
WeightingParametersdataclassWeighting-function parameters.
• group / guidance / description
• a / b / f1_khz / f2_khz / c_db / c_db_as_printed / k_db [dB]
• in_air / hearing_range_hz
p.a, p.f1_khz, p.c_db
hearing_groupsfunctionHearing-group codes of a guidance version.
• guidance (Default: "nmfs-2024")
Codes are not portable between versions
hearing_groups("southall-2019")
WEIGHTING_GUIDANCEtupleSelectable guidance versions.
"nmfs-2024", "nmfs-2018", "southall-2019"
WEIGHTING_GUIDANCE[0]
exposure_criteriafunctionPublished TTS and injury onset criteria.
• group / guidance
• impulsive (Default: False)
exposure_criteria("VHF", impulsive=True)

• ExposureCriteria
ExposureCriteriadataclassTTS / injury onset criteria.
• group / guidance / impulsive
• tts_sel / injury_sel / tts_peak_spl / injury_peak_spl [dB or None]
• injury_label ("PTS" / "AUD INJ") / sel_reference / peak_reference / source
crit.injury_sel, crit.injury_peak_spl
weighted_exposurefunctionWeight a band spectrum, accumulate it and compare with the criteria.
• frequency_hz [Hz] / band_sel [dB] / group
• guidance / impulsive (Default: True) / n_events (Default: 1) / peak_spl [dB]
weighted_exposure(f, sel, "LF", n_events=3000)

• WeightedExposureResult
WeightedExposureResultdataclassWeighted-exposure assessment.
• frequencies [Hz] / band_sel / weighting / weighted_band_sel [dB]
• unweighted_sel / weighted_sel / cumulative_sel [dB] / peak_spl [dB or None] / n_events
• criteria / sel_margin / tts_margin / peak_margin / tts_peak_margin [dB or None]
• exceeds_injury / exceeds_tts / guidance / group
• .plot(): weighted spectrum vs criteria
res.cumulative_sel, res.exceeds_injury
group_audiogramfunctionMarine-mammal group audiogram (Southall et al. 2019 Eq. 1), dB.
• frequency_hz [Hz] / group
• normalized (Default: False → Table 2; True → Table 3)
group_audiogram(f, "VHF")

• AudiogramResult
orca_audiogramfunctionKiller-whale audiogram (Ainslie Eq. 11.159), dB re 1 µPa.
• frequency_hz [Hz], 500 Hz to 80 kHz
Three-branch fit; 39.0 dB at 22.6 kHz, 51.2 dB at 50 kHz
orca_audiogram(50e3)

• AudiogramResult
AudiogramResultdataclassHearing-threshold result.
• frequencies [Hz] / threshold [dB]
• group / source / in_air
• best_frequency [Hz] / best_threshold [dB]
• .plot(): threshold vs frequency
res.threshold, res.best_threshold
audiogram_parametersfunctionFit parameters of a published group audiogram.
• group / normalized
audiogram_parameters("HF")

• AudiogramParameters
AudiogramParametersdataclassGroup-audiogram fit parameters.
• group / t0 [dB] / f1_khz / f2_khz [kHz] / a [dB/decade] / b
• r_squared / in_air
p.t0, p.f1_khz
AUDIOGRAM_GROUPStupleGroups with a published audiogram (no LF: F1 is never printed).
HF, VHF, SI, PCW, OCW, PCA, OCA
"VHF" in AUDIOGRAM_GROUPS
BEST_HEARING_FREQUENCY_KHZdictSouthall Table 4 f0 per group (original, normalized) [kHz].BEST_HEARING_FREQUENCY_KHZ["HF"]
ORCA_AUDIOGRAM_RANGE_KHZtupleValidity range of Ainslie Eq. (11.159): (0.5, 80) kHz.ORCA_AUDIOGRAM_RANGE_KHZ[1] # 80.0
perceived_noisinessfunctionPer-band perceived noisiness (ICAO Annex 16 App. 2), noys.
• spl: 24 one-third-octave band levels 50 Hz–10 kHz [dB]
perceived_noisiness(spl)
NOY_BANDSarrayThe 24 noy one-third-octave bands [Hz] (ICAO Annex 16 App. 2).
50 Hz to 10 kHz
NOY_BANDS[0] # 50.0
perceived_noise_levelfunctionPerceived noise level PNL (ICAO Annex 16), PNdB.
• spl: 24 band levels [dB]
= 40 + (10/lg2)·lg N
perceived_noise_level(spl)
tone_correctionfunctionTone correction C (ICAO Annex 16, slope method), dB.
• spl: 24 band levels [dB]
1.5 dB threshold, cap 6⅔ dB
tone_correction(spl)
effective_perceived_noise_levelfunctionEPNL from a spectral time history (ICAO Annex 16), EPNdB.
• spectra: (K, 24) band levels [dB]
• dt (Default: 0.5) [s]
• reference_time (Default: 10) [s]
• procedure: 'aeroplane' (tone correction from 80 Hz, Default) / 'helicopter' (from 50 Hz, App. 2 4.3.1)
EPNL = PNLTM + D
res = aircraft.effective_perceived_noise_level(spectra)

• EPNLResult
epnl_from_pnltfunctionEPNL + 10 dB-down limits from a PNLT series (ICAO Annex 16).
• pnlt: PNLT(k) [PNdB]
• dt (Default: 0.5) [s]
• reference_time (Default: 10) [s]
epnl, pnltm, kf, kl = aircraft.epnl_from_pnlt(pnlt)
EPNLResultdataclassEPNL result.
• frequencies [Hz] / times [s]
• pnl / tone_correction / pnlt [PNdB, dB]
• pnltm / duration_correction / epnl
• band_limits (kF, kL)
• .plot(): PNL/PNLT time history
res.epnl, res.pnltm, res.band_limits
verify_aircraft_noise_systemfunctionIEC 61265 measurement-system verification.
• directional: {f: {angle: |Δsens| dB}} (Table 1)
• frequency_response / linearity / resolution
filters via verify_filter_class
res = verify_aircraft_noise_system(directional=meas)

• AircraftSystemComplianceResult
AircraftSystemComplianceResultdataclassIEC 61265 verdict on a measurement chain.
• passes: conjunction of the checks, False over no measurement
• checks: one entry per checked quantity, with quantity, limit, value and ok
res.passes, res.checks
sae_band_attenuationfunctionOne-third-octave-band atmospheric absorption (SAE ARP 5534).
• frequencies [Hz] / path_length [m]
• temperature_c (Default: 25) / relative_humidity_percent (Default: 70) / atmospheric_pressure_kpa (Default: 101.325)
δ_B from pure-tone δ_t=α·s (α from ISO 9613-1)
sae_band_attenuation(freqs, 7620.0)

• AircraftBandAttenuation
AircraftBandAttenuationdataclassAircraft band-absorption result.
• frequencies [Hz] / band_attenuation [dB] / midband_attenuation [dB] / coefficient [dB/m]
• path_length / temperature_c / relative_humidity_percent / atmospheric_pressure_kpa
• .plot(): band vs pure-tone mid-band
res.band_attenuation
npd_levelfunctionNPD event-level interpolation (ECAC Doc 29 §4.2).
• powers / distances [m] / levels [dB] (shape P×D)
• power / distance [m]
linear in power (Eq. 4-3), log-linear in distance (Eq. 4-4)
npd_level(P, D, L, 16000, 1500)
npd_curvefunctionNPD level over a distance sweep at one power.
• powers / distances / levels
• power / query_distances (Default: log sweep)
npd_curve(P, D, L, 20000)

• NpdLevelResult
NpdLevelResultdataclassNPD distance-sweep result.
• distances [m] / levels [dB] / power
• table_distances / table_levels
• .plot(): level vs slant distance
res.distances, res.levels
lateral_attenuationfunctionExcess lateral attenuation Λ(β,ℓ) (ECAC Doc 29 Eq. 4-18/4-19).
• elevation_deg β / lateral_m ℓ
lateral_attenuation(10, 500)
engine_installation_correctionfunctionEngine-install lateral directivity ΔI(φ) (Eq. 4-15/4-16).
• depression_deg φ / mounting: "wing"|"fuselage"|"propeller"
engine_installation_correction(20, "wing")
duration_correctionfunctionDuration correction ΔV = 10·lg(Vref/Vseg) (Eq. 4-14).
• reference_speed / segment_speed
duration_correction(82.3, 90)
noise_fractionfunctionFinite-segment noise fraction ΔF (Eq. 4-20).
• q [m] / segment_length λ [m] / scaled_distance dλ [m]
noise_fraction(0, 5000, 100)
impedance_adjustmentfunctionAcoustic-impedance adjustment of NPD data (Eq. 4-6/4-7).
• temperature_c [°C] / atmospheric_pressure_kpa [kPa]
= 10·lg(ρc/409.81); +0.074 dB at ISA
impedance_adjustment(15, 101.325)
start_of_roll_directivityfunctionStart-of-roll rearward directivity ΔSOR (Eq. 4-22/4-24/4-25).
• azimuth_deg ψ (arccos q/dSOR) / distance_m dSOR
• engine: "jet"|"turboprop"; 0 ahead (ψ<90°)
start_of_roll_directivity(120, 300, "jet")
AerodromeAtmospheredataclassAerodrome air of the Doc 29 impedance adjustment (Eq. 4-6/4-7).
• temperature_c [°C] (15) / atmospheric_pressure_kpa [kPa] (101.325)
AerodromeAtmosphere(25.0, 100.0)
FlightSegmentStatedataclassWhat each flight-path segment is doing (one entry per segment).
• ground_roll / landing_roll masks / bank ε [°] (§4.5.2)
FlightSegmentState(ground_roll=gr)
event_levelfunctionSingle-event SEL/LAmax of a flight path at a receiver (Eq. 4-8/4-10/4-11).
• path (N,5): x,y,z,power,speed / observer (x,y,z)
• NPD powers / distances / exposure_levels / maximum_levels
• reference_speed / mounting / metric: "exposure"|"maximum"
• atmosphere: AerodromeAtmosphere / segments: FlightSegmentState
event_level(path, obs, P, D, SEL, LMAX)

• FlyoverResult
noise_contourfunctionSingle-event noise level over a ground grid → contour.
• path / NPD tables / x / y grids [m]
• reference_speed / mounting / metric
• atmosphere: AerodromeAtmosphere / segments: FlightSegmentState
noise_contour(path, P, D, SEL, LMAX, x=gx, y=gy)

• NoiseContourResult
FlyoverResultdataclassSingle-event result.
• level [dB] / metric / segment_levels [dB] / observer
• .plot(): per-segment contributions
res.level
NoiseContourResultdataclassGround-grid contour result.
• x / y [m] / levels [dB] (Ny×Nx) / metric
• .plot(): filled contours
res.levels
load_anp_databasefunctionLoad an EASA ANP fleet database (NPD curves + default profiles).
• path: CSV export directory, or None for the bundled curated subset
db = aircraft.load_anp_database()

• AnpDatabase
AnpDatabaseclassParsed ANP database wiring real aircraft into the Doc 29 chain.
• .aircraft(id) / .aircraft_ids / .npd_curves(id, op, metric) / .profile(id, op, profile_id=)
• .event_level(id, obs, op) / .noise_contour(id, op, x=, y=)
db.noise_contour("747100", "departure", x=gx, y=gy)

• AnpAircraft
AnpAircraftdataclassOne ANP aircraft type: metadata + NPD/profile access + Doc 29 wiring.
• aircraft_id / description / engine_type / num_engines / weight_class / mounting / npd_id
• .npd_curves(op, metric) / .profile(op) / .event_level(obs, op) / .noise_contour(op, x=, y=)
db.aircraft("747100").mounting
AnpNpdCurvesdataclassANP NPD curves for one aircraft, metric and operation.
• powers / distances [m] / levels [dB] (P×D) / metric / operation
• .level(power, distance) / .plot(): level vs slant distance
db.npd_curves("747100", "departure", "SEL")
AnpProfiledataclassANP default fixed-point trajectory as a Doc 29 flight path.
• path (N,5): x,y,z,power,speed [SI] / ground_roll / landing_roll masks
• .plot(): altitude vs along-track distance
db.profile("747100", "departure").path
AerodromedataclassAerodrome, weather and runway of a Doc 29 Appendix B profile.
• elevation_ft / temperature_c / sea_level_pressure_inhg / headwind_kt (8) / runway_gradient_ratio
• .temperature_ratio() θ / .pressure_ratio() δ / .density_ratio() σ / .pressure_altitude_ft() h (Eq. B-1..B-8)
Aerodrome(elevation_ft=1000.0, temperature_c=25.0)
PerformanceAircraftdataclassOne aeroplane's Appendix B coefficient set.
• engines N / max_static_thrust_lb / max_landing_weight_lb / .approach_weight_lb (0.9·MLW)
• jet_coefficients / propeller_coefficients / aerodynamic_coefficients / .flap(op, id)
db.performance_aircraft("A320-211")
JetEngineCoefficientsdataclassCorrected net thrust polynomial E+F·Vc+Ga·h+Gb·h²+H·T (Eq. B-9).
• e [lb] / f [lb/kt] / ga [lb/ft] / gb [lb/ft²] / h [lb/°C]
JetEngineCoefficients(25000, -25, 0.3, 1e-5, 0)
PropellerEngineCoefficientsdataclassPropeller thrust (326·η·Pp/Vt)/δ (Eq. B-12).
• efficiency η / power_hp Pp per engine
PropellerEngineCoefficients(0.85, 9500)
AerodynamicCoefficientsdataclassOne flap configuration (ANP aerodynamic table).
• drag_ratio R / ground_roll_coefficient B [ft/lb] / speed_coefficient C or D [kt/√lb]
• a missing coefficient is None, not zero
AerodynamicCoefficients(drag_ratio=0.07)
DepartureStepdataclassOne ANP departure procedural step (Doc 29 B6.1).
• step_type: Takeoff|Climb|Accelerate|Level|Level-Accelerate / thrust_rating / flap_id
• end_altitude_ft / rate_of_climb_ft_per_min / end_calibrated_airspeed_kt / energy_share_percent / distance_ft / bank_angle_deg
DepartureStep("Climb", "MaxTakeoff", "5", 1500.0)
ApproachStepdataclassOne ANP approach procedural step (Doc 29 B7.1).
• step_type: Descend|Descend-Decel|Descend-Idle|Level|Level-Decel|Level-Idle|Land|Decelerate / flap_id
• start_altitude_ft / start_calibrated_airspeed_kt / descent_angle_deg / touchdown_roll_ft / distance_ft / start_thrust_percent
ApproachStep("Descend", "30", 1000.0, 135.0, 3.0)
departure_profilefunctionFly a departure procedure into a flight profile (Doc 29 B6).
• aircraft / steps (first must be a Take-off) / weight_lb / aerodrome
departure_profile(acft, steps, weight_lb=W, aerodrome=apt)

• FlightProfile
approach_profilefunctionFly an approach procedure into a flight profile (Doc 29 B7).
• aircraft / steps (one Land step anchors distance 0) / aerodrome / weight_lb (0.9·MLW)
• solved backwards from touchdown: distances are negative until the runway
approach_profile(acft, steps, aerodrome=apt)

• FlightProfile
FlightProfiledataclassA flown procedure as an ordered Doc 29 flight profile.
• points / .distance_ft / .altitude_ft / .true_airspeed_kt / .corrected_net_thrust_lb
• .plot(): height and thrust vs distance
db.flight_profile("A320-211", "D", aerodrome=apt)
ProfilePointdataclassOne profile point in the standard's units.
• distance_ft (signed) / altitude_ft AFE / true_airspeed_kt / corrected_net_thrust_lb per engine
• thrust may be negative: an idle descent is drag
profile.points[0].corrected_net_thrust_lb
RotorcraftHemispheredataclassRotorcraft noise hemisphere source (ECAC Doc 32).
• frequencies [Hz] / azimuth φ / polar θ [°] / levels [dB] (A×P×F) / distance (60 m)
• .plot(): fore-aft directivity / .mirrored(): φ → −φ (Eq. 2)
h.levels
hemisphere_source_levelfunctionInterpolated source level L(fc,φ,θ) (Eq. 13-15).
• hemisphere / azimuth_deg φ / polar_deg θ
• energy-bilinear + nearest-bin fill
hemisphere_source_level(h, 0, 90)
hover_ring_hemispherefunctionHemisphere from a ground-ring hover measurement (§A.3.5).
• frequencies [Hz] / bearings [°] / levels (B×F) [dB] / distance (70 m)
• constant-φ extension; mapping: "constant_phi"|"bearing"
hover_ring_hemisphere(f, brg, L)
hover_derived_hemispherefunctionHOGE/idle hemisphere derived from in-ground hover (Table 3).
• condition: "out_of_ground_hover"|"reduced_rpm_idle"|"full_rpm_idle"
• offset_db measured Approach 2 difference (default: +12/−12/−2.5 dB)
hover_derived_hemisphere(h, "full_rpm_idle")
spherical_spreading_adjustmentfunctionΔLs = −20·lg(r/60) (ECAC Doc 32 Eq. 24).
• distance r [m]
spherical_spreading_adjustment(600)
atmospheric_adjustmentfunctionΔLa = −α(f)·(r−60) (Eq. 26/27; ISO 9613-1 α; Table 4).
• frequencies [Hz] / distance r [m]
• temperature_c / relative_humidity_percent / atmospheric_pressure_kpa
atmospheric_adjustment(f, 1060)
ground_effect_adjustmentfunctionΔLg over an impedance plane (Chien-Soroka, Eq. 28-35).
• frequencies / source_height / receiver_height / horizontal_distance
• flow_resistivity σ or CNOSSOS class "A"-"H"
ground_effect_adjustment(f, 150, 1.5, 500)
flight_condition_weightsfunctionHemisphere blend weights for a flight condition (NORAH2 Eq. 3-10).
• database airspeeds / path_angles_deg [°] + query airspeed / path_angle_deg
• Delaunay triangle blend inside the hull, nearest outside
• scaling_factor Ffc (2) / triangles lookup table
flight_condition_weights(V, G, 60, 2.5)
interpolated_source_levelfunctionSource level between hemispheres (Eq. 8/10 over Eq. 13).
• hemispheres + database conditions + query condition
• azimuth_deg φ / polar_deg θ
interpolated_source_level(hs, V, G, 60, 2.5, 0, 90)
flight_path_kinematicsfunctionTrack kinematics by central differences (Eq. 16-21).
• times [s] / positions (N,3) [m]
• Vg, VA, heading, curvature, bank Φ = atan(K·Vg²/g), path angle γ
flight_path_kinematics(t, xyz)

• FlightPathKinematics
FlightPathKinematicsdataclassTrack kinematics result.
• ground_speed / airspeed [m/s] / heading / bank_angle_deg / path_angle_deg [°] / curvature [rad/m]
• .plot(): speed and angle profiles
kin.airspeed
RotorcraftAtmospheredataclassAir of a rotorcraft event (Eq. 26/27).
• temperature_c [°C] (25) / relative_humidity_percent [%] (70) / atmospheric_pressure_kpa [kPa] (101.325)
• atmospheric_method: "iso9613"|"sae"
RotorcraftAtmosphere(atmospheric_method="sae")
RotorcraftGrounddataclassGround under a rotorcraft event (§A.4.3-A.4.5).
• receiver_height [m] (1.2) / ground_elevation [m] / flow_resistivity σ or class
• terrain (x, y, z model) + terrain_resolution [m]
RotorcraftGround(flow_resistivity="D")
RotorcraftTrackStatedataclassPer-point flight state overriding the derived kinematics (Eq. 16-21).
• airspeed / path_angle_deg / heading / bank_angle_deg, scalar or (N,)
RotorcraftTrackState(heading=180.0)
FlightConditionInterpolationdataclassHow a flight condition blends the database hemispheres (Eq. 3-10).
• scaling_factor Ffc (2) / triangles lookup table
FlightConditionInterpolation(triangles=tri)
rotorcraft_event_levelfunctionSingle-event time history and metrics at a receiver (Doc 32 §6.1).
• hemispheres + conditions / times / positions / receiver (x,y)
• level_offset [dB] (Eq. 2 substitution)
• ground: RotorcraftGround / atmosphere: RotorcraftAtmosphere
• track_state: RotorcraftTrackState / interpolation: FlightConditionInterpolation
rotorcraft_event_level(hs, V, G, t, xyz, (x, y))

• RotorcraftEventResult
RotorcraftEventResultdataclassSingle-event result.
• times (recorded) / band_levels / a_levels [dB(A)]
• la_max / sel / sel_10db / pnlt / pnltm / epnl
• .plot(): LA(t) history with the 10 dB-down window
res.sel, res.epnl
rotorcraft_noise_contourfunctionSingle-event SEL/LASmax over a ground grid (Doc 32 §6.3).
• event inputs + x / y grids [m]
• metric: "exposure"|"maximum"
• ground: RotorcraftGround, whose flow_resistivity / ground_elevation also take one value per grid point
rotorcraft_noise_contour(hs, V, G, t, xyz, x=gx, y=gy)

• RotorcraftNoiseContourResult
RotorcraftNoiseContourResultdataclassRotorcraft ground-grid contour result.
• x / y [m] / levels [dB(A)] (Ny×Nx) / metric
• .plot(): filled contours
res.levels
mean_ground_planefunctionMean ground plane of a terrain section (NORAH2 Eq. 36-40).
• distances / heights [m] (polyline)
• continuous least squares in closed form
mean_ground_plane(d, z)

• MeanGroundPlaneResult
MeanGroundPlaneResultdataclassFitted plane.
• slope a / intercept b [m]
• .height(d) / .equivalent_height(d, z) (orthogonal)
• .plot(): section + plane
res.slope
mean_flow_resistivityfunctionLog-mean flow resistivity along a path (Eq. 41).
• lengths [m] / resistivities [Pa·s/m²] per segment
mean_flow_resistivity(d, sig)
diffraction_attenuationfunctionPure diffraction ΔLd per band (Eq. 42-44).
• path_difference δ [m] (negative allowed) / edge_height h0 [m]
• edge_span e (C″, multiple edges) / capped (25 dB)
diffraction_attenuation(f, 0.5, edge_height=10)
terrain_screening_adjustmentfunctionGround + screening over a vertical section (§A.4.4-A.4.5).
• source / receiver (d, z) [m] / distances / heights (terrain)
• flow_resistivity: value, class or per segment (Eq. 41)
• clear path → mean-plane ground effect; blocked → rubber band + Eq. 45-47
terrain_screening_adjustment(f, S, R, d, z)

• TerrainScreeningResult
TerrainScreeningResultdataclassSection result.
• adjustment [dB] (replaces the flat ΔLg) / screened / path_difference δ [m] / diffraction_points
• .plot(): section geometry
res.adjustment
slant_distancefunctionRotor-centre-to-microphone slant distance (IEC 61400-11).
• hub_height H [m]
• rotor_diameter_m D [m]
• rotor_axis (Default: "horizontal" → R0 = H+D/2, Formula 1; "vertical" → R0 = H+D, Formula 2)
= √(H² + R0²)
slant_distance(80.0, 100.0)
apparent_sound_power_levelfunctionApparent sound power level (IEC 61400-11 Formula 26), dB re 1 pW.
• band_levels: background-corrected A-weighted band SPL [dB]
• r1: slant distance [m]
= L_p − 6 + 10·lg(4π R1²/S0)
apparent_sound_power_level(levels, r1)
wind_turbine_tonalityfunctionTonal 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).
• levels [dB] / frequencies [Hz]: 1-D, equal length (≥ 3), strictly increasing and uniformly spaced (narrowband), covering the whole critical band
• tone_frequency: optional [Hz] (≥ 20 Hz)
res = environment.wind_turbine_tonality(levels, freqs)

• WindTurbineTonalityResult
WindTurbineTonalityResultdataclassWind-turbine tonality result.
• tone_frequency [Hz] / critical_bandwidth [Hz]
• tone_level / masking_level / tonality [dB]
• audibility_criterion / tonal_audibility [dB]
• is_audible / has_identified_tone (False → exclude from 9.5.1 bin averaging)
• .plot(): spectrum + critical band + masking
res.tonal_audibility, res.is_audible
WindTurbineNoiseWarningwarning classIEC 61400-11 advisory.
Emitted when the tonality inputs leave the standard's stated domain of validity
warnings.simplefilter('error', WindTurbineNoiseWarning)
noise_criterionfunctionNC rating, clause 5.2.2 two-step (ANSI/ASA S12.2-2019).
• levels: octave-band SPL [dB] (the 10 bands 16 Hz–8 kHz without frequencies)
• frequencies: optional band centres [Hz] (subset allowed)
nc = room.noise_criterion(levels)

• NCResult; NC-(SIL) designation, tangency when exceeded
room_criterionfunctionRC Mark II rating (ANSI/ASA S12.2-2019 Annex D).
• levels: octave-band SPL [dB]
• frequencies: optional band centres [Hz]
rc = room.room_criterion(levels)

• RCResult; LMF average + 'N'/'R'/'H'/'RH' tag
nc_curvefunctionNC curve levels (Table 1).
• index: NC designation 15–70 (intermediate values interpolated band by band)
nc_curve(35) # [82, 71, 60, ...]

• 10 band levels [dB], 16 Hz–8 kHz
rc_curvefunctionRC Mark II curve (Table D.1).
• index: RC designation (value at 1000 Hz)
rc_curve(35)

• −5 dB/octave line, 10 bands [dB]
NCResultdataclassNC rating result.
• rating: NC designation (NaN outside NC-15…NC-70, see out_of_range)
• sil, tangency_rating, method, label
• governing_frequency: tangency band [Hz]
• frequencies [Hz], levels [dB]
• .plot()
nc.rating, nc.label
RCResultdataclassRC Mark II result.
• rating: LMF rounded [dB], int
• lmf: 500/1000/2000 Hz average [dB]
• classification: 'N'/'R'/'H'/'RH'
• reference_curve [dB], frequencies [Hz], levels [dB]
• .plot()
rc.rating, rc.classification
age_thresholdfunctionAge-related hearing threshold distribution (ISO 7029:2017).
• age: years (≥ 18)
• sex: 'male'/'female' (Default: 'male')
• fractile: population fractile in (0, 1) (Default: 0.5)
• frequencies: subset of the 11 audiometric frequencies [Hz] (Default: None → 125–8000 Hz)
at = hearing.age_threshold(60, 'male')

• AgeThresholdResult; median at 4 kHz = 20.2 dB
AUDIOMETRIC_FREQUENCIESndarrayThe eleven audiometric frequencies of ISO 389-7:2005 Table 1 [Hz], the axis every threshold in this module is aligned with.hearing.AUDIOMETRIC_FREQUENCIES # 125 ... 8000
FIELDStupleThe listening fields reference_threshold accepts: 'free-field', 'diffuse-field'.hearing.FIELDS
SEXEStupleThe populations age_threshold accepts (ISO 7029:2017 tabulates the two separately): 'male', 'female'.hearing.SEXES
reference_thresholdfunctionReference threshold of hearing, 0 dB HL (ISO 389-7:2005 Table 1).
• field: 'free-field' or 'diffuse-field' (Default: 'free-field')
• frequencies: optional subset [Hz]
t = hearing.reference_threshold()

• dB SPL per audiometric frequency (1 kHz → 2.4)
RETSPL_FREQUENCIES_HZ / EARPHONES / EARPHONE_COUPLERSconstantISO 389-1 Tables 1 and 2: the twenty-three test frequencies, the three earphone cases the standard prints a reference level for, and the coupler each of them is calibrated on.hearing.EARPHONE_COUPLERS['TDH 39'] # 'IEC 60303 acoustic coupler'
earphone_reference_level / hearing_level_to_coupler_splfunctionISO 389-1:1998: what 0 dB HL is on a supra-aural earphone, and what an audiogram is worth in the coupler.
• earphone_reference_level(earphone, frequencies): the RETSPL, for 'DT 48' or 'TDH 39' (Table 1, IEC 60303 coupler) or 'other supra-aural' (Table 2, IEC 60318 artificial ear)
• hearing_level_to_coupler_spl(hearing_level, earphone, frequencies): the audiogram plus that reference, which is all hearing level means
hearing.earphone_reference_level('TDH 39', [1000.0])

• array([7.]) dB
AgeThresholdResultdataclassAge threshold distribution.
• age, sex, fractile
• frequencies [Hz]
• median: deviation from age 18 [dB]
• spread_upper / spread_lower: half-Gaussian su/sl [dB]
• threshold: value at fractile [dB]
• .plot()
at.median, at.threshold
niptsfunctionNoise-induced permanent threshold shift (ISO 1999:2013 §6.3).
• l_ex: LEX,8h [dB]
• years: exposure duration (10–40 established; 1–10 extrapolated by Formula 3)
• fractile: (0, 1) (Default: 0.5)
• frequencies: subset [Hz] (Default: None → 500–6000 Hz)
n = hearing.nipts(95.0, 20.0)

• NiptsResult; N50 at 4 kHz = 23.0 dB
htlanfunctionThreshold associated with age and noise, H′ = H + N − HN/120 (ISO 1999 Formula 1).
• age: years (≥ 18), sex: 'male'/'female'
• l_ex: LEX,8h [dB], years
• fractile: (0, 1) applied to both components (Default: 0.5)
• frequencies
h = hearing.htlan(60, 'male', 95.0, 20.0)

• HtlanResult; H′ at 4 kHz = 39.3 dB
NiptsResultdataclassNIPTS distribution.
• l_ex, years, fractile
• frequencies [Hz]
• median: N50 (Formula 2/3) [dB]
• value: NIPTS at fractile (Formula 4/5) [dB]
• spread_upper / spread_lower: du/dl [dB]
• .plot()
n.median, n.value
HtlanResultdataclassCombined HTLAN result.
• age, sex, l_ex, years, fractile
• frequencies [Hz]
• htla: age component H [dB]
• nipts: noise component N [dB]
• threshold: combined H′ [dB]
• .plot()
h.htla, h.nipts, h.threshold
combine_age_and_noisefunctionAge and noise components combined, H′ = H + N − HN/120 (ISO 1999 Formula 1).
• htla: age-associated threshold H [dB]
• nipts_value: noise-induced shift N [dB]
• both taken at the same population percentage; exposed for the user-supplied database B of clause 6.2.3
combine_age_and_noise(36.0, 19.0) # 49.3

• ISO 1999 Annex C: 19 − 36·19/120 = 13.3 dB of shift remains
NoiseInducedHearingLossWarningwarning classISO 1999 domain advisory.
Emitted outside the validated domain: exposure duration beyond 1–40 yr (§6.3.1), fractile in the tails ISO calls unreliable (Q < 5 % or > 95 %, §6.3.2), or LEX,8h above the 100 dB of Annex D
warnings.simplefilter('error', NoiseInducedHearingLossWarning)
predicted_prominencefunctionPredicted prominence P of an impulse (NT ACOU 112 Formula 1).
• onset_rate: slope of the A/F level onset [dB/s] (> 0; qualifies above 10 dB/s)
• level_difference: level rise over the onset [dB] (> 0)
predicted_prominence(50.0, 20.0) # 7.7

• P = 3 lg(rate) + 2 lg(diff)
impulse_adjustmentfunctionLAeq adjustment KI (Formula 2).
• prominence: P
impulse_adjustment(7.7) # 4.86

• 1.8(P − 5) dB for P > 5, else 0
impulse_prominencefunctionGoverning prominence and adjustment of a set of impulses (clauses 7–8); only onset rates > 10 dB/s qualify (clause 4.5).
• onset_rates [dB/s]
• level_differences [dB]
r = environment.impulse_prominence([50, 120], [20, 15])

• ImpulseProminenceResult (P = 8.59, KI = 6.46 dB)
rating_levelfunctionRating level LAr,T over a reference time (clause 8 Note 1).
• laeq: LAeq,N per sub-interval [dB]
• adjustment: KI,N per sub-interval [dB]
• durations, reference_time: same time unit
rating_level([55, 60], [0, 4.9], [20, 10], 30) # 60.9
ImpulseProminenceResultdataclassImpulse-prominence verdict.
• onset_rates [dB/s], level_differences [dB]
• per_impulse: P of each impulse
• qualifies: onset rate > 10 dB/s mask (clause 4.5)
• prominence: governing (highest qualifying) P
• adjustment: KI of the governing qualifying impulse [dB] (0 when none qualifies)
• .plot()
r.prominence, r.adjustment
ImpulseProminenceWarningwarning classNT ACOU 112 advisory.
Emitted when a supplied level rise does not qualify as an impulse (clause 4.5)
warnings.simplefilter('error', ImpulseProminenceWarning)
impulsive_sound_adjustmentfunctionObjective impulsive-sound adjustment from a calibrated signal (ISO/PAS 1996-3:2022).
• signal: sound pressure [Pa], fs [Hz]
• dt: LpAF sampling interval [s] (10–25 ms; Default 0.02)
• onset_rate_method: 'least_squares' or 'upper_half' pass-by variant
• calibration_offset [dB], laeq [dB]
r = environment.impulsive_sound_adjustment(sig, fs)

• ImpulsiveSoundResult (P, KI, category)
sound_pressure_level_historyfunctionA-weighted, F time-weighted level history LpAF (ISO/PAS 1996-3 Clause 4).
• signal [Pa], fs [Hz]
• dt: sampling interval [s] (10–25 ms; Default 0.02)
• reference_pressure_pa [Pa], calibration_offset [dB]
t, lpaf = environment.sound_pressure_level_history(sig, fs)
detect_onsetsfunctionDetect LpAF onsets: start/end points, level difference and least-squares onset rate (ISO/PAS 1996-3 Clause 4, procedures a–d).
• levels: LpAF [dB], dt [s]
• onset_rate_method: 'least_squares' / 'upper_half'
onsets = environment.detect_onsets(lpaf, 0.02)
LevelHistorydataclassA frequency- and time-weighted level trace with its time axis.
• times [s], levels [dB], dt [s]
• unpacks as (times, levels) for the callers that always did
hist = environment.sound_pressure_level_history(sig)
hist.plot() # the L_pAF trace
ImpulsiveSoundResultdataclassObjective impulsive-sound verdict (ISO/PAS 1996-3).
• times [s], levels: LpAF [dB], dt [s]
• onsets: detected ImpulseOnsets
• prominence: governing P, adjustment: KI [dB]
• category: 'not impulsive' / 'regular impulsive' / 'highly impulsive'
• laeq, adjusted_laeq [dB]
• .governing_onset, .plot()
r.adjustment, r.category
ImpulseOnsetdataclassA single detected LpAF onset (ISO/PAS 1996-3 Clause 3).
• index_start/index_end, time_start/time_end [s]
• level_start/level_end [dB]
• level_difference: LD = Le − Ls [dB]
• onset_rate: OR [dB/s]
• prominence: P, qualifies: OR > 10 dB/s
o.onset_rate, o.level_difference
ImpulsiveSoundWarningwarning classISO/PAS 1996-3 advisory.
Emitted when no onset with a gradient above 10 dB/s is found (adjustment is 0 dB)
warnings.simplefilter('error', ImpulsiveSoundWarning)
frequency_weighted_selfunctionFrequency-weighted single-event sound exposure level from band levels (ISO 13474:2009 Equation (5)).
• band_levels_db: band levels L_E(j) [dB] on the last axis; leading axes kept, so (N_atm, N_exc, n_bands) gives every replica at once
• weighting_db: weighting w(j) of each band [dB] (A, C or any other)
environment.frequency_weighted_sel(bands_db, a_weighting_db)

• 10 lg Σ 10^(0.1 (L_E(j) + w(j))) [dB]
replica_probabilitiesfunctionProbability of each replica atmosphere, the product of its two class probabilities (ISO 13474 Equation (14)).
• absorption_probabilities: one per atmospheric-absorption class
• excess_attenuation_probabilities: one per excess-attenuation class
p = environment.replica_probabilities([1.0], p_exc)

• array (N_atm, N_exc)
long_term_selfunctionLong-term average single-event sound exposure level (ISO 13474 Equation (7)), or the rating level with K (Equation (8)).
• levels_db: L_E,w,k,l of each replica [dB], any shape
• probabilities: same shape, summing to one
• rating_adjustment_db: K for highly impulsive sound [dB] (Default: 0)
environment.long_term_sel(levels_db, p)

• Annex A LT1 = 37.0 dB
turbulence_level_shiftfunctionShift Δμ of each Gaussian subclass, σ² ln 10 / 20 (ISO 13474 Equation (22) in closed form).
• sigma_db: standard deviation of the turbulent spread [dB]
environment.turbulence_level_shift(5.0) # 2.878

• [dB]
sel_distributionfunctionStatistical distribution of the single-event sound exposure level (ISO 13474:2009 clause 5, Equations (10) to (25)).
• levels_db: L_E,w of each replica atmosphere [dB], any shape
• probabilities: same shape, summing to one
• sigma_db: turbulent spread [dB] (Default: 5.0, the value clause 5 says is typical)
• subclasses: N_sub per class (Default: 10, as Annex A)
d = environment.sel_distribution(levels_db, p)

• SelDistribution
SelDistributiondataclassThe ISO 13474 distribution: sorted classes, their boundaries and densities, and the spread density.
• levels_db, probabilities, lower_bounds_db / upper_bounds_db [dB], class_densities_per_db [1/dB] (Equations (10) to (15))
• subclass_centres_db [dB], sigma_db, level_shift_db [dB], subclasses (Equations (17) to (22))
• long_term_level_db (Equation (7), LT1) and distribution_long_term_level_db (Equation (A.4), LT2) [dB]
• replicas: the input replicas of each class
• .class_density(x_db), .density(x_db), .exceedance(x_db) (Equation (24)), .exceedance_level(percent) (Equation (25))
• .plot(view='classes' / 'density' / 'exceedance')
d.exceedance_level(50.0) # 31.5 dB
d.plot(view='exceedance')
PERCEIVED_AFFECTIVE_QUALITY_ATTRIBUTESconstantThe eight attributes of the perceived affective quality, part 2 of Method A (ISO/TS 12913-2 Figure C.4), in printed order.
pleasant, chaotic, vibrant, uneventful, calm, annoying, eventful, monotonous: the variables p, ch, v, u, ca, a, e, m of ISO/TS 12913-3 Formulas (A.1) and (A.2)
environment.PERCEIVED_AFFECTIVE_QUALITY_ATTRIBUTES[0] # 'pleasant'
QuestionnaireScaledataclassOne scale of the soundscape questionnaire as ISO/TS 12913-2 Annex C prints it (misprints included).
• method ("A"/"B"), part, figure, subject
• question, instruction, items
• categories: left to right, scale_values: Table A.1 or B.1
• continuous: a mark anywhere on the scale (Method B)
environment.METHOD_A_SCALES[2].categories[0] # 'Strongly agree'
METHOD_A_SCALESmappingMethod A of ISO/TS 12913-2 (C.3.1), part number to QuestionnaireScale.
1: sound source identification (Figure C.2), 2: perceived affective quality (C.4), 3: assessment of the surrounding sound environment (C.5), 4: appropriateness (C.6); scale values of ISO/TS 12913-3 Table A.1 (parts 1 and 4 run 1 to 5 from the left, parts 2 and 3 run 5 to 1)
environment.METHOD_A_SCALES[3].scale_values # (5, 4, 3, 2, 1)
METHOD_A_ALTERNATIVE_PART_1constantFigure C.3 of ISO/TS 12913-2, the three-source alternative to Figure C.2 for part 1.
A QuestionnaireScale with the categories and scale values of Figure C.2
environment.METHOD_A_ALTERNATIVE_PART_1.items[0]
METHOD_B_SCALESconstantThe four continuous-category scales of Figure C.7, part 1 of Method B (ISO/TS 12913-2 C.3.2.3).
A tuple of QuestionnaireScale: loud, unpleasant, appropriate, visit again; scale value 1 at the left-hand tick to 5 at the right-hand one (Table B.1)
environment.METHOD_B_SCALES[0].question # 'How loud is it here?'
METHOD_B_MAXIMUM_SOURCESconstantThe most sound sources a participant may rank in part 2 of Method B (ISO/TS 12913-2 C.3.2.4).environment.METHOD_B_MAXIMUM_SOURCES # 8
PLEASANTNESS_EVENTFULNESS_RANGEconstantHalf-range of the coordinates of Formulas (A.1) and (A.2), 4 + √32 ≈ 9.66 (ISO/TS 12913-3 A.3).
Dividing by it maps P and E to ±1
environment.PLEASANTNESS_EVENTFULNESS_RANGE # 9.657
method_a_scale_valuesfunctionScale value of a ticked Method A box (ISO/TS 12913-3 Table A.1).
• positions: box counted from the left, 1 to 5 (NaN for a blank)
• part: 1 to 4 (parts 2 and 3 run 5 to 1)
environment.method_a_scale_values([1, 5], part=2) # [5., 1.]
method_a_summaryfunctionMedian and range of Method A scale values per site and item (ISO/TS 12913-3 A.2, Table A.1).
• scale_values: mapping item to values, 1-D array (parts 3, 4) or (responses, items) array
• part: 1 to 4
• sites: site of each response (Default: one site "all")
s = environment.method_a_summary(values, part=2, sites=sites)

• MethodASummary
MethodASummarydataclassOrdinal statistics of Method A per site and item.
• part, items, sites
• medians, minima, maxima, ranges, counts: shape (sites, items)
• .plot()
s.medians[0], s.ranges[0]
pleasantness_eventfulnessfunctionPleasantness P and eventfulness E per respondent and per site (ISO/TS 12913-3 A.3, Formulas (A.1) and (A.2)).
• scale_values: the eight attributes of part 2, mapping or (respondents, 8) array, 5 = strongly agree
• sites: site of each respondent (Default: one site "all")
• central_tendency: "median" (A.2) or "mean" of each attribute per site
pe = environment.pleasantness_eventfulness(values, sites=sites)

• PleasantnessEventfulness
PleasantnessEventfulnessdataclassThe two soundscape dimensions of Figure A.1.
• sites, attribute_values: per-site statistic of each attribute
• pleasantness, eventfulness: per site, in ±9.66
• respondent_pleasantness, respondent_eventfulness, respondent_sites, respondent_counts
• .normalized_pleasantness, .normalized_eventfulness: in ±1
• .plot(normalized=True, respondents=False): the model of Figure A.1
pe.normalized_pleasantness
pe.plot(respondents=True)
spearman_rank_correlationfunctionSpearman's rank correlation for ordinal data (ISO/TS 12913-3 A.4, Formula (A.3) untied, (A.4) tied).
• x, y: paired values, at least three pairs
• alternative: "two-sided" (Default), "greater", "less"
c = environment.spearman_rank_correlation(site_p, laeq)

• SoundscapeCorrelation with r and its p-value (Student t, n − 2 degrees of freedom)
pearson_correlationfunctionPearson's correlation for interval data (ISO/TS 12913-3 B.3, Formulas (B.1) and (B.2), covariance over n).
• x, y: paired values, at least three pairs
• alternative: "two-sided" (Default), "greater", "less"
c = environment.pearson_correlation(mean_rating, laeq)

• SoundscapeCorrelation
SoundscapeCorrelationdataclassA correlation coefficient with its probability value.
• method: "spearman" / "pearson", formula: "(A.3)", "(A.4)" or "(B.1)"
• coefficient, p_value, t_statistic, degrees_of_freedom, alternative
• x, y, x_ranks, y_ranks (Spearman), .n
• .plot()
c.coefficient, c.p_value
method_b_scale_valuesfunctionScale value of a mark on a Method B continuous-category scale, 1 + 4f to one decimal (ISO/TS 12913-3 B.2).
• marked_fraction: position from the left-hand tick (0) to the right-hand one (1)
environment.method_b_scale_values(0.62) # 3.5
method_b_summaryfunctionMean, standard deviation and confidence interval of Method B ratings per site (ISO/TS 12913-3 B.2, Table B.1).
• scale_values: mapping scale to values, 1-D array or (responses, scales) array of the Figure C.7 scales
• sites: site of each response
• confidence_level (Default: 0.95)
b = environment.method_b_summary(values, sites=sites)

• MethodBSummary
MethodBSummarydataclassInterval statistics of Method B per site and scale.
• items, sites
• means, standard_deviations (n − 1), confidence_lower / confidence_upper (Student t), medians, counts
• confidence_level
• .plot()
b.means[0], b.confidence_upper[0]
method_b_source_rankingfunctionMedian and range of the rank of each recognised sound source (ISO/TS 12913-3 B.2, ISO/TS 12913-2 C.3.2.4).
• rankings: per participant, the sources listed, most noticeable first, at most eight
• sites: site of each participant
r = environment.method_b_source_ranking([["traffic", "birds"], ["birds"]])

• SourceRanking
SourceRankingdataclassOrdinal statistics of the source ranking per site.
• sources, sites, participants
• median_ranks, lowest_ranks, highest_ranks, rank_ranges, mentions: shape (sites, sources)
• .plot()
r.sources, r.median_ranks[0]
SoundscapeParticipantsdataclassISO/TS 12913-2 A.2 a) to e): how the participants were selected, residents or visitors, lay or expert, age and gender distribution, other relevant information.
Every item required; an empty one raises naming its clause
environment.SoundscapeParticipants(selection="...", ...)
SoundscapeAcousticEnvironmentdataclassISO/TS 12913-2 A.3 a) to h): the studied acoustic environment.
• environment_type: "real", "recorded", "virtual"
• sound_sources, weather_and_wind, time_of_year_and_day, measurement_points
• measurement_results: the seven results of A.3 f) by symbol (LAeq,T, LCeq,T, LAF5,T, LAF95,T, N5, N95, Nrmc)
• site_description (field or recorded), recording_and_reproduction (recorded or virtual)
environment.SoundscapeAcousticEnvironment(..., measurement_results=bi.reporting_results())
SoundscapeDataCollectiondataclassISO/TS 12913-2 A.4 a) to e): how the perception data were collected.
• methods, questions, language, instrument_copy (required)
• rating_scale_construction, behaviour_observation (when the study used them)
environment.SoundscapeDataCollection(methods="...", ...)
SoundscapeReportdataclassThe minimum reporting requirements of ISO/TS 12913-2 Annex A (normative), checked when built.
• participants (A.2), acoustic_environment (A.3), data_collection (A.4)
environment.SoundscapeReport(participants, environment_record, collection)
BINAURAL_PARAMETERSmappingISO/TS 12913-3 Table D.1, row name to BinauralParameter.
"sound_pressure_level", "loudness", "sharpness", "tonality", "roughness", "fluctuation_strength"
environment.BINAURAL_PARAMETERS["loudness"].metrics
BinauralParameterdataclassOne row of Table D.1.
• parameter, metrics (the printed symbols), average_allowed, reference
environment.BINAURAL_PARAMETERS["roughness"].reference # '[32]'
binaural_indicatorsfunctionEvery metric of ISO/TS 12913-3 Table D.1 at each ear, with the representative value of D.2.
• x: equalized binaural recording (2, samples), left first, or a two-channel Signal
• fs [Hz], calibration_factor (to Pa)
• field: "free" (Default) or "diffuse"
• parameters: rows of Table D.1 (Default: all)
• sharpness S5/Saverage/S95 reported as not implemented; recordings under 3 min or 44.1 kHz emit SoundscapeWarning
bi = environment.binaural_indicators(x, 48000, parameters=("sound_pressure_level", "loudness"))

• BinauralIndicators
BinauralIndicatorsdataclassThe binaural analysis of a recording.
• metrics: symbol to BinauralMetric, in Table D.1 order
• not_implemented: symbol to the reason
• parameters, fs [Hz], duration_s [s], field
• .representative(symbol), .reporting_results() (ISO/TS 12913-2 A.3 f))
• .plot(parameter=None)
bi.representative("LAeq,T")
bi.plot(parameter="loudness")
BinauralMetricdataclassOne metric at both ears.
• symbol, parameter, left, right, unit, method
• .representative: the higher ear (D.2), .mean: their average
bi.metrics["N5"].representative
SoundscapeWarningwarning classISO/TS 12913-2 Annex D advisory.
Emitted for a recording shorter than the 3 min of D.3 or sampled below the 44.1 kHz of D.6
warnings.simplefilter('error', SoundscapeWarning)
multiple_shock_assessmentfunctionFull multiple-shock assessment from seat acceleration (ISO 2631-5:2018).
• acceleration: vertical seat az(t) [m/s²], fs [Hz]
• start_age: years, years: exposure years, days_per_year
• exposure_time / measurement_time: scale Dz to a daily dose (Default: None)
• sex: 'male'/'female' (Default: 'male')
• mz: MPa per m/s² (Default: sex-specific)
res = vibration.multiple_shock_assessment(az, fs, start_age=25, years=30, days_per_year=220)

• MultipleShockResult
seat_to_spine_transferfunctionSeat-to-spine transfer function H(ω) (clause 5.2 Formula 1).
• frequencies [Hz]
H = vibration.seat_to_spine_transfer(freqs)

• Complex response; unity at 0 Hz
spinal_responsefunctionVertical spinal response Az(t) (Formula 2).
• acceleration: seat az(t) [m/s²]
• fs [Hz]
Az = vibration.spinal_response(az, fs)

• Same length as the input [m/s²]
response_peaksfunctionPositive response peaks Az,i (clause 5.3).
• response: Az(t)
peaks = vibration.response_peaks(Az)

• Maxima between zero crossings [m/s²]
dose_from_peaksfunctionAcceleration dose Dz from peaks (Formula 3).
• peaks: Az,i [m/s²]
dz = vibration.dose_from_peaks(peaks)

• Dz = 1.07 (Σ Az,i⁶)^(1/6) [m/s²]
acceleration_dosefunctionAcceleration dose Dz from a time history (Formulas 2 + 3).
• acceleration: seat az(t) [m/s²], fs [Hz]
dz = vibration.acceleration_dose(az, fs)

• Dz [m/s²]
daily_dosefunctionDaily dose Dzd (Formula 4).
• dose: Dz [m/s²]
• exposure_time td / measurement_time tm: same unit
daily_dose(4.0, 8.0, 2.0) # 5.04

• Dz (td/tm)^(1/6) [m/s²]
daily_dose_multifunctionDaily dose from several exposure conditions (Formula 5).
• doses: Dz,j [m/s²]
• exposure_times / measurement_times: per condition
dzd = vibration.daily_dose_multi(dz, td, tm)

• [Σ Dz,j⁶ (td,j/tm,j)]^(1/6) [m/s²]
compression_dosefunctionDaily compressive stress Sd (Annex C Formula C.1).
• daily_dose_value: Dzd [m/s²]
• mz: MPa per m/s² (Default: 0.029, 82 kg male)
compression_dose(5.0) # 0.145

• Sd = mz·Dzd [MPa]
static_stressfunctionStatic compressive stress Sstat = mz·9.81 (Annex C).
• mz (Default: 0.029)
static_stress() # 0.284

• [MPa]
ultimate_strengthfunctionUltimate lumbar strength Su at an age (Formula C.4).
• age: years
• sex: 'male'/'female' (Default: 'male')
ultimate_strength(45.0) # 4.41

• 6.75 − Sage·age [MPa]
injury_riskfunctionCumulative injury stress variable R (Formula C.3).
• daily_compression: Sd [MPa]
• start_age, years, days_per_year
• sex, mz
R = vibration.injury_risk(0.5, start_age=25, years=30, days_per_year=220) # 0.509
injury_probabilityfunctionProbability of lumbar injury P(R) (Formula C.5, Weibull).
• risk: R
• sex (Default: 'male')
injury_probability(0.509) # 0.0389

• 1 − exp(−(R/α)^β) in 0–1
MultipleShockResultdataclassMultiple-shock health assessment.
• acceleration_dose Dz, daily_dose Dzd [m/s²]
• compression_dose Sd [MPa]
• risk R, probability P(R)
• sex, start_age, years, days_per_year
• peaks [m/s²], risk_thresholds: R at 10/50/90 % (Table C.2)
• .plot()
res.risk, res.probability
object_fractionfunctionObject fraction ψ of an enclosed space (EN 12354-6 Formula 3).
• object_volumes [m³]
• volume: empty space V [m³]
object_fraction([12.0, 8.0], 500.0) # 0.04
hard_object_absorptionfunctionEquivalent absorption area of a hard object (Formula 4).
• object_volume: Vobj [m³]
hard_object_absorption(8.0) # 4.0

• Aobj = Vobj^(2/3) [m²]
air_absorption_areafunctionEquivalent absorption area of the air (Formula 2).
• m: power attenuation of air [Np/m]
• volume V [m³]
• object_fraction ψ (Default: 0.0)
air_absorption_area(0.001, 500.0) # 2.0

• Aair = 4mV(1 − ψ) [m²]
equivalent_absorption_areafunctionTotal equivalent sound absorption area (Formula 1).
• surfaces: sequence of (area, absorption_coefficient) pairs (coefficient scalar or per band)
• objects: object areas Aobj [m²] (Default: ())
• air_area: Aair [m²] (Default: 0.0)
A = room.equivalent_absorption_area([(100.0, 0.03), (50.0, 0.6)], objects=[4.0], air_area=2.0) # 39.0
reverberation_timefunctionReverberation time from the absorption area (Formula 5).
• absorption_area A [m²]
• volume V [m³]
• object_fraction ψ (Default: 0.0)
• speed_of_sound c0 [m/s] (Default: 345.6 → factor 0.16)
reverberation_time(39.0, 500.0) # 2.05

• T = 55.3/c0 · V(1 − ψ)/A [s]
enclosed_space_reverberationfunctionPredicted A and T per octave band (EN 12354-6 Clause 4).
• surfaces: (area, per-band α) pairs
• volume V [m³]
• objects [m²], object_fraction ψ
• air_condition: air-attenuation key, e.g. '20C_50-70' (Default: None → neglect air)
• frequencies [Hz] (Default: 125–8000 Hz octaves)
• speed_of_sound [m/s]
res = room.enclosed_space_reverberation(surfaces, 500.0, air_condition="20C_50-70")

• ReverberationResult
ReverberationResultdataclassEnclosed-space absorption result.
• frequencies [Hz]
• absorption_area: A per band [m²]
• reverberation_time: T per band [s]
• volume [m³], object_fraction
• .plot()
res.absorption_area, res.reverberation_time
sabine_reverberation_time / eyring_reverberation_time / millington_sette_reverberation_timefunctionStatistical RT prediction (T = k·V/(term + 4mV), k = 24 ln10 / c0).
• volume V [m³]
• surfaces: (area, α) pairs (α scalar or per band)
• air_attenuation: m [Np/m] (Default: 0.0; see air_attenuation_m)
• speed_of_sound (Default: 343 → k = 0.161)
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_timefunctionAnisotropic RT prediction for a shoebox room.
• dimensions: (Lx, Ly, Lz) [m]
• absorptions: mean α of the (x, y, z) wall pairs (scalar or per band)
• air_attenuation [Np/m], speed_of_sound
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_absorptionfunctionArea-weighted mean absorption ᾱ = ΣSᵢαᵢ / ΣSᵢ.
• surfaces: (area, α) pairs
mean_absorption([(90.0, 0.1), (10.0, 0.9)]) # 0.18
reverberation_time_modelsfunctionAll five RT models for a shoebox room, per band.
• dimensions (Lx, Ly, Lz) [m]
• absorptions: (αx, αy, αz) wall-pair means (scalar or per band)
• air_attenuation [Np/m], frequencies [Hz], speed_of_sound
res = room.reverberation_time_models((10,7,3.5), (ax, ay, az), frequencies=f)

• ReverberationModelResult
ReverberationModelResultdataclassFive-model RT comparison.
• frequencies [Hz]
• sabine/eyring/millington_sette/fitzroy/arau_puchades: T per band [s]
• volume [m³], surface_area [m²]
• .models: dict keyed by name
• .plot()
res.arau_puchades, res.models['Fitzroy']
apparent_dynamic_stiffnessfunctionApparent dynamic stiffness s't (EN 29052-1 Formula 4).
• resonant_frequency_hz fr [Hz] (scalar/array)
• total_mass_per_area_kg_m2 m't [kg/m²]
s't = 4π²·m't·fr² [N/m³]
apparent_dynamic_stiffness(25.0, 200.0) # 4.935e6 N/m³
plot_dynamic_stiffness_rigfunctionResonance rig to scale.
• specimen_side (Default: 0.2 m), specimen_thickness (Default: 0.02 m)
• load_mass (Default: 8 kg)
• language
plot_dynamic_stiffness_rig()
enclosed_gas_stiffnessfunctionEnclosed-gas dynamic stiffness s'a (EN 29052-1 Formula 7).
• thickness_m d [m]
• porosity ε (0-1)
• atmospheric_pressure_pa p₀ [Pa] (Default: 1e5 = 0,1 MPa)
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_stiffnessfunctionInstalled s' by airflow resistivity (EN 29052-1 clause 8.2).
• apparent_stiffness_n_m3 s't [N/m³]
• airflow_resistivity_kpa_s_m2 r [kPa·s/m²], by name only
• gas_stiffness_n_m3 s'a [N/m³] (Default: None; required below r = 100)
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, airflow_resistivity_kpa_s_m2=50.0, gas_stiffness_n_m3=3e6) # 23e6
natural_frequencyfunctionFloating-floor natural frequency f0 (EN 29052-1 Formula 2).
• dynamic_stiffness_n_m3 s' of the installed layer [N/m³] (scalar/array)
• mass_per_area_kg_m2 m' [kg/m²]
f0 = (1/2π)√(s'/m')
natural_frequency(10e6, 120.0) # 45.9 Hz
floating_floor_resonancefunctionFull EN 29052-1 chain → result.
• resonant_frequency_hz, total_mass_per_area_kg_m2, floor_mass_per_area_kg_m2
• airflow_resistivity_kpa_s_m2 (Default: inf), thickness_m, porosity, atmospheric_pressure_pa
res = materials.floating_floor_resonance(25.0, 200.0, 120.0)

• DynamicStiffnessResult
ResilientLayer / PUBLISHED_RESILIENT_LAYERS / resilient_layerdataclass / mapping / functionA resilient layer as a catalogue row, and the fifteen of Hopkins Table A3 (printed p. 610).
• keyed '<table>/<row>': 'hopkins-2007-table-a3/<material>_<density>_<thickness>', e.g. 'hopkins-2007-table-a3/mineral_wool_rock_60_30'
• optional dynamic_stiffness_n_m3 s′ of the installed layer and apparent_dynamic_stiffness_n_m3 s′t of the test specimen [N/m³], density_kg_m3, thickness_mm, plus every hedge of CatalogueRow; Table A3 prints s′ and fills only the first
• .natural_frequency(mass_per_area_kg_m2, *, airflow_resistivity_pa_s_m2=None, gas_stiffness_n_m3=None) → f₀ [Hz] (Formula 2); a row with only s′t needs r [Pa·s/m²] and, below 100 kPa·s/m², s′a, and goes through clause 8.2; without r it raises CatalogueError
• Measured specimens, not declared product values: design with the manufacturer's s′ to EN 29052-1
layer = materials.resilient_layer('hopkins-2007-table-a3/mineral_wool_rock_60_30')
layer.natural_frequency(mass_per_area_kg_m2=100.0) # 50.3 Hz
ResilientMaterialdataclassOne resilient material's dynamic modulus, as a page printed it.
• dynamic_youngs_modulus_pa [Pa], density_kg_m3 [kg/m³], static_load_pa [Pa] (about 2 kPa, the load it was measured under)
• printed as ranges, held in ranges; a layer's s' is the modulus over its thickness
rock = materials.resilient_moduli_named('rock wool')[0]
rock.ranges['dynamic_youngs_modulus_pa'] # (270000.0, 330000.0)

• PUBLISHED_RESILIENT_MODULI, resilient_moduli_named
PUBLISHED_RESILIENT_MODULImappingSix resilient materials' dynamic moduli, keyed '<table>/<row>'.
• Vigran (2008) Table 8.3 (PDF page 339): glass wool, two rock wools, polystyrene and polyurethane foam, cork
• the modulus rises with the static load, by about 30 % from 2 to 4 kPa for rock wool, so it describes a layer under that load
len(materials.PUBLISHED_RESILIENT_MODULI) # 6

• ResilientMaterial, resilient_moduli_named
resilient_moduli_namedfunctionEvery published resilient material whose name contains the text.
• name: matched without case; 'rock wool' answers with both rock wools, which only their densities tell apart
• empty when nothing matches
len(materials.resilient_moduli_named('rock wool')) # 2

• PUBLISHED_RESILIENT_MODULI
DynamicStiffnessResultdataclassDynamic-stiffness measurement result.
• apparent_stiffness/gas_stiffness/dynamic_stiffness [N/m³]
• resonant_frequency [Hz], floor_mass_per_area [kg/m²]
• natural_frequency [Hz]
• .plot()
res.dynamic_stiffness, res.natural_frequency
DynamicStiffnessWarningwarning classEN 29052-1 advisory.
Emitted when the enclosed-gas term makes s′ unresolvable (clause 8.2)
warnings.simplefilter('error', DynamicStiffnessWarning)
convert_frffunctionConvert between any two FRFs (ISO 7626-1 Table 1).
• value: complex FRF value(s) of kind source
• frequency f [Hz] (scalar/array, broadcast)
• source/target: receptance/mobility/accelerance/dynamic_stiffness/impedance/apparent_mass
Pivots through the receptance H
convert_frf(2e-3, 80.0, "mobility", "impedance") # 500 N.s/m
FRF_UNITSmappingSI unit per FRF form (ISO 7626-1 Table 1, read-only).
Keyed by 'receptance', 'mobility', 'accelerance', ...
FRF_UNITS['mobility'] # 'm/(N·s)'
sdof_receptance / sdof_mobility / sdof_accelerancefunctionClosed-form SDOF resonator FRFs (ISO 7626-1 Table 1 / 3.1.2 definitions).
• frequency f [Hz] (scalar/array)
• mass m [kg], stiffness k [N/m], damping c [N·s/m]
H = 1/(k − ω²m + jωc); Y = jωH; A = −ω²H
`sdof_mobility(10.07, 2.0, 8000.0, 5.0) #
resonance_frequencyfunctionUndamped SDOF natural frequency (closed form).
• mass m [kg], stiffness k [N/m]
f0 = (1/2π)√(k/m)
resonance_frequency(2.0, 8000.0) # 10.07 Hz
rigid_mass_calibration_checkfunctionOperational rigid-mass calibration (ISO 7626-2 7.5.2).
• frf: measured FRF (complex or magnitude)
• frequencies [Hz], mass m [kg]
• quantity: 'accelerance' (|A| = 1/m) / 'mobility' (|Y| = 1/(ωm))
• tolerance (Default: 0.05 = ±5 %)
res = vibration.rigid_mass_calibration_check(frf, f, 10.0)

• RigidMassCalibrationResult
RigidMassCalibrationResultdataclassRigid-mass calibration verdict (ISO 7626-2 7.5.2).
• frequencies [Hz], measured/expected/deviation per band
• within_tolerance: per-band flags, passes: overall
• mass [kg], quantity, tolerance
res.passes, res.deviation
random_error_percentfunctionNormalized random error of an averaged FRF (ISO 7626-2 Annex A).
• coherence: γ² per frequency, in (0, 1]
• n_averages: n ≥ 1
ε = √((1−γ²)/(2nγ²)) [%]; 8.1.3 requires < 5 % at resonances
random_error_percent(0.8, 75) # 4.08 %
sdof_mobility_resultfunctionSDOF driving-point mobility → result.
• frequency f [Hz] (array)
• mass, stiffness, damping
res = vibration.sdof_mobility_result(f, 2.0, 8000.0, 5.0)

• MobilityResult
MobilityResultdataclassMobility FRF over frequency (ISO 7626-1).
• frequencies [Hz], mobility Y [m/(N·s)]
• driving_point: bool (i = j)
• .magnitude / .phase
• .to(target): any Table-1 kind
• .plot():
Y(f)
transfer_stiffness_level / loss_factorfunctionTransfer-stiffness level & loss factor (ISO 10846-2/-3 3.17, -1 3.8).
• transfer_stiffness_level(k, reference=1.0): Lₖ = 20 lg(|k|/k₀) [dB re 1 N/m]
• loss_factor(k): η = Im(k)/Re(k)
transfer_stiffness_level(1e6) # 120 dB
transfer_stiffness_directfunctionDirect method (ISO 10846-2).
• blocking_force F₂,b [N]
• input_displacement u₁ [m]
k₂,₁ = F₂,b/u₁
transfer_stiffness_direct(5.0, 1e-6) # 5e6 N/m
transfer_stiffness_indirectfunctionIndirect method (ISO 10846-3 Formula 1).
• frequency f [Hz] (scalar/array)
• transmissibility T = u₂/u₁ (complex)
• blocking_mass m₂ [kg]
• flange_mass m_f [kg] (Default: 0.0)
k₂,₁ = −(2πf)²(m₂+m_f)T; warns (TransferStiffnessWarning) where |T| > 0.1 (Inequality 2: ΔL1,2 < 20 dB)
transfer_stiffness_indirect(500.0, 0.01, blocking_mass=10.0)
TRANSMISSIBILITY_LIMITfloatIndirect-method validity limit (ISO 10846-3 6.1, Inequality 2).
0.1: |T| ≤ 0.1 ⇔ ΔL1,2 ≥ 20 dB keeps Formula (1) within 1 dB (12 %)
TRANSMISSIBILITY_LIMIT # 0.1
REFERENCE_STIFFNESSfloatReference stiffness k0 for the level Lk [N/m] (ISO 10846-2/-3, 3.17).
1.0
REFERENCE_STIFFNESS # 1.0
blocking_force_ratiofunctionDelivered/blocking force ratio (ISO 10846-1 Eq. 6).
• driving_point_stiffness k₂,₂ [N/m] (complex)
• termination_stiffness k_t [N/m] (complex, non-zero)
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_transmissibilityfunctionMass-loaded Kelvin-Voigt transmissibility (model).
• frequency f [Hz]
• mass m [kg], stiffness k [N/m], damping c [N·s/m] (Default: 0.0)
T = (k+jωc)/(k−ω²m+jωc)
base_transmissibility(f, 8.0, 1e6, 120.0)
indirect_transfer_stiffness_resultfunctionIndirect-method sweep → result.
• frequency f [Hz] (array)
• transmissibility T (complex)
• blocking_mass m₂ [kg], flange_mass (Default: 0.0)
res = vibration.indirect_transfer_stiffness_result(f, t, 8.0)

• TransferStiffnessResult
TransferStiffnessResultdataclassDynamic transfer stiffness over frequency (ISO 10846).
• frequencies [Hz], transfer_stiffness k₂,₁ [N/m]
• blocking_mass m₂ [kg] or None
• valid: lines that meet their adequacy conditions, or None (all); the indirect method sets |T| ≤ 0.1
• .magnitude / .levels (dB re 1 N/m) / .loss_factor
• .to(target): "impedance"/"apparent_mass"
• .band_average(): BandAveragedStiffness over the valid lines
• .plot(): Lₖ(f)
res.levels, res.band_average().levels
band_averaged_stiffnessfunctionOne-third-octave band average of a narrow-band stiffness (ISO 10846-2 F. 6, -3 F. 7, -4 F. 11, -5 F. 6).
• frequencies [Hz] (distinct), stiffness k [N/m] (complex)
• valid: lines that enter the average (Default: every line)
k_av = {(1/n) Σ |k(fᵢ)|²}^½ over n ≥ 5 lines per base-ten band; a band of one to four valid lines is NaN and warns (TransferStiffnessWarning)
bands = vibration.band_averaged_stiffness(f, k)

• BandAveragedStiffness
BandAveragedStiffnessdataclassOne-third-octave band averages of a stiffness (ISO 10846).
• nominal_frequencies (ISO 266) / center_frequencies (exact midband) [Hz]
• stiffness k_av [N/m], NaN where fewer than five lines; line_counts
• .determined, .levels L_k,av [dB re 1 N/m]
• .plot(): the band levels, undetermined bands marked
bands.levels, bands.determined
MIN_FREQUENCIES_PER_BANDconstantFewest lines a band average is taken over (every part's band average: "a minimum of n = 5 frequencies").
5
MIN_FREQUENCIES_PER_BAND # 5
TransferStiffnessWarningwarning classISO 10846 advisory.
Emitted when an adequacy condition fails (|T| > 0.1, ΔL₁,₂ < 20 dB, unwanted input within 15 dB, m₀ over its limit) or a band holds fewer than five lines. Subclass of PhonometryWarning
warnings.simplefilter('error', TransferStiffnessWarning)
check_blocked_output / check_unwanted_inputfunctionIs the output blocked, and the input unidirectional? (ISO 10846-5 Inequalities 1 and 2; -2 Ineq. 1 and 3, -3 Ineq. 2 and 5, -4 Ineq. 2 and 7).
• frequencies [Hz]
• check_blocked_output(f, input_acceleration_level_db, output_acceleration_level_db): L_a1 − L_a2 ≥ 20 dB
• check_unwanted_input(f, excitation_level_db, unwanted_level_db): ≥ 15 dB; one row per direction, the loudest decides
Warns (TransferStiffnessWarning) where the condition fails
vibration.check_blocked_output(f, la1, la2).passes

• LevelDifferenceCheck
LevelDifferenceCheckdataclassA level-difference condition judged frequency by frequency.
• frequencies [Hz], difference_db, limit_db (20 or 15), condition ("blocked_output"/"unwanted_input")
• .holds per frequency, .passes; no truth value
• .plot()
check.holds
check_output_massfunctionIs the mass in front of the output force transducers light enough? (ISO 10846-4 Inequality 3, -2 Inequality 2).
• frequencies [Hz], output_mass_kg m₀ [kg]
• output_force_level_db L_F2 re 1 µN, output_acceleration_level_db L_a2 re 1 µm/s²
m₀ ≤ 0.06·10^(L_F2/20)/10^(L_a2/20) kg = 0.06 |F₂|/|a₂|; warns (TransferStiffnessWarning) where it fails
vibration.check_output_mass(f, 0.4, lf2, la2).passes

• OutputMassCheck
OutputMassCheckdataclassThe output mass against its ISO 10846-4 Inequality (3) limit.
• frequencies [Hz], output_mass_kg, mass_limit_kg [kg]
• .holds, .passes; .inertia_ratio r = m₀|a₂|/|F₂|; .bias_bound_db −20 lg(1 − r), 0.54 dB on the bound (NOTE 1: 0.5 dB)
• .plot()
check.bias_bound_db
effective_blocking_massfunctionEffective mass of a blocking mass (ISO 10846-4 Formula 6, -3 Formula 4).
• frequencies [Hz] (increasing), force_n F₂, first_acceleration_m_s2 a′₁, second_acceleration_m_s2 a″₁ (phasors)
• blocking_mass_kg m₂ [kg], by name only
m₂,eff = |2F₂/(a′₁ + a″₁)|
vibration.effective_blocking_mass(f, F, a1, a2, blocking_mass_kg=20.0)

• EffectiveBlockingMass
EffectiveBlockingMassdataclassEffective blocking mass and its upper limit f₃ (ISO 10846-4 Inequality 5, -3 Inequality 3).
• frequencies [Hz], effective_mass_kg, blocking_mass_kg [kg]
• .deviation_db 20 lg(m₂,eff/m₂); .upper_frequency_limit_hz f₃, the 1 dB crossing from 40 Hz up (None if never); .valid; .ignored_below_hz (40)
• .plot()
em.upper_frequency_limit_hz
driving_point_stiffnessfunctionDynamic driving-point stiffness (ISO 10846-5 Formula 3).
• frequencies [Hz] (increasing; lines from 1 Hz to 20 Hz needed)
• input_force_n F₁, input_acceleration_m_s2 a₁ (phasors)
• output_acceleration_m_s2, unwanted_acceleration_m_s2 (Default: None): check Inequalities 1 and 2 and exclude the lines that fail
k₁,₁ = −(2πf)² F₁/a₁
res = vibration.driving_point_stiffness(f, F1, a1)

• DrivingPointStiffnessResult
DrivingPointStiffnessResultdataclassDriving-point stiffness and the transfer stiffness it stands for (ISO 10846-5 6.2, Formulas 6 and 7).
• frequencies [Hz], driving_point_stiffness k₁,₁ [N/m], adequate (or None)
• .levels, .loss_factor; .low_frequency_level_db (1 Hz to 20 Hz); .threshold_level_db (2 dB below)
• .upper_limiting_frequency_hz f_UL (None if never reached); .valid
• .band_average(): k_av(1,1) ≈ k_av(2,1) within 2 dB
• .plot()
res.upper_limiting_frequency_hz, res.band_average().levels
driving_point_uncertaintyfunctionUncertainty budget of a driving-point band level (ISO 10846-5 Annex B, Table B.1).
• band_level_db L̂_k,av [dB re 1 N/m]
• repeatability_range_db 2p [dB], by name only (u_rep = p/√3)
• signal_uncertainty_db (0.3), instrumentation_uncertainty_db (0.5), test_rig_uncertainty_db (1/(2√3)), discrepancy_uncertainty_db (2/√3), linearity_uncertainty_db (1.5/(2√3))
Built on metrology.combine_uncertainty; U = 2u (B.3)
vibration.driving_point_uncertainty(118.0, repeatability_range_db=0.6).expanded_uncertainty_db

• DrivingPointUncertainty
DrivingPointUncertaintydataclassAn ISO 10846-5 Annex B budget.
• budget: the metrology.UncertaintyResult, one row per Formula (B.1) input
• .band_level_db, .combined_uncertainty_db (B.2), .coverage_factor (2), .expanded_uncertainty_db (B.3)
• .plot(): the contributions with u and U
u.expanded_uncertainty_db
infinite_plate_impedance / infinite_plate_mobility / infinite_plate_point_mobilityfunctionThin-plate point mobility Z = C√(B'm'') (Cremer Table 5.1).
• bending_stiffness B' [N·m], mass_per_area m'' [kg/m²]
• location: 'centre' (C=8) / 'edge' (C=3.5); real, frequency-independent
infinite_plate_impedance(1e4, 10)

• float or MobilityResult
infinite_beam_mobility / infinite_beam_impedance / infinite_beam_moment_mobility / infinite_beam_point_mobilityfunctionSlender-beam point mobility Y = (1−j)/(4m'cB) (Cremer Table 5.1).
• frequency [Hz], bending_stiffness B [N·m²], mass_per_length m' [kg/m]
• location: 'centre'/'end'; 45°, ∝ ω^−½
infinite_beam_mobility(100, 200, 5)

• complex or MobilityResult
beam_bending_wave_speed / plate_bending_wave_speedfunctionFree bending wave speed, cB = (B ω²/m')^¼ for a beam and (B' ω²/m'')^¼ for a plate.
• frequency [Hz]
• beam: bending_stiffness B = EI [N·m²], mass_per_length m' [kg/m]
• plate: bending_stiffness B' [N·m], mass_per_area m'' [kg/m²]
• ∝ √f, so it crosses the speed of sound at fc
plate_bending_wave_speed(500.0, 4.2e3, 20.0)
longitudinal_rod_mobilityfunctionPoint mobility of an infinite rod, Y = 1/(ρ cL S) (Cremer Table 5.1).
• density ρ [kg/m³], longitudinal_wave_speed cL [m/s], cross_section_area S [m²]
• Real and frequency-independent, unlike the bending mobilities
longitudinal_rod_mobility(7800.0, 5100.0, 1e-4)
longitudinal_rod_impedance / injected_power / plate_bending_stiffnessfunctionRod 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_frequencyfunctionPlate radiation efficiency σ(f) (Hopkins 2.9, Leppington/Maidanik).
• frequency [Hz], length_x/length_y [m], critical_frequency fc [Hz]
• boundary: 'simply_supported'/'clamped', baffle: 'infinite'/'perpendicular'
• σ → 1 above fc; fc = (c₀²/2π)√(m''/B')
radiation_efficiency(f, 1.5, 1.25, 2100)

• RadiationEfficiencyResult
plot_plate_geometryfunctionBaffled rectangular plate to scale.
• length_x, length_y [m]
• boundary (title label)
• language
plot_plate_geometry(1.2, 0.8)

• Also RadiationEfficiencyResult.plot_geometry()
RadiationEfficiencyResultdataclassPlate radiation efficiency over frequency (Hopkins 2.9.4).
• radiation_efficiency σ, radiation_index 10 lg σ [dB]
• critical_frequency fc, .plot(); feeds sound_power_from_vibration as ε
res.radiation_efficiency
junction_transmissionfunctionBending-wave transmission of a rigid plate junction (Hopkins 5.2.1.3, Cremer 1973, Craik 1981/1996).
• junction: 'X'/'T1'/'T2'/'L'
• two plates' thickness h, wave_speed cL, surface_density ρs
• angles_deg grid (Default: 0–90°)
junction_transmission('X', 0.1, 3200, 240, 0.1, 3200, 240)

• JunctionTransmissionResult
plot_junction_geometryfunctionPlate junction (L/T1/T2/X) to scale.
• junction, thickness1, thickness2 [m]
• language
plot_junction_geometry('X', 0.14, 0.2)

• Also JunctionTransmissionResult.plot_geometry()
JunctionTransmissionResultdataclassAngle-resolved bending-wave transmission at a rigid junction (Hopkins 5.2.1.3).
• chi, psi, critical_frequency1/critical_frequency2 fc [Hz], angles_deg, corner τ12(θ), straight τ13(θ) or None
• corner_average/straight_average (Eq. 5.6), corner_reduction_index Kij (symmetric), .plot()
res.corner_average # 1/12 for identical X
junction_wave_parametersfunctionWave parameters χ, ψ of a plate pair (Hopkins 5.10/5.11).
• two plates' h [m], cL [m/s], ρs [kg/m²]
• χ = √(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_coefficientfunctionτ12(θ) around a corner (Hopkins 5.12) / τ13(θ) across a straight section (5.13).
• angle_rad θ [rad], chi, psi, junction
• corner is 0 for χ < sinθ; straight only for 'X'/'T1'
corner_transmission_coefficient(0.0, 1.0, 1.0, 'X') # 1/8
inline_transmission_coefficientfunctionNormal-incidence transmission across an in-line junction (Hopkins 5.14, Cremer 1973).
• chi, psi; τ = 1 for identical plates
inline_transmission_coefficient(1.0, 1.0) # 1.0
angular_average_transmission_coefficientfunctionDiffuse-field angular average ∫₀^{π/2} τ(θ)cosθ dθ (Hopkins 5.6).
• chi, psi, junction, section: 'corner'/'straight'
angular_average_transmission_coefficient(1.0, 1.0, 'X') # 1/12
coupling_loss_factorfunctionSEA coupling loss factor from τ (Hopkins 2.154).
• transmission_coefficient τ, group_velocity cg [m/s]
• junction_length L [m], frequency f [Hz], plate_area S [m²]
η = cg·L·τ/(2π²fS)
coupling_loss_factor(1/12, 200, 4, 500, 10)
right_angle_transmission_coefficientfunctionτ12 of a right-angle plate junction, closed form (Norton & Karczub 6.53-6.55).
• thickness1, thickness2 [m]; density1/density2 [kg/m³], wave_speed1/wave_speed2 [m/s]
• incidence: 'random' (Default, Eq. 6.55) / 'normal' (Eq. 6.53)
• feed to coupling_loss_factor with cg = 2cB to get Norton Eq. (6.52)
right_angle_transmission_coefficient(0.003, 0.0055, density1=2700, density2=2700, wave_speed1=5432, wave_speed2=5432)
point_connection_coupling_loss_factorfunctionη12 of plates joined at N points (bolts/rivets/spot welds) (Norton & Karczub 6.56).
• frequency [Hz], n_connections N
• thickness1/thickness2 [m], surface_density1/surface_density2 [kg/m²], wave_speed1/wave_speed2 [m/s], plate_area1 S1 [m²]
• falls as 1/f (a line junction falls as 1/√f)
point_connection_coupling_loss_factor(f, 12, thickness1=0.003, ...)
power_injection_clffunctionExperimental SEA: CLFs from one drive plus reciprocity (Norton & Karczub 6.8/6.15).
• frequency [Hz], energy1/energy2 E = M⟨v²⟩ [J]
• internal_loss_factor1/2, modal_density1/2 [1/Hz]
• η12 = η2·E2/(E1 − E2·n1/n2), η21 = η12·n1/n2
power_injection_clf(500, 0.087, 0.013, 4.4e-3, 2.4e-3, 0.557, 0.606)

• PowerInjectionResult
power_injection_matrixfunctionTwo-drive power-injection inversion (no reciprocity assumed).
• frequency [Hz], energies (2, 2, nb) [J], input_powers (2, nb) [W]
• returns all four loss factors; reciprocity becomes a check
power_injection_matrix(f, e, p)

• PowerInjectionResult
PowerInjectionResultdataclassLoss-factor budget of a two-subsystem SEA model.
• coupling_loss_factor12/21, internal_loss_factor1/2, energy1/2, input_power1/2, modal_density1/2, method
• input_power, dissipated_power, transmitted_power, coupling_strength η12/η1, modal_density_ratio, .plot()
res.coupling_loss_factor12, res.input_power
flat_plate_modal_density / bar_modal_density / beam_modal_densityfunctionModal densities of structural elements (Norton & Karczub 6.23-6.25).
• plate: n = S√12/(2cL·t) (equals π·S·fc/c₀² exactly)
• bar: n = 2L/cL; beam: n = L(ρA/EI)^¼/√(2πf) (falls with f)
flat_plate_modal_density(8.73, 0.005, 5432.3) # 0.557 /Hz
cylindrical_shell_modal_density / ring_frequencyfunctionAverage modal density of a thin-walled cylinder (Norton & Karczub 6.26-6.29, Szechenyi).
• frequency [Hz], area S [m²], thickness t [m], mean_radius a [m], longitudinal_wave_speed cL [m/s], band: 'octave'/'third'
• three regimes about fr = cL/(2πa)
cylindrical_shell_modal_density(500, 9.42, 0.003, 0.75, 5432.3)
seat_factor / seat_transmission / SeatTransmissionResultfunction / dataclassWhat a seat does to the vibration under it (ISO 10326-1 Formula (2)).
• seat_factor(a_wS, a_wP): the SEAT factor, below 1 when the seat attenuates
• seat_transmission(seat_runs, platform_runs): one test from its runs, each set averaged only if it holds the ± 5 % of 10.2.1
• .seat_factor, .attenuates, .corrected_acceleration(intended), .plot()
vibration.seat_transmission([0.72, 0.70, 0.71], [1.02, 1.00, 0.99]).seat_factor

• 0.708
corrected_seat_acceleration / resonance_transmissibilityfunctionThe corrected seat magnitude and the resonance ratio (ISO 10326-1 Clause 10).
• corrected_seat_acceleration(a_wS, a_wP, intended): the seat magnitude scaled to the input the test intended (10.2.3, Formula (4); the printed Formula (3) is an identity, see the errata)
• resonance_transmissibility(a_S, a_P): Formula (5), the damping test at the suspension resonance
vibration.corrected_seat_acceleration(0.70, 1.00, 1.10) # 0.77
mean_of_test_runs / RUN_AGREEMENT_TOLERANCE / TEST_RUNSfunction / constantThe three runs a seat test is made of (ISO 10326-1 10.2.1, 10.3).
• the arithmetic mean of runs that agree within ± 5 % of it, and a refusal when they do not
• tolerance= tightens the band for an application standard that asks for less
vibration.mean_of_test_runs([1.02, 1.00, 0.99]) # 1.003
DAMPING_TEST_MASS_KG / DAMPING_TEST_MASS_TOLERANCE / ACTIVE_DAMPING_TEST_MASS_KG / UNITY_TRANSMISSIONconstantThe masses and the neutral value of ISO 10326-1.
• 75 kg ± 1 % of inert mass for the damping test (10.3)
• 60 kg where the suspension is actively damped (9.5.1)
• 1, the ratio at which the seat passes the vibration through unchanged, which says nothing about it being rigid; Clause 11 leaves acceptance values to the application standard
vibration.DAMPING_TEST_MASS_KG # 75.0
guideline_velocity / BUILDING_CLASSESfunction / constantGuideline peak velocity for a structural-vibration assessment (DIN 4150-3 Tables 1 and 3).
Keeping to a value meets the standard's criterion and certifies nothing; exceeding one is not a finding of damage
• building_class: 'commercial', 'residential' or 'sensitive'
• frequency [Hz], needed only at the foundation for short-term vibration
• location: 'foundation' or 'top_floor'; duration: 'short_term' or 'long_term'
• massive_structure=True doubles the commercial row (5.1)
vibration.guideline_velocity('residential', 30) # 10.0 mm/s
pipeline_guideline_velocity / PIPELINE_MATERIALSfunction / constantGuideline peak velocity on a buried pipeline (DIN 4150-3 Table 2).
• material: 'welded_steel' 100, 'concrete_or_flanged_metal' 80, 'masonry_or_plastic' 50 mm/s
• duration='long_term' halves them, which is the reduction 6.3 allows
vibration.pipeline_guideline_velocity('welded_steel') # 100.0
assess_building_vibration / DamageAssessmentfunction / dataclassOne measured peak velocity against its guideline value.
• velocity_mm_s plus the same building_class, frequency_hz, location and duration
• .guideline_mm_s, .ratio, .within_guideline, .plot() drawing Bild 1 with the measurement on it
vibration.assess_building_vibration(4.2, building_class='residential', frequency_hz=18).ratio # 0.6
bending_stress / storey_fundamental_frequencyfunctionFrom a velocity to a stress, and the storey estimate (DIN 4150-3 6.2 and 6.4).
• bending_stress(peak_velocity_m_s, dynamic_modulus_pa=, density_kg_m3=, load_ratio=, mode_factor=), Formula (1); note the m/s
• storey_fundamental_frequency(n) = 10/n Hz, from about five storeys up
vibration.bending_stress(0.01, dynamic_modulus_pa=3e10, density_kg_m3=2400)

• 1.47e5 Pa
BuildingDamageWarningwarning classA DIN 4150-3 rule used outside the range the standard offers it for.
Emitted by storey_fundamental_frequency below STOREY_FREQUENCY_MIN_STOREYS, where 10/n is an extrapolation rather than the rule of 6.4
warnings.simplefilter("error", vibration.BuildingDamageWarning)
foundation_guideline_curvefunctionBild 1 as two arrays, ready to plot.
• building_class, and frequency to sample elsewhere than the four printed corners
• returns (frequency_hz, guideline_mm_s)
vibration.foundation_guideline_curve('sensitive')

• (1, 10, 50, 100) Hz, (3, 3, 8, 10) mm/s
SHORT_TERM_FOUNDATION_MM_S / FOUNDATION_FREQUENCIES_HZ / SHORT_TERM_TOP_FLOOR_MM_S / LONG_TERM_TOP_FLOOR_MM_S / PIPELINE_MM_SconstantThe three printed tables of DIN 4150-3, as data.
• Table 1 at the foundation, by class, at 1, 10, 50 and 100 Hz
• Table 1 in the topmost floor plane: 40 / 15 / 8 mm/s
• Table 3, long-term: 10 / 5 / 2.5 mm/s; Table 2, pipelines: 100 / 80 / 50 mm/s
vibration.SHORT_TERM_FOUNDATION_MM_S['residential'] # (5.0, 5.0, 15.0, 20.0)
FLOOR_VERTICAL_MM_S / MASSIVE_STRUCTURE_FACTOR / PIPELINE_LONG_TERM_FACTOR / BENDING_STRESS_CONSTANT / STOREY_FREQUENCY_NUMERATOR_HZ / STOREY_FREQUENCY_MIN_STOREYSconstantThe numbers DIN 4150-3 prints in sentences rather than in tables.
• 20 mm/s vertical for a floor (5.2); the factor 2 for massive engineering structures (5.1)
• the 50 % of 6.3; the 1,73 of Formula (1)
• the 10 Hz and the five storeys of 6.4
vibration.FLOOR_VERTICAL_MM_S # 20.0
fundamental_period / fundamental_frequency / PERIOD_MODELSfunction / constantEmpirical fundamental translation mode of a building (ISO 4866 Annex D).
• fundamental_period returns T in seconds, fundamental_frequency returns f in hertz
• model: 'storeys' (T = 0,1 n), 'height' (T = k₁h), 'height_width' (T = k₂h/√b), 'slenderness' (T = k₃(h/√b)√(h/(h+b)))
• storeys, height_m, width_m as the model needs them, and only those: an argument the form does not use is refused
• coefficient defaults to the middle of the range D.2 prints for that form
vibration.fundamental_frequency('height_width', height_m=60, width_m=20)

• 0.76 Hz
height_fundamental_frequency / HEIGHT_FREQUENCY_CONSTANT_HZ_M / HEIGHT_PERIOD_COEFFICIENT_S_PER_Mfunction / constantThe fit ISO 4866 D.2 closes with, to 163 measured buildings.
• f = 46/h hertz, or T = 0,022 h seconds, scalar or array
• D.3 goes on to report that computed frequencies correlate with measurement worse than this line does
vibration.height_fundamental_frequency(46) # 1.0 Hz
empirical_frequency_bounds / EMPIRICAL_FREQUENCY_TOLERANCEfunction / constantThe error an empirical prediction carries (ISO 4866 D.2).
• ± 50 %, which the annex calls not uncommon and typical of empirical formulae
• returns (lower, upper) in hertz
vibration.empirical_frequency_bounds(2.0) # (1.0, 3.0)
estimate_fundamental_frequency / BuildingFrequencyEstimatefunction / dataclassOne prediction with the coefficient and band it carries.
• .frequency_hz, .period_s, .model, .coefficient, .height_m
• .bounds_hz the ± 50 % band, .plot() Figure D.1 with the estimate on it
vibration.estimate_fundamental_frequency('height', height_m=46).bounds_hz
PERIOD_COEFFICIENT_RANGES / STOREY_PERIOD_COEFFICIENT_S / DAMPING_RATIO_RANGEconstantWhat ISO 4866 Annex D prints as ranges rather than values, damping included: it reports measurements and offers no estimator.
• k₁ 0,014 to 0,03, k₂ 0,087 to 0,109, k₃ 0,06 to 0,08 (D.2)
• the storey rule as a period, 0,1 s per storey
• damping measured between 0,5 % and 2,1 % of critical, with no predictor at all (D.4)
vibration.PERIOD_COEFFICIENT_RANGES['height'] # (0.014, 0.03)
ZoneBoundaries / evaluation_zoneclass / functionEvaluation zones of machine vibration (ISO 20816-1 6.3.2.3).
• ZoneBoundaries(a_b, b_c, c_d): the three boundaries, rising, in whichever quantity the applicable part states
• evaluation_zone(magnitude, boundaries) → 'A'/'B'/'C'/'D'; a magnitude on a boundary is the top of the zone below
z = vibration.ZoneBoundaries(2.8, 7.1, 11.2)
vibration.evaluation_zone(3.4, z) # 'B'
allowable_velocityfunctionFrequency-shaped velocity criterion (ISO 20816-1 Figure 9, Formula C.1).
• frequency f [Hz]
• constant_velocity_mm_s vA [mm/s], zone_factor Zbound (see ZONE_LIMIT_FACTORS: 1 / 2.56 / 6.4)
• corner_low_hz fx, corner_high_hz fy [Hz]
• exponent_low k, exponent_high m (Default: 1, constant displacement below and constant acceleration above)
vibration.allowable_velocity(100, constant_velocity_mm_s=1.12, corner_low_hz=10, corner_high_hz=1000)
VectorChangeResultdataclassA change in vibration between two steady states (ISO 20816-1 Annex D).
• magnitude the change itself, phase_deg its direction
• initial / final the two states as (magnitude, phase)
• magnitude_change: what a magnitude-only comparison would have reported
• .plot(unit='mm/s'): the polar diagram of Figure D.1
vibration.vibration_vector_change(3, 40, 2.5, 180).plot(unit='mm/s')
vibration_vector_changefunctionChange in vibration read as a vector (ISO 20816-1 Annex D).
• initial_magnitude, initial_phase_deg, final_magnitude, final_phase_deg
• .magnitude the real change, .magnitude_change what a magnitude comparison reports
vibration.vibration_vector_change(3, 40, 2.5, 180)

• 5.17 mm/s against −0.5
TYPICAL_BOUNDARY_LADDER_MM_S / TYPICAL_ZONE_BOUNDARY_RANGES_MM_S / ZONE_LIMIT_FACTORSconstantISO 20816-1 Table C.1 and Annex C.2.
• the ladder of 14 preferred magnitudes, 0.28 to 45 mm/s
• the typical range of each boundary: A/B 0.71–4.5, B/C 1.8–9.3, C/D 4.5–14.7 mm/s
• the zone factors of Formula (C.1): A 1, B 2.56, C 6.4
vibration.TYPICAL_ZONE_BOUNDARY_RANGES_MM_S['B/C'] # (1.8, 9.3)
MachineZoneLimits / INDUSTRIAL_MACHINE_ZONESdataclass / constantZone boundaries of the industrial-machine tables (ISO 10816-3 Tables A.1 and A.2).
• keyed by (group, support): 'group_1' above 300 kW to 50 MW, 'group_2' above 15 kW to 300 kW; 'rigid' or 'flexible'
• .displacement_um and .velocity_mm_s, each a ZoneBoundaries
• broad-band r.m.s. from 10 Hz to 1 kHz, or from 2 Hz below 600 r/min
vibration.INDUSTRIAL_MACHINE_ZONES['group_2', 'rigid'].velocity_mm_s.b_c # 2.8
industrial_machine_zonefunctionGrade an industrial machine against its table (ISO 10816-3 5.2.3).
• group, support
• displacement_um and/or velocity_mm_s, whichever was measured
• with both, the more restrictive grading applies
• scalar in, letter out; array in, one letter per reading
vibration.industrial_machine_zone('group_2', 'rigid', displacement_um=50, velocity_mm_s=2.0) # 'C'
is_significant_change / alarm_limit / trip_limitfunctionOperational limits with numbers (ISO 10816-3 5.3 and 5.4).
• is_significant_change(change, zone_b_upper): more than a quarter of the upper limit of zone B, up or down
• alarm_limit(baseline, zone_b_upper): that quarter above the baseline, capped at 1.25 times the limit
• trip_limit(zone_c_upper): 1.25 times the upper limit of zone C
vibration.alarm_limit(0.9, 2.8) # 1.6
vibration.trip_limit(4.5) # 5.625
SIGNIFICANT_CHANGE_FRACTION / OPERATIONAL_LIMIT_HEADROOMconstantThe two fractions the operational limits are built from (ISO 10816-3 5.3, 5.4.1 and 5.4.2).
• SIGNIFICANT_CHANGE_FRACTION = 0.25, of the upper limit of zone B
• OPERATIONAL_LIMIT_HEADROOM = 1.25, the multiple neither limit should exceed
vibration.OPERATIONAL_LIMIT_HEADROOM * 4.5 # 5.625
GEAR_UNIT_ZONES / gear_unit_zone_boundariesconstant / functionGear-unit zone boundaries (ISO 20816-9 Tables 2, 3 and 4).
• keyed by quantity, then by rating number: 'displacement' (shaft relative peak-to-peak, µm), 'velocity' (housing r.m.s., mm/s), 'acceleration' (housing true peak, m/s²)
• every row is three consecutive rungs of one ladder, with the rating as the B/C boundary
• a rating with no printed row is refused, not interpolated
vibration.gear_unit_zone_boundaries('velocity', 8.0).as_tuple

• (5.0, 8.0, 12.5)
GearUnitRatings / GEAR_UNIT_CLASSESdataclass / constantThe classification of typical gear units (ISO 20816-9 Table 5).
• keyed by (class, subclass): class 'I' to 'IV', subclass 'a', 'b_low' or 'b_high'
• .displacement, .velocity, .acceleration; the last is None on every b) row, where the table prints no information
vibration.GEAR_UNIT_CLASSES['III', 'a'].velocity # 8.0
gear_shaft_displacement_limit / gear_housing_velocity_limitfunctionThe two rating curves of ISO 20816-9 Annex A.
• Figure A.1: flat to 50 Hz, then 10 dB per decade down
• Figure A.2: flat from 45 Hz to 1590 Hz, then 14 dB per decade down on both sides, which is Formula (C.1) of Part 1 with those corners
vibration.gear_housing_velocity_limit(3000, rating=8.0)

• 5.13 mm/s
GEAR_DISPLACEMENT_CORNER_HZ / GEAR_DISPLACEMENT_SLOPE_DB_PER_DECADE / GEAR_VELOCITY_CORNERS_HZ / GEAR_VELOCITY_SLOPE_DB_PER_DECADE / GEAR_ACCEPTANCE_HEADROOMconstantThe numbers the notes under Figures A.1 and A.2 print, and the acceptance ceiling of 8.3.
• 50 Hz and 10 dB per decade for displacement
• 45 Hz to 1590 Hz and 14 dB per decade for velocity
• 1.25, the multiple of the A/B boundary an acceptance criterion should not normally exceed
vibration.GEAR_VELOCITY_CORNERS_HZ # (45.0, 1590.0)
bearing_fault_frequenciesfunctionRolling-bearing kinematic fault lines (Norton & Karczub 8.4-8.14).
• speed_rpm N, n_elements Z, element_diameter d, pitch_diameter D
• contact_angle_deg φ, rotating_race: 'inner'/'outer'
• lines: shaft, FTF, FTF_rel, BSF, BDF, BPFO, BPFI; BPFO + BPFI = Z·fs
bearing_fault_frequencies(2000, 15, 6, 34, contact_angle_deg=12.96) # BPFO 207 Hz

• FaultFrequencyResult
gear_mesh_frequenciesfunctionGear-mesh frequency and sideband family (Norton & Karczub 8.3).
• speed_rpm, n_teeth; harmonics, sidebands, sideband_rate [Hz]
• GMF = N·fs, sidebands at k·GMF ± m·f_mod
gear_mesh_frequencies(1500, 28, sidebands=2)

• FaultFrequencyResult
induction_motor_frequenciesfunctionMotor electrical and rotor-slot lines (Norton & Karczub 8.19/8.20).
• speed_rpm, poles p, rotor_bars R; slip s or supply_frequency fe
• slot_harmonics, sidebands
• lines: 1x, 2x, fe, 2fe, f_slip, FP, fsh = R·fs
induction_motor_frequencies(3600, 6, 60) # 2fe 360 Hz, fsh 3600 Hz

• FaultFrequencyResult
blade_pass_frequenciesfunctionFan/pump blade-pass tones and lobed patterns (Norton & Karczub 8.15-8.18).
• speed_rpm, n_blades; harmonics, n_vanes V, lobe_orders
• BPF = n·N·fs; lobes mL = nN ± kV turning at nN·fs/mL
blade_pass_frequencies(3500, 6, n_vanes=4) # BPF 350 Hz

• FaultFrequencyResult
FaultFrequencyResult / FaultLine / combine_fault_lines / shaft_ratedataclass / functionPredicted fault lines of one machine element.
• lines (name, frequency, order, family, description), shaft_rate, source
• res['BPFO'], names, frequencies, orders, as_dict(), harmonics(name, n), within(low, high)
• .plot(spectrum=envelope_result) overlays the lines on a measured envelope spectrum
res['BPFO'] # 207.0
wave_vibration_reduction_indexfunctionWave-approach vibration reduction index Kij (Hopkins 5.116).
• transmission_coefficient τ, critical_frequency_receiver fc_j [Hz]
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_accelerationfunctionVibratory velocity level (ISO/TS 7849-1 Eq. 3/8).
• velocity_level(v, reference=5e-8): 20 lg(v/v₀) [dB]
• 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_VELOCITYfloatReference velocity v0 [m/s] (ISO/TS 7849-1).
5e-8
REFERENCE_VELOCITY # 5e-08
NORMALIZED_IMPEDANCEfloatNormalized characteristic impedance Zc,n of air [N·s/m³] (23 °C, 101,3 kPa).
411.0
NORMALIZED_IMPEDANCE # 411.0
mean_velocity_levelfunctionMean surface velocity level (ISO/TS 7849-1 Eq. 10/11).
• levels L_v,i [dB]
• areas S_i (Eq. 11) or None → energetic mean (Eq. 10)
mean_velocity_level([60, 66, 63])
radiation_factorfunctionA-weighted radiation factor ε (ISO/TS 7849 Eq. 4/8).
• sound_power P [W], area S [m²]
• mean_square_velocity ⟨v²⟩ [(m/s)²]
• impedance Z_c (Default: 411 N·s/m³)
ε = P/(Z_c·⟨v²⟩·S)
radiation_factor(3e-4, 2.0, 1e-6) # 0.365
radiated_sound_power_levelfunctionSound power level from vibration (ISO/TS 7849-1 Eq. 12, -2 Eq. 15).
• velocity_level L_v [dB]
• area S [m²]
• radiation_factor ε (Default: 1.0 → Part 1 upper limit)
L_W = L_v + 10 lg(S/S₀) + 10 lg(ε) + 10 lg(411/400)
radiated_sound_power_level(80.0, 1.6)
extraneous_velocity_correctionfunctionCorrection K1A for extraneous vibration (ISO/TS 7849-1 Table 2).
• level_difference ΔLv [dB]; ΔLv≥10→0, ΔLv<3→3
extraneous_velocity_correction(6.0) # 1.0 dB
sound_power_from_vibrationfunctionBundle a vibration → power determination.
• velocity_level L_v per band [dB]
• area S [m²], radiation_factor ε (Default: 1.0)
• frequencies [Hz] or None
res = emission.sound_power_from_vibration(lv, 1.6, radiation_factor=eps, frequencies=f)

• VibrationSoundPowerResult
VibrationSoundPowerResultdataclassSound power radiated by surface vibration (ISO/TS 7849).
• velocity_level / sound_power_level / radiation_factor per band
• area S [m²], frequencies [Hz] or None
• .total_level: band-summed L_W [dB]
• .plot()
res.sound_power_level, res.total_level
spatial_mean_velocity_level / plate_loss_factorfunctionReception-plate helpers (EN 15657 Formula 12/13).
• spatial_mean_velocity_level(levels): 10 lg(mean 10^(Lv,i/10)) [dB]
• plate_loss_factor(f, Ts): η = 2.2/(f·Ts)
spatial_mean_velocity_level([78, 80, 82])
mean_free_velocity_levelfunctionMean free velocity level (ISO 9611:1996 eq. (9)).
• levels: free-velocity levels at the N contact points [dB re 5e-8 m/s]
Energy mean over positions
mean_free_velocity_level([70, 72, 74]) # 72.3 dB
structure_borne_power_levelfunctionReception-plate injected power level (EN 15657 Formula 14).
• velocity_level L_v [dB re 1e-9 m/s]
• frequency f [Hz], mass_per_area m [kg/m²], area S [m²]
• loss_factor η > 0
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_powerfunctionSource quantities (EN 15657 Formulae 15/17).
• equivalent_blocked_force_level(L_Ws_low, Y_plate): L_Fb,eq = L_Ws − 10 lg(Re Y/Y0) [dB re 1e-6 N]
• 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 = building.characteristic_reception_plate_power(building.equivalent_blocked_force_level(61.7, 5.34e-6))
equivalent_free_velocity_level / source_mobility_from_levelsfunctionSource quantities (EN 15657 Formulae 18/19).
• equivalent_free_velocity_level(L_Ws_high, Y_plate): L_vf,eq [dB re 1e-9 m/s]
• source_mobility_from_levels(L_vf,eq, L_Fb,eq): |Y_S,eq| [m/(N·s)]
y_s = building.source_mobility_from_levels(lvf, lfb)
reception_plate_powerfunctionReception-plate determination → result (EN 15657 clause 7).
• velocity_level L_v (per band), frequency [Hz]
• mass_per_area, area
• loss_factor η or reverberation_time Ts
res = building.reception_plate_power(lv, f, 600, 2.0, reverberation_time=0.8)

• StructureBornePowerResult
StructureBornePowerResultdataclassReception-plate injected structure-borne power (EN 15657).
• power_level L_Ws / velocity_level / loss_factor per band
• mass_per_area, area, frequencies [Hz] or None
• .total_level: band-summed L_Ws [dB]
• .plot()
res.power_level, res.total_level
coupling_term / coupling_term_force_source / coupling_term_velocity_sourcefunctionCoupling term D_C (EN 12354-5 Formula 19b/c/d).
• coupling_term(Ys, Yi, transfer_mobility=0): 10 lg(|Ys+Yi+Yk|²/(|Ys|·Re Yi))
• force source: 10 lg(|Ys|/Re Yi)
• velocity source: −10 lg(|Ys|·Re Zi)
coupling_term(2e-4+1e-4j, 3e-5+1e-5j)
installed_structure_borne_power_levelfunctionInstalled power (EN 12354-5 Formula 18b).
• characteristic_power_level L_Ws,c [dB] (the converted EN 15657 level, not the raw Formula 14 plate power)
• coupling_term D_C [dB]
L_Ws,inst = L_Ws,c − D_C
installed_structure_borne_power_level(82.0, 8.5)
installed_power_from_reception_platefunctionAnnex I mobility correction (EN 12354-5).
• reception_plate_level L_Ws,n [dB]
• receiver_mobility Y_∞,i [m/(N·s)]
• plate_mobility Y_∞,rec (Default: 5e-6)
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_levelfunctionPath & total normalised SPL (EN 12354-5 Formula 18a/17).
• path: L_Ws,inst − D_sa − R_ij,ref − 10 lg(S/S0) − 10 lg(A0/4)
• total: 10 lg(Σ 10^(L/10)) over paths (axis 0)
total_structure_borne_pressure_level(path_levels)
REFERENCE_AREAfloatReference area S0 = A0 [m²] (EN 12354-5 Formula 18a).
10.0
REFERENCE_AREA # 10.0
installed_source_predictionfunctionFull installed-source prediction → result (EN 12354-5).
• characteristic_power_level L_Ws,c, coupling_term D_C
• paths: dicts with adjustment_term, flanking_reduction_index, element_area
• frequencies [Hz] or None
res = building.installed_source_prediction(lwc, dc, paths, frequencies=f)

• InstalledSourceResult
InstalledSourceResultdataclassInstalled structure-borne sound prediction (EN 12354-5).
• path_levels (paths×bands), total_level L_n,s per band
• installed_power_level per band, frequencies [Hz] or None
• .overall_level: band-summed total [dB]
• .plot(): the cascade
res.total_level, res.overall_level
typical_element_mobility / TABLE_D1_QUANTITIESfunction / dictMobility of typical construction elements (EN 12354-5 Table D.1).
• structure: 'mass' [2πfM]⁻¹, 'bar_end' [ρcLS]⁻¹, 'beam' [7,6ρtw√(cLtf)]⁻¹, 'plate' [2,3cLρt²]⁻¹, 'pipe' [63ρtr√(cLrf)]⁻¹, 'mass_spring'
• the row's own describing quantities as keywords; TABLE_D1_QUANTITIES lists them
• frequency [Hz] for the four rows whose expression contains f, rejected by the other two
typical_element_mobility('plate', density=2300, longitudinal_velocity=3800, thickness=0.14) # 2.54e-6 m/(N·s)
tapping_machine_force_level / TABLE_F1_FORCE_LEVEL / TABLE_F1_OCTAVE_BANDSfunction / tupleISO tapping machine force level (EN 12354-5 Table F.1).
• octave bands 31,5 Hz to 4 kHz: 139, 142, 145, 148, 151, 154, 156, 156 dB re 1e-6 N (the caption prints "re 1 pN"; see ERRATA)
• substitution source of clause D.1.2.3, low-mobility receiving structures
tapping_machine_force_level()
tapping_machine_force_level_estimatefunctionClosed form printed under Table F.1 (EN 12354-5).
• frequency f [Hz], bandwidth 'octave' (2,5f) or 'third' (0,8f)
L_F = 10 lg(k f/10⁻¹²) dB re 1e-6 N; tracks the table only up to about 1000 Hz
tapping_machine_force_level_estimate(1000, bandwidth='third') # 149.03 dB
tapping_machine_characteristic_power_level / tapping_machine_coupling_termfunctionTapping machine as a force source (EN 12354-5 Formulae D.9a/D.9b).
• power: L_Ws,c = L_F − 5 − 10 lg f (≈115 dB re 1 pW per 1/3 octave)
• coupling: −10 lg(ωMYi) + 10 lg[1 + (ωMYi)²], hammer_mass M (Default: 0,5 kg)
tapping_machine_coupling_term(500.0, 1.07e-6)
structure_to_airborne_adjustmentfunctionAdjustment term D_sa (EN 12354-5 Formula F.3).
• frequency f [Hz], critical_frequency fc [Hz], mass_per_area m [kg/m²]
• radiation_factor σ (Default: 1.0)
D_sa = 10 lg(400 fc σ/(m f²)); normally negative, and Formula 18a subtracts it
structure_to_airborne_adjustment(500.0, 200.0, 92.0) # -24.6 dB
multi_junction_adjustment / MINIMUM_MULTI_JUNCTION_KIJfunction / floatMulti-junction ΔK (EN 12354-5 clause F.1).
• junctions ≥ 1 → 0 dB (single), 4 dB (two), 6 dB (three or more)
• the resulting Kij is floored at MINIMUM_MULTI_JUNCTION_KIJ = −5.0 dB
multi_junction_adjustment(2) # 4.0
airfunctionHumid air (IEC 61094-2:2009 Annex F, CIPM-2007).
• temperature_c t [°C], required
• static_pressure_pa p_s [Pa] (Default: None → 101 325, warns)
• relative_humidity_percent H [%] (Default: None → 50, warns)
• co2_mole_fraction x_c (Default: None → 0,000 4, silent)
f = fluids.air(temperature_c=23.0, static_pressure_pa=101325.0, relative_humidity_percent=50.0)

• Fluid; rho = 1.1860848 kg/m³, c0 = 345.86652 m/s
FluiddataclassOne fluid at one state, and what its model fixed there.
• temperature_c, static_pressure_pa, composition, model, validity, properties
• accessors density, speed_of_sound, heat_capacity_ratio, viscosity, thermal_diffusivity, thermal_conductivity, specific_heat_capacity
• closed by identity: characteristic_impedance, kinematic_viscosity, and prandtl_number unless the model printed one of its own, which wins
f.characteristic_impedance # rho c
PUBLISHED_FLUIDSmappingThe fluid states this library has read from a published page, keyed '<table>/<row>'.
• Bies 5e Table C.1 prints three fluids before its solids: air at 20 °C, fresh water at 20 °C and sea water at 13 °C
• Each names its page, with the printed folio, in its model, because for a transcribed state the table is what produced it
• The four airs that sit elsewhere in the tree are deliberately not here: each belongs beside the model or standard that fixes it, and gathering them would make the medium depend on three of the domains that stand on it
• Not a table to look values up in: air at measured conditions is air() and sea water is sea_water()
fluids.PUBLISHED_FLUIDS['bies-2017-table-c1-fluids/fresh_water'].speed_of_sound # 1497.0

• Fluid
GasdataclassOne gas of a published table: the two numbers that close its state.
• molar_mass_kg_mol M [kg/mol], heat_capacity_ratio γ, plus the hedges every catalogue row carries
• ideal_state(temperature_c=..., static_pressure_pa=...) → Fluid, carrying the row's page in its model
• a gas has no one density or speed of sound, which is why this is not a Fluid and not in PUBLISHED_FLUIDS
fluids.PUBLISHED_GASES['bies-2017-table-c2/methane'].ideal_state(temperature_c=20.0).speed_of_sound # 447.9

• ideal_gas, Fluid
PUBLISHED_GASESmappingThe gases this library has read from a published page, keyed '<table>/<row>'.
• Bies 5e Table C.2 prints thirty-seven gases and Hopkins Table A1 six, and both print air
• each row holds the molar mass and the ratio of specific heats, which between them close every state the gas can be in
• six cells of Table C.2 are not served: four molar masses that do not belong to the molecule their row names and two ratios outside what the quantity can be, each refusing with what the page prints and pointing at docs/ERRATA.md
• saturated steam prints an interval, 1,25 to 1,32, so it has no single ratio and says so
fluids.PUBLISHED_GASES['hopkins-2007-table-a1/argon'].heat_capacity_ratio # 1.67

• Gas
gases_namedfunctionEvery published row for a gas name, across the tables.
• name: the gas as a table prints it, matched without case and ignoring a parenthesis, so 'air' finds 'Air (dry)'
• returns both books' readings rather than choosing: carbon dioxide is 1,30 in one and 1,33 in the other
[g.table for g in fluids.gases_named('air')] # ['bies-2017-table-c2', 'hopkins-2007-table-a1']

• PUBLISHED_GASES
NonlinearityParameterdataclassOne published value of the nonlinearity parameter B/A, with the conditions it was measured at.
• b_over_a: B/A, dimensionless; the coefficient of nonlinearity is 1 + B/(2A)
• temperature_c [°C]; static_pressure_pa [Pa] only on the rows of the one table that prints a pressure, year only on the one that prints a year
• attributed_to['b_over_a']: the paper the value comes from, spelled out from the chapter's reference list; uncertainty['b_over_a']: the plus-or-minus where the page prints one
row = fluids.nonlinearity_named('mercury')[0]
row.b_over_a, row.temperature_c # (7.8, 30)

• PUBLISHED_NONLINEARITY, nonlinearity_named
PUBLISHED_NONLINEARITYmappingA hundred and sixty-four published values of B/A, keyed '<table>/<row>'.
• Rossing (2014) Tables 8.1 to 8.4: pure water from 0 to 100 °C, water up to 50 MPa, organic liquids, liquid metals and liquefied gases
• one row per measurement, so a substance measured by several papers is several rows that do not agree: at 30 °C water is 5.18 to 5.38
• not a model: nothing interpolates between temperatures or papers
fluids.PUBLISHED_NONLINEARITY['rossing-2014-table-8-2/water_30c_50mpa'].b_over_a # 5.82

• NonlinearityParameter, nonlinearity_named
nonlinearity_namedfunctionEvery published B/A whose substance name contains the text.
• name: matched without case against the name the page prints; 'water' answers with Tables 8.1 and 8.2 and the sea water of Table 8.4
• empty when nothing matches, which is not an error
len(fluids.nonlinearity_named('water')) # 81

• PUBLISHED_NONLINEARITY
characteristic_impedancefunctionCharacteristic impedance rho c [Pa·s/m].
• density ρ [kg/m³]
• speed_of_sound c [m/s]
The medium's own quantity, so it moved here from the impedance tube that used to publish it; Fluid exposes the same thing as a property
fluids.characteristic_impedance(1.186, 343.2) # 407.04
sea_waterfunctionSea water at one point of the ocean.
• temperature_c T [°C], required
• salinity_psu S (Default: 35)
• depth_m (Default: 0)
• latitude_deg (Default: 45)
• sound_speed_model: unesco (default), del_grosso, mackenzie, medwin
fluids.sea_water(temperature_c=10.0)

• Fluid; rho = 1027.04 kg/m³, c = 1489.83 m/s. No heat-capacity ratio: no source here prints one
sea_water_densityfunctionDensity of sea water (Ainslie 2010 Eq. 4.6, after Pierce 1989).
• temperature_c T [°C]
• salinity_psu S
• absolute_pressure_pa P_w [Pa], absolute
fluids.sea_water_density(temperature_c=10.0, salinity_psu=35.0, absolute_pressure_pa=101989.16) # 1027.04

• ρ [kg/m³]
sea_water_sound_speedfunctionSpeed of sound in sea water, m/s.
• temperature_c [°C] / salinity [ppt] / depth [m]
• model: "unesco" (default) / "del_grosso" / "mackenzie" / "medwin"
• latitude (Default: 45)
fluids.sea_water_sound_speed(25, 35, 1000)
depth_to_absolute_pressure_pafunctionAbsolute static pressure at a depth (Ainslie 2010 Eq. 4.11).
• depth_m z [m]
• latitude_deg (Default: 45)
Not zero at the surface: Eq. (4.11) puts 98 066,5 x 1,04 = 101 989,16 Pa there, which is Ainslie's own reference and 664 Pa above the 101 325 Pa standard atmosphere
fluids.depth_to_absolute_pressure_pa(depth_m=0.0) # 101989.16
depth_to_gauge_pressure_mpafunctionGauge pressure at a depth (Leroy & Parthiot 1998).
• depth_m Z [m]
• latitude_deg (Default: 45)
Zero at the surface; what the UNESCO and Del Grosso sound speeds want
fluids.depth_to_gauge_pressure_mpa(depth_m=1000.0) # 10.106
FluidWarningwarning classState outside the domain its model states for itself.
Annex F states 15 °C to 27 °C, 60 kPa to 110 kPa, 10 % to 90 % RH; outside it the result is an extrapolation, not a refusal
warnings.simplefilter("error", fluids.FluidWarning)
Emitted by fluids.air
FluidAssumptionWarningwarning classA condition the caller did not supply was assumed.
Names the assumed values and what they are worth; passing every condition silences it
warnings.simplefilter("error", fluids.FluidAssumptionWarning)
Emitted by fluids.air
FluidPropertyUnavailableexceptionA quantity the model does not determine.
Raised instead of returning a number no source printed; names the model and what it does fix
f.density # on a model that fixes only a speed of sound
plate_longitudinal_speed / youngs_modulus_from_plate_speedfunction / functionQuasi-longitudinal wave speed along a plate, and back (Hopkins Eq. 2.21).
• youngs_modulus_pa E [Pa] or longitudinal_speed_m_s cL [m/s]
• density_kg_m3 ρ, poisson_ratio ν between -1 and 1
• cL = sqrt(E / (ρ (1 - ν²))): the value the building-acoustics tables print
solids.plate_longitudinal_speed(2.0e11, density_kg_m3=7800.0, poisson_ratio=0.28) # 5274.6
beam_longitudinal_speed / youngs_modulus_from_beam_speedfunction / functionQuasi-longitudinal wave speed along a beam, and back (Hopkins Eq. 2.20).
• youngs_modulus_pa E [Pa] or longitudinal_speed_m_s cL [m/s]
• density_kg_m3 ρ
• cL = sqrt(E / ρ): a beam is unconstrained on its sides, so ν does not appear
solids.beam_longitudinal_speed(2.0e11, density_kg_m3=7800.0) # 5063.7
bulk_longitudinal_speed / youngs_modulus_from_bulk_speedfunction / functionPure longitudinal wave speed in an unbounded solid, and back (Norton & Karczub Eq. 1.225).
• youngs_modulus_pa E [Pa] or longitudinal_speed_m_s cL' [m/s]
• density_kg_m3 ρ, poisson_ratio ν between -1 and 0.5
• cL' = sqrt(E (1 - ν) / (ρ (1 + ν)(1 - 2ν))): the speed an elastic solver integrates, not the one a plate table prints
solids.bulk_longitudinal_speed(2.0e11, density_kg_m3=7800.0, poisson_ratio=0.28) # 5724.8
thickness_critical_frequency_product / DEFAULT_SPEED_OF_SOUND_M_Sfunction / floatThe h f_c column of a materials table, from the plate wave speed.
• plate_speed_m_s cL,p [m/s]
• speed_of_sound c0 [m/s] (Default: 343)
• h f_c = c0² sqrt(12) / (2 π cL,p), the exact constant: the rounded 1.8 of ISO 12354-1 misses Hopkins Table A2 by 0.8 %
solids.thickness_critical_frequency_product(5270.0) # 12.31 m Hz, Table A2 prints 12.3
SolidMaterialdataclassOne row of a published materials table, with what the cell said.
• Every quantity optional, because no two books print the same columns; .why_missing(field) says what the page had instead
• Three speeds are three fields: bar_longitudinal_speed_m_s, plate_longitudinal_speed_m_s and bulk_longitudinal_speed_m_s, and longitudinal_speed_m_s holds the one a page prints without saying which, because at ν = 0,3 the plate speed is 4,8 % above the bar speed and the bulk speed 16 % above it
• Four loss factors: flexural_loss_factor, longitudinal_loss_factor, in_situ_loss_factor, and loss_factor for a page that prints one and does not say which
• basis, approximate, ranges, bounded_above, unquantified: what the cell was, when it was not a value; basis[field] is 'estimated' for a cell the page marks as an estimate
• derived: field → how this library computed it; borrowed: field → the material a book took it from
• attributed_to: per-cell credit; variant: which specimen, when a page prints several under one name
• .basis_of(field), .is_approximate(field), .is_derived(field), .printed(field) to narrow or be refused
steel = solids.PUBLISHED_SOLIDS['hopkins-2007-table-a2/steel']
steel.youngs_modulus_pa # 1.996e11, derived

• steel.attributed_to['flexural_loss_factor'] # 'Heckl, 1981'
PUBLISHED_SOLIDSmappingTwo hundred and nineteen published solids from six books, keyed '<table>/<row>'.
• Hopkins Table A2, twenty-five building materials (PDF pages 635-636)
• Cremer 3e Table 4.3, thirteen metals over fifteen rows (PDF page 201), the one table that prints E, G, ν and both speeds together
• Mechel Table 3, thirty-eight construction materials, plastics and metals (PDF pages 544-545), with no Poisson ratio, so its rows stop at the bar speed
• Bies 5e Table C.1, one hundred and five metals, building materials, woods, plastics and honeycomb panels (PDF pages 747-750), whose loss factor column is two quantities and not a range
• Long 2e Table 12.1, eighteen building materials credited to Beranek and Ver (PDF page 487), and Arau-Puchades Table 4.1, seventeen over eighteen rows (PDF page 129), neither of which says which longitudinal wave it prints
• The key names the table because four of them print a steel and they are not the same steel
• Only four of Hopkins' twenty-five Poisson ratios are measurements; the rest carry the book's 'Estimate' footnote and say so
• Not a specification: block densities vary by manufacturer, which is why the pages print ranges
solids.PUBLISHED_SOLIDS['cremer-2005-table-4-3/gold']

• SolidMaterial, solids_named
solids_namedfunctionEvery published row for a material, across the books.
• Matches SolidMaterial.name without regard to case; empty when no page names it
• Comparing two books has to be a deliberate act: a lookup returning one steel would be choosing between published values for you
solids.solids_named('Steel') # two rows, two tables

• PUBLISHED_SOLIDS
DampingMaterialdataclassOne commercial damping material, with the temperature and the frequency its loss factor peaks at.
• max_loss_factor is the greatest loss factor the material reaches, not the loss factor at any temperature you happen to have
• peak_temperature_at_10_hz_c, peak_temperature_at_100_hz_c, peak_temperature_at_1000_hz_c: where that peak sits at each frequency the table prints, because the band moves up in temperature as the material is worked faster
• youngs_modulus_max_pa at the stiff end, youngs_modulus_min_pa at the soft end, youngs_modulus_transition_pa in the band where the loss factor peaks, which is the one that belongs beside it
• loss_modulus_max_pa is the imaginary part, about max_loss_factor * youngs_modulus_transition_pa
• .peak_temperature_c(frequency_hz) refuses a frequency the table does not print rather than reading the nearest column
• converted: the page is in degrees Fahrenheit and psi, so every converted cell keeps the figure and the unit the page prints, ('3e5', 'psi')
ear = solids.damping_named('EAR C-1002')[0]
ear.peak_temperature_c(100) # where its peak sits at 100 Hz

• PUBLISHED_DAMPING, damping_named
PUBLISHED_DAMPINGmappingSeventeen commercial damping materials, keyed '<table>/<row>'.
• Vér & Beranek 2e TABLE 14.1 (PDF page 599), the only table in this library where a loss factor carries the temperature and the frequency that decide it
• Every other loss factor here is a single number with neither, which is a property of a material only in the sense that a photograph is a property of a room
• Not measurements: the page's own footnote says the values were read off published curves, and the text says to get damping data from the supplier
• Three cells are corrupted in the printing, are registered in docs/ERRATA.md and are refused rather than guessed
solids.PUBLISHED_DAMPING['ver-beranek-2006-table-14-1/ear_c_1002']

• DampingMaterial, damping_named
damping_namedfunctionEvery published damping material whose name contains the text.
• Matches DampingMaterial.name without regard to case; empty when no page names it
• A tuple and not one row, because a name can be printed by more than one table
solids.damping_named('3M') # five rows

• PUBLISHED_DAMPING
DampingTreatmentdataclassOne damping treatment, rated by the decay rate of the chapter's standard steel panel.
• decay_rate_db_s$ [\text{dB}/\text{s}] \text{at} 160 \text{Hz} \text{on} \text{a} 50 \times 50 \times 0{,}6 \text{cm} \text{plate}, $temperature_c [°C], adhered_area_percent [%], surface_density_kg_m2 [kg/m²]
• a decay rate is the treatment on that plate, not a property of the material; at 160 Hz the plate's loss factor is the rate over 4 368, and it is not computed here
• two rows print "No" for the bonded area, which why_missing hands back
row = solids.damping_treatments_named('metal')[0]
row.decay_rate_db_s # 400

• PUBLISHED_DAMPING_TREATMENTS, damping_treatments_named
PUBLISHED_DAMPING_TREATMENTSmappingEight asphalt felt damping treatments, keyed '<table>/<row>'.
• Harris (1977) Table 14.2 (PDF page 496): one to four plies, plain, punched or notched, bonded or loose, under carpet or a metal sheet
• most decay rates printed as a range, from 1 dB/s to 400
len(solids.PUBLISHED_DAMPING_TREATMENTS) # 8

• DampingTreatment, damping_treatments_named
damping_treatments_namedfunctionEvery published damping treatment whose description contains the text.
• name: matched without case against the Spanish description the page prints
• empty when nothing matches
len(solids.damping_treatments_named('muescado')) # 3

• PUBLISHED_DAMPING_TREATMENTS
SolidNonlinearitydataclassOne solid's ultrasonic nonlinearity parameter, as a page printed it.
• nonlinearity_parameter: the page's β_avg = −(3 + K3/K2), averaged over the [100], [110] and [111] directions; dimensionless
• comparable with a liquid's B/A + 2, not with its B/A
• bonding: covalent, ionic, metallic, van der Waals or isotropic, in the page's words
solids.solid_nonlinearity_named('NaCl')[0].nonlinearity_parameter # 14.6

• PUBLISHED_SOLID_NONLINEARITY, solid_nonlinearity_named
PUBLISHED_SOLID_NONLINEARITYmappingEight solids' nonlinearity parameters, keyed '<table>/<row>'.
• Rossing (2014) Table 6.5 (PDF page 261)
• five rows are crystal structures or bonding classes, three name a material; fused silica is the one negative value
len(solids.PUBLISHED_SOLID_NONLINEARITY) # 8

• SolidNonlinearity, solid_nonlinearity_named
solid_nonlinearity_namedfunctionEvery published solid whose printed name contains the text.
• name: matched without case; 'FCC' answers with both face-centred cubic rows
• empty when nothing matches
len(solids.solid_nonlinearity_named('FCC')) # 2

• PUBLISHED_SOLID_NONLINEARITY
OrthotropicWooddataclassOne wood's orthotropic plate constants, as a page printed them.
• By Rossing's Eq. (15.86): plate_stiffness_d1_pa = Ex/12μ along the grain, plate_stiffness_d3_pa = Ey/12μ across it, plate_stiffness_d2_pa = νxy·Ey/6μ the Poisson coupling and plate_stiffness_d4_pa = Gxy/3 the twisting stiffness, in pascals
• Not moduli: D1 is the along-grain modulus over 12μ, so none of them compares with SolidMaterial.youngs_modulus_pa, and the plate thickness enters separately
• relative_scaling_factor is the fourth root of D1 over D3, as the page prints it: the stretch across the grain of the equivalent isotropic plate
• .basis_of(field) answers 'estimated' for the cells the caption calls intelligent guesses rather than measurements
maple = solids.orthotropic_wood_named('maple')[0]
maple.basis_of('plate_stiffness_d2_pa') # 'estimated'

• PUBLISHED_ORTHOTROPIC_WOOD, orthotropic_wood_named
PUBLISHED_ORTHOTROPIC_WOODmappingTwo orthotropic woods, keyed '<table>/<row>'.
• Rossing (2014) Table 15.5 (PDF page 632), after Woodhouse, whom every row credits
• The only wood here that is not isotropic: spruce is thirteen times stiffer along the grain than across it (D1 over D3)
• Maple's printed scaling factor does not follow from its own row, and the defect is registered in docs/ERRATA.md
solids.PUBLISHED_ORTHOTROPIC_WOOD['rossing-2014-table-15-5/spruce']

• OrthotropicWood, orthotropic_wood_named
orthotropic_wood_namedfunctionEvery published orthotropic wood whose name contains the text.
• Matches OrthotropicWood.name without regard to case; empty when no page names it
solids.orthotropic_wood_named('spruce')

• PUBLISHED_ORTHOTROPIC_WOOD
PlateauMaterialdataclassOne material's plateau-method constants, as a page printed them.
• surface_density_per_mm_kg_m2 is the density divided by a thousand, kept in the unit the method uses it in
• coincidence_height_db is the height of the plateau: the transmission loss the method draws as a horizontal line over the coincidence region
• plateau_frequency_ratio is the width of the plateau, the page's B/A
al = solids.plateau_material_named('alumin')[0]
al.surface_density_per_mm_kg_m2 * 3 # kg/m2 of a 3 mm sheet

• PUBLISHED_PLATEAU_DATA, plateau_material_named
PUBLISHED_PLATEAU_DATAmappingEight materials' plateau-method constants, keyed '<table>/<row>'.
• Norton & Karczub 2e Table 3.1 (PDF page 261)
• What the plateau method needs to sketch a single panel's transmission loss without solving the plate model, and what building.PLATEAU_MATERIALS and building.plateau_transmission_loss read
solids.PUBLISHED_PLATEAU_DATA['norton-karczub-2003-table-3-1/steel']

• PlateauMaterial, plateau_material_named
plateau_material_namedfunctionEvery published plateau-method material whose name contains the text.
• Matches PlateauMaterial.name without regard to case; empty when no page names it
solids.plateau_material_named('glass')

• PUBLISHED_PLATEAU_DATA
ideal_gas / MOLAR_GAS_CONSTANT / IDEAL_GAS_VALIDITYfunction / float / strA gas from the two numbers a gas table prints.
• temperature_c t [°C], required
• heat_capacity_ratio γ (> 1: it is c_p/c_v and c_p − c_v is the gas constant), molar_mass_kg_mol M [kg/mol], required
• static_pressure_pa p [Pa] (Default: None → 101 325, warns)
• c = sqrt(γRT/M) and ρ = pM/(RT), so a gas that is not air or water is computed rather than typed
• the density is light by 1 − Z, the compressibility factor's distance from unity: 0,7 % for CO₂ and 2 % for SF₆
• no viscosity, no thermal conductivity and no Prandtl number: nothing in the closure determines them
fluids.ideal_gas(temperature_c=20.0, heat_capacity_ratio=1.67, molar_mass_kg_mol=0.040, static_pressure_pa=101300.0)

• Fluid; c = 319.0 m/s, rho = 1.663 kg/m³, which is Hopkins Table A1 for argon
DEFAULT_STATIC_PRESSURE_PAfloatOne standard atmosphere [Pa].
101325.0
DEFAULT_STATIC_PRESSURE_PA # 101325.0
DEFAULT_RELATIVE_HUMIDITY_PERCENTfloatHumidity assumed when none is supplied [%].
50.0. There is no standard humidity: Annex F's own examples use 50 % and 65 %
DEFAULT_RELATIVE_HUMIDITY_PERCENT # 50.0
DEFAULT_CO2_MOLE_FRACTIONfloatCO₂ mole fraction assumed when none is supplied.
0.0004, the value Clause F.2 recommends for laboratory conditions
DEFAULT_CO2_MOLE_FRACTION # 0.0004
ISO1683_REFERENCE_VALUESmappingThe ISO 1683:2015 reference values every level is counted from, keyed [medium][quantity].
• 'gas', Table 1: sound_pressure 20 µPa, sound_exposure (20 µPa)² s, sound_power 1 pW, sound_energy 1 pJ, sound_intensity 1 pW/m²
• 'liquid', Table 2: the same five re 1 µPa and 1 µPa² s, particle_displacement 1 pm, particle_velocity 1 nm/s, particle_acceleration 1 µm/s² and distance 1 m
• 'solid', Table 3: displacement 1 pm, velocity 1 nm/s, acceleration 1 µm/s², force 1 µN, and velocity_alternative 50 nm/s from note b
• every value in SI; the private references of the package read it, and scripts/check_reference_values.py keeps them doing so
metrology.ISO1683_REFERENCE_VALUES['gas']['sound_pressure'].value # 2e-05
ReferenceValuedataclassOne row of the ISO 1683 table.
• quantity, medium ('gas' / 'liquid' / 'solid'), value [in unit], unit (SI), printed (as the page prints it, prefix and all), table ('Table 1' to 'Table 3', or 'Table 3, note b')
row = metrology.ISO1683_REFERENCE_VALUES['solid']['force']

• row.value, row.unit # (1e-06, 'N')
verify_conformancefunctionThe conformance rule of IEC TC 29 (IEC 60942:2017 5.1.15, IEC 61672-1:2013 5.1.21).
• deviation: measured deviation from the design goal, signed
• uncertainty: actual expanded uncertainty, 95 % coverage
• acceptance_limits: one number for ±, or (lower, upper), one end of which may be open ((70.0, math.inf) for a stop-band minimum)
• max_uncertainty: maximum-permitted expanded uncertainty
• unit: label for the figure (Default: 'dB')
Conforms when the deviation is within the limits AND the uncertainty within the maximum, both inclusive; the uncertainty is not added to the deviation
v = metrology.verify_conformance(-1.2, uncertainty=0.3, acceptance_limits=(-1.2, 1.0), max_uncertainty=0.5)

• v.passes # True (IEC 61672-1 Table C.1, example 7)
ConformanceVerificationdataclassOne deviation judged by the TC 29 rule.
• deviation, uncertainty, lower_limit, upper_limit, max_uncertainty, unit
• passes, deviation_within_limits, uncertainty_within_maximum
• outcome 1 to 4 (E.2.2 / C.2.2) and reason, worded as Tables E.1 and C.1 print it
• share_of_acceptance_limit, share_of_max_uncertainty
• no truth value: bool(v) raises; .plot() draws it as Figure E.1
v.outcome, v.reason
verify_sound_calibratorfunctionA sound calibrator against IEC 60942:2017.
• calibrator_class: 'LS', 'LS/M', '1', '1/M' or '2' (Table 1)
• measurements: a SoundCalibratorMeasurements
• nominal_frequency_hz: selects the rows of Tables 2, 5, 7, A.1, A.3 and A.4; refused where the class has no limit (5.1.2)
• environmental_test: 'full' (Tables 5 and 6) or 'abbreviated' (A.6.4.7) (Default: 'full')
Every requirement given is judged by verify_conformance
res = metrology.verify_sound_calibrator('1', record, nominal_frequency_hz=1000.0)

• SoundCalibratorVerification
SoundCalibratorMeasurementsdataclassWhat a laboratory measured on a calibrator.
• one pair per requirement, deviation and expanded uncertainty: level_deviation_db, fluctuation_db, frequency_deviation_percent, distortion_percent, supply_voltage_deviation_db, environmental_level_deviation_db, environmental_level_in_band_deviation_db, environmental_frequency_deviation_percent, field_immunity_deviation_db, each with its ..._uncertainty_...
• static_pressure_correction_db: the manufacturer's correction for an LS/M or 1/M pistonphone, added to the level
• each field one number or one per condition; .pairs(requirement)
metrology.SoundCalibratorMeasurements(level_deviation_db=0.12, level_uncertainty_db=0.10)
SoundCalibratorRequirementdataclassOne IEC 60942 requirement, judged on each of its measurements.
• name, clause, tables, verifications (one ConformanceVerification each)
• passes, unit, acceptance_limits, max_uncertainty
• no truth value; .plot() draws its measurements as Figure E.1
res.requirement('level').passes
SoundCalibratorVerificationdataclassThe IEC 60942:2017 verdict on one calibrator setting.
• calibrator_class, nominal_frequency_hz, environmental_test, measurements
• requirements in the order of CALIBRATOR_REQUIREMENTS; requirement(name), failed
• passes: every requirement measured passes (False when nothing was measured)
• no truth value; .plot() draws the share of each allowance used
res.passes, res.failed
CalibratorTableRowdataclassOne row of an IEC 60942 table keyed by a range of nominal frequencies.
• lower_hz, upper_hz, includes_lower, includes_upper (as the printed "> 63 to < 160" says)
• class_ls, class_1, class_2, None where the table prints a dash
• .contains(nominal_frequency_hz), .for_class(calibrator_class)
metrology.LEVEL_ACCEPTANCE_LIMITS_DB[2].class_1 # 0.25
CALIBRATOR_CLASSESconstantIEC 60942:2017 Table 1 classes and designations: ('LS', 'LS/M', '1', '1/M', '2')'1/M' in metrology.CALIBRATOR_CLASSES
CALIBRATOR_REQUIREMENTSconstantThe requirements verify_sound_calibrator grades: 'level', 'fluctuation', 'frequency', 'distortion', 'supply_voltage', 'environmental_level', 'environmental_level_in_band', 'environmental_frequency', 'field_immunity'metrology.CALIBRATOR_REQUIREMENTS[0] # 'level'
LEVEL_ACCEPTANCE_LIMITS_DBtupleIEC 60942:2017 Table 2, sound pressure level [dB]: 0.10 / 0.25 / 0.40 (LS / 1 / 2) from 160 Hz to 1.25 kHz; class 1 alone elsewhere, 0.30 to 0.50 dBmetrology.LEVEL_ACCEPTANCE_LIMITS_DB[2].class_2 # 0.4
FLUCTUATION_ACCEPTANCE_LIMITS_DBtupleIEC 60942:2017 Table 2, short-term level fluctuation [dB]: 0.03 / 0.07 / 0.15 from 160 Hz to 1.25 kHz; class 1 0.20 dB to 63 Hz and 0.10 dB below 160 Hzmetrology.FLUCTUATION_ACCEPTANCE_LIMITS_DB[0].class_1 # 0.2
SUPPLY_VOLTAGE_ACCEPTANCE_LIMITS_DBmappingIEC 60942:2017 Table 3, effect of supply voltage [dB]: LS 0.02, 1 0.06, 2 0.16metrology.SUPPLY_VOLTAGE_ACCEPTANCE_LIMITS_DB['1'] # 0.06
FREQUENCY_ACCEPTANCE_LIMITS_PERCENTmappingIEC 60942:2017 Table 4, frequency [% of the specified frequency]: LS 0.7, 1 0.7, 2 1.7metrology.FREQUENCY_ACCEPTANCE_LIMITS_PERCENT['2'] # 1.7
ENVIRONMENTAL_LEVEL_ACCEPTANCE_LIMITS_DBtupleIEC 60942:2017 Table 5, level over the environmental range [dB]: 0.10 / 0.25 / 0.40 from 160 Hz to 1.25 kHz; class 1 0.25 to 0.60 dB elsewheremetrology.ENVIRONMENTAL_LEVEL_ACCEPTANCE_LIMITS_DB[-1].class_1 # 0.6
ENVIRONMENTAL_FREQUENCY_ACCEPTANCE_LIMITS_PERCENTmappingIEC 60942:2017 Table 6, frequency over the environmental range [%]: LS 0.7, 1 0.7, 2 1.7metrology.ENVIRONMENTAL_FREQUENCY_ACCEPTANCE_LIMITS_PERCENT['LS'] # 0.7
DISTORTION_ACCEPTANCE_LIMITS_PERCENTtupleIEC 60942:2017 Table 7, maximum total distortion + noise [%]: 2.0 / 2.5 / 3.0 from 160 Hz to 1.25 kHz; class 1 3.0 elsewheremetrology.DISTORTION_ACCEPTANCE_LIMITS_PERCENT[1].class_ls # 2.0
LEVEL_MAX_UNCERTAINTY_DBtupleIEC 60942:2017 Table A.1, generated level [dB, 95 %]: 0.10 / 0.15 / 0.35 from 160 Hz to 1.25 kHz; class 1 0.20 to 0.50 dB elsewheremetrology.LEVEL_MAX_UNCERTAINTY_DB[2].class_1 # 0.15
FLUCTUATION_MAX_UNCERTAINTY_DBtupleIEC 60942:2017 Table A.1, short-term fluctuation [dB, 95 %]: 0.02 / 0.03 / 0.05 from 160 Hz to 1.25 kHzmetrology.FLUCTUATION_MAX_UNCERTAINTY_DB[2].class_ls # 0.02
FREQUENCY_MAX_UNCERTAINTY_PERCENTmappingIEC 60942:2017 Table A.2, frequency [%, 95 %]: 0.2 for every classmetrology.FREQUENCY_MAX_UNCERTAINTY_PERCENT['1'] # 0.2
DISTORTION_MAX_UNCERTAINTY_PERCENTtupleIEC 60942:2017 Table A.3, total distortion + noise [%, 95 %]: 0.5 / 0.5 / 1.0 from 160 Hz to 1.25 kHz; class 1 1.0 elsewheremetrology.DISTORTION_MAX_UNCERTAINTY_PERCENT[1].class_2 # 1.0
ENVIRONMENTAL_LEVEL_MAX_UNCERTAINTY_DBtupleIEC 60942:2017 Table A.4, level over the environmental range [dB, 95 %]: 0.10 / 0.15 / 0.20 from 160 Hz to 1.25 kHz; manufacturer's corrections included, Table A.1 excludedmetrology.ENVIRONMENTAL_LEVEL_MAX_UNCERTAINTY_DB[1].class_2 # 0.2
ENVIRONMENTAL_FREQUENCY_MAX_UNCERTAINTY_PERCENTmappingIEC 60942:2017 Table A.5, frequency over the environmental range [%, 95 %]: 0.2 for every classmetrology.ENVIRONMENTAL_FREQUENCY_MAX_UNCERTAINTY_PERCENT['2'] # 0.2
SUPPLY_VOLTAGE_MAX_UNCERTAINTY_DBmappingIEC 60942:2017 A.5.5.7 and A.5.5.8, supply-voltage difference [dB, 95 %]: LS 0.02, 1 and 2 0.04metrology.SUPPLY_VOLTAGE_MAX_UNCERTAINTY_DB['2'] # 0.04
FIELD_IMMUNITY_ACCEPTANCE_LIMITS_DBmappingIEC 60942:2017 5.9.4.2, level change in a power- or radio-frequency field [dB]: LS 0.10, 1 0.25, 2 0.45metrology.FIELD_IMMUNITY_ACCEPTANCE_LIMITS_DB['1'] # 0.25
FIELD_IMMUNITY_MAX_UNCERTAINTY_DBmappingIEC 60942:2017 A.7.4.8, that level change [dB, 95 %]: 0.05 for every class, the field measurement excludedmetrology.FIELD_IMMUNITY_MAX_UNCERTAINTY_DB['LS'] # 0.05
ABBREVIATED_LEVEL_REDUCTIONS_DBmappingIEC 60942:2017 A.6.4.7, reduction of the Table 5 limits in the abbreviated test [dB]: LS 0.05, 1 0.05, 2 0.10metrology.ABBREVIATED_LEVEL_REDUCTIONS_DB['2'] # 0.1
ABBREVIATED_FREQUENCY_ACCEPTANCE_LIMITS_PERCENTmappingIEC 60942:2017 A.6.4.7, frequency limits of the abbreviated test [%]: LS 0.5, 1 0.5, 2 1.3metrology.ABBREVIATED_FREQUENCY_ACCEPTANCE_LIMITS_PERCENT['2'] # 1.3
adjustment_factorsfunctionAdjustment factors K(φ) of one plane of readings (IEC 61183:1994 Formulas (6), (7), (A.1), (A.2)).
• step_deg: the angular step Δφ [°], dividing 180° into at least two steps
• planes: the number of planes n, Δα = 180°/n (Default: 2, the X-Y and X-Z planes of Annex A; 4 halves every factor, NOTE 2 of A.6; 1 doubles it, Formula (A.4))
• the 360/Δφ factors from 0°, read-only; with the poles in every plane's sum they add up to 1
• warns SphereDivisionWarning above the 3 % of A.1.6
metrology.adjustment_factors(10.0)[[0, 1, 9]].round(5)

• [0.00095 0.00378 0.02179], Table A.1
largest_element_fractionfunctionThe largest element a set of incidence angles divides the sphere into (IEC 61183 A.1.6, A.1.7).
• step_deg [°], planes (Default: 2)
• the ring element nearest 90° or the polar cap, whichever is larger; one plane is judged on the two-plane division it stands for
metrology.largest_element_fraction(10.0) # 0.02179, the 2,2 % of A.1.7
SphereDivisionWarningwarning classThe angular step leaves an element larger than 3 % of the sphere.
Emitted by adjustment_factors, directivity_factor and axisymmetric_directivity_factor (IEC 61183 A.1.6)
warnings.simplefilter('error', metrology.SphereDivisionWarning)
directivity_factorfunctionDirectivity factor from readings in two or more planes (IEC 61183 Formula (A.3)).
• levels_db: L(φ) [dB], one row per plane, each at φ = 0, Δφ, …, 360° − Δφ: (2, 36) for Annex A
• reference_level_db: L_rd [dB] (Default: None → the first plane's reading at 0°)
• the readings at 0° and 180° enter every plane's sum, so an omnidirectional meter reads γ = 1; counted once, 10 lg γ would come out 0,008 dB high for that meter and more for a directional one
d = metrology.directivity_factor(levels)

• DirectivityFactor; d.directivity_index_db
axisymmetric_directivity_factorfunctionDirectivity factor of a rotationally symmetric meter from one plane (IEC 61183 Formula (A.4)).
• levels_db: L(φ, h) [dB], 1-D, at φ = 0, Δφ, …
• reference_level_db [dB] (Default: None → the reading at 0°)
metrology.axisymmetric_directivity_factor(levels[0])

• DirectivityFactor
equal_area_directivity_factorfunctionDirectivity factor from 38 equal-area elements (IEC 61183 Formula (A.5)).
• horizontal_levels_db: 20 readings [dB] at the directions of equal_area_incidence_angles
• vertical_levels_db: 18 readings [dB], the same without the poles
• reference_level_db [dB] (Default: None → the horizontal reading at 0°)
metrology.equal_area_directivity_factor(h_db, v_db)

• DirectivityFactor, every weight 1/38
equal_area_incidence_anglesfunctionThe 38 directions of the equal-area division (IEC 61183, note to A.1.8).
• each direction halves its element's area in polar angle: φk = arccos[1 − (4k − 1)/19]
• returns (horizontal, vertical) [°], 20 and 18, read-only
• the note prints 77,9° and 282,1° where this gives 77,85° and 282,15° (errata)
h, v = metrology.equal_area_incidence_angles()
h[4].round(1) # 77.8
DirectivityFactordataclassThe directivity factor of a meter at one frequency.
• incidence_angles_deg, plane_angles_deg [°], levels_db [dB], weights: one entry per reading, read-only
• reference_level_db [dB], gamma, largest_element_fraction, formula ('A.3' / 'A.4' / 'A.5'), each checked when built
• .directivity_index_db = 10 lg γ [dB], .relative_levels_db [dB]
• .plot(view=): 'response' (polar, one curve per plane) / 'weights'
d.gamma, d.directivity_index_db
random_incidence_sensitivityfunctionRandom-incidence sensitivity level, band by band (IEC 61183 Formulas (1), (A.6)).
• frequencies_hz [Hz], increasing
• free_field_level_db: G_F = L_rd − L_o [dB]
• directivity_index_db: 10 lg γ [dB]; either may be one value for every band
• G_RI = G_F − 10 lg γ
r = metrology.random_incidence_sensitivity([1000, 8000], 0.0, [0.05, 2.45])

• RandomIncidenceSensitivity
RandomIncidenceSensitivitydataclassG_F, 10 lg γ and G_RI at each frequency.
• frequencies_hz [Hz], free_field_level_db, directivity_index_db, random_incidence_level_db [dB], read-only
• .correction_db = G_RI − G_F [dB]
• .plot(view=): 'levels' / 'correction'
r.correction_db # [-0.05 -2.45]
diffuse_field_sensitivityfunctionDiffuse-field sensitivity level by comparison with a reference meter (IEC 61183 Formulas (8) to (11)).
• frequencies_hz [Hz]; indicated_level_db L_D and reference_indicated_level_db L_D,ref [dB]
• exactly one of reference_random_incidence_level_db (9), reference_free_field_level_db (10) or reference_pressure_level_db (11) [dB]
• reference_directivity_index_db with (10), reference_diffuse_pressure_difference_db with (11) [dB] (Default: None → IEC61183_TABLE_B1 at each preferred frequency)
metrology.diffuse_field_sensitivity(f, l_d, l_ref, reference_pressure_level_db=0.0)

• DiffuseFieldSensitivity
DiffuseFieldSensitivitydataclassThe comparison of IEC 61183 clause 5, route by route.
• frequencies_hz [Hz], indicated_level_db, reference_indicated_level_db, reference_sensitivity_level_db, reference_correction_db [dB], route ('random_incidence' / 'free_field' / 'pressure')
• .level_difference_db ΔG_D, .reference_diffuse_field_level_db G_D,ref, .diffuse_field_level_db G_D [dB]
• .plot(): the three against frequency
dd.diffuse_field_level_db
IEC61183_TABLE_B1mappingIEC 61183:1994 Table B.1, the type LS2aP/LS2F microphone, keyed by preferred frequency [Hz].
• 25 Hz to 20 kHz; the row printed "25 to 800" at each preferred frequency it covers
• each value a ReferenceMicrophoneRow; rounded to 0,05 dB by the table
metrology.IEC61183_TABLE_B1[8000.0].directivity_index_db # 2.45
ReferenceMicrophoneRowdataclassOne row of Table B.1.
• directivity_index_db: 10 lg γ_ref [dB]
• diffuse_pressure_difference_db: Δ_DP, diffuse-field less pressure sensitivity level [dB]
metrology.IEC61183_TABLE_B1[16000.0].diffuse_pressure_difference_db # 3.05
exact_frequenciesfunctionExact base-ten frequencies between two limits (IEC 62585 Annex H, Formula (H.1)).
• lowest_hz, highest_hz [Hz], inclusive
• fraction: the step-width designator b (Default: 12, the one-twelfth octaves of Table H.1; 1 the exact octaves, 3 the thirds)
• f_x = 1000 · 10^(3x/10b) [Hz], read-only
metrology.exact_frequencies(1000, 10000)[31] / 1000 # 5.956621
adjustment_valuefunctionThe adjustment value at the calibration check frequency (IEC 62585 Annex A).
• frequencies_hz [Hz], the check frequency among them; free_field_indicated_level_db [dB] before the adjustment; calibrator_reading_db: L4′ on the calibrator at the same sensitivity [dB]
• keyword-only: calibrator_level_db L1 [dB]; incident_level_db [dB] (Default: None → L1); tolerance_db [dB], infinite where a band does not pull the fit (Default: None → equal weights); pressure_indicated_level_db [dB] (Default: None); check_frequency_hz (Default: 1000)
• least-squares fit s = −Σ w d / Σ w, w = 1/t² (the module's reading of a text with no formula); ΔL = L1 − (L4′ + s)
a = metrology.adjustment_value(f, l_ff, 94.35, calibrator_level_db=94.0)

• AdjustmentValue; a.adjustment_db
AdjustmentValuedataclassThe free-field response before the adjustment and what the fit makes of it.
• frequencies_hz [Hz], free_field_deviation_db [dB], calibrator_level_db, calibrator_reading_db [dB], check_frequency_hz [Hz], tolerance_db, pressure_deviation_db [dB] or None, read-only
• derived, never stored: .weights, .sensitivity_adjustment_db s, .calibrator_indicated_level_db L4, .adjustment_db ΔL, .check_frequency_offset_db L2 − L1, .free_field_indicated_level_db L2, .pressure_indicated_level_db L3, .pressure_to_free_field_correction_db [dB]
• .plot(): the deviation before and after, with the tolerances
a.sensitivity_adjustment_db, a.check_frequency_offset_db
sound_calibrator_correctionfunctionFree-field corrections for a multi-frequency sound calibrator (IEC 62585 Annex D, Formula (D.7)).
• frequencies_hz [Hz]; slm_free_field_level_db, reference_free_field_level_db, slm_calibrator_level_db, reference_calibrator_level_db [dB]: L_ind1 to L_ind4, one value per frequency or one row per determination
• keyword-only: reference_free_field_correction_db C_FF,RM from IEC/TS 61094-7 [dB]; free_field_level_difference_db, calibrator_level_difference_db [dB] (Default: 0); microphones: the microphone of each row, so the range is taken over the microphones (Default: None, each row its own)
c = metrology.sound_calibrator_correction(f, l1, l2, l3, l4, reference_free_field_correction_db=c_rm)

• FreeFieldCorrection, clause 12
comparison_coupler_correctionfunctionFree-field corrections for a comparison coupler (IEC 62585 Annex E, Formula (E.6)).
• as sound_calibrator_correction, with slm_coupler_level_db and reference_coupler_level_db [dB], named by what each reading is of (Formula (E.6) exchanges the two labels of Figure E.1, an erratum)
• keyword-only: coupler_level_difference_db: the level at the meter less that at the reference [dB] (Default: 0); microphones (Default: None)
metrology.comparison_coupler_correction(f, l1, l2, l_slm, l_rm, reference_free_field_correction_db=c_rm)

• FreeFieldCorrection, clause 13
electrostatic_actuator_correctionfunctionFree-field corrections normalised at the check frequency, for an electrostatic actuator (IEC 62585 Annex F, Formula (F.13)).
• frequencies_hz [Hz]; slm_free_field_level_db, reference_free_field_level_db, slm_actuator_level_db [dB]
• keyword-only: reference_sensitivity_level_db S_RM [dB re 1 V/Pa]; reference_channel_gain_db G_RC [dB] (Default: 0); actuator_level_db L_EA [dB] (Default: 0); free_field_level_difference_db [dB] (Default: 0); check_frequency_hz f0 (Default: 1000); microphones (Default: None)
• zero at f0
metrology.electrostatic_actuator_correction(f, l1, l2, l3, reference_sensitivity_level_db=s_rm)

• FreeFieldCorrection, clause 14
FreeFieldCorrectiondataclassThe corrections of every determination, their mean and their range.
• frequencies_hz [Hz], corrections_db (determinations × frequencies) [dB], reference_correction_db [dB], source ('sound_calibrator' / 'comparison_coupler' / 'electrostatic_actuator'), check_frequency_hz (actuator only), microphones (one label per row, or None), read-only
• .correction_db mean, .microphone_corrections_db the mean of each microphone, .range_db over the microphones, largest less smallest [dB], .determinations, .microphone_count, .formula ('D.7' / 'E.6' / 'F.13'), .clause (12 / 13 / 14)
• .plot(): the mean, the range band and the reference's part
c.correction_db, c.range_db, c.clause
correction_uncertainty_budgetfunctionThe uncertainty budget of a correction, 15 components of Table I.1 (IEC 62585 Annex I).
• values_db: the value of each component as Table I.2 states it, keyed 'a1' to 'a15' [dB]
• keyword-only: repeatability_dof of a15; frequency_hz [Hz]; correction_db [dB] (Default: 0); static_pressure_kpa [kPa]: below 97 adds the clause 6 component, outside 80 to 105 refused (Default: None); additional_components: further Quantity objects (Default: none); coverage (Default: 0.95)
• on combine_uncertainty, sensitivities ±1, Welch-Satterthwaite dof, Student k
b = metrology.correction_uncertainty_budget(table_i2, repeatability_dof=2, frequency_hz=1000)

• b.coverage_factor # 2.042 (Table I.2 prints 2,11, an erratum)
CorrectionUncertaintyBudgetdataclassOne budget at one frequency.
• frequency_hz [Hz], descriptors, symbols, values_db [dB], divisors, dofs, uncertainty (the UncertaintyResult, refused unless it is the combination of the columns), coverage, read-only
• .standard_uncertainties_db, .combined_uncertainty_db, .expanded_uncertainty_db [dB], .effective_dof, .coverage_factor, .correction_db
• .plot(): one bar per component, Type A apart, with u_c, k and U
b.combined_uncertainty_db, b.effective_dof # 0.0590 29.98
IEC62585_TABLE_I1mappingIEC 62585:2012 Table I.1, the likely components of the uncertainty of a correction, keyed 'a1' to 'a15'.
• each value an UncertaintyComponentRow: the symbol, the description, the distribution and the divisor (√3 rectangular, 2 for C_FF,RM, 1 for the repeatability)
metrology.IEC62585_TABLE_I1["a7"].divisor # 2.0
UncertaintyComponentRowdataclassOne row of Table I.1.
• symbol, description, distribution ('rectangular' / 'normal'), divisor
metrology.IEC62585_TABLE_I1["a15"].symbol # 'Repeatability'
maximum_expanded_uncertaintyfunctionThe maximum permitted expanded uncertainty of a correction (IEC 62585 clauses 9 to 14).
• frequencies_hz [Hz]
• keyword-only: clause, 9 to 14 (10 from 63 Hz only)
• 0,25 dB to 4 kHz and 0,35 dB above (9); 0,25, 0,35 to 8 kHz, 0,45 (10); 0,20, 0,30 (11); 0,25, 0,35 below 10 kHz, 0,50 from 10 kHz (12 to 14) [dB], read-only; a frequency within 2 % of a boundary reads as it
metrology.maximum_expanded_uncertainty([3981.07, 10000.0], clause=12) # [0.25 0.5]
verify_correction_uncertaintyfunctionVerify the expanded uncertainties of a set of corrections against the maxima of their clause (IEC 62585 clauses 5, 9 to 14).
• frequencies_hz [Hz]; expanded_uncertainty_db [dB]
• keyword-only: clause; correction_db [dB] and coverage_factor, for the clause 15 documentation (Default: None); correction_range_db [dB], clauses 12 to 14 only (Default: None)
• a value equal to its maximum passes, and one that reaches it through floating-point arithmetic
v = metrology.verify_correction_uncertainty(f, u, clause=c.clause, correction_range_db=c.range_db)

• CorrectionUncertaintyVerification
CorrectionUncertaintyVerificationdataclassThe verdict of one clause on a set of corrections.
• clause, frequencies_hz [Hz], expanded_uncertainty_db, correction_db, coverage_factor, correction_range_db [dB], read-only
• .maximum_uncertainty_db [dB], derived from the clause
• .passes; bool() raises; .uncertainty_passes, .range_passes, .margin_db, .failing_frequencies_hz, .subject
• .plot(): U and the range against the stepped maximum
• .report(path, *, metadata=None): one-page PDF fiche of clause 15 n) and o)
v.passes
v.report("iec62585.pdf")
combine_uncertaintyfunctionGUM law of propagation of uncertainty (ISO/IEC Guide 98-3 clause 5).
• model: measurement function f(x1…xN)
• quantities: input Quantity objects, in argument order
• 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 = metrology.combine_uncertainty(lambda a, b: a*b, [metrology.Quantity(10.0, 0.1), metrology.Quantity(5.0, 0.2)])

• UncertaintyResult; uc = 2.062
monte_carlofunctionMonte Carlo propagation (Guide 98-3-1, Supplement 1).
• model: vectorised f(x1…xN)
• quantities: input Quantity objects
• trials: M ≥ 2 (Default: 1000000; fixed, no adaptive 7.9)
• coverage: interval probability (Default: 0.95)
• seed: reproducibility (Default: None)
• inputs sampled independently (no 6.4.8 multivariate path)
mc = metrology.monte_carlo(model, quantities, seed=1)

• MonteCarloResult (mean, u, coverage interval)
rectangularfunctionType B quantity, rectangular PDF (GUM 4.3.7).
• value, half_width a, name
rectangular(20.0, 0.5)

• Quantity with u = a/√3 = 0.289
triangularfunctionType B quantity, triangular PDF (GUM 4.3.9).
• value, half_width a, name
triangular(20.0, 0.5)

• Quantity with u = a/√6
u_shapedfunctionType B quantity, U-shaped (arcsine) PDF.
• value, half_width a, name
u_shaped(20.0, 0.5)

• Quantity with u = a/√2
coverage_factorfunctionCoverage factor k from the t-distribution (GUM clause 6, Annex G).
• coverage: coverage probability in (0, 1) (Default: 0.95)
• dof: effective degrees of freedom (Default: inf → the normal quantile)
metrology.coverage_factor() # 1.960
metrology.coverage_factor(0.95, dof=10) # 2.228
expanded_uncertaintyfunctionk and U = k·uc(y) of a GUM result (clause 6).
• result: an UncertaintyResult
• coverage (Default: 0.95)
The same answer as result.expanded(coverage), as a function
k, U = metrology.expanded_uncertainty(u)
QuantitydataclassInput quantity of a measurement model (GUM clause 4).
• value: estimate xi
• uncertainty: u(xi) ≥ 0
• distribution: 'gaussian'/'rectangular'/'triangular'/'u-shaped' (Default: 'gaussian')
• dof: degrees of freedom (Default: inf)
• name: budget label
Quantity(94.0, 0.3, name="calibrator")
UncertaintyResultdataclassGUM propagation result.
• value: y = f(x1…xN)
• combined_uncertainty: uc(y)
• sensitivities: ci = ∂f/∂xi
• contributions: |ci|·u(xi)
• effective_dof: Welch–Satterthwaite
• names
• .plot(): uncertainty budget
u.combined_uncertainty, u.contributions
MonteCarloResultdataclassMonte Carlo result.
• value: sample mean
• standard_uncertainty: sample std
• interval: (low, high) coverage interval (§7.7)
• coverage, trials
mc.value, mc.interval
UncertaintyWarningwarning classGUM propagation advisory.
Emitted when a propagation falls back outside its nominal assumptions
warnings.simplefilter('error', UncertaintyWarning)
trend_testfunctionNonparametric trend test on a sequence (Bendat & Piersol 4.5.2).
• values: ≥ 10 observations or estimates
• 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)
• alpha: two-sided significance (Default: 0.05)
res = metrology.trend_test(values)

• TrendTestResult; B&P Example 4.4: A = 86, accepted in (64, 125]
TrendTestResultdataclassTrend-test verdict.
• statistic: reverse arrangements A or runs r
• bounds: acceptance region (lower, upper], p_value, trend_free
• mean, std: null moments (Eqs. 4.54–4.55)
• values, method, n, alpha, median (runs-classification median)
• .plot(): tested sequence with the verdict
res.statistic, res.bounds, res.trend_free
stationarity_testfunctionStationarity test on segment statistics (Bendat & Piersol 10.3.1.1).
• x, fs
• n_segments (Default: 20, as B&P Example 10.3), statistic: 'mean_square' (Default) / 'rms' / 'mean' / 'variance'
• method, alpha as trend_test
Trailing samples beyond equal segments are discarded
res = metrology.stationarity_test(x, fs)

• StationarityTestResult
StationarityTestResultdataclassStationarity verdict on a record.
• segment_values, segment_times [s], segment_duration [s]
• count, bounds, p_value, stationary, mean, std
• statistic, method, alpha, n_segments, fs
• .plot(): segment sequence with the verdict
res.stationary, res.segment_values
level_crossing_ratefunctionLevel-crossing rates vs the Rice expectation (Bendat & Piersol 5.5.1).
• x, fs (mean removed first; oversample the band)
• levels [signal units] (Default: 13 levels over ±3 RMS)
• nperseg: Welch length for the spectral moments
Gaussian: N0 = 2√(m2/m0), Na = N0·exp(−a²/2σ²)
res = metrology.level_crossing_rate(x, fs)

• LevelCrossingResult
LevelCrossingResultdataclassCrossing rates (both slopes).
• levels, rates [1/s], rice_rates [1/s]
• zero_crossing_rate, zero_crossing_rate_rice, apparent_frequency [Hz] = N0/2
• sigma, duration [s], fs
• .plot(): measured dots vs the Rice curve
res.zero_crossing_rate, res.apparent_frequency
peak_statisticsfunctionPeak rate, irregularity factor and peak heights (Bendat & Piersol 5.5.2–5.5.4).
• x, fs (mean removed; band-limit before: m4 weights G(f) by f⁴)
• nperseg: Welch length for the moments
M = √(m4/m2), r = N0/2M ∈ (0, 1]
res = metrology.peak_statistics(x, fs)

• PeakStatisticsResult
PeakStatisticsResultdataclassPeak (maxima) statistics.
• peak_rate, peak_rate_rice [1/s], zero_crossing_rate_rice, irregularity_factor
• peak_values: sorted standardized heights z = a/σ
• .peak_exceedance(z) / .peak_density(z): Rice mixture (Eqs. 5.217/5.223; Rayleigh at r = 1, Gaussian at r → 0)
• .plot(): empirical exceedance vs the Rice curves
res.irregularity_factor, res.peak_exceedance(4.0)
power_spectral_densityfunctionWelch PSD with statistical error analysis (Bendat & Piersol Ch. 8).
• x, fs
• 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)
• scaling: 'density' [units²/Hz] / 'spectrum' [units²]
• confidence: chi-square CI level (Default: 0.95)
res = signals.power_spectral_density(x, fs)

• SpectralDensityResult (psd, CI, nd, ε)
cross_spectral_densityfunctionWelch cross-spectral density with magnitude/phase errors (Eqs. 9.33/9.52).
• x, y, fs
• window, nperseg, overlap, scaling as above
res = signals.cross_spectral_density(x, y, fs)

• CrossSpectralDensityResult
coherent_output_spectrumfunctionGvv = γ²·Gyy, noise remainder and spectral SNR (Eqs. 9.55–9.56, 9.73).
• x (input), y (output), fs
• window, nperseg, overlap, scaling as above
res = signals.coherent_output_spectrum(x, y, fs)

• CoherentOutputSpectrumResult
fractional_octave_smoothingfunctionConstant-power 1/n-octave smoothing of a spectrum.
• frequencies, values
• fraction: the n of 1/n octave (Default: 3)
• domain: 'power'/'amplitude'/'db' (Default: 'power')
s = signals.fractional_octave_smoothing(f, psd, 3.0)

• smoothed array, same domain; flat spectra unchanged
miso_coherencefunctionMultiple & partial coherence of a MISO system (Bendat & Piersol Ch. 7).
• inputs: q input records, q ≥ 2 (sequence of 1-D arrays or a (q, n) array), output, fs
• order: conditioning order (Default: 0..q−1)
• window, nperseg, overlap, scaling as above
res = signals.miso_coherence([x1, x2], y, fs)

• MISOCoherenceResult
MISOCoherenceResultdataclassMultiple/partial coherence of q correlated inputs and one output.
• ordinary_coherence (q×F), multiple_coherence γ²y:x, partial_coherence (q×F, conditioned per order)
• coherent_output_spectra Gvi (q×F, Σ Gvi + noise_psd = output_psd)
• multiple_coherence_random_error (Eq. 9.98), coherent_output_random_error (Eq. 9.100)
• .dominant_input(): per-band index of the strongest source
• .plot(): coherent output spectra + coherences
res.multiple_coherence, res.dominant_input()
resolution_bias_errorfunctionFirst-order resolution bias at a resonance peak, εb ≈ −(Be/Br)²/3 (Eq. 8.141).
• resolution_bandwidth Be [Hz]
• half_power_bandwidth Br [Hz]
resolution_bias_error(1.0, 4.0) # -1/48
noise_signalfunctionColored Gaussian noise with an exact power-law PSD slope.
• fs, seconds (Default: 1.0)
• color: 'white'/'pink'/'red'/'blue'/'violet' (0/−3.01/−6.02/+3.01/+6.02 dB/oct)
• rms (Default: 1.0)
• seed: bit-reproducible per seed
pink = signals.noise_signal(48000, 10.0, color='pink', seed=7)
tone_burstfunctionIEC 60268-1 tone burst (Clause A2): zero-crossing start, integral full periods.
• fs, frequency, cycles
• amplitude (Default: 1.0)
• repetitions + repetition_rate [bursts/s]: repetitive train (Clause A2.2)
• pre_silence, post_silence [s]
res = signals.tone_burst(48000, 5000, 25, repetition_rate=10, repetitions=4)

• ToneBurstResult
resample_signalfunctionPolyphase resampling with an explicit anti-alias spec (Kaiser FIR designed here).
• x, fs, fs_new (rational ratio, e.g. 160/147)
• stopband_attenuation_db (Default: 120)
• transition_width: fraction of the smaller Nyquist (Default: 0.05)
• max_denominator (Default: 1000)
res = signals.resample_signal(x, 44100, fs_new=48000)

• ResampledSignalResult (signal + designed taps)
fractional_delayfunctionBand-limited delay by a fractional number of samples (phase ramp).
• x, delay [samples] (fractional, negative = advance)
• mode: 'linear' (zero-padded, for transients; Default) / 'circular' (periodic records, machine-exact on bin-centered tones)
y = signals.fractional_delay(x, 0.37)
window_metricsfunctionFigures of merit of any scipy window (Harris 1978).
• window: name or (name, param) tuple
• n: length (Default: 1024), DFT-even sampling as in Welch
m = signals.window_metrics('hann', 2048)

• WindowMetricsResult
multitaper_psdfunctionThomson multitaper PSD from one whole record (Percival & Walden Ch. 7).
• x, fs
• time_half_bandwidth: NW (Default: 4), n_tapers: K (Default: 2·NW−1, capped at 2·NW)
• adaptive: Thomson weights (Default: True)
• scaling, confidence as above
res = signals.multitaper_psd(x, fs)

• MultitaperSpectralDensityResult
ToneBurstResultdataclassTone-burst record.
• signal, envelope (rectangular gate), fs
• burst_seconds, burst_samples, onset_sample
• repetition_rate, period_samples, duty_cycle
• .plot(): waveform + gating envelope
res.signal, res.duty_cycle
ResampledSignalResultdataclassResampled record with its anti-alias design.
• signal, fs, original_fs, up, down
• filter_taps, n_taps, passband_edge_hz, stopband_edge_hz
• stopband_attenuation_db, transition_width
res.signal, res.stopband_attenuation_db
WindowMetricsResultdataclassWindow figures of merit.
• enbw_bins, .enbw_hz(fs), coherent_gain
• scalloping_loss_db, worst_case_processing_loss_db (positive losses)
• highest_sidelobe_db (negative, re main lobe), mainlobe_width_3db_bins
• .plot(): window + spectrum with metrics marked
m.enbw_bins # 1.5 for Hann
SpectralDensityResultdataclassWelch PSD with its statistical quality.
• frequencies, psd, ci_lower/ci_upper, confidence
• random_error = 1/√nd, n_segments, n_averages (effective nd), degrees_of_freedom
• resolution_bandwidth Be [Hz]
• .plot(): PSD in dB with the CI band
res.psd, res.n_averages, res.random_error
MultitaperSpectralDensityResultdataclassMultitaper PSD with per-frequency dof.
• frequencies, psd, ci_lower/ci_upper, confidence
• degrees_of_freedom ν(f), random_error = √(2/ν)
• weights (K×F), eigenvalues λk, time_half_bandwidth, n_tapers, resolution_bandwidth 2W [Hz], adaptive
• .plot(): density with the CI band
res.psd, res.degrees_of_freedom
CrossSpectralDensityResultdataclassWelch CSD with per-bin errors.
• csd (complex), magnitude, phase (unwrapped), coherence
• magnitude_random_error, phase_std [rad]
• .plot(): magnitude, phase ±σ, coherence
res.magnitude, res.phase_std
CoherentOutputSpectrumResultdataclassSISO output decomposition.
• output_psd Gyy, coherent_psd Gvv, noise_psd Gnn
• snr, snr_db, random_error (Eq. 9.73), snr_random_error, coherence_bias
• .plot(): spectra + SNR panel
res.coherent_psd, res.snr_db
spectrogramfunctionCalibrated STFT power spectrogram (B&P 12.6.4.2): the Welch segmentation without the averaging.
• x, fs
• window, nperseg, overlap, scaling as above
Column mean = Welch PSD bin by bin; a tone reads A²/2 ('spectrum') in every column
res = signals.spectrogram(x, fs, nperseg=1024, overlap=0.75)

• SpectrogramResult
zoom_fftfunctionNarrow-band spectrum on a fine grid via chirp-Z (B&P 11.5.4).
• x, fs, f_min, f_max
• n_points (Default: one per record resolution fs/N)
• window (Default: 'hann')
Tone on an analysis frequency reads amplitude A / power A²/2 exactly
res = signals.zoom_fft(x, fs, f_min=980.0, f_max=1016.0)

• ZoomFFTResult
SpectrogramResultdataclassSTFT power over the time-frequency plane.
• times, frequencies, power (freq × time)
• time_resolution T_B [s], resolution_bandwidth Be [Hz], random_error (= 1, unaveraged), n_segments, hop
• .plot(): dB image (raster)
res.power[:, 0], res.time_resolution
ZoomFFTResultdataclassZoom spectrum with amplitude calibration.
• frequencies, spectrum (complex, |·| = tone amplitude), amplitude, power (= A²/2)
• bin_spacing (grid) vs resolution_bandwidth Be (true resolution)
• .plot(): power in dB over the band
res.frequencies[res.amplitude.argmax()]
correlationfunctionAuto/cross-correlation via zero-padded FFT (B&P 11.4.2).
• x, y (Default: None → autocorrelation), fs
• normalization: 'biased' (1/N) / 'unbiased' (1/(N−|r|)) / 'coefficient' (ρ ∈ [−1, 1]) (Default: 'unbiased')
• max_lag [s] (Default: full N−1)
res = signals.correlation(x, y, fs, normalization='coefficient')

• CorrelationResult
correlation_random_errorfunctionε[R̂xy(τ)] = [1+ρ⁻²]^½/√(2BT) (Eqs. 8.109/8.112).
• coefficient ρxy(τ)
• signal_bandwidth B [Hz], duration T [s]
Valid for T ≥ 10·|τ|, BT ≥ 5
correlation_random_error(1/11, 100.0, 5.0) # 0.349 (Example 8.5)
time_delayfunctionTDE: direct correlator, GCC (Knapp & Carter) or phase slope (Eq. 5.101b).
• x, y, fs
• method: 'gcc' (Default) / 'direct' / 'phase'
• weighting: 'none'/'roth'/'scot'/'phat' (Default)/'ml' (Table I)
• window, nperseg, overlap: shared Welch core ('gcc'/'phase')
• max_delay [s], interpolation: 'parabolic' (Default)/'none', upsample (Default: 1)
• signal_bandwidth [Hz]: enables the Eq. 8.129 delay uncertainty
res = signals.time_delay(x, y, fs, weighting='phat', upsample=16)

• TimeDelayResult
impulse_response_delayfunctionSub-sample IR delay [s]: peak location refined by local upsampling + parabola.
• ir, fs
• reference: optional IR the delay is measured against (direct correlator)
• interpolation (Default: 'parabolic'), upsample (Default: 8)
t0 = signals.impulse_response_delay(ir, fs) # ~1e-3-sample accuracy
align_impulse_responsesfunctionAlign an IR onto a reference by its estimated sub-sample delay.
• ir, reference, fs
• interpolation, upsample as above
Exact band-limited fractional shift (zero-padded phase ramp)
res = signals.align_impulse_responses(ir_b, ir_a, fs)

• AlignedImpulseResponseResult
envelopefunctionHilbert envelope, instantaneous phase & frequency (B&P Ch. 13).
• x, fs
• decimation_factor (Default: 1)
• antialias: zero-phase FIR decimation (Default: True; False = plain subsampling, the ECMA-internal convention)
res = signals.envelope(x, fs, decimation_factor=32)

• EnvelopeResult
CorrelationResultdataclassCorrelation estimate.
• lags [s], values, coefficient (always carried), normalization, kind
• .random_error(signal_bandwidth): per-lag ε (Eqs. 8.109/8.112)
• .plot()
res.lags, res.values, res.random_error(2000.0)
TimeDelayResultdataclassTime-delay estimate.
• delay [s], delay_samples (fractional), method, weighting
• lags, correlation (the searched curve), peak_correlation ρ̂xy
• delay_std (Eq. 8.129), delay_interval ±2σ (Eq. 8.130) with signal_bandwidth
• .plot(): correlation with the delay marked
res.delay, res.delay_std
AlignedImpulseResponseResultdataclassAligned IR pair.
• aligned, reference, delay [s], delay_samples
• .plot(): overlay
res.aligned, res.delay_samples
EnvelopeResultdataclassEnvelope analysis.
• times [s], envelope, phase [rad, unwrapped], instantaneous_frequency [Hz]
• fs (output rate), signal, signal_fs, decimation_factor, antialias
• .plot(): signal + envelope, instantaneous frequency
res.envelope, res.instantaneous_frequency
envelope_spectrumfunctionAmplitude spectrum of the envelope: modulations as lines (B&P 13.3).
• x, fs
• kind: 'magnitude' (Default) / 'squared' (square-law detector, Fig. 13.11)
• window (Default: 'hann', coherent-gain corrected), nfft
• remove_dc (Default: True; mean kept in mean_level)
AM tone A0, m: line A0·m at fm ('magnitude')
res = signals.envelope_spectrum(x, fs)

• EnvelopeSpectrumResult
EnvelopeSpectrumResultdataclassEnvelope spectrum.
• frequencies [Hz], amplitude (line heights), mean_level, kind
• times, envelope (detector output), window, remove_dc, fs, nfft
• .plot(): envelope + spectrum
res.amplitude, res.mean_level
time_synchronous_averagefunctionExtract a periodic waveform of known period_s by time domain averaging (McFadden 1987 Eq. 5).
• x, fs, period_s [s] (one revolution)
• 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)
• n_harmonics: comb-response span (Default: 8)
Non-integer fs·period_s aligned by band-limited fractional delay
res = signals.time_synchronous_average(x, fs, period_s=1/32)

• SynchronousAverageResult
SynchronousAverageResultdataclassTime synchronous average.
• period_waveform, times [s], residual, residual_rms
• n_averages, samples_per_period, period_s, fs, interpolated
• noise_reduction_db = 10·log₁₀N, amplitude_snr_gain = √N
• comb_frequencies [Hz], comb_response (|C(f)|)
• .plot(): averaged waveform + comb filter
res.period_waveform, res.noise_reduction_db
comb_filter_responsefunctionMagnitude of the N-period_s synchronous-averaging comb filter (McFadden 1987 Eq. 8).
• frequencies [Hz], period_s [s], n_averages
|C(f)| = |sin(N·π·f·T)/(N·sin(π·f·T))|: unit teeth at harmonics k/T, nodes at j/(N·T)
c = signals.comb_filter_response(freqs, 1/32, 20)
regularized_inverse_filterfunctionKirkeby frequency-dependent regularized inversion (Kirkeby & Nelson 1999 Eq. (17)).
• response: measured IR (array or ImpulseResponseResult; its fs rides along)
• fs: Sample rate [Hz]
• f_range: (f1, f2) equalized to unity (Required)
• regularization_inside (Default: 1e-6) / regularization_outside (Default: 1.0), fractions of max|H|²
• transition_octaves (Default: 1/3), n_fft, delay (Default: n_fft//2)
inv = signals.regularized_inverse_filter(ir, f_range=(100, 10000))

• InverseFilterResult
InverseFilterResultdataclassRegularized inverse filter.
• inverse (time domain), spectrum (with modeling delay), response_spectrum, regularization = ε(f), frequencies, f_range, delay, fs
• flatness_db: worst in-band deviation of |H·H_inv| from 0 dB
• max_gain_db: out-of-band boost (≤ the 1/(2√ε) cap)
• .apply(x): equalize, delay removed; .plot()
flat = inv.apply(recording)
cepstrumfunctionPower/real/complex cepstrum (Havelock Chs. 27/87).
• x, fs
• kind: 'power' (Default, IDFT of ln|X|²) / 'real' (ln|X|) / 'complex' (invertible, phase unwrapped)
• nfft: even, ≥ record (Default: record length)
Echo a at t0: rahmonics (−1)^(n+1)·aⁿ/n at n·t0
res = signals.cepstrum(x, fs, kind='complex')

• CepstrumResult
CepstrumResultdataclassCepstrum.
• quefrencies [s], cepstrum, kind, fs, nfft, linear_phase_samples
• .invert(): homomorphic round trip (complex kind only)
• .plot(): cepstrum vs quefrency
res.cepstrum, res.invert()
lifterfunctionLifter a log spectrum: envelope vs fine structure (Havelock Ch. 27).
• x, fs, cutoff [s]
• mode: 'lowpass' (Default, spectral envelope) / 'highpass' (ripple)
• nfft
Modes exactly complementary in dB
res = signals.lifter(x, fs, cutoff=0.004)

• LifterResult
LifterResultdataclassLiftered log spectrum.
• frequencies [Hz], spectrum_db, liftered_db
• quefrencies, cepstrum (real), cutoff, mode, fs, nfft
• .plot(): cepstrum + cutoff, spectrum overlay
res.liftered_db
echo_detectionfunctionEcho delay + reflection coefficient off the power cepstrum.
• x, fs
• min_quefrency [s] (Default: 16 samples), max_quefrency [s] (Default: nfft/2)
• nfft
Peak height = a exactly for one in-record echo
res = signals.echo_detection(ir, fs, min_quefrency=0.002)

• EchoDetectionResult
EchoDetectionResultdataclassDetected echo.
• delay [s], delay_samples, reflection_coefficient
• quefrencies, cepstrum, search_range, fs, nfft
• .plot(): cepstrum with the peak marked
res.delay, res.reflection_coefficient
minimum_phasefunctionMinimum-phase response from |H| via the real cepstrum (B&P 13.1.4).
• response: one-sided response or plain magnitude, rfft layout (DC–Nyquist)
• oversample: trig-interpolated cepstral anti-aliasing factor (Default: 8)
Input phase ignored; magnitude zeros floored at 1e-15 of the peak
h_min = signals.minimum_phase(np.abs(H))

• complex minimum-phase response, same bins
group_delayfunctionGroup delay τ_g = −(1/2π)·dφ/df of a sampled response.
• response: one-sided complex, rfft layout
• fs [Hz]
Unwrapped phase, central differences; needs < π phase advance per bin
tau = signals.group_delay(H, fs) # seconds
excess_phasefunctionExcess (all-pass) phase: unwrap(arg H) − φ_min.
• response: one-sided complex, rfft layout
• oversample (Default: 8)
0 for minimum phase, −2πf·t₀ for pure latency; the realizability limit of any stable causal inverse
phi_x = signals.excess_phase(H) # rad, 0 at DC
phase_decompositionfunctionMinimum-phase / all-pass decomposition of a response.
• response: one-sided complex, rfft layout (e.g. np.fft.rfft(ir))
• fs [Hz]
• oversample (Default: 8)
res = signals.phase_decomposition(np.fft.rfft(ir), fs)

• PhaseDecompositionResult
PhaseDecompositionResultdataclassPhase decomposition.
• frequencies [Hz], magnitude, phase (measured, unwrapped, 0 at DC)
• minimum_phase, excess_phase [rad], group_delay, excess_group_delay [s]
• minimum_phase_response (complex), fs
• .plot(): magnitude, phases, group delays
res.excess_phase, res.excess_group_delay
sound_power_anechoicfunctionPrecision sound power in an (hemi-)anechoic room (ISO 3745:2012).
• levels_positions: (NM, NB) position levels [dB]
• surface: 'sphere'/'hemisphere'
• radius r [m]
• background_levels + frequencies: for K1i
• areas: partial areas Si (Eq. 13) (Default: equal-area Eq. 12)
• temperature_c [°C] (Default: 23), static_pressure_kpa [kPa] (Default: 101.325)
• air_absorption_coefficient: α(f) [dB/m] for C3
• sigma_omc [dB] (Default: 0), coverage_factor k (Default: 2.0)
res = emission.sound_power_anechoic(levels, 'hemisphere', radius=2.0, frequencies=f)

• PrecisionSoundPowerResult
PrecisionSoundPowerResultdataclassISO 3745 sound power result.
• sound_power_level [dB], sound_power_level_a [dB]
• surface_pressure_level, mean_pressure_level [dB]
• background_correction: K1i (NM, NB) [dB]
• c1, c2, c3: meteorological corrections [dB]
• directivity_index DIi, non_uniformity_index VIr [dB]
• surface_area [m²], surface
• uncertainty, uncertainty_bands, coverage_factor
• .plot()
res.sound_power_level, res.uncertainty
precision_positionsfunctionISO 3745 microphone coordinates (Annex D/E).
• surface: 'sphere' (Table D.1) / 'hemisphere' (Tables E.1/E.2)
• radius r [m]
• array: 'general'/'broadband' (Default: 'general')
• count: 20 or 40 (Default: 40)
xyz = emission.precision_positions('hemisphere', radius=2.0)

• (40, 3) coordinates [m]
precision_background_correctionfunctionPer-position background correction K1i (ISO 3745 Eq. 11).
• source_levels / background_levels: (NM, NB) [dB]
• frequencies [Hz]: per-band criterion (10 dB for 250–5000 Hz, 6 dB outside)
k1 = emission.precision_background_correction(src, bg, f)

• K1i [dB]; clamped + SoundPowerWarning below the criterion
meteorological_correctionsfunctionCorrections C1, C2, C3 (ISO 3745 Eq. 14 block).
• temperature_c θ [°C] (Default: 23), static_pressure_kpa ps [kPa] (Default: 101.325)
• air_absorption_coefficient: α(f) [dB/m] for C3 (Default: None → C3 = 0)
• radius r [m] (Default: 1.0)
met = emission.meteorological_corrections(temperature_c=23.0, static_pressure_kpa=101.325)

• MeteorologicalCorrection; C1 = −0.128 dB, C2 = 0 at reference
MeteorologicalCorrectiondataclassC1/C2/C3 corrections.
• c1: reference-quantity correction [dB]
• c2: radiation-impedance correction [dB]
• c3: air-absorption correction [dB], scalar or per band
met.c1, met.c2, met.c3
precision_uncertaintyfunctionExpanded uncertainty U = k·√(σR0² + σomc²) (ISO 3745 Eq. 24/25).
• sigma_r0: reproducibility (Tables 2/3) [dB]
• sigma_omc [dB] (Default: 0.0)
• coverage_factor k (Default: 2.0; 1.6 one-sided)
precision_uncertainty(0.5) # 1.0

• U [dB], scalar or per band
sound_power_intensity_precisionfunctionSound power by intensity scanning, precision (ISO 9614-3:2002).
• partial_intensity: (N, NB) signed In,i [W/m²]
• areas: partial areas Si [m²]
• frequencies [Hz]: for LWA
• temperature_c [°C] (Default: 23), barometric_pressure_pa [Pa] (Default: 101325): for LW0 (Eq. 10)
res = emission.sound_power_intensity_precision(In, areas, frequencies=f)

• PrecisionIntensityResult
PrecisionIntensityResultdataclassISO 9614-3 scanning result.
• partial_power: Pi = In,i·Si [W]
• sound_power P, sound_power_level LW [dB] (NaN where P ≤ 0)
• sound_power_level_normalized: LW0 [dB]
• not_applicable_band: per-band bool
• surface_area [m²], sound_power_level_a [dB]
• .plot()
res.sound_power_level, res.not_applicable_band
precision_field_indicatorsfunctionISO 9614-3 Annex B field indicators.
• segment_intensity: (N, NB) signed In,j [W/m²]
• segment_pressure_levels: (N, NB) Lpj [dB]
• time_window_intensity: (M, NB) for FT (Default: None)
fi = emission.precision_field_indicators(In, lp)

• PrecisionFieldIndicators
PrecisionFieldIndicatorsdataclassAnnex B indicators (per band).
• ft: temporal variability (= F1) or None
• f_pi_unsigned: F_pIn unsigned (= F2)
• f_pi_signed: F_pIn signed (= F3), ≥ unsigned
• fs: field non-uniformity FS (= F4)
fi.f_pi_signed, fi.fs
precision_qualificationfunctionThe five ISO 9614-3 Annex C acceptance criteria.
• indicators: PrecisionFieldIndicators
• scan_intensity_level_1/_2: LIn per scan [dB] (criterion 1)
• pressure_residual_index: δpI0 [dB] (criterion 2, K = 10)
• field_nonuniformity_1/_2: FS per scan density (criterion 5)
• frequencies [Hz] or repeatability_limit: Table 1 limit s
q = emission.precision_qualification(fi, pressure_residual_index=18.0)

• PrecisionCriteria
PrecisionCriteriadataclassAnnex C pass/fail per band.
• criterion_1…criterion_5: bool arrays or None where not evaluable
• qualified: conjunction of criteria 1–4 or None
q.qualified, q.criterion_2
plane_wave_frequency_rangefunctionWorking plane-wave range (f_l, f_u) (ISO 10534-2 §4.2–4.5).
• spacing s [m]
• speed_of_sound c0 [m/s]
• diameter_m d [m] (Default: None → spacing bound only)
• shape: 'circular'/'rectangular'/'square' (Default: 'circular')
plane_wave_frequency_range(0.05, 343.2, diameter_m=0.1) # (343.2, 1990.6)

• [Hz]
plane_wave_frequency_range_astmfunctionWorking plane-wave range (f_l, f_u) (ASTM E2611-19 6.2.3–6.2.5, 6.5.4).
• spacing s [m]
• speed_of_sound c [m/s]
• diameter_m d [m] (Default: None → spacing bound only)
• shape: 'circular'/'rectangular'/'square' (Default: 'circular')
plane_wave_frequency_range_astm(0.05, 343.2, diameter_m=0.1) # (68.6, 2011.2)

• [Hz]; f_u s < 0.40 c, f_u d < 0.586 c (0.500 rectangular)
plot_impedance_tube_geometryfunctionTo-scale side view of the ISO 10534-2 tube.
• spacing s, x1 [m]
• diameter_m d [m], shape (Default: 'circular')
• sample_thickness [m] (Default: 50 mm nominal)
• language
plot_impedance_tube_geometry(spacing=0.05, x1=0.15, diameter_m=0.10)

• Dimensioned drawing + plane-wave range; also ImpedanceTubeResult.plot_geometry()
plot_transmission_tube_geometryfunctionTo-scale side view of the ASTM E2611 tube.
• l1, s1, l2, s2, thickness [m]
• diameter_m d [m], shape (Default: 'circular')
• language
plot_transmission_tube_geometry(l1=0.10, s1=0.05, l2=0.20, s2=0.05, thickness=0.05, diameter_m=0.10)

• Four microphones + termination; also TransferMatrix.plot_geometry()
speed_of_sound_iso10534functionSpeed of sound (ISO 10534-2 Eq. 5).
• temperature_c t [°C]
speed_of_sound_iso10534(temperature_c=19.85) # 343.2

• c0 = 343.2 √(T/293) [m/s], T = 273.15 + t
air_density_iso10534functionAir density (ISO 10534-2 Eq. 7).
• temperature_c t [°C]
• atmospheric_pressure_kpa [kPa] (Default: 101.325)
air_density_iso10534(temperature_c=19.85) # 1.186

• ρ [kg/m³]
speed_of_sound_astmfunctionSpeed of sound (ASTM E2611-19 Eq. 4).
• temperature_c T [°C]
speed_of_sound_astm(temperature_c=20.0) # 343.2

• 20.047 √(273.15 + T) [m/s]
air_density_astmfunctionAir density (ASTM E2611-19 Eq. 5).
• temperature_c T [°C]
• atmospheric_pressure_kpa P [kPa] (Default: 101.325)
air_density_astm(temperature_c=20.0) # 1.202

• ρ [kg/m³]
hydraulic_diameterfunctionHydraulic diameter of a rectangular tube, 4A/P (ISO 10534-2 A.2.1.5).
• width w [m]
• height h [m]
hydraulic_diameter(0.08, 0.04) # 0.0533

• d_h = 2wh/(w + h) [m]; feed to tube_attenuation_constant
tube_attenuation_constantfunctionLower-bound tube attenuation k0″ (ISO 10534-2 Eq. A.18).
• frequency f [Hz]
• speed_of_sound c0 [m/s]
• diameter_m d [m] (hydraulic for rectangular)
tube_attenuation_constant(1000.0, 343.2, 0.1) # 0.0179

• [Np/m]
tube_wavenumberfunctionComplex wavenumber k0 = k0′ − j k0″ (ISO 10534-2 §2.6).
• frequency f [Hz]
• speed_of_sound c0 [m/s]
• attenuation: k0″ [Np/m] (Default: None → lossless)
tube_wavenumber(1000.0, 343.2, attenuation=0.018)

• 18.308 − 0.018j [1/m]
mic_calibration_factorfunctionMicrophone-mismatch calibration factor Hc (ISO 10534-2 Eq. 10).
• h12_config1: H12 in the standard configuration
• h12_config2: H12 with the microphones interchanged
hc = materials.mic_calibration_factor(h12_a, h12_b)

• Hc = √(H12ᴵ/H12ᴵᴵ) (complex)
apply_mic_calibrationfunctionApply the calibration factor (Eq. 13).
• h12_uncorrected
• calibration_factor: Hc
h12 = materials.apply_mic_calibration(h12_raw, hc)

• H12 = H12,raw/Hc
reflection_factorfunctionComplex reflection factor at the sample surface (ISO 10534-2 Eq. 17).
• h12: corrected transfer function
• spacing s [m]
• x1: sample to the farther microphone [m]
• wavenumber: complex k0
r = materials.reflection_factor(h12, spacing=0.05, x1=0.15, wavenumber=k0)

• r = (H12 − HI)/(HR − H12)·e^(+2jk0x1)
absorption_from_reflectionfunctionNormal-incidence absorption coefficient (Eq. 18).
• reflection: complex r
absorption_from_reflection(0.5) # 0.75

• α = 1 − |r|²
surface_impedancefunctionAbsolute surface impedance Z (Eq. 19).
• reflection: complex r
• characteristic_impedance: ρc0 [rayl]
surface_impedance(0.5, 407.0) # 1221

• Z = ρc0(1 + r)/(1 − r) [rayl]
normalized_surface_impedancefunctionNormalised surface impedance Z/(ρc0) (Eq. 19).
• reflection: complex r
normalized_surface_impedance(0.5) # 3.0
normalized_surface_admittancefunctionNormalised surface admittance Gρc0 (Eq. 20).
• reflection: complex r
normalized_surface_admittance(0.5) # 0.333

• (1 − r)/(1 + r)
two_microphone_impedancefunctionFull two-microphone reduction (ISO 10534-2 Clause 7).
• h12: corrected transfer function
• frequency f [Hz]
• spacing s [m], x1 [m]
• speed_of_sound c0 [m/s], characteristic_impedance ρc0 [rayl]
• attenuation: k0″ [Np/m] (Default: None)
• diameter_m + shape: activate the plane-wave range check
res = materials.two_microphone_impedance(h12, frequency=f, spacing=0.05, x1=0.15, speed_of_sound=343.2, characteristic_impedance=407.0)

• ImpedanceTubeResult
ImpedanceTubeResultdataclassTwo-microphone result per frequency.
• frequencies [Hz]
• reflection: complex r (Eq. 17)
• surface_impedance [rayl], normalized_impedance (Eq. 19)
• absorption: α = 1 − |r|² (Eq. 18)
• Retains spacing, x1, diameter_m, shape when supplied
res.absorption, res.normalized_impedance
ImpedanceTubeWarningwarning classISO 10534-2 advisory.
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_levelfunctionStanding-wave ratio from ΔL (ISO 10534-1 Eq. 15).
• level_difference: Lmax − Lmin [dB]
standing_wave_ratio_from_level(20.0) # 10.0

• s = 10^(ΔL/20)
standing_wave_reflection_magnitudefunctionReflection magnitude from the SWR (Eq. 14).
• swr: s ≥ 1
standing_wave_reflection_magnitude(10.0) # 0.818

• |r| = (s − 1)/(s + 1)
standing_wave_reflectionfunctionComplex reflection factor from the standing wave (Eqs. 17–23).
• swr: s
• first_min_distance: x_min1 [m]
• wavelength: λ0 [m]
standing_wave_reflection(10.0, 0.05, 0.4) # -0.818j

• phase φ = π(4x_min1/λ0 − 1)
standing_wave_absorptionfunctionAbsorption from the SWR (Eqs. 9 + 14).
• swr: s ≥ 1
standing_wave_absorption(10.0) # 0.331

• α = 4s/(s + 1)²
standing_wave_normalized_impedancefunctionNormalised impedance from the standing wave (Eqs. 24–26).
• swr, first_min_distance [m], wavelength [m]
standing_wave_normalized_impedance(10.0, 0.05, 0.4)

• 0.198 − 0.98j
wave_decompositionfunctionDecompose the field into (A, B, C, D) (ASTM E2611-19 Eqs. 17–20).
• h1…h4: microphone transfer functions
• l1, s1, l2, s2: geometry [m]
• wavenumber k
• diameter_m + shape: activate the plane-wave range check
A, B, C, D = materials.wave_decomposition(h1, h2, h3, h4, l1=0.2, s1=0.05, l2=0.2, s2=0.05, wavenumber=k)

• Forward/backward amplitudes, both sides
face_quantitiesfunctionFace pressures and velocities (Eq. 21).
• a, b, c, d: wave amplitudes
• wavenumber k, thickness d [m], characteristic_impedance ρc
p0, pd, u0, ud = materials.face_quantities(A, B, C, D, wavenumber=k, thickness=0.05, characteristic_impedance=407.0)
transfer_matrix_two_loadfunctionTwo-load transfer matrix (ASTM E2611-19 Eqs. 17–22).
• load_a, load_b: (H1, H2, H3, H4) per termination
• l1, s1, l2, s2, thickness [m]
• wavenumber, characteristic_impedance
• frequencies (retained for .plot()), diameter_m + shape: range check
T = materials.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)

• TransferMatrix
transfer_matrix_one_loadfunctionOne-load transfer matrix, symmetric specimen (Eqs. 23–24).
• load: (H1, H2, H3, H4)
• Same geometry/frequency/range-check parameters as transfer_matrix_two_load
T = materials.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)

• Requires reciprocity + symmetry
air_layer_transfer_matrixfunctionAnalytic loss-free air-layer matrix (validation reference).
• wavenumber k
• thickness d [m]
• characteristic_impedance ρc [rayl]
T = materials.air_layer_transfer_matrix(k, 0.05, 407.0)

• det(T) = 1, T11 = T22
TransferMatrixdataclassAcoustic transfer matrix [[T11, T12], [T21, T22]] (ASTM E2611-19 Eq. 16).
• t11, t12, t21, t22: complex, scalar or per frequency
• Solver-built matrices retain l1/s1/l2/s2, thickness, diameter_m, shape, frequencies, air_characteristic_impedance (so .plot() needs no arguments)
T.t11, T.t12
airflow_resistancefunctionAirflow resistance R = Δp/qv (ISO 9053-1:2018 §3.1).
• pressure_drop_pa Δp [Pa]
• volume_flow_rate qv [m³/s]
airflow_resistance(2.0, 0.0005) # 4000.0

• [Pa·s/m³]
specific_airflow_resistancefunctionSpecific airflow resistance Rs (§3.2).
• resistance R + area A, or pressure_drop_pa Δp + velocity u
specific_airflow_resistance(4000.0, 0.01) # 40.0

• Rs = R·A = Δp/u [Pa·s/m]
airflow_resistivityfunctionAirflow resistivity σ = Rs/d (§3.3).
• specific_resistance Rs [Pa·s/m]
• thickness d [m]
airflow_resistivity(40.0, 0.05) # 800.0

• [Pa·s/m²]
linear_airflow_velocityfunctionLinear airflow velocity u = qv/A (§3.4).
• volume_flow_rate qv [m³/s]
• area A [m²]
linear_airflow_velocity(5e-6, 0.01) # 0.0005

• [m/s]
static_airflow_resistancefunctionStepwise static-method determination (ISO 9053-1 §7.5).
• velocities u [m/s], pressure_drops_pa Δp [Pa] (≥ 2 steps)
• area A [m²]
• thickness d [m] (Default: None → no σ)
• evaluation_velocity [m/s] (Default: 0.0005)
res = materials.static_airflow_resistance([0.0005, 0.001, 0.002], [0.02, 0.041, 0.086], 0.01, 0.05)

• StaticAirflowResult (Rs = 40.0, σ = 800)
StaticAirflowResultdataclassStatic-method result at the evaluation velocity.
• resistance R [Pa·s/m³], specific_resistance Rs [Pa·s/m]
• resistivity σ [Pa·s/m²] or None
• evaluation_velocity [m/s], pressure_drop_pa [Pa]
• linear_coefficient a (zero-velocity Rs), quadratic_coefficient b
res.specific_resistance, res.resistivity
piston_volume_flow_ratefunctionRMS piston volume flow qv = 2πf·h·AP (ISO 9053-2 §6.2).
• frequency f [Hz]
• stroke_amplitude h [m]
• piston_area AP [m²]
piston_volume_flow_rate(2.0, 0.005, 0.01) # 0.000628

• [m³/s]
alternating_airflow_resistancefunctionAlternating-method resistance (ISO 9053-2:2020 Formula 2).
• level_specimen Lps / level_termination Lpt [dB]
• piston_stroke_specimen hs / piston_stroke_termination ht [m]
• frequency f [Hz] (1–4 Hz), cavity_volume V [m³]
• static_pressure_pa [Pa] (Default: 101325)
• kappa_prime κ′ (Default: 1.4; use effective_kappa for Annex A conformity)
• background_level Lpb [dB] (Default: None)
r = materials.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)

• R [Pa·s/m³]; AirflowResistanceWarning when criteria fail
ANNEX_A_AIRFluidThe air of the ISO 9053-2:2020 Annex A.3 reference state (23 °C, 101 325 Pa, 50 % RH).
345,866 52 m/s, 1,186 084 8 kg/m³, κ = 1,400 757 3, plus the conductivity and specific heat Clause F.6 gives
• the default of thermal_boundary_layer_thickness and effective_kappa; pass a computed fluids.air() to work in the air of the laboratory instead
materials.ANNEX_A_AIR.speed_of_sound # 345.86652
thermal_boundary_layer_thicknessfunctionThermal boundary-layer thickness b (ISO 9053-2 Formulas A.4/A.5).
• frequency f [Hz]
• Air properties (Default: Annex A.3 values)
thermal_boundary_layer_thickness(2.0) # 0.00183

• [m]
effective_kappafunctionEffective ratio of specific heats κ′ (Formula A.7).
• cavity_surface S [m²], cavity_volume V [m³]
• frequency f [Hz]
• Air properties (Default: Annex A.3 values)
effective_kappa(0.0471, 7.854e-4, 2.0) # 1.37

• The Annex A.3 worked example
delany_bazleyfunctionDelany–Bazley one-parameter porous model (Mechel 2e G.11; Bies 5e Table D.1).
• frequency f [Hz]
• flow_resistivity σ [Pa·s/m²]
• coefficients: preset name or (C1…C8) (Default: 'delany_bazley' rockwool/fibreglass)
• fluid: Fluid (Default: PUBLISHED_AIR, 343.0 m/s and 1.205 kg/m³)
• Warns outside 0.01 < X < 1 (X = ρf/σ)
med = materials.delany_bazley(f, 20000.0)

• PorousMediumResult
mikifunctionMiki (1990) positive-real revision of Delany–Bazley.
• frequency f [Hz]
• flow_resistivity σ [Pa·s/m²]
• fluid: Fluid (Default: PUBLISHED_AIR)
• Stays passive below the fit range; warns outside 0.01 < f/σ < 1
med = materials.miki(f, 20000.0)

• PorousMediumResult
johnson_champoux_allardfunctionJCA five-parameter rigid-frame model (Cox & D'Antonio 3e Eqs. 6.19–6.25).
• frequency f [Hz], flow_resistivity σ [Pa·s/m²]
• porosity φ, tortuosity T = α∞
• viscous_length Λ / thermal_length Λ′ [m]
• fluid: Fluid carrying the air state the model needs, viscosity, Prandtl number, ratio of specific heats and static pressure (Default: PUBLISHED_AIR)
med = materials.johnson_champoux_allard(f, 20000.0, porosity=0.98, tortuosity=1.05, viscous_length=8.7e-5, thermal_length=1.7e-4)

• PorousMediumResult
limp_framefunctionLimp-frame correction of any rigid-frame model (Allard & Atalla 2e Eqs. 11.53-11.55, Panneton 2007).
• medium: a rigid-frame PorousMediumResult
• frame_density ρ₁ [kg/m³] (bulk density of the frame)
• porosity φ (Default: 1.0)
• keeps K_e, corrects ρ_e; → ρ_t = ρ₁ + φρ₀ as ω → 0 and → rigid as ρ₁ → ∞
soft = materials.limp_frame(jca, frame_density=30.0, porosity=0.98)

• PorousMediumResult, model 'materials.limp_frame(...)'
decoupling_frequencyfunctionZwikker-Kosten decoupling frequency Fd (Allard & Atalla 2e Sect. 11.3.4 / Eq. 6.90).
• flow_resistivity σ [Pa·s/m²]
• porosity φ, frame_density ρ₁ [kg/m³]
• Fd = σφ²/(2πρ₁): above it the frame stands still
gw = materials.PUBLISHED_POROUS['allard-2009-table-6-1/domisol_coffrage']
decoupling_frequency(gw.printed('flow_resistivity_pa_s_m2'), porosity=gw.printed('porosity'), frame_density=gw.printed('frame_density_kg_m3')) # 43.27

• [Hz]
limp_frame_applicable / LIMP_FRAME_CRITERIAfunction / mappingPublished rule of thumb for treating a frame as limp (Allard & Atalla 2e pp. 253-254).
• frame_bulk_modulus K_c [Pa]
• criterion: 'doutres' (0.2, Default) / 'beranek' (0.05)
• fluid_bulk_modulus K_f [Pa] (Default: 101325, isothermal air) → the book's "bulk modulus lower than 20 kPa"
limp_frame_applicable(20e3) # True

• bool
biot_wavesfunctionThe three Biot waves of a poroelastic layer (Allard & Atalla 2e Eqs. 6.67–6.84).
• medium: the rigid-frame PorousMediumResult of the pores
• porosity φ, tortuosity α∞
• frame_density ρ₁ [kg/m³], shear_modulus N [Pa] (complex, Im ≥ 0)
• poisson_ratio ν (Default: 0)
w = materials.biot_waves(jca, porosity=0.94, tortuosity=1.06, frame_density=130.0, shear_modulus=2.2e6*(1+0.1j))

• BiotWavesResult
BiotWavesResultdataclassTwo compressional waves and one shear wave.
• compressional_wavenumber_1 / _2, shear_wavenumber δ [rad/m]
• velocity_ratio_1 / _2 / _3 μ (fluid over frame)
• elastic_p / _q / _r P, Q, R [Pa]; density_11 / _12 / _22
• .airborne_wavenumber, .frame_borne_wavenumber, .airborne_velocity_ratio, .frame_borne_velocity_ratio, .airborne_is_second
• .plot(): the three wavenumbers vs frequency
w.airborne_wavenumber, w.plot()
biot_surface_impedancefunctionHard-backed Biot layer at normal incidence, closed form (Allard & Atalla 2e Eqs. 6.107–6.108).
• waves: a BiotWavesResult
• thickness l [m]
• Glued backing; one layer; normal incidence only
zs = materials.biot_surface_impedance(w, 0.10)

• complex [Pa·s/m]
poroelastic_transfer_matrix`function$**6 \times 6 \text{layer} \text{matrix} $[T p] = [Γ(−h)][Γ(0)]⁻¹(Allard & Atalla 2e Eq. 11.34, Table 11.1).**<br>•waves, thicknessh [m]<br>•transverse_wavenumber` kt = k sin θ [rad/m] (Default: 0)
• Field vector [v1s, v3s, v3f, σ33s, σ13s, σ33f]
t = materials.poroelastic_transfer_matrix(w, 0.05)

• (n, 6, 6) complex
frame_bulk_modulusfunctionBulk modulus Kb of the frame in vacuum (Allard & Atalla 2e Eq. 6.29).
• shear_modulus N [Pa], poisson_ratio ν
• Kb = 2N(ν+1)/(3(1−2ν)); feeds limp_frame_applicable
frame_bulk_modulus(2.2e6, 0.0)

• complex [Pa]
frame_elastic_coefficientfunctionLongitudinal coefficient Kc of the frame in vacuum (Allard & Atalla 2e Eq. 6.111).
• shear_modulus N [Pa], poisson_ratio ν
• Kc = 2(1−ν)N/(1−2ν) = Kb + 4N/3
frame_elastic_coefficient(2.2e6, 0.0) # 4.4e6

• complex [Pa]
frame_quarter_wave_resonancefunctionλ/4 frame resonance of a glued layer (Allard & Atalla 2e Eq. 6.110).
• thickness l [m]
• shear_modulus N, poisson_ratio ν, frame_density ρ₁
• fr = (1/4l)√(Re(Kc)/ρ₁): the peak no equivalent fluid produces
frame_quarter_wave_resonance(0.10, shear_modulus=2.2e6*(1+0.1j), poisson_ratio=0.0, frame_density=130.0) # 459.9

• [Hz]
PorousMediumResultdataclassEquivalent-fluid characterisation.
• characteristic_impedance Zc [Pa·s/m], wavenumber k [rad/m] (Im < 0)
• effective_density, bulk_modulus (surface-normalised)
• .normalized_impedance, .normalized_wavenumber
• .plot(): normalised Zc/k components
med.characteristic_impedance, med.plot()
PorousMaterialdataclassOne row of a published table of porous-material parameters.
• Every quantity optional, because no two tables print the same columns; .why_missing(field) says what the page had instead, and .printed(field) narrows or refuses
• flow_resistivity_pa_s_m2, porosity, tortuosity, viscous_length_um, thermal_length_um, thermal_permeability_m2, frame_density_kg_m3, thickness_mm
• youngs_modulus_pa, shear_modulus_pa (real), poisson_ratio, structural_loss_factor: a page printing N(1 + jη) has printed shear_modulus_pa and structural_loss_factor
• approximate, ranges, bounded_above, reported, unquantified: what the cell was, when it was not a value
• derived: field → how this library computed it; attributed_to: per-cell credit; variant: which specimen, when a page prints several under one name
• .medium(f) → PorousMediumResult; .frame_constants() → (N, ν) with N complex, refusing a row without its loss factor rather than reading it as 0
• Not a material database: a real specimen is characterised to ISO 9053 and ISO 10534-2
foam = materials.PUBLISHED_POROUS['allard-2009-table-13-1/foam']
med = foam.medium(f)

• foam.source prints the page
PUBLISHED_POROUSmappingA hundred and ninety-four porous rows from twenty-six published tables, keyed '<table>/<row>'.
• Two kinds of row: a specimen is one measured sample with every parameter a model needs, and a compiled row is one quantity over a class of material, almost always an interval
• Allard & Atalla 2e, the specimen rows of nineteen tables over eight chapters, each one the input to a worked example of the book
• Cox & D'Antonio 3e Tables 6.2, 6.3, 6.5, 6.8 and 6.9 and Mechel 2e Sect. G.1 and G.11, compiled from the literature; seven of the eight porosity ranges Cox credits to Mechel match Mechel's own page to the digit
• The key names the table because the book prints one foam in four chapters and one glass wool in two, sometimes with a column the other page leaves out
• Table 6.1 prints the glass wool's shear modulus in N/cm², Table 11.8 prints the same specimen's Young's modulus in pascals, and E/(2(1+ν)) reconciles them
• Table 9.1 prints its lengths in millimetres and Table 13.1 in metres; all of them are stored in micrometres
• Table 11.5 prints the word 'model' where a screen's tortuosity would go, and the row keeps the word rather than a number
• The plates, septa and impervious screens these pages also print are not porous materials and are not here
materials.PUBLISHED_POROUS['allard-2009-table-11-2/soft_fibrous']

• PorousMaterial, porous_materials_named
porous_materials_namedfunctionEvery published row for a specimen name, across the tables.
• Matches PorousMaterial.name without regard to case; empty when no page names it
• Five pages print a 'Foam' and they are five different foams, so a lookup returning one would be choosing between published parameter sets for you
materials.porous_materials_named('Foam') # five rows, five tables

• PUBLISHED_POROUS
ResistiveSheetdataclassOne thin resistive facing, with the flow resistance of one square metre of it.
• specific_flow_resistance_pa_s_m is R_s = Δp/v, per unit area [Pa·s/m], the N·s/m³ of the page and the mks rayl of an older literature; it is not the per-metre flow_resistivity_pa_s_m2 of PorousMaterial, and the two differ by a thickness
• normalized_flow_resistance is the same resistance over ρ₀c₀, as two of the tables print it; .reference_impedance_pa_s_m() divides one column by the other and gives back the impedance that table used
• wires_per_cm, wire_diameter_um, thickness_mm, mass_per_area_kg_m2, nonlinearity_factor: what each table describes its facing by
• surface_density_g_m2 is the same mass per unit area under the heading and in the unit the cloth table prints it in, g/m²; weave_construction is that table's weave, held as the text it is, '60 × 58', two counts over a length the page never states
• table says which of the three printed tables the row came from; the maker is in attributed_to['row'] on the cloth table, which credits one per row, and in attributed_to['table'] on the sintered one, which credits one for all eleven
mesh = materials.resistive_sheet_named('80')[0]
mesh.specific_flow_resistance_pa_s_m # 24.6 Pa·s/m

• PUBLISHED_FLOW_RESISTANCE, resistive_sheet_named
PUBLISHED_FLOW_RESISTANCEmappingTwenty-nine thin resistive facings from three published tables, keyed '<table>/<row>'.
• Vér & Beranek 2e TABLE 8.5 (PDF page 266), five woven wire mesh cloths; TABLE 8.6 (PDF page 267), thirteen glass fibre cloths; TABLE 8.7 (PDF page 267), eleven sintered porous metal sheets, one data file and one citation each
• A resistance per unit area [Pa·s/m], for the facing over an absorber, and not the flow resistivity [Pa·s/m²] of PUBLISHED_POROUS
• TABLE 8.7 prints its two resistance columns once per block and blank beneath; the value is carried down and each row that received it names the row it came from
• The surface density of TABLE 8.6 is held as the page prints it, in g/m², and its note carries the oz/yd² beside it: the two printings disagree by about eleven per cent on all thirteen rows, one wrong factor, and the page does not say which column has it
• Not a specification: the pages give no measurement method, no laboratory and no standard, and the values are the linear part of the resistance, for low particle velocity only
materials.PUBLISHED_FLOW_RESISTANCE['ver-beranek-2006-table-8-7/sintered_fm_122']

• ResistiveSheet, resistive_sheet_named
resistive_sheet_namedfunctionEvery facing a page labels with this name, matched whole.
• Matches ResistiveSheet.name without regard to case, and whole rather than in part, because these pages name their rows by mesh count and product code: a partial match would answer '12' with a mesh, two cloths and four sintered sheets
• A tuple and not one row, because a name can be printed by more than one table
materials.resistive_sheet_named('FM 122')

• PUBLISHED_FLOW_RESISTANCE
AbsorptionSpectrumdataclassOne finish of a published absorption table, with its Sabine coefficient in each octave band.
• absorption_coefficient_63 … absorption_coefficient_8000: one field per band, the band's centre frequency in hertz as the suffix, None where the page prints no value
• .bands() the bands the row prints; .spectrum() → {band_hz: coefficient}; .absorption_coefficient(band_hz) narrows or refuses, naming the row and the band
• mounting: the ASTM C423 mounting the page prints beside the row, 'A', 'E400', 'F' or empty; the same board on two mounts is two rows, because the airspace behind it changes what it does
• thickness and density stay in name and variant as the page prints them; the hedges of every catalogue row apply band by band
• a measurement of a specimen in a room, not a property of a material: representative, never a specification
row = materials.PUBLISHED_ABSORPTION['bies-2017-table-6-2/carpet_heavy_on_concrete']
row.spectrum() # {125: 0.02, 250: 0.06, ...}

• PUBLISHED_ABSORPTION, AbsorptionAreaSpectrum
AbsorptionAreaSpectrumdataclassA row a table prints as an equivalent absorption area per person, per seat or per cubic metre of air rather than as a coefficient.
• absorption_area_63_m2 … absorption_area_8000_m2, in square metres per unit of per, which is 'person' for an audience row
• kept apart from the coefficients because it is added to a room's absorption, not multiplied by a surface, and the unit is in the field name so it cannot be mistaken for one
• a row in sabins has been converted, and converted[field] keeps the page's figure and its unit, ('4.0', 'sabins')
materials.PUBLISHED_ABSORPTION_AREAS['bies-2017-table-6-2/audience_per_person_seated'].spectrum()[500] # 0.44 m² per person

• PUBLISHED_ABSORPTION_AREAS
ABSORPTION_BANDS_HZconstantThe octave bands an absorption table can print: 63 Hz to 8 kHz.
• (63, 125, 250, 500, 1000, 2000, 4000, 8000); a table prints six or seven of them and the others stay empty on every row
materials.ABSORPTION_BANDS_HZ
PUBLISHED_ABSORPTIONmappingFour hundred and fifty-five absorption coefficient rows from five published tables, keyed '<table>/<row>'.
• Bies 5e Table 6.2, fifty-nine rows in eight groups, two of which are areas per person and live in PUBLISHED_ABSORPTION_AREAS
• Long 2e Table 7.1, a hundred and two rows in eleven groups, with an ASTM C423 mounting on sixty-two of them and fifteen finishes printed on two mounts
• Cox & D'Antonio 3e Appendix A, a hundred and sixty-one rows in twenty-two groups, compiled from twenty-nine sources and credited row by row in attributed_to; every cell of it is a number
• Arau-Puchades (1999) Tabla 6.1, ninety-six of its ninety-nine numbered rows, names in Spanish as printed, two of them intervals in ranges; the three that are the air attenuation coefficient m in reciprocal metres are not served
• Everest 4e Appendix, forty-one rows in three groups, each with the source the page prints beside it in a column of its own; two rows the page marks with a dash carry no credit
• the book says the values are selected from the literature, that reverberation times from them are approximate only, and that manufacturer's data or a measurement is better
• the transcription was made twice, from the rendered pages, by readers who never saw each other's work, and compared cell by cell before either was kept
• of the ten finishes both books describe, five agree in every band and five differ in exactly one cell, which is why absorption_named returns every match rather than choosing one
materials.PUBLISHED_ABSORPTION['bies-2017-table-6-2/glass_heavy_plate'].absorption_coefficient(125) # 0.18

• AbsorptionSpectrum, absorption_named
PUBLISHED_ABSORPTION_AREASmappingThe four rows the same pages print as an absorption area rather than a coefficient, keyed '<table>/<row>'.
• Bies 5e Table 6.2 prints an audience seated and standing as SαˉS\bar{\alpha} in square metres, the quantity of its Equation (6.78)
• Long 2e Table 7.1 prints a musician with his instrument, in bare figures its note reads as sabins, and the air itself at 50 % relative humidity, in sabins per 1000 cubic feet; both are converted to square metres and marked converted
materials.PUBLISHED_ABSORPTION_AREAS['bies-2017-table-6-2/audience_per_person_standing'].per # 'person'

• AbsorptionAreaSpectrum
absorption_namedfunctionEvery published coefficient row whose printed name contains a fragment.
• name: a fragment, matched without case, because a finish is described rather than named and no two books describe one the same way
• 'carpet' answers with every carpet of every table, and the caller reads the names to pick the one that is theirs
[r.name for r in materials.absorption_named('carpet')] # twenty-one carpets; 'moqueta' finds the Spanish ones

• PUBLISHED_ABSORPTION
CarpetdataclassOne carpet as a page printed it: its pile, what it is laid on, and its NRC.
• noise_reduction_coefficient, the mean absorption at 250 to 2000 Hz; no band can be recovered from it
• pile_weight_kg_m2 [kg/m²], pile_height_mm [mm], pile_surface and fibre in the page's words, mounting (bare concrete or a hair pad)
• four pile weights whose two printed halves disagree are misprinted and serve nothing
row = materials.carpets_named('nylon')[0]
row.noise_reduction_coefficient # 0.5

• PUBLISHED_CARPETS, carpets_named
PUBLISHED_CARPETSmappingNineteen carpets, keyed '<table>/<row>'.
• Harris 3e Table 30.2 (PDF page 704), eleven on bare concrete, NRC 0,25 to 0,55, and Table 30.3 (PDF pages 704 to 705), eight on a hair pad, NRC 0,40 to 0,70
• credited to the American Carpet and Rug Institute, the chapter's Reference 5
len(materials.PUBLISHED_CARPETS) # 19

• Carpet, carpets_named
carpets_namedfunctionEvery published carpet whose construction, surface or fibre contains the text.
• name: matched without case against the Spanish words the page prints, so 'nylon', 'lana' or 'de nudo'
• empty when nothing matches
len(materials.carpets_named('nylon')) # 3

• PUBLISHED_CARPETS
porosity_from_bulk_densityfunctionOpen porosity of a fibrous material from its two densities (Hopkins 2007 Eq. 1.160, printed p. 80).
• bulk_density_kg_m3 ρ [kg/m³], fibre_density_kg_m3 ρ_fibre [kg/m³]
• φ = 1 − ρ/ρ_fibre; holds for solid fibres with a binder of negligible mass
• Refuses a bulk density at or above the fibre density
materials.porosity_from_bulk_density(60.0, fibre_density_kg_m3=2 600.0) # 0.977

• φ, between 0 and 1
airflow_resistivity_from_bulk_density / FibreResistivityFitfunction / classAirflow resistivity of a mineral wool from its bulk density (Hopkins 2007 Eq. 1.165, printed p. 81).
• bulk_density_kg_m3 ρ [kg/m³]
• fit: a published FibreResistivityFit carrying k1, k2, fibre_diameter_um and the bulk-density range it was fitted over
• r = k₁ρ^(1+k₂)/d² with d in micrometres
• Warns outside the fitted range: it is a regression through measured points, not a law
materials.airflow_resistivity_from_bulk_density(60.0, fit=materials.ROCK_WOOL_LONGITUDINAL_FIT) # 23 226

• σ [Pa·s/m²]
ROCK_WOOL_LATERAL_FIT / ROCK_WOOL_LONGITUDINAL_FIT / ROCK_WOOL_FIBRE_DENSITY_KG_M3constantThe rock wool of Hopkins Fig. 1.49, as its page prints it (printed p. 81).
• lateral k₁ = 353, k₂ = 0,63 over 31 to 155 kg/m³
• longitudinal k₁ = 780, k₂ = 0,59 over 38 to 162 kg/m³
• fibre diameter 4,75 µm, fibre density 2 600 kg/m³
• Mineral wool is anisotropic: the longitudinal resistivity is the higher of the two
materials.ROCK_WOOL_LATERAL_FIT.k1 # 353.0

• FibreResistivityFit, float
viscous_characteristic_lengthfunctionΛ from the three parameters that are measured routinely (Allard & Atalla 2e Eq. 5.25, printed p. 80).
• flow_resistivity_pa_s_m2 σ, porosity φ, tortuosity α∞
• fluid: Fluid (Default: PUBLISHED_AIR), for its viscosity
• shape_factor c (Default: 1.0)
• Λ = (8ηα∞/(σφ))^½/c; within a factor of two on 18 of the 23 specimens the book prints with all four columns, and nowhere near a carpet
materials.viscous_characteristic_length(40 000.0, porosity=0.94, tortuosity=1.06) # 6.4e-05

• Λ [m]
fibre_characteristic_lengths / FibreCharacteristicLengthsfunction / classBoth lengths of a fibrous layer from its geometry (Allard & Atalla 2e Eqs. 5.29 and 5.30, printed p. 81).
• fibre_radius_m R [m], bulk_density_kg_m3 ρ, fibre_density_kg_m3 ρ_fibre [kg/m³]
• Λ = Rρ_fibre/(2ρ), Λ′ = 2Λ, the fibre length per unit volume eliminated through its own definition
• A different model from viscous_characteristic_length, and the lower estimate of the two throughout
materials.fibre_characteristic_lengths(2.375e-6, bulk_density_kg_m3=60.0, fibre_density_kg_m3=2 600.0)

• FibreCharacteristicLengths: viscous_length_m, thermal_length_m
DELANY_BAZLEY_COEFFICIENTSmappingBies 5e Table D.1 coefficient presets (C1…C8).
'delany_bazley' (rockwool/fibreglass), 'garai_pompoli' (polyester), 'dunn_davern' / 'wu' (foams)
DELANY_BAZLEY_COEFFICIENTS['garai_pompoli']
DELANY_BAZLEY_VALIDITYtupleStated fit range in X = ρf/σ.
(0.01, 1.0)
DELANY_BAZLEY_VALIDITY # (0.01, 1.0)
MIKI_VALIDITYtupleMiki fit range in f/σ.
(0.01, 1.0)
MIKI_VALIDITY # (0.01, 1.0)
PUBLISHED_AIRFluidThe air the Johnson-Champoux-Allard model was published with.
343.0 m/s, 1.205 kg/m³, 1.84·10⁻⁵ Pa·s, Pr = 0.71, γ = 1.4, 101325 Pa
• a phonometry.fluids.Fluid: pass a computed one to depart from the published constants
• the fluid argument of the slow-sound and metadiffuser models defaults to it
PUBLISHED_AIR.density # 1.205
layered_absorberfunctionTransfer-matrix multilayer prediction at one angle_rad (Cox & D'Antonio Eq. 2.29; Bies Eq. D.95; Mechel D.4).
• frequency f [Hz]
• layers: stack from the incidence side (AirLayer, PorousLayer, PoroelasticLayer, PerforatedPlateLayer, MicroperforatedPlateLayer, MembraneLayer)
• angle_rad θ [rad] (Default: 0)
• termination: 'rigid'/'free'/complex Z [Pa·s/m] (Default: 'rigid')
• fluid: Fluid (Default: PUBLISHED_AIR)
res = materials.layered_absorber(f, [materials.PorousLayer(0.05, med)])

• LayeredAbsorberResult
plot_absorber_stackfunctionTo-scale cross-section of a layer stack.
• layers: front layer first (or a single layer)
• language
plot_absorber_stack(layers)

• Dimensioned drawing, rigid backing at right; also LayeredAbsorberResult.plot_geometry() and layer.plot()
LayeredAbsorberResultdataclassOblique-incidence prediction.
• surface_impedance Zs, normalized_impedance
• reflection R(θ), absorption α(θ)
• transfer_matrix: (2, 2, n) chain matrix (det = 1)
• .plot(): α(f) with |R| overlaid
res.absorption, res.surface_impedance
diffuse_field_absorptionfunctionRandom-incidence (Paris) absorption (Mechel D.5 Eq. 9).
• frequency, layers, termination as layered_absorber
• angle_limit_rad [rad] (Default: π/2; 75°–87° truncations in use)
• quadrature_points (Default: 64, Gauss–Legendre)
dif = materials.diffuse_field_absorption(f, layers)

• DiffuseFieldAbsorptionResult
DiffuseFieldAbsorptionResultdataclassParis-integral result.
• absorption: α_dif(f)
• angle_limit_rad [rad]
• .plot()
dif.absorption
statistical_absorptionfunctionClosed-form Paris integral, locally reacting plane (Mechel D.5 Eq. 10).
• normalized_impedance z = Zs/(ρc) (Re z > 0)
• angle_limit_rad [rad] (Default: π/2)
• Maximum over passive z is the published 0.951
statistical_absorption(1.567 + 0j) # 0.951
AirLayerdataclassPlain air gap.
• thickness d [m] (0 allowed → transparent)
AirLayer(0.05)
PorousLayerdataclassPorous layer.
• thickness d [m]
• medium: PorousMediumResult on the solver frequency grid
PorousLayer(0.05, med)
PoroelasticLayerdataclassPorous layer with an elastic frame (full Biot theory).
• thickness d [m]
• medium: the rigid-frame PorousMediumResult on the solver grid
• porosity φ, tortuosity α∞, frame_density ρ₁ [kg/m³]
• shear_modulus N [Pa] (complex), poisson_ratio ν (Default: 0)
• Switches layered_absorber to the global-matrix assembly; transfer_matrix is then NaN
PoroelasticLayer(0.05, med, 0.94, 1.06, 130.0, 2.2e6*(1+0.1j))
PerforatedPlateLayerdataclassRigid perforated plate.
• thickness t, hole_radius a [m]
• open_area ε (0–1)
• end_correction δ per end (Default: None → Fok/Nesterov of ε)
PerforatedPlateLayer(0.006, 0.0025, 0.05)
MicroperforatedPlateLayerdataclassMaa microperforated plate.
• thickness t, hole_radius a [m] (submillimetre)
• open_area ε
• end_correction δ (Default: 0.85)
MicroperforatedPlateLayer(0.0002, 0.0001, 0.005)
MembraneLayerdataclassLimp impervious membrane.
• surface_density m [kg/m²]
• resistance r [Pa·s/m] (Default: 0)
MembraneLayer(5.0)
perforated_plate_impedancefunctionPerforated-plate transfer impedance (Cox & D'Antonio Eqs. 7.6/7.12).
• frequency, thickness, hole_radius, open_area, end_correction
• fluid: Fluid (Default: PUBLISHED_AIR)
z = materials.perforated_plate_impedance(f, thickness=0.006, hole_radius=0.0025, open_area=0.05)

• complex [Pa·s/m]
microperforated_plate_impedancefunctionMaa's exact MPP impedance (Cox & D'Antonio Eqs. 7.33–7.35).
• frequency, thickness, hole_radius, open_area
• end_correction δ (Default: 0.85)
• Bessel circular-capillary kernel
z = materials.microperforated_plate_impedance(f, thickness=0.0002, hole_radius=0.0001, open_area=0.005)

• complex [Pa·s/m]
membrane_impedancefunctionMembrane transfer impedance r + jωm (Cox Eq. 7.14; Bies Eq. D.96).
• frequency, surface_density m [kg/m²]
• resistance r (Default: 0)
z = materials.membrane_impedance(f, surface_density=5.0)

• complex [Pa·s/m]
perforation_end_correctionfunctionEnd-correction factor δ(ε) = 0.85(1 − 1.47√ε + 0.47ε^1.5) (Cox Table 7.1).
• open_area ε
perforation_end_correction(0.05) # 0.575

• per orifice end
helmholtz_resonance_frequencyfunctionShallow-cavity perforate resonance (Cox Eq. 7.4).
• cavity_depth d, plate_thickness t, hole_radius a [m]
• open_area ε, end_correction δ
• speed_of_sound
helmholtz_resonance_frequency(cavity_depth=0.025, plate_thickness=0.006, hole_radius=0.0025, open_area=0.05)

• f0 = (c/2π)√(ε/(t′d)) [Hz]
membrane_resonance_frequencyfunctionMembrane mass-spring resonance (Cox Eqs. 7.9/7.10).
• surface_density m [kg/m²], cavity_depth d [m]
• isothermal (Default: False)
• fluid: Fluid; the isothermal spring divides by the fluid's own ratio of specific heats (Default: PUBLISHED_AIR)
membrane_resonance_frequency(surface_density=5.0, cavity_depth=0.05) # ≈120

• ≈ 60/√(md) (50/√(md) isothermal) [Hz]
PorousAbsorberWarningwarning classPorous-model advisory.
Emitted when the Delany–Bazley / Miki regressions are evaluated outside their published fit range; values are still returned
warnings.simplefilter('error', PorousAbsorberWarning)
slit_helmholtz_absorberfunctionSlit panel loaded with Helmholtz resonators (Jiménez et al. Appl. Sci. 2017).
• frequency f [Hz], resonators: one/many HelmholtzResonator
• slit_height h, lattice_step a, period_m d [m]
• angle_rad θ [rad] (Default: 0)
• end_correction, slit_radiation (Default: True)
• visco-thermal slit + square-duct losses
res = materials.slit_helmholtz_absorber(f, hr, slit_height=1e-3, lattice_step=3e-2, period_m=5e-2)

• SlitResonatorAbsorberResult
plot_slit_absorber_geometryfunctionTo-scale cross-section of one period_m of the slit panel.
• resonators (one per lattice step)
• slit_height h, lattice_step a, period_m d [m]
• language
plot_slit_absorber_geometry([hr], slit_height=1e-3, lattice_step=0.03, period_m=0.05)

• Also SlitResonatorAbsorberResult.plot_geometry()
plot_helmholtz_resonator_geometryfunctionTo-scale cross-section of a square-section Helmholtz resonator.
• resonator: HelmholtzResonator
• language
plot_helmholtz_resonator_geometry(hr)

• Also HelmholtzResonator.plot()
SlitResonatorAbsorberResultdataclassSlow-sound panel prediction.
• surface_impedance Z = T11/T21, normalized_impedance
• reflection R(θ), absorption α = 1 − |R|²
• effective_wavenumber, effective_impedance
• transfer_matrix: (2, 2, n)
• .plot(): α(f) with |R| overlaid
res.absorption, res.plot()
critical_coupling_designfunctionSolve geometry for perfect absorption at a frequency (critical coupling, Eq. 9).
• target_frequency f0 [Hz], base resonator
• lattice_step a, period_m d [m], angle_rad θ
• tunes cavity length + slit height so the reflection zero is real
• warns if α does not reach ≈1
d = materials.critical_coupling_design(300.0, hr, lattice_step=3e-2, period_m=5e-2)

• CriticalCouplingResult
CriticalCouplingResultdataclassPerfect-absorption design outcome.
• resonator, slit_height: solved geometry
• absorption (≈1), normalized_impedance (≈1)
• converged, target_frequency, angle_rad
d.resonator, d.slit_height, d.absorption
HelmholtzResonatordataclassSquare-cross-section Helmholtz resonator.
• neck_length l_n, neck_side w_n [m]
• cavity_length l_c, cavity_side w_c [m]
HelmholtzResonator(1e-3, 3e-3, 30e-3, 27e-3)
helmholtz_resonator_impedancefunctionResonator acoustic impedance Z_HR with visco-thermal losses (Jiménez et al. APL 2016 Eq. A23).
• frequency, resonator
• slit_height, lattice_step for neck→slit end correction
• end_correction (Default: True)
z = materials.helmholtz_resonator_impedance(f, hr)

• complex [Pa·s/m³]
slit_effective_propertiesfunctionNarrow-slit visco-thermal ρ_s, κ_s (Stinson 1991; Eq. 6).
• frequency, slit_height h [m]
• fluid: Fluid (Default: PUBLISHED_AIR)
• limit jωρ_s → 12η/h² as ω → 0
rho_s, kap_s = materials.slit_effective_properties(f, slit_height=1.2e-3)
rectangular_duct_propertiesfunctionSquare-duct visco-thermal ρ, κ (Stinson 1991; Eqs. 7–8).
• frequency, side [m]
• sum_terms (Default: 40)
• limit jωρ → 28.454η/side² as ω → 0
rho, kap = materials.rectangular_duct_properties(f, side=3e-3)
SlowSoundAbsorberWarningwarning classSlow-sound absorber advisory.
Emitted when critical_coupling_design cannot reach perfect absorption within tolerance
warnings.simplefilter('error', SlowSoundAbsorberWarning)
AirflowResistanceWarningwarning classISO 9053 advisory.
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_coefficientfunctionPractical coefficients αp (ISO 11654 §4.1).
• third_octave_alpha_s: 15 one-third-octave αs, 200–5000 Hz (sequence or mapping keyed by band)
ap = materials.practical_absorption_coefficient(alpha_s)

• 5 octave values (250–4000 Hz), 0.05 steps, capped at 1.00
weighted_absorptionfunctionWeighted absorption αw + class (ISO 11654 §4.2).
• alpha_p: the 5 octave practical coefficients
w = materials.weighted_absorption([0.25, 0.7, 0.95, 1.0, 0.85])

• AbsorptionRatingResult (αw = 0.55, class D, 'MH')
weighted_absorption_from_third_octavefunctionαw from 15 one-third-octave αs, retaining them for the fiche (ISO 11654 §4.1–4.2).
• third_octave_alpha_s: 15 αs, 200–5000 Hz (sequence or mapping keyed by band)
w = materials.weighted_absorption_from_third_octave(alpha_s)

• AbsorptionRatingResult carrying third_octave_alpha_s / third_octave_bands
absorption_classfunctionSound absorption class (Table B.1).
• alpha_w: multiple of 0.05 in [0, 1]
absorption_class(0.7) # 'C'

• 'A'–'E' or 'Not classified'
AbsorptionRatingResultdataclassαw rating result.
• alpha_w: shifted curve read at 500 Hz
• shape_indicator: 'L'/'M'/'H' concatenation or ''
• absorption_class: 'A'–'E'/'Not classified'
• shift, unfavourable_sum (≤ 0.10)
• band_centers [Hz], measured, shifted_reference
• .plot()
w.alpha_w, w.absorption_class
OCTAVE_BANDStupleISO 11654 octave rating bands [Hz].
(250, 500, 1000, 2000, 4000)
OCTAVE_BANDS # (250, ..., 4000)
THIRD_OCTAVE_BANDStupleISO 11654 one-third-octave input bands [Hz].
200 Hz to 5000 Hz (15 bands)
THIRD_OCTAVE_BANDS[0] # 200
REFERENCE_CURVEmappingISO 11654 Figure 1 reference curve (read-only).
Keyed by octave band [Hz] → coefficient
REFERENCE_CURVE[250] # 0.8
check_ceiling_specimen / CeilingSpecimenCheck / TARGET_SPECIMEN_AREA_M2 / TEST_OBJECT_SIZE_M / TYPE_E_DEPTH_MM / MAX_DEFLECTION_MMfunction / dataclass / constantThe test arrangement EN 16487 fixes, clause 4.
• 10,80 m² of specimen, laid out in 0,6 m by 0,6 m objects, so a laboratory's own room does not change the answer
• mounting type E hangs it 200 mm below the ceiling; the panels may sag no more than 5 mm
• support_width_mm, support_height_mm, support_centre_distance_m: the support units of 4.1.1.2.3.6; relative_humidity_percent: one value per measurement, each held to the 50 % of 4.2.2
• check: deflection_ok, substructure_ok, fixture_ok, supports_ok, humidity_ok (None without a humidity) and satisfied over them; area_error_m2 and ce_marking_depth reported and not judged, since the area is a target and the 200 mm is the CE marking depth
materials.check_ceiling_specimen(area_m2=10.8, mounting="E", depth_mm=200.0)
mounting_type / MOUNTING_TYPES / SUBSTRUCTURE_LIMITS_MM / SUBSTRUCTURE_SPACING_M / SUPPORT_SECTION_MM / MIN_SUPPORT_SPACING_M / MIN_FIXTURE_DENSITY_KG_M2 / MIN_ROOM_EDGE_ANGLE_DEGfunction / mapping / constantHow the specimen hangs, and on what.
• the four mountings of EN ISO 354 Annex B this code uses: A against a hard surface, B glued with a 3 mm space, E suspended, J a discrete absorber
• the exposed substructure at most 30 mm wide and 50 mm deep, on a 0,6 m grid, hung from 50 mm by 50 mm supports at least 1,2 m apart, the section and centre distance of which check_ceiling_specimen judges
• a fixture counts as part of the specimen from 20 kg/m², and the specimen edges sit at least 10° off the room's own; the grid and the angle are targets and not judged
materials.mounting_type("E")
air_absorption_correction / AIR_CORRECTION_LIMIT / MIN_RELATIVE_HUMIDITY_PERCENTfunction / constantWhat the air in the room absorbs, 4.2.1.
• 4V(m₂ − m₁)/S, as an absorption coefficient, from the attenuation with and without the specimen
• over 0,05 the result is not reported: the air is doing too much of the absorbing to attribute it to the ceiling
• the room is held at 50 % relative humidity or more, which is what keeps that term small at 4 kHz; check_ceiling_specimen(relative_humidity_percent=...) judges it for each measurement
materials.air_absorption_correction(volume_m3=200.0, specimen_area_m2=10.8, attenuation_with=m2, attenuation_empty=m1)
reproducibility_uncertainty / CEILING_UNCERTAINTY / WEIGHTED_UNCERTAINTY / EN16487_COVERAGE_FACTORfunction / mapping / constantWhat two laboratories will differ by, Table 1.
• the reproducibility standard deviation band by band: 0,23 at 125 Hz and 250 Hz, then 0,11, 0,10, 0,10 and 0,13 up to 4 kHz
• 0,08 for the weighted single number α_w
• expanded with k = 2,8, which is the factor the standard prints rather than the usual 2
materials.reproducibility_uncertainty() # one per octave band
SuspendedCeilingWarningwarning classThe test arrangement is outside a condition EN 16487 states.
• a deflection over 5 mm, a substructure over 30 mm by 50 mm, a fixture under 20 kg/m², a type E plenum that is not 200 mm, an air correction over 0,05
• the specimen area is not one of them: 4.1.1.1.1 asks for "as close to 10,80 m² as possible", which is a target rather than a tolerance, so the check reports the difference and leaves the judgement to the laboratory
warnings.simplefilter('error', SuspendedCeilingWarning)
Emitted by materials.absorbers.suspended_ceilings
speed_of_sound_iso17497functionSpeed of sound (ISO 17497-1 Eq. 2).
• temperature_c t [°C]
speed_of_sound_iso17497(temperature_c=20.0) # 343.2

• 343.2 √((273.15 + t)/293.15) [m/s]
air_attenuation_coefficientfunctionEnergy attenuation m from ISO 9613-1 α (ISO 17497-1 Eq. 3).
• pressure_attenuation_db_per_m: α [dB/m]
air_attenuation_coefficient(0.005) # 0.00115

• m ≈ α/4.343 [1/m]
random_incidence_absorptionfunctionRandom-incidence absorption αs (ISO 17497-1 Eq. 1).
• volume V [m³], area S [m²]
• c1/T1: static base plate, no sample
• c2/T2: with the test sample
• m1/m2: air attenuation [1/m] (Default: 0)
a_s = materials.random_incidence_absorption(200.0, 10.8, c1=343.0, t1=2.5, c2=343.2, t2=1.8) # 0.463
specular_absorption_coefficientfunctionSpecular absorption αspec (Eq. 4).
• volume, area
• c3/T3: rotating base plate, no sample
• c4/T4: sample on the rotating turntable
• m3/m4 (Default: 0)
a_spec = materials.specular_absorption_coefficient(200.0, 10.8, c3=c3, t3=t3, c4=c4, t4=t4)

• Includes the energy lost to scattering
scattering_coefficientfunctionRandom-incidence scattering coefficient s (Eq. 5).
• alpha_spec, alpha_s
• truncate_negative: clip s < 0 to 0 (Default: True); s > 1 is kept
scattering_coefficient(0.45, 0.30) # 0.214

• s = (αspec − αs)/(1 − αs)
scattering_coefficient_spectrumfunctionScattering spectrum s(f) (Eq. 5).
• frequencies: one-third-octave centres [Hz]
• specular_absorption, random_absorption: per band
• truncate_negative (Default: True)
res = materials.scattering_coefficient_spectrum(f, a_spec, a_s)

• ScatteringResult
ScatteringResultdataclassScattering spectrum result.
• frequencies [Hz]
• scattering: s per band
• random_incidence: αs, specular: αspec
• .plot()
res.scattering
base_plate_scatteringfunctionScattering of the base plate alone (Eq. 6).
• volume, area
• c1/T1: static, c3/T3: rotating
• m1/m3 (Default: 0)
s_base = materials.base_plate_scattering(200.0, 10.8, c1=c1, t1=t1, c3=c3, t3=t3)

• Quality metric vs Table 1
check_base_plate_scatteringfunctionVerify the base plate against Table 1 (Clause 6.2).
• scattering: mapping by band [Hz] or 18 values ordered as BASE_PLATE_BANDS
check_base_plate_scattering(s_base) # ()

• Offending band centres; ScatteringDiffusionWarning if any
BASE_PLATE_BANDStupleISO 17497-1 base-plate check bands [Hz].
100 Hz to 5000 Hz (18 one-third octaves)
BASE_PLATE_BANDS[0] # 100
BASE_PLATE_MAX_SCATTERINGmappingTable 1 base-plate scattering limits (read-only).
Keyed by band [Hz] → maximum s
BASE_PLATE_MAX_SCATTERING[500] # 0.05
reverberation_time_uncertaintyfunctionStandard uncertainty of a mean T (ISO 17497-1 Eq. A.1).
• times: N ≥ 2 spatially-averaged measurements [s]
reverberation_time_uncertainty([2.31, 2.28, 2.35]) # 0.0203

• Standard error of the mean [s]
absorption_coefficient_uncertaintyfunctionUncertainty of a Sabine coefficient (Eqs. A.3/A.4).
• volume, area
• speed_of_sound [m/s]
• T_a/u_a, T_b/u_b: the two situations [s]
u_alpha = materials.absorption_coefficient_uncertainty(200.0, 10.8, speed_of_sound=343.2, t_a=2.5, u_a=0.02, t_b=1.8, u_b=0.02)
scattering_coefficient_uncertaintyfunctionUncertainty of the scattering coefficient (Eq. A.5).
• alpha_spec, alpha_s
• u_alpha_spec, u_alpha_s
u = materials.scattering_coefficient_uncertainty(0.45, 0.30, 0.02, 0.02)

• ScatteringUncertainty (U = 2u, 95 %)
ScatteringUncertaintydataclassScattering uncertainty result.
• u_scattering: combined standard u_s
• expanded: U = 2u_s
u.u_scattering, u.expanded
PUBLISHED_SCATTERINGmappingForty-six measured surfaces from a published table, keyed '<table>/<row>'.
• Cox & D'Antonio 3e Appendix D, nine groups from sinusoidal corrugation and battens through blocks, pyramids and grooves to hemispheres and vegetation
• measured at full or model scale according to ISO 17497-1, and credited row by row to the seven papers the appendix lists; the book says nothing else about them
• the only one of the book's four appendices whose numbers were measured rather than computed
• how wide the method is: the same battens read 0.28 and 0.44 at 630 Hz in two papers, and one cell of the table is 1.17
• the transcription was made twice, from the rendered pages, by readers who never saw each other's work
row = materials.PUBLISHED_SCATTERING['cox-2017-appendix-d/pyramids_h_30_5_cm_l_b_h']
row.spectrum()[2000] # 0.58

• ScatteringCoefficientSpectrum, scattering_named
ScatteringCoefficientSpectrumdataclassOne surface of a published table, with its scattering coefficient in each one-third octave band.
• scattering_coefficient_100 … scattering_coefficient_5000, dimensionless, None where the page prints a dash or nothing
• .bands(), .spectrum() → {band_hz: s}, .scattering_coefficient(band_hz) narrows or refuses, naming the row and the band
• the geometry is in name as the page prints it and the family is in group, because 'h = w = 10 cm, L = 2h' means nothing on its own
row.scattering_coefficient(5000) # ValueError: the page prints a dash there

• PUBLISHED_SCATTERING
SCATTERING_BANDS_HZconstantThe one-third octave bands a published scattering table can print: 100 Hz to 5 kHz.
• (100, 125, 160, ..., 4000, 5000), eighteen of them; twenty of Cox's rows stop at 4 kHz and ten print a dash there
materials.SCATTERING_BANDS_HZ[-1] # 5000
scattering_namedfunctionEvery published surface whose description or group heading contains a fragment.
• name: matched without case against both, because the useful word is usually in the heading
• 'pyramid' answers with four rows, two of which the page describes identically
len(materials.scattering_named('vegetation')) # 6

• PUBLISHED_SCATTERING
PUBLISHED_DIFFUSIONmappingTwenty-nine surfaces at three angles each, from a published table, keyed '<table>/<row>'.
• Cox & D'Antonio 3e Appendix B, seven sections from periodicity and depth through triangles and semiellipses to Schroeder diffusers
• normalized diffusion coefficients of ISO 17497-2, computed with a 2D boundary element model and not measured, which is the difference between this table and PUBLISHED_SCATTERING
• the page prints three lines per surface, headed 0, 57 and Random, so a surface is three rows and variant says which
• what an array does that one device does not: one semicylinder is 0.77 at 1 kHz at random incidence and twelve of it are 0.22
• the transcription was made twice, from the rendered pages, by readers who never saw each other's work
row = materials.PUBLISHED_DIFFUSION['cox-2017-appendix-b/2_30_cm_deep_semicylinders_random']
row.spectrum()[5000] # 0.65

• NormalizedDiffusionSpectrum, diffusion_named
NormalizedDiffusionSpectrumdataclassOne surface at one angle of incidence, with its coefficient in each one-third octave band.
• diffusion_coefficient_100 … diffusion_coefficient_5000, dimensionless; this appendix fills every cell
• angle_of_incidence_deg: 0 or 57, and None on a random incidence row, which is a mean over ten angles and is none of them
• .bands(), .spectrum() → {band_hz: d}, .diffusion_coefficient(band_hz) narrows or refuses
• group carries the numbered section heading, which is where the geometry a row is short for is printed
row.why_missing('angle_of_incidence_deg') # the page prints "Random" there

• PUBLISHED_DIFFUSION
DIFFUSION_BANDS_HZconstantThe one-third octave bands a published diffusion coefficient table can print: 100 Hz to 5 kHz.
• (100, 125, 160, ..., 4000, 5000), the same eighteen the scattering tables use, and Cox's appendix fills all of them on all eighty-seven rows
materials.DIFFUSION_BANDS_HZ[0] # 100
diffusion_namedfunctionEvery published surface whose description or section heading contains a fragment.
• name: matched without case against both, because the geometry is in the heading
• a surface answers with its three angles, so '12 periods, 7.32 m wide' gives three rows
[r.variant for r in materials.diffusion_named('12 periods, 7.32 m wide')]
# ['normal', '57 degrees', 'random']

• PUBLISHED_DIFFUSION
PUBLISHED_PREDICTED_SCATTERINGmappingA hundred and nineteen rows of computed scattering, keyed '<table>/<row>'.
• Cox & D'Antonio 3e Tables C.1, C.2 and C.3: two three-dimensional predictions at normal and random incidence over 250 Hz to 4 kHz, and one two-dimensional one over 100 Hz to 5 kHz at 0, 56.9 and random incidence
• kept apart from PUBLISHED_SCATTERING, which is measured, so that a solver's number and a reverberation room's cannot be mixed unnoticed; no key is shared and the classes differ
• the two three-dimensional tables are credited to Lee and Sakuma (2015), which the appendix prints as a source line under each
• the book's own warnings about the coefficient, which reads absorption as scattering and redirection as dispersion, are in the about of each table
row = materials.PUBLISHED_PREDICTED_SCATTERING['cox-2017-table-c1/sinusoidal_cross_section_h_4_cm_l_20_cm']
row.model # 'three-dimensional boundary element prediction'

• PredictedScatteringSpectrum, predicted_scattering_named
PredictedScatteringSpectrumdataclassOne predicted surface at one angle, with its coefficient in each one-third octave band.
• scattering_coefficient_100 … scattering_coefficient_5000, dimensionless; the three-dimensional tables leave the four lowest empty and say why
• angle_of_incidence_deg: 0 or 56.9, and None where the page prints a word, "Random" or "All/any", which why_missing tells apart
• model: the solver behind the row, which is what separates these from the measured ones
• .bands(), .spectrum(), .scattering_coefficient(band_hz)
row.scattering_coefficient(100) # ValueError: the page has nothing there

• PUBLISHED_PREDICTED_SCATTERING
predicted_scattering_namedfunctionEvery predicted surface whose description or heading contains a fragment.
• name: matched without case against both, because the topology is in the heading
• 'batten' answers with sixteen rows across two tables
len(materials.predicted_scattering_named('sinusoidal cross-section')) # 12

• PUBLISHED_PREDICTED_SCATTERING
directional_diffusion_coefficientfunctionDirectional diffusion coefficient d_θ (ISO 17497-2 Formulas 5/6).
• levels: n ≥ 2 reflected SPL [dB] (−inf = zero energy)
• area_weights: Ni (Formula 8) (Default: None → equal-area Formula 5)
directional_diffusion_coefficient([-10., -12., -15., -11., -13.]) # 0.854
directional_diffusionfunctionPolar response + its coefficient.
• angles_deg [°], levels [dB]
• weights: Ni (Default: None)
res = materials.directional_diffusion(angles_deg, levels)

• DiffusionResult
plot_goniometer_geometryfunctionFree-field diffusion goniometer in plan, to scale.
• source_distance (Default: 10 m), receiver_radius (Default: 5 m)
• angular_step (Default: 5°, 37 microphones)
• sample_width [m] (Default: 0.6)
• language
plot_goniometer_geometry()
DiffusionResultdataclassPolar diffusion result.
• angles_deg [°], levels [dB]
• coefficient: d_θ (autocorrelation)
• .plot(), .report()
res.coefficient
diffusion_spectrumfunctionDiffusion spectrum d(f) (ISO 17497-2 Clause 8.5).
• frequencies: one-third-octave centres [Hz]
• diffusion: d per band (directional, or random-incidence via Clause 8.4)
• normalized: d_n per band (Default: None)
res = materials.diffusion_spectrum(f, d, normalized=d_n)

• DiffusionSpectrum
DiffusionSpectrumdataclassDiffusion spectrum result.
• frequencies [Hz]
• diffusion: d per band
• normalized: d_n per band or None
• .plot(), .report()
res.diffusion
normalized_diffusion_coefficientfunctionNormalised coefficient d_θ,n (Formula 7).
• d_theta: test surface
• d_theta_reference: flat reference
normalized_diffusion_coefficient(0.6, 0.2) # 0.5

• (d − d_r)/(1 − d_r)
area_factorsfunctionPer-receiver area weights Ni (Clause 8.3 Formula 8).
• elevations: θ [°], 0–90
• delta_theta [°]
• delta_phi [°] (Default: None → delta_theta)
n_i = materials.area_factors([0, 15, 30, 45, 60, 75, 90], delta_theta=15.0)

• Dimensionless, min 1
random_incidence_diffusionfunctionRandom-incidence diffusion coefficient d (Clause 8.4).
• directional_coefficients: d_θ per source
• weights: source weights (Default: None → equal; 2-D uses TWO_DIMENSIONAL_SOURCE_WEIGHTS)
d = materials.random_incidence_diffusion(d_thetas, weights=TWO_DIMENSIONAL_SOURCE_WEIGHTS)
TWO_DIMENSIONAL_SOURCE_WEIGHTStupleISO 17497-2 single-plane source weights.
(1, 3, 3, 3, 3) for 0°, ±30°, ±60°
TWO_DIMENSIONAL_SOURCE_WEIGHTS
ScatteringDiffusionWarningwarning classISO 17497 advisory.
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_sequencefunctionQuadratic residue sequence s_n (Cox & D'Antonio Eq. 10.2).
• prime: odd prime generator N
quadratic_residue_sequence(7) # [0 1 4 2 2 4 1]

• s_n = n² mod N
qrd_well_depthsfunctionQRD well depths d_n (Cox & D'Antonio Eq. 10.3).
• prime: generator N
• design_frequency f0 [Hz]
• speed_of_sound c [m/s] (Default: 343)
qrd_well_depths(7, 500.0) # d_max 0.196 m

• d_n = s_n λ0/(2N)
plot_qrd_geometryfunctionTo-scale QRD well profile.
• depths d_n [m], well_width w [m]
• repetitions (Default: 1), fin_width [m] (Default: w/12)
• language
plot_qrd_geometry(materials.qrd_well_depths(7, 500.0), 0.12, repetitions=2)

• Also DiffuserPolarResponse.plot_geometry()
MetadiffuserWelldataclassOne slit of a metadiffuser panel (Jiménez et al. Sci. Rep. 2017).
• slit_height h [m]
• resonators: tuple of HelmholtzResonator, face to backing
• None in a well sequence = flat rigid strip (R = 1)
MetadiffuserWell(14.7e-3, (hr, hr))

• lattice a = L/M
metadiffuser_reflectionfunctionPer-well reflection spectra R_n(f) of a metadiffuser.
• frequency f [Hz], wells: MetadiffuserWell/None sequence
• depth L, period_m d [m]; angle_deg θ [rad] (Default: 0)
• resonator_geometry "slit"/"square" (Default: slit)
• 2-D visco-thermal TMM per slit
panel = materials.metadiffuser_reflection(f, wells, depth=0.02, period_m=0.07)

• MetadiffuserResult
MetadiffuserResultdataclassMetadiffuser spectra, one reflection row per well.
• reflection (N, F), well_absorption (N, F)
• absorption: face average 1 − mean|R_n|²
• retains wells/depth/period_m
panel.plot(); panel.plot_geometry()

• .plot() α per well; .plot_geometry() panel section
metadiffuser_polar_responsefunctionFar-field polar response of a metadiffuser at one frequency.
• frequency f [Hz], wells, depth L, period_m d [m]
• angles_deg [°], source_angle_deg ψ [°], repetitions (Default: 1)
• Fraunhofer of R_n(f), no obliquity factor (Sci. Rep. Eq. (1))
pol = materials.metadiffuser_polar_response(2000.0, wells, depth=0.02, period_m=0.07, repetitions=6)

• DiffuserPolarResponse
metadiffuser_diffusion_spectrumfunctionNormalized diffusion spectrum d_n(f) of a metadiffuser.
• frequencies [Hz], wells, depth L, period_m d [m]
• normalised against the same-footprint flat panel
• ISO 17497-2 directional coefficient per band
metadiffuser_diffusion_spectrum(f, wells, depth=0.02, period_m=0.07)

• DiffusionSpectrum
plot_metadiffuser_panel_geometryfunctionTo-scale metadiffuser panel cross-section.
• wells, depth L, period_m d [m]
• numbered slits, resonators shelved into the septum
• language
plot_metadiffuser_panel_geometry(wells, depth=0.02, period_m=0.07)

• Also MetadiffuserResult.plot_geometry()
predict_diffuser_polar_responsefunctionPredicted far-field polar response (Cox & D'Antonio Eq. 5.8).
• well_width w [m], frequency f [Hz]
• depths d_n [m] or reflection R_n (exactly one)
• angles_deg [°] (Default: semicircle), source_angle_deg ψ [°]
• repetitions Np (Default: 1)
s = materials.predict_diffuser_polar_response(0.10, 2000.0, depths=d, repetitions=5)

• DiffuserPolarResponse
predicted_diffusion_spectrumfunctionPredicted diffusion spectrum d(f) of a design.
• well_width [m], frequencies [Hz]
• depths d_n [m]
• repetitions (Default: 1)
• normalize: also d_n vs flat reference (Default: True)
res = materials.predicted_diffusion_spectrum(0.10, f, depths=d, repetitions=5)

• DiffusionSpectrum
DiffuserPolarResponsedataclassPredicted diffuser polar response.
• frequency [Hz]
• angles_deg [°], levels [dB] (peak at 0)
• coefficient: d_θ
• .plot()
s.coefficient
DEFAULT_POLAR_ANGLEStupleISO 17497-2 single-plane receiver angles.
−90° to 90° in 5° steps (37 receivers)
DEFAULT_POLAR_ANGLES[0] # -90
adrienne_windowfunctionAdrienne temporal window (ISO 13472-1 Clause 6.4).
• fs [Hz]
• flat_duration [s] (Default: 0.005)
• leading_duration [s] (Default: 0.0005), trailing_duration [s] (Default: 0.005)
• leading_edge/trailing_edge: 'blackman-harris' or 'cosine-squared'
w = materials.adrienne_window(48000)

• Rising edge + flat top + falling edge, peak 1.0
geometric_spreading_factorfunctionGeometrical-spreading factor Kr (Clause 4.1).
• source_height ds [m] (Default: 1.25)
• mic_height dm [m] (Default: 0.25)
geometric_spreading_factor() # 0.6667

• Kr = (ds − dm)/(ds + dm)
geometric_spreading_factor_anglefunctionOblique factor Kr,θ (Annex F).
• incidence_angle_rad θ [rad]
• source_height, mic_height
geometric_spreading_factor_angle(np.pi/6) # 0.764
reflected_path_delayfunctionReflected-path delay Δτ = 2dm/c (Annex C).
• mic_height dm [m] (Default: 0.25)
• speed_of_sound c [m/s] (Default: 340.0)
reflected_path_delay() # 0.001471

• [s]
insitu_reflection_factorfunctionComplex reflection factor r(f) (ISO 13472-1 Clause 4.1).
• incident_ir / reflected_ir: windowed impulse responses
• source_height, mic_height [m]
• incidence_angle_rad [rad] (Default: 0)
• fs + delay: undo the reflected-path offset (Default: None)
• n: FFT length
r = materials.insitu_reflection_factor(hi, hr, fs=48000, delay=dtau)

• (1/Kr)·Hr(f)/Hi(f) at the rfft bins
insitu_absorption_from_reflectionfunctionα from the reflection factor (Clause 4.1).
• reflection: complex r
alpha = materials.insitu_absorption_from_reflection(r)

• α = 1 − |r|²
power_reflection_coefficientfunctionPower reflection factor QW(f), direct energy route.
• incident_ir, reflected_ir
• source_height, mic_height, incidence_angle_rad, n
qw = materials.power_reflection_coefficient(hi, hr)

• (1/Kr²)|Hr/Hi|², offset-independent
insitu_absorption_coefficientfunctionNarrow-band absorption α(f) (Clause 4.1).
• Same parameters as power_reflection_coefficient
alpha = materials.insitu_absorption_coefficient(hi, hr)

• α = 1 − QW(f)
one_third_octave_absorptionfunctionAggregate narrow-band α into one-third octaves.
• frequency [Hz], absorption
• f_min (Default: 250), f_max (Default: 4000; 1600 for Part 2) [Hz]
• clip_negative (Default: True)
fc, ab = materials.one_third_octave_absorption(f, alpha)

• Band centres + linear-averaged α (nan if empty)
insitu_absorption_spectrumfunctionEnd-to-end in-situ spectrum (ISO 13472-1).
• incident_ir, reflected_ir, fs [Hz]
• geometry + incidence_angle_rad
• f_min/f_max [Hz], clip_negative
res = materials.insitu_absorption_spectrum(hi, hr, 48000)

• InsituAbsorptionResult
plot_insitu_geometryfunctionIn-situ absorption set-up to scale.
• source_height (Default: 1.25 m), mic_height (Default: 0.25 m)
• sampled_radius (Default: 1.34 m)
• language
plot_insitu_geometry()

• Also InsituAbsorptionResult.plot_geometry()
InsituAbsorptionResultdataclassIn-situ absorption spectrum.
• frequencies: one-third-octave centres [Hz]
• absorption: α per band (nan when empty)
• .plot()
res.absorption
absorption_reference_correctedfunctionReference-corrected road absorption (Annex B).
• road_reflection / reference_reflection: measured Qp (complex, same geometry)
alpha = materials.absorption_reference_corrected(q_road, q_ref)

• 1 − |Qp,road/Qp,ref|²; removes chain error and Kr
max_sampled_area_radiusfunctionMaximum sampled-area radius (Annex A).
• window_width Tw [s]
• source_height, mic_height, speed_of_sound
max_sampled_area_radius(0.005) # 1.34

• [m], the Annex A worked example
msa_major_axisfunctionMajor axis of the oblique sampled ellipsoid (Annex F).
• window_width Tw [s]
• projected_distance dp [m]
• source_height, mic_height, speed_of_sound
msa_major_axis(0.005, 0.0) # 3.2

• a = cTw + √((ds + dm)² + dp²) [m]
spot_tube_upper_frequencyfunctionSpot-tube upper frequency (ISO 13472-2 §5.4.1).
• diameter_m d [m]
• speed_of_sound (Default: 340.0)
spot_tube_upper_frequency(0.1) # 1972

• f_u = 0.58c0/d [Hz]
spot_microphone_spacing_boundsfunctionSpacing bounds (s_min, s_max) (§5.4.2).
• speed_of_sound (Default: 340.0)
• f_min (Default: 220), f_max (Default: 1800) [Hz]
spot_microphone_spacing_bounds() # (0.0773, 0.085)

• [m], brackets the nominal 81 mm
check_spot_frequency_rangefunctionAdvise outside 250–1600 Hz (ISO 13472-2 Scope).
• frequency [Hz]
check_spot_frequency_range(f)

• RoadAbsorptionWarning out of range
spot_internal_loss_correctionfunctionInternal-loss (system) correction (Annex A).
• measured_absorption, system_absorption: same bands
• clip_negative (Default: True)
spot_internal_loss_correction([0.12, 0.10], [0.02, 0.03]) # [0.1, 0.07]

• Subtractive Part-2 correction
DEFAULT_SOURCE_HEIGHTfloatISO 13472-1 mandatory source height ds [m].
1.25
DEFAULT_SOURCE_HEIGHT # 1.25
DEFAULT_MIC_HEIGHTfloatISO 13472-1 mandatory microphone height dm [m].
0.25
DEFAULT_MIC_HEIGHT # 0.25
DEFAULT_SPEED_OF_SOUNDfloatDefault speed of sound for the road methods [m/s].
340.0
DEFAULT_SPEED_OF_SOUND # 340.0
PART1_FREQUENCY_RANGEtupleISO 13472-1 valid band range [Hz].
(250.0, 4000.0)
PART1_FREQUENCY_RANGE
SPOT_FREQUENCY_RANGEtupleISO 13472-2 valid band range [Hz].
(250.0, 1600.0)
SPOT_FREQUENCY_RANGE
SPOT_NARROW_BAND_RANGEtupleISO 13472-2 narrow-band range [Hz].
(220.0, 1800.0)
SPOT_NARROW_BAND_RANGE
RoadAbsorptionWarningwarning classISO 13472 advisory.
Emitted for frequencies outside the valid in-situ road-absorption ranges; results there are advisory
warnings.simplefilter('error', RoadAbsorptionWarning)
frequency_weightingfunctionVibration frequency weighting H(f) (ISO 8041-1:2017 Formula 5).
• name: one of WEIGHTING_NAMES
• frequencies [Hz] (> 0)
wr = vibration.frequency_weighting('Wk', [1.0, 8.0, 63.0])

• WeightingResponse; |H| = [0.482, 1.036, 0.186]
weighting_factorsfunctionWeighting factors |H(f)| (the Wi of ISO 2631-1 Eq. 9).
• name, frequencies [Hz]
weighting_factors('Wh', [16.0])

• Magnitude per frequency
apply_weightingfunctionApply a weighting to a time signal (frequency domain, exact response).
• signal: acceleration (1D) [m/s²]
• fs [Hz]
• name: one of WEIGHTING_NAMES
aw_t = vibration.apply_weighting(a, fs, name="Wk")

• Weighted signal, same length (circular FFT filtering)
WeightingResponsedataclassWeighting response.
• name
• frequencies [Hz]
• response: complex H
• magnitude, magnitude_db [dB]
• .plot()
wr.magnitude, wr.magnitude_db
WEIGHTING_NAMEStupleISO 8041-1 weighting names.
('Wb', 'Wc', 'Wd', 'We', 'Wf', 'Wh', 'Wj', 'Wk', 'Wm')
'Wk' in WEIGHTING_NAMES # True
weighted_accelerationfunctionWeighted r.m.s. from a band spectrum (ISO 2631-1 Eq. 9 / ISO 5349-1 Eq. A.1).
• band_accelerations: ai per band [m/s²]
• frequencies: band centres [Hz]
• weighting: name
ws = vibration.weighted_acceleration([0.1, 0.3, 0.2], [4.0, 8.0, 16.0], 'Wk')

• WeightedSpectrum; aw = 0.36 m/s²
WeightedSpectrumdataclassWeighted band spectrum.
• frequencies [Hz], band_accelerations [m/s²]
• weighting_name, weighting_factors
• weighted: Wi·ai [m/s²]
• overall: aw [m/s²]
• .plot()
ws.overall
running_rmsfunctionRunning r.m.s. of a weighted signal (ISO 2631-1 Eqs. 2/3).
• signal [m/s²], fs [Hz]
• integration_time τ [s] (Default: 1.0)
• method: 'linear' (Eq. 2) or 'exponential' (Eq. 3) (Default: 'linear')
env = vibration.running_rms(aw_t, fs)

• aw(t0) per sample [m/s²]
mtvvfunctionMaximum transient vibration value (Eq. 4).
• signal [m/s²], fs [Hz]
• integration_time [s] (Default: 1.0)
mtvv(aw_t, fs)

• max aw(t0) [m/s²]
vibration_dose_valuefunctionVibration dose value VDV (Eq. 5).
• signal: weighted acceleration [m/s²]
• fs [Hz]
vdv = vibration.vibration_dose_value(aw_t, fs)

• (∫aw⁴dt)^(1/4) [m/s^1.75]
motion_sickness_dose_valuefunctionMotion sickness dose value MSDV (ISO 2631-1 clause 9).
• signal: Wf-weighted acceleration [m/s²]
• fs [Hz]
msdv = vibration.motion_sickness_dose_value(aw_t, fs)

• (∫aw²dt)^(1/2) [m/s^1.5]
crest_factorfunctionCrest factor of a weighted signal (clause 6.2.1).
• signal [m/s²]
crest_factor(aw_t)

• peak/r.m.s.; HumanVibrationWarning above 9
vibration_total_valuefunctionVibration total value av/ahv (ISO 2631-1 Eq. 10).
• components: axis-weighted r.m.s. [m/s²]
• 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

• √(Σ kj²awj²) [m/s²]
wbv_exposure_basisfunctionWhole-body A(8) basis of Directive 2002/44/EC (Annex Part B).
• a_wx, a_wy: Wd-weighted axis r.m.s. [m/s²]
• a_wz: Wk-weighted axis r.m.s. [m/s²]
wbv_exposure_basis(0.35, 0.28, 0.62) # 0.62

• max(1.4·awx, 1.4·awy, awz) [m/s²], the dominant axis (not the vector total av)
daily_exposurefunctionDaily exposure A(8) for one operation (ISO 5349-1 Eq. 2).
• total_value: ahv (hand-arm) or aw,max (whole-body) [m/s²]
• duration_s: T [s]
daily_exposure(3.0, 4*3600) # 2.12

• ahv √(T/8h) [m/s²]
partial_exposurefunctionPartial exposure Ai(8) of one operation (Eq. 2).
• total_value [m/s²], duration_s [s]
partial_exposure(3.0, 2*3600) # 1.5
combine_partial_exposuresfunctionCombine partial exposures (Eq. 3).
• partials: Ai(8) [m/s²]
combine_partial_exposures([1.5, 2.1]) # 2.58

• √(Σ Ai(8)²) [m/s²]
hav_daily_exposurefunctionA(8) for several operations (ISO 5349-1 Eq. 3).
• total_values: ahvi [m/s²]
• durations_s: Ti [s]
hav_daily_exposure([3.0, 5.0], [2*3600, 3600]) # 2.32
energy_equivalent_accelerationfunctionEnergy-equivalent magnitude aw,e (ISO 2631-1 Eq. B.3).
• magnitudes [m/s²], durations_s [s]
energy_equivalent_acceleration([0.5, 1.0], [3600, 1800]) # 0.707
hav_vwf_lifetime_yearsfunctionYears to 10 % vibration-white-finger prevalence (ISO 5349-1 Eq. C.1).
• a8: A(8) [m/s²] (> 0)
hav_vwf_lifetime_years(2.5) # 12.0

• Dy = 31.8 A(8)^−1.06 [years]
exposure_assessmentfunctionAssess a daily exposure (Directive 2002/44/EC Article 3).
• value: A(8) [m/s²] or VDV [m/s^1.75]
• kind: 'hav'/'wbv'
• metric: 'a8' (Default) or 'vdv' (whole-body only)
ea = vibration.exposure_assessment(3.0, kind='hav')

• ExposureAssessment (zone 'action')
ExposureAssessmentdataclassDirective assessment.
• value, kind, metric
• action_value (EAV), limit_value (ELV)
• exceeds_action, exceeds_limit
• zone: 'below action'/'action'/'limit'
ea.zone, ea.exceeds_limit
daily_vibration_exposurefunctionA(8) from several operations, assessed (ISO 5349 + Directive).
• total_values [m/s²], durations_s [s]
• kind: 'hav'/'wbv'
• labels (Default: None → 'op 1', …)
res = vibration.daily_vibration_exposure([3.0, 5.0], [2*3600, 3600], kind='hav')

• DailyVibrationExposure (A(8) = 2.32)
DailyVibrationExposuredataclassAssessed daily exposure.
• a8 [m/s²]
• labels, total_values, durations_s, partials
• assessment: ExposureAssessment
• .plot()
res.a8, res.assessment.zone
HumanVibrationWarningwarning classHuman-vibration advisory.
Emitted for a crest factor above 9 (ISO 2631-1 6.2.2) or other out-of-range measurement conditions
warnings.simplefilter('error', HumanVibrationWarning)
verify_weighting / WeightingVerificationfunction / dataclassDoes a vibration meter's frequency weighting meet ISO 8041-1 (Tables 4 and 5)?
• name, frequencies [Hz], measured_factors (linear, not dB)
• expanded_uncertainty_percent: the testing laboratory's own U, which extends the measured deviation (13.1 and 14.1); Default None, the bare deviation
• .passes, .deviation_percent, .failing_frequencies_hz, .worst_deviation_percent, .expanded_uncertainty_percent, .plot()
• the weighting only: indication, linearity, overload and the environmental tests are hardware measurements this does not stand in for
vibration.verify_weighting('Wk', [16.0], [0.86]).passes # True (+11.9 %, inside +12 %)
verify_phase_response / PhaseVerificationfunction / dataclassDoes its phase response meet the phase column of ISO 8041-1 Table 5?
• name, frequencies_hz (ascending), measured_phase_deg on the continuous branch Annex B prints
• .characteristic_deviation_deg (Formula (6), one per adjacent pair, attributed to the lower frequency), .deviation_deg, .tolerance_deg, .passes, .peak_deviation_percent, .plot()
• only for a meter reporting a parameter not based on r.m.s. values (Table 5 footnote a)
vibration.verify_phase_response('Wk', [8.0, 10.0, 12.5], phases).passes
characteristic_phase_deviation / peak_deviation_percentfunctionThe two formulae the phase criterion is made of.
• Formula (6): abs((f_n Δφ_{n+1} − f_{n+1} Δφ_n) / (f_{n+1} − f_n)) [degrees], N − 1 values
• Formula (H.4): the peak-value deviation that costs, 0,48 sin Δφ0 × 100 %, an approximation Annex H limits to Δφ0 below 30°
vibration.peak_deviation_percent(12.0) # 9.98 %
NOMINAL_FREQUENCY_RANGE_HZconstantThe nominal frequency range of each weighting (ISO 8041-1 Table 1).
• Wh 8 to 1 000, whole-body 0,5 to 80, Wm 1 to 80, Wf 0,1 to 0,5
• the printed round numbers, not the band centres 10**(k/10) Annex B tabulates at
vibration.NOMINAL_FREQUENCY_RANGE_HZ['Wm'] # (1.0, 80.0)
ISO8041_COVERAGE_FACTOR / MAX_EXPANDED_UNCERTAINTY_PERCENTconstantWhat a testing laboratory's uncertainty is expanded with, and how far it may reach.
• k = 2 (13.1 and 14.1; 12.1 prints "no less than 2"), named for its standard because hearing.COVERAGE_FACTOR is a different one (1,65, ISO 9612)
• the maximum permitted expanded uncertainty per test clause, e.g. 4,5 % for 12.11.2 and 0,01 % for the timing clauses
vibration.MAX_EXPANDED_UNCERTAINTY_PERCENT['12.13'] # 3.0 %
PVEM_MAX_EXPANDED_UNCERTAINTY_PERCENTconstantThe same limits for a personal vibration exposure meter (ISO 8041-2:2021 clauses 12 and 13).
• keyed by the Part 2 clause number: 11 figures over 10 clauses (12.10.2 prints one for the reference range and one for the other ranges), each 12.x figure the one Part 1 prints for the same clause
• 13.9 is Part 2's periodic verification (5 %), not Part 1's one-off indication test (2 %), which is why each part has its own table
vibration.PVEM_MAX_EXPANDED_UNCERTAINTY_PERCENT['12.11.2'] # 4.5 %
weighting_tolerance_percent / phase_tolerance_degreesfunctionThe band ISO 8041-1 Table 5 allows, region by region.
• +12 % / −11 % in the central region, +26 % / −21 % in the skirts, no lower limit in the tails
• the phase band applies only to a meter reporting a parameter not based on r.m.s. values (Table 5 footnote a), which is why it is a separate call
vibration.weighting_tolerance_percent('Wk', [16.0]) # (12.0, -11.0)
TRANSITION_FREQUENCIES_HZ / CENTRAL_TOLERANCE_PERCENT / SKIRT_TOLERANCE_PERCENT / TAIL_TOLERANCE_PERCENT / UNCONSTRAINED_BELOWconstantTables 4 and 5 of ISO 8041-1, as data.
• the four transition frequencies per weighting, built from the printed 10**(k/10) exponents
• the three bands, each (upper %, lower %, phase °)
• −100 %, which is the absence of a lower limit rather than a wide one
vibration.TRANSITION_FREQUENCIES_HZ['Wk']

• (0.251, 0.631, 63.1, 158.5) Hz
REFERENCE_FREQUENCY_HZ / REFERENCE_ACCELERATION_M_S2 / reference_indicationconstant / functionThe ISO 8041-1 Table 1 reference conditions.
• the calibration frequency per weighting, from the radians per second the standard prints
• the reference r.m.s. acceleration, 1 m/s² whole-body, 10 hand-transmitted, 0,1 low-frequency
• reference_indication(name) is their product with the weighting factor there, which is what a conforming meter shows
vibration.reference_indication('Wh') # 2.02 m/s²
indication_tolerance_percent / INDICATION_TOLERANCE_PERCENT / LOW_FREQUENCY_INDICATION_TOLERANCE_PERCENT / LOW_FREQUENCY_WEIGHTINGfunction / constantHow far the indication itself may sit from the truth (ISO 8041-1 Table 2).
• 4 % at the reference frequency, and 5 % for the low-frequency whole-body case, which is Wf
vibration.indication_tolerance_percent('Wf') # 5.0
PVEM_INDICATION_TOLERANCES_PERCENTconstantTable 2 of a personal vibration exposure meter (ISO 8041-2:2021).
• 'indication' 4 %, 'low-frequency indication' 5 %, 'weighting consistency' 3 %: the first two rows of the Part 1 table
• no running r.m.s. row, because Part 2 5.13 declares the running r.m.s. not applicable to a PVEM
vibration.PVEM_INDICATION_TOLERANCES_PERCENT['weighting consistency'] # 3.0
band_limiting_response / band_limiting_factors / apply_band_limitingfunctionThe band-limiting stage of a weighting on its own (ISO 8041-1 Formulae (1) and (2)).
• the two-pole Butterworth high-pass and low-pass pair every weighting starts with, without the transition and step stages
• apply_band_limiting(signal, fs=None, *, name) filters with it, which is what the band-limiting row of the burst tables is measured on
vibration.band_limiting_factors('Wk', [1.0])

• 0.9874
band_limited_weighting_factor / WEIGHTING_CONSISTENCY_TOLERANCE_PERCENTfunction / constantThe weighting factor a band-limited channel actually shows (ISO 8041-1 Table 2, row 2).
• the design goal times the band-limiting response, which is what a meter indicates when both stages are in the path
• the 3 % row 2 allows between the two
vibration.band_limited_weighting_factor('Wk', [16.0])
running_rms_decay_timefunctionHow long the running r.m.s. takes to fall to 10 % of its steady value (ISO 8041-1 5.13).
• integration_time_s, and method selecting linear or exponential averaging
• the quantity Table 11 prints, timed from the moment the signal is shut off
vibration.running_rms_decay_time(1.0, method='linear')
verify_running_rms_decay / RunningRmsDecayVerification / RUNNING_RMS_DECAY_RATE_DB_PER_S / RUNNING_RMS_DECAY_TIME_S / RUNNING_RMS_CONSISTENCY_TOLERANCE_PERCENTfunction / dataclass / constantDoes the running r.m.s. decay at the printed rate (ISO 8041-1 Tables 10 and 11)?
• measured_time_s, with integration_time_s and method keyword-only
• .passes, .printed_time_s, .tolerance_s, .lower_time_s, .upper_time_s, .deviation_s, .plot()
• the decay in decibels per second and the time to fall, per integration time, for linear and exponential averaging
• the 2 % the indication may differ by
vibration.RUNNING_RMS_DECAY_RATE_DB_PER_S[1]

• (1.0, 3.8, 4.9) s, dB, dB
verify_signal_burst_response / SignalBurstVerificationfunction / dataclassA meter's response to the saw-tooth burst of ISO 8041-1 5.9 (Tables 7 to 9).
• application, weighting, the measured indications per burst length
• .passes, .deviation_percent, .failing_cycle_counts, .plot()
• graded on a zero-state simulation, which is what the printed tables come from
vibration.verify_signal_burst_response('whole-body', 'Wk', measured)
sawtooth_burst / signal_burst_indications / SawtoothBurstTest / SAWTOOTH_BURST_TESTSfunction / dataclass / constantThe burst signal itself and what a conforming meter reads from it (Table 6).
• sawtooth_burst(...) builds the waveform: angular frequency, start time, cycle count, repeat and total duration
• the three applications, 500 rad/s hand-arm, 100 whole-body and 2,5 low-frequency
vibration.SAWTOOTH_BURST_TESTS['whole-body'].cycle_counts

• (1, 2, 4, 8, 16)
SIGNAL_BURST_RESPONSE / BURST_TOLERANCE_PERCENT / BAND_LIMITINGconstantTables 7, 8 and 9 as data, and the tolerance each column carries.
• 228 printed cells keyed by (application, weighting, cycles), with None for the continuous row
• 10 % on the r.m.s. and MTVV columns, 12 % on VDV
• 'band-limiting' names the row measured with the weighting stages out of the path
vibration.BURST_TOLERANCE_PERCENT['vdv'] # 12.0
REFERENCE_ACCELERATIONfloatVibration reference acceleration [m/s²].
1e-6 (ISO 1683 acceleration level reference)
REFERENCE_ACCELERATION # 1e-06
REFERENCE_DURATION_SfloatDaily-exposure reference duration T0 [s].
28800 (8 h)
REFERENCE_DURATION_S # 28800.0
HAV_EAV_A8floatHand-arm exposure action value [m/s²].
2.5 (Directive 2002/44/EC)
HAV_EAV_A8 # 2.5
HAV_ELV_A8floatHand-arm exposure limit value [m/s²].
5.0
HAV_ELV_A8 # 5.0
WBV_EAV_A8floatWhole-body A(8) action value [m/s²].
0.5
WBV_EAV_A8 # 0.5
WBV_ELV_A8floatWhole-body A(8) limit value [m/s²].
1.15
WBV_ELV_A8 # 1.15
WBV_EAV_VDVfloatWhole-body VDV action value [m/s^1.75].
9.1
WBV_EAV_VDV # 9.1
WBV_ELV_VDVfloatWhole-body VDV limit value [m/s^1.75].
21.0
WBV_ELV_VDV # 21.0
measure_vibration_immission / VibrationMeterReadingfunction / dataclassWhat a DIN 45669-1 vibration meter displays for one record (5.1.6).
• velocity_mm_s [mm/s], fs_hz [Hz]
• keyword-only: working_range ('building' 1-80 Hz, Default; 'railway' 4-315 Hz), takt_duration_s (Default: 30)
• .peak_velocity_mm_s, .kbf, .kbf_max, .takt_maxima, .kbf_takt_rms, .measuring_time_s, .averaging_time_s, .above_detection_limit, .plot()
• start the record before the event: a record that opens at full amplitude leaves the filter's switch-on transient in the max-hold
r = vibration.measure_vibration_immission(v, 2048.0)

• r.kbf_max, r.kbf_takt_rms
kb_signal / kbf_signalfunctionThe KB signal and the weighted vibration severity (3.10.1, Formula (1)).
• KB(t) is the velocity band-limited, frequency-weighted and normalised by 1 mm/s, so it is dimensionless
• KB_F(t) is its running r.m.s. with τ = 0,125 s ("Fast")
• keyword-only: working_range, and time_constant_s for a comparison the standard does not allow a meter
vibration.kbf_signal(v, 2048.0).max() # KB_Fmax
takt_maxima / takt_maximum_rmsfunctionThe clock maxima and their r.m.s., Formula (2).
• one maximum per whole 30 s clock interval; a part-interval is dropped (5.1.6.4)
• a maximum at or below 0,1 enters the sum as zero and its interval still counts in N
vibration.takt_maximum_rms([0.8, 0.05]) # 0.566
band_limitation_response / kb_weighting_responsefunctionFormulae (3) and (4), complex, at the frequencies asked for.
• two-pole Butterworth pairs at 0,8 f_u and f_o / 0,8, and the 5,6 Hz pole that makes the KB weighting
• the magnitudes are Formulae (5) and (6)
abs(vibration.kb_weighting_response([16.0])) # 0.944
verify_vibration_meter / VibrationMeterVerificationfunction / dataclassDoes a meter's amplitude response meet DIN 45669-1 Tables 2 and 3?
• frequencies_hz, measured_response (any consistent unit: only the shape is graded)
• keyword-only: weighting ('kb' Default, or 'unweighted'), working_range, reference_frequency_hz (Default: 16)
• .deviation_percent (Formula (7)), .lower_percent, .upper_percent, .within_tolerance, .passes, .worst_frequency_hz, .plot()
• the response only: Clause 6 also asks for linearity, overload and the environmental tests
vibration.verify_vibration_meter(f, measured).passes
response_tolerance_percent / RESPONSE_TOLERANCE_LOWER_PERCENT / RESPONSE_TOLERANCE_UPPER_PERCENTfunction / constantTables 2 and 3, as bands of the working range.
• 10 % from 1,25 f_u to 0,8 f_o, 20 % out to 0,5 f_u and 2 f_o
• 100 % below that band is the absence of a lower limit, and the upper limit applies only where the response is above 0,01
vibration.response_tolerance_percent([100.0])

• (20.0, 20.0) %
assessment_weighting_response / assessment_weighting_tapsfunctionThe three Annex E weighting filters (Table E.1).
• the target magnitude is the guideline curve of DIN 4150-3 Table 1 inverted and normalised to its 1-10 Hz value
• assessment_weighting_taps(fs_hz, *, building_class, numtaps=None) designs the symmetric FIR the annex asks for, which has the linear phase a peak measurement needs
vibration.assessment_weighting_response([50.0], building_class='residential')

• 0.333
assessment_velocity / assess_short_term_vibration / AssessmentVelocityfunction / dataclassShort-term vibration on a building judged without a dominant frequency (Annex E).
• velocity_mm_s [mm/s], fs_hz [Hz], keyword-only building_class and numtaps
• .assessment_velocity_mm_s = |v_Bn|max, .guide_value_mm_s, .ratio, .within_guideline, .plot()
• the verdict reads like DIN 4150-3: keeping to the value is what the standard promises about, exceeding it moves the question to Clauses 4.2 to 4.4
vibration.assess_short_term_vibration(v, 2048.0, building_class='residential').within_guideline
dominant_frequency / DominantFrequencyfunction / dataclassThe dominant frequency of a short-term event (Annex D).
• method='zero_crossing' (Default: the crossings around the largest amplitude are half a period apart) or 'fourier'
• .frequency_hz, .method, .candidates (the two largest spectral values, Fourier only)
• the two can disagree, which is the ambiguity Annex E removes
vibration.dominant_frequency(v, 2048.0).frequency_hz
WORKING_RANGES_HZ / BAND_LIMIT_CORNER_FACTOR / KB_CORNER_HZ / KB_TIME_CONSTANT_SconstantThe four numbers the chain is built from (5.2.3, 3.10.1.2).
• 1 Hz to 80 Hz for buildings and 4 Hz to 315 Hz next to a railway
• the 0,8 between a band limit and its filter corner, the 5,6 Hz of the weighting and the 0,125 s of the running r.m.s.
vibration.WORKING_RANGES_HZ['railway'] # (4.0, 315.0)
TAKT_DURATION_S / TAKT_SUPPRESSION_THRESHOLD / KB_DETECTION_LIMIT / VELOCITY_DETECTION_LIMIT_MM_SconstantThe clock interval and the limits below which a meter promises nothing.
• 30 s per clock interval (5.1.6.4), and the 0,1 of Formula (2)
• 0,05 mm/s on the peak velocity and 0,02 on the weighted vibration severity (5.2.2)
vibration.TAKT_DURATION_S # 30.0
KB_REFERENCE_FREQUENCY_HZ / KB_REFERENCE_INDICATIONS / KB_INDICATION_TOLERANCE_PERCENTconstantThe reference conditions of 5.2.10 and what they must show (6.2.3.12).
• a 1 mm/s sine at 16 Hz, and the four values it produces: 1,00 mm/s, 0,667, 0,680 and 0,680
• 4 % is how far the display may sit from them
vibration.KB_REFERENCE_INDICATIONS['kbf_max'] # 0.68
KB_TEST_INDICATIONS / KB_PULSE_RESPONSE_PERCENTconstantTable 9 and Table 8, as data.
• the KB_F, KB_Fmax and KB_FTm a 1 mm/s sine shows at 1, 5,6, 31,5, 80 and 315 Hz
• Corrigendum 1's redraft of the burst table: eight burst durations of an 80 Hz sine and the KB_Fmax each shows as a percentage of the continuous display
• the |v|max row of Table 9 is not here; it contradicts Formula (5), see docs/ERRATA.md
vibration.KB_TEST_INDICATIONS[31.5]

• (0.693, 0.7, 0.7)
ASSESSMENT_GUIDE_VALUES_MM_S / ASSESSMENT_WEIGHTING_TOLERANCEconstantTable E.2 and the band Table E.1 allows a realised filter.
• 20, 5 and 3 mm/s, one per building class, independent of frequency
• 5 % either side of the target magnitude
vibration.ASSESSMENT_GUIDE_VALUES_MM_S['sensitive'] # 3.0
check_loose_mounting / MountingCheckfunction / dataclassMay the transducer be set down without fastening? (DIN 45669-2 5.3.2, 5.3.3)
• peak_acceleration_m_s2 [m/s²], upper_frequency_hz [Hz], keyword-only direction ('vertical' or 'horizontal') and surface ('hard' Default, 'soft')
• .acceptable, .frequency_limit_hz (100 vertical, 40 horizontal), .peak_acceleration_limit_m_s2 (3), .device (what it stands on: rounded feet, or the spiked device on a covering)
vibration.check_loose_mounting(1.2, 63.0, direction='horizontal').acceptable # False
instrument_confidence_limit_percent / INSTRUMENT_CONFIDENCE_LIMITS_PERCENTfunction / constantTable 3 of DIN 45669-2: how far a conforming meter may still be from the truth.
• quantity 'rms' (15 %, 25 %) or 'peak' (20 %, 35 %), accuracy_class 1 (Default) or 2
• the classes are those of the 1995 Part 1; the 2010 edition dropped them, so class 1 is the column for a meter of today
vibration.instrument_confidence_limit_percent('peak') # 20.0
mass_loading_ratio / MASS_LOADING_RATIO_LIMITfunction / constant7.2.4: the mass the transducer adds to the object, at most a hundredth.
• coupled_mass_kg [kg], keyword-only vibrating_mass_kg [kg]
• the ratio to compare with 0.01
vibration.mass_loading_ratio(2.5, vibrating_mass_kg=600.0) # 0.0042
LOOSE_MOUNTING_LIMITS_HZ / LOOSE_MOUNTING_PEAK_ACCELERATION_M_S2 / WAX_MOUNTING_HORIZONTAL_LIMIT_HZ / SPIKED_DEVICE_MASS_KGconstantThe mounting numbers of DIN 45669-2.
• 100 Hz vertically and 40 Hz horizontally for a loose transducer, at up to 3 m/s² peak
• 80 Hz for the horizontal component on a sensitive hard surface with adhesive wax (Table 1)
• about 2.5 kg for the spiked device with the transducer (5.3.3.1)
vibration.LOOSE_MOUNTING_LIMITS_HZ['horizontal'] # 40.0
GROUND_COUPLING_DEVIATION_DB / EMISSION_POINT_TRACK_DISTANCE_M / CLEARANCE_TO_DISTURBING_BODY_FACTORconstantThe placement numbers of 5.1.4 and 5.3.4.1.
• up to 15 dB from the ground coupling alone
• 8 m from the nearest track for a railway emission point, and at least 1.5 times the largest dimension of a disturbing body away from it
vibration.GROUND_COUPLING_DEVIATION_DB # 15.0
assess_people_in_buildings / PeopleAssessmentfunction / dataclassThe verdict of DIN 4150-2 Clause 6.2 on one immission (Figure 2).
• kb_fmax, guide (a GuideValues), keyword-only kb_ftr (needed only when the verdict comes down to it), source ('general' Default, 'road', 'railway', 'urban_railway', 'quarry_blasting'), rare_short_events
• KB_Fmax at or below A_u is met, and so, as a rule, is one above it by less than the 15 % of 5.4 (Example 3), flagged in .within_uncertainty; above A_o is not, unless the source is a railway or the events are rare; between, KB_FTr against A_r
• .complies, .criterion ('A_u', 'A_o' or 'A_r'), .within_uncertainty, .plot()
• compared at the decimals the guide value is printed with, half up, which is how Example 4 reads 0,154 as 0,15
vibration.assess_people_in_buildings(0.47, g, kb_ftr=0.154).complies # True
guide_values / GuideValues / GUIDE_VALUESfunction / dataclass / constantTable 1: the guide values by kind of area, day and night.
• area 'industrial', 'commercial', 'mixed', 'residential' or 'sensitive'; keyword-only time_of_day ('day' Default, 'night') and source
• .a_u, .a_o, .a_r; an urban surface railway raises A_u and A_r by 1,5 (6.5.3.3); quarry blasting under the conditions of 6.5.1 takes the daytime A_o of row 1 in a mixed or residential area
vibration.guide_values('residential').a_r # 0.07
construction_guide_values / CONSTRUCTION_GUIDE_VALUES / CONSTRUCTION_STAGESfunction / constantTable 2: a construction site by working days and stage, with the interpolation of Figure 3.
• duration_days, whole working days 1 to 78, keyword-only stage ('I' Default, 'II', 'III') and area (not 'sensitive', to which 6.5.4.2 says the table does not apply)
• 2 to 6 days interpolated between the one-day column and the column that starts at 7, at the two decimals Figure 3 prints; A_o 5, or 6 in a commercial or industrial area
vibration.construction_guide_values(4).a_u # 0.6
assessment_vibration_severity / admissible_exposure_sfunctionFormulae (4a), (4b) and (5): KB_FTr over the assessment period, and the exposure A_r allows.
• kb_ftm and exposure_s [s], one per stretch; keyword-only time_of_day and in_rest_time (weight 2, day only)
• admissible_exposure_s(kb_ftm, a_r) is (4b) turned around, as Example 2 does it
vibration.assessment_vibration_severity([0.16, 0.39], [21600, 5400]) # 0.154
railway_takt_maximum_rms / railway_takt_spread / railway_assessment_severity / RailwayAssessment / admissible_trains_per_hourfunction / dataclassAnnex A: a railway by classes of train, and Figure D.1.
• (A.1) KB_FTm over the clock intervals a class occupies, (A.2) the spread of its square, (A.3) KB_FTr weighted by the intervals each class occupies of the 1920 or 960 of the period, with .lower and .upper from a spread
• admissible_trains_per_hour(kb_ftm, a_r) = 120 (A_r / KB_FTm)², one interval per train
vibration.railway_assessment_severity([0.82, 0.22], [288, 192]).kb_ftr # 0.325
kb_from_peak_velocity / kb_fmax_from_peak_velocity / PEAK_TO_KB_FACTORSfunction / constantClause 7: an estimate of KB_Fmax from an unweighted record, Formulae (6) and (7) with Table 3.
• peak_velocity_mm_s [mm/s], frequency_hz [Hz], keyword-only kind (the row of Table 3, 'harmonic' to 'single_event')
• KB = v_max / (√2 √(1 + (5,6 Hz / f)²)), times c_F
vibration.kb_fmax_from_peak_velocity(4.0, 14.0, kind='single_event_resonant') # 2.10
ASSESSMENT_PERIOD_S / ASSESSMENT_TAKT_COUNT / DAY_REST_TIME_S / REST_TIME_WEIGHT / KB_UNCERTAINTY_PERCENTconstantThe times and the weights of DIN 4150-2.
• 16 h by day and 8 h by night (3.7.3), 1920 and 960 clock intervals (Annex A)
• 4 h of rest hours in the day (3.7.4), the weight 2 of Formula (5), the 15 % of 5.4
vibration.ASSESSMENT_TAKT_COUNT['night'] # 960
RARE_EVENTS_PER_DAY / BLASTING_EXCEPTION_KB_FMAX / CONSTRUCTION_BLASTING_A_O / URBAN_RAILWAY_FACTOR / RAILWAY_NIGHT_INVESTIGATION_KBconstantThe source-specific numbers of 6.5.
• up to 3 short events a day are judged on A_o alone; quarry blasting under the conditions of 6.5.1 may reach 8 a few times a year; a site's blasting is held to A_o = 8
• 1,5 on A_u and A_r for an urban surface railway; by night a clock maximum above 0,6 on a surface line or 0,3 underground is a reason to look into the cause (6.5.3.5)
vibration.URBAN_RAILWAY_FACTOR # 1.5
GUIDE_VALUES_2023 / ROAD_EXISTING_TOLERANCE_FACTOR / ROAD_NIGHT_INVESTIGATION_KB / INDUCED_SEISMIC_PEAK_FACTOR / BLASTING_MAX_PER_WEEK / induced_seismic_kb_fmaxconstant / functionWhat E DIN 4150-2:2023-08 changes: Table 1 with the night A_u of a mixed area at 0,1, and two sources of its own.
• guide_values(..., edition='2023') reads the draft, and its GuideValues carry the edition and the period, which assess_people_in_buildings follows: no shortcut inside the 15 % above A_u, a railway compared with A_o and a road by night not, with a clock maximum above 0,6 as a reason to look into the cause (6.5.2), source='road_existing' with A_u and A_r tolerated 1,5 times over (6.5.2), source='induced_seismic' held by night to the daytime A_o (6.5.1.3)
• induced_seismic_kb_fmax(peak_velocity_mm_s) = 0,44 v_max; at most 15 blasts a week where successive ones count as one
vibration.guide_values('mixed', time_of_day='night', edition='2023').a_u # 0.1
train_category_rms / train_kb_fmax / railway_kb_fmaxfunctionE DIN 4150-2:2023-08 6.5.3.2, Formulae (5), (7) and (8): a railway by category of train.
• train_category_rms(kb_fti_zug): the r.m.s. of one clock maximum per passage, nothing zeroed below 0,1
• train_kb_fmax(kb_ftm_zug): 1,5 times the r.m.s. of each category; railway_kb_fmax the largest of them, the KB_Fmax of the line
vibration.train_category_rms([0.379, 0.369, 0.348]) # 0.366
train_assessment_severity / train_weighting_factor / TRAIN_WEIGHTING_FACTORS / TRAIN_KINDS / TRAIN_KB_FMAX_FACTORfunction / constantFormula (6) and Table 2 of the draft, and Formula (11) and Table E.1 of E DIN 45672-3:2023-02.
• train_assessment_severity(kb_ftm_zug, trains, *, alpha, time_of_day): each category weighted by its trains out of the 1920 or 960 intervals and by alpha; a category at or below 0,1 counts as zero
• train_weighting_factor(kind, *, alignment): 0,7 for a tram on the surface to 1,3 for a freight train over 600 m
vibration.train_assessment_severity([0.24, 0.44], [28, 8], alpha=[0.9, 1.0]) # 0.039
railway_guide_values / RAILWAY_NEW_LINE_NIGHT_A_O / assess_railway_change / RailwayChange / RAILWAY_CHANGE_TOLERANCE_PERCENTfunction / constant / dataclass6.5.3.5 and 6.5.3.6 of the draft: a line to be built new, and one to be altered.
• railway_guide_values(area, *, time_of_day, alignment): Table 1 with the night A_o of a new line, 0,6 on the surface, 0,3 underground outside an industrial or commercial area
• assess_railway_change(*, kb_fmax_before, kb_fmax_after, kb_ftr_before, kb_ftr_after, guide, time_of_day): met where the planned case keeps to A_u, or to A_o and A_r, or exceeds those by an increase under 25 %, every condition that applies holding, as the draft's Example 9 does; .complies, .kb_fmax_met, .kb_ftr_met, .kb_ftr_increase_percent
vibration.railway_guide_values('mixed', time_of_day='night').a_o # 0.6
predict_floor_spectrum / predict_train_category / TrainCategoryPredictionfunction / dataclassE DIN 45672-3:2023-02 Formula (1) and the chain of Clause 7: the spectrum a floor will feel, and the KB values from it.
• predict_floor_spectrum(emission_db, *, ground_db, foundation_db, floor_db, mitigation_db): every term added, band by band, so a mitigation goes in negative
• predict_train_category(emission_db, *, frequencies_hz, ...) runs (1), the Table 2 weighting (8), the sum (9), 1,5 times it (10) and 3 times that (12): .floor_db, .weighted_db, .sum_level_db, .kb_ftm, .kb_fmax, .peak_velocity_mm_s, .plot()
vibration.predict_train_category(emission, ground_db=bb, floor_db=df).kb_ftm
kb_weighted_levels_db / takt_maximum_kb / peak_velocity_from_kb_mm_s / velocity_spectrum_um_s / KB_WEIGHTING_TABLE_DB / KB_ASSESSMENT_BANDS_HZ / TAKT_MAXIMUM_FACTOR / PEAK_VELOCITY_FACTORfunction / constantClause 7 of E DIN 45672-3 piece by piece.
• Table 2, the KB weighting rounded to a tenth of a decibel from 4 Hz to 80 Hz, added by kb_weighted_levels_db(levels_db, frequencies_hz)
• takt_maximum_kb(weighted_levels_db) = c_T1 v_0 10^(L/20) with c_T1 = 1 and v_0 = 5·10⁻⁵ mm/s (Formula (9)); peak_velocity_from_kb_mm_s(kb_fmax_zug) = 3 times it (Formula (12)); velocity_spectrum_um_s(levels_db) in micrometres per second (Formula (13))
vibration.takt_maximum_kb([78.1]) # 0.4018
rescale_emission_for_speed / ground_transmission_db / ground_attenuation_coefficient_per_m / SPEED_RESCALING_LIMIT / GEOMETRIC_DECAY_EXPONENT_RANGEfunction / constantClauses 5.2 and 5.3 of E DIN 45672-3: the emission at another speed and the way through the ground.
• rescale_emission_for_speed(levels_db, *, speed_from_km_h, speed_to_km_h): 20 lg of the ratio, for a change of up to 30 % (Formula (3))
• ground_transmission_db(frequencies_hz, *, distance_m, reference_distance_m, exponent, damping_ratio, shear_wave_speed_m_s): spreading with n, usually 0,2 to 0,4 on the surface, and damping with alpha_R = 2π f D / c_s (Formulae (4) to (6))
vibration.ground_transmission_db([8.0], distance_m=20.0, reference_distance_m=10.0, exponent=0.3) # -1.81
ground_to_floor_transfer_db / ground_to_foundation_transfer_db / foundation_to_floor_transfer_db / GROUND_TO_FLOOR_DB / GROUND_TO_FOUNDATION_DB / FOUNDATION_TO_FLOOR_DB / FOUNDATION_TO_FLOOR_RATIOS / FLOOR_NATURAL_FREQUENCIES_HZ / PREDICTION_BAND_CENTRES_HZfunction / constantAnnex A of E DIN 45672-3: the six tables of level differences into and inside a building.
• ground to floor (Tables A.1 and A.2) for a concrete or timber floor by its natural frequency, one column per frequency, for every storey
• ground to foundation (Tables A.3 and A.4) for a basement or a ground floor, as 'mean', 'lower' or 'upper'
• foundation to floor (Tables A.5 and A.6) against the ratio of the band to the natural frequency, interpolated in decibels over the logarithm of the ratio, nan where the print has none
vibration.ground_to_floor_transfer_db('concrete', floor_natural_frequency_hz=8.0)[3] # 15.0
point_to_line_transition_distance_m / line_source_correction_db / train_decay_exponent / train_velocity_ratio / LINE_SOURCE_EXPONENT_CORRECTION / RECOMMENDED_DISTANCES_Mfunction / constantAnnex B and Table 1 of E DIN 45672-3: a train is a line of point sources, and how far a prediction should reach.
• R_0 = L² / lambda (Formula (B.1)); 20 n_Korr lg(r / r_0) with n_Korr 0,3 or 0,5 by how the point decay was fitted (Formula (B.2)); the exponent of a train and the piecewise decay of Figure B.1
• the distances of Table 1: 25 m from a surface tram to 200 m from freight on soft ground
vibration.train_decay_exponent(1.0) # 0.7
far_field_velocity_mm_s / geometric_exponent / reference_distance_m / attenuation_coefficient_per_m / material_damping_factor / SOURCE_EXPONENTS / TRAIN_CHAIN_EXPONENT_RANGE / LOOSE_GROUND_DAMPING_RATIOfunction / constantDIN 4150-1:2001-06 Clause 4.2: how far vibration carries through the ground.
• far_field_velocity_mm_s(reference_velocity_mm_s, distance_m, *, reference_distance_m, exponent, attenuation_per_m): Formula (2), spreading with the exponent of Figure 1 and damping with alpha = 2π D / lambda, beyond R_1 = a/2 + lambda_R (Formula (1))
• geometric_exponent(*, geometry, character, wave): 0, 0,5, 1 or 1,5; a train decays with 0,3 to 0,5; loose ground has a damping ratio of 0,01 at most in a first estimate
vibration.far_field_velocity_mm_s(0.44, [80.0], reference_distance_m=13.0, exponent=1.0, attenuation_per_m=0.005) # 0.051
soil_building_natural_frequency_hz / soil_building_frequency_guide_hz / foundation_transfer_max / floor_transfer_max / storey_frequency_hz / LOOSE_GROUND_SYSTEM_DAMPING / FOUNDATION_TRANSFER_ABOVE_RESONANCE / FLOOR_DAMPING_RATIO_RANGE / MEDIUM_SOIL_SHEAR_WAVE_SPEED_M_S / STOREY_FORMULA_MIN_STOREYSfunction / constantDIN 4150-1 Clause 4.3: the building on its ground.
• Formula (3), the natural frequency of the building as a mass on the spring of the ground, about 15 Hz for one or two storeys, 8 Hz to 12 Hz for two to six and under 8 above six on medium ground (c_s 150 to 200 m/s), two storeys taking the union of the two ranges it is printed in
• the most a foundation passes at resonance, 1 / (2 D_0) = 2 for loose ground, and 0,5 above it; the most a floor amplifies, 1 / (2 D_1) = 10 to 25 for concrete; 10 / n Hz for the lowest horizontal mode of n ≥ 5 storeys (Formula (4))
vibration.floor_transfer_max(0.02) # 25.0
blast_peak_velocity_mm_s / impact_peak_velocity_mm_s / fall_energy_kj / BLASTING_RELEVANT_DISTANCE_Mfunction / constantDIN 4150-1 Clause 5.1: single events in the far field.
• blast_peak_velocity_mm_s(charge_kg, distance_m, *, coefficient_mm_s, charge_exponent, distance_exponent): k (L/L_0)^b (R/R_0)^-m with constants from trial blasts (Formula (5))
• impact_peak_velocity_mm_s(fall_energy_kj, distance_m, *, coefficient_mm_s, distance_exponent): the same with the root of the fall energy G h (Formula (6)); quarry blasting is rarely relevant beyond 1500 m, construction blasting beyond 400 m
vibration.fall_energy_kj(25506.0, drop_height_m=70.0) # 1.79e6
track_excitation_frequency_hz / RAIL_SUPPORT_SPACING_M / VEHICLE_NATURAL_FREQUENCIES_HZ / TRACK_TRANSMITTED_BANDS_HZ / RAIL_INFLUENCE_RANGE_M / MACHINE_FREQUENCY_BANDS_HZfunction / constantDIN 4150-1 Clauses 5.3 and 5.4: what a track and a machine excite at.
• f_A = v_Z / d and its multiples for sleepers 0,6 m to 0,9 m apart; the car body at 1 Hz to 3 Hz and the bogie at 6 Hz to 10 Hz whatever the speed; ballast passes 40 Hz to 80 Hz, a mass-spring system 5 Hz to 20 Hz; rail vibration reaches 80 m
• counter-blow hammers 4 Hz to 8 Hz, forging presses 5 Hz to 15 Hz sideways, frame saws 4 Hz to 8 Hz
vibration.track_excitation_frequency_hz(20.0, spacing_m=0.6) # [33.3]
machine_hall_velocity_mm_s / machine_count_correction / MACHINE_COUNT_CORRECTION / MACHINE_COUNT_AXISfunction / constantDIN 4150-1 Clause 5.4.2, Formula (7) and Figure 3: a hall of similar machines.
• machine_hall_velocity_mm_s(reference_velocity_mm_s, machine_count, *, reference_count): chi v_B sqrt(N), measured with N_B of them running
• chi is printed only as a nomogram, for N_B of 3, 5, 10, 30, 60 or 100 from 4 to 100 machines, and is here as the curves read off the page at a five-hundredth
vibration.machine_hall_velocity_mm_s(0.44, [60.0], reference_count=3) # 1.0
evaluate_train_passage / TrainPassagefunction / dataclassOne train passage reduced the way DIN 45672-2 reduces it (Clauses 5 to 7).
• velocity_mm_s [mm/s] as the transducer gives it, fs_hz [Hz], an integer
• keyword-only: t2_s (the passage, read off the record), t1_s (Default: 4 s centred on the peak, never longer than T₂), t3_s (Default: the whole record), upper_band_hz (Default: 315; down to 80)
• .intervals_s, .interval_rms_mm_s, .peak_velocity_mm_s, .running_rms_max_mm_s, .kbf_max, .event_velocity_mm_s, .event_level_db, .band_centres_hz, .band_interval_levels_db (one row per stretch), .band_max_levels_db, .plot(), .plot_spectrum()
• the record goes through the railway band limitation of DIN 45669-1 before anything is read
p = vibration.evaluate_train_passage(v, 2048, t2_s=(6.75, 23.25))

• p.event_velocity_mm_s, p.band_max_levels_db
running_velocity_rms / running_velocity_level / running_acceleration_levelfunctionFormulae (1) to (3): the running r.m.s. with τ = 125 ms, and its levels.
• levels re v₀ = 5·10⁻⁸ m/s and a₀ = 10⁻⁶ m/s²
• started from rest: the mean square is 14 % short after 2τ and 2 % after 4τ, the r.m.s. about half that
vibration.running_velocity_level(v, 2048)[-1]
interval_rms / centred_intervalfunctionFormulae (4) and (5), and the stretch T₁ of Clause 5 a).
• interval_rms(values, fs_hz, interval_s=(start, end)): handed the velocity it is Formula (4), handed the running r.m.s. it is Formula (5)
• centred_interval(v, fs_hz, duration_s=4): the largest amplitude in the middle, moved rather than cut where the record ends
vibration.interval_rms(v, 2048, interval_s=(8.0, 20.0))
event_velocity / event_velocity_level / combined_event_velocityfunctionFormulae (8) to (10): the event value referred to an hour, its level, and an hour of passages.
• v_E = ṽ₃ √(T₃ / 3600 s), from interval_rms_mm_s and duration_s
• the passages of an hour add in square
vibration.event_velocity(0.1, 36.0) # 0.01
passage_average_velocity / passage_average_levelfunctionClause 9: the energy average over repeated passages.
• r.m.s. values as the root of the mean square, levels as the level of the mean energy
• keyword-only axis: passage_average_level(spectra, axis=0) averages third-octave spectra band by band
vibration.passage_average_level([60, 70]) # 67.40
amplitude_distribution / AmplitudeDistributionfunction / dataclassFormula (11): the amplitude distribution density and its cumulative function (Clause 6.3).
• keyword-only bins (Default: 101, equal bins across the range of the stretch)
• .edges_mm_s, .density_per_mm_s, .cumulative
vibration.amplitude_distribution(v).cumulative[-1] # 1.0
narrowband_psd / passage_energy_spectral_density / spectral_density_levelfunctionFormulae (12) to (14), and the level Figure 7 draws.
• narrowband_psd(v, fs_hz, resolution_hz=1.25): Welch with a Hanning window and half a block of overlap, as a SpectralDensityResult
• passage_energy_spectral_density(psd, duration_s): Formula (13) as printed, G₂ T₂ / 2, a two-sided density
• spectral_density_level(psd): 10 lg(G / G₀) with G₀ = (5·10⁻⁸ m/s)²/Hz
vibration.narrowband_psd(v, 2048).nperseg / 2048 # 0.8
third_octaves_from_narrowband / THIRD_OCTAVE_LINES / NARROWBAND_RESOLUTION_HZfunction / constantFormula (23) with Table 1: a narrow-band spectrum back into third octaves.
• each band takes its Table 1 count of lines, the ones nearest its nominal centre on a logarithmic axis: the lines inside the nominal edges wherever the count is what they hold
• six lines fall between bands and five are in two, as nominal edges leave them; a band the spectrum does not hold whole is left out
• refuses a spectrum not spaced 1,25 Hz, the spacing the counts are written for
c, rms = vibration.third_octaves_from_narrowband(f, psd)
velocity_psd_from_voltage / elastic_insertion_loss / band_sum_levelfunctionAnnex A and Annex B.
• Annex A: a density in V²/Hz divided by κ_A² κ_V², keyword-only sensitivity_v_per_mm_s and gain
• (B.1) the insertion loss of an elastic element, L₁ − L₂ per band, which is also the difference spectrum of (B.2)
• (B.3) the energy sum of the bands
vibration.band_sum_level([60, 60]) # 63.01
VELOCITY_LEVEL_REFERENCE_MM_S / EVENT_REFERENCE_DURATION_S / T1_DURATION_S / PASSAGE_BANDS_HZconstantThe numbers DIN 45672-2 is built from.
• v₀ = 5·10⁻⁸ m/s, here 5e-5 mm/s (Formula (2); the 50 nm/s of note b of ISO 1683:2015 Table 3, 34 dB from its 1 nm/s)
• 3600 s, the hour of Formula (8), and 4 s, the recommended T₁
• 4 Hz to 315 Hz, the third-octave range of 7.2
vibration.VELOCITY_LEVEL_REFERENCE_MM_S # 5e-05
poisson_ratio_from_wave_speeds / shear_modulus_from_wave_speed / youngs_modulus_from_wave_speedsfunctionDIN 45672-1 Clause 4.5: the ground's constants from its two wave speeds.
• Formula (3) ν = (v_p² − 2v_s²) / (2(v_p² − v_s²)) and Formula (5) G = v_s² ρ
• E = 2G(1 + ν), not the printed E = v_p² ρ, which is the P-wave modulus; see docs/ERRATA.md
• speeds in m/s, keyword-only density_kg_m3
vibration.poisson_ratio_from_wave_speeds(400.0, 180.0) # 0.373
compression_wave_speed / shear_strain_amplitudefunctionFormula (1) corrected, and Formula (4).
• v_p = √(2G(1 − ν) / (ρ(1 − 2ν))), the continuum; the print is short of the factor 2
• γ̂ = v̂ / v_s, with the velocity amplitude in m/s
vibration.shear_strain_amplitude(2e-4, shear_wave_speed_m_s=180.0)
GROUND_WAVE_SPEED_RANGES_M_S / SHEAR_STRAIN_LINEAR_LIMITconstantWhat Clause 4.5 gives for natural ground.
• compression waves 200-2000 m/s and shear waves 10-1000 m/s
• 10⁻⁴: the shear strain up to which Figure 1 has the modulus about constant
vibration.SHEAR_STRAIN_LINEAR_LIMIT # 0.0001
fdtd_simulationfunction2D acoustic FDTD wave simulation (staggered grid, leapfrog).
• c: sound-speed map [m/s], (ny, nx) array or scalar with shape
• dx: grid spacing [m]
• duration: physical time to simulate [s]
• sources: GaussianPulse | CWSource | SignalSource list
• probes: (ix, iy) pressure-probe cells
• boundaries: "rigid" | "absorbing" | per-side mapping (name or real impedance [Pa·s/m])
• obstacle_mask: boolean (ny, nx) rigid-cell map / rho / cfl / damping / absorbing_layer_cells / snapshot_every
res = simulation.fdtd_simulation(343, 0.01, 0.02, shape=(200, 300), sources=[simulation.GaussianPulse(ix=60, iy=100, half_width_s=3e-4)], probes=[(200, 100)])

• FDTDResult
FDTDResultdataclassFDTD simulation result.
• times [s] / pressures [Pa] per probe / probes / probe_positions [m]
• dx / dt / shape / size [m] / sources / snapshots / snapshot_times / obstacle_mask
• .plot(): probe histories; .plot(kind="snapshot"): pressure field
res.pressures, res.times
res.plot()
FDTD2DclassFDTD stepping engine (frame-by-frame access).
• c [m/s] / dx [m] / rho [kg/m³] / cfl / shape
• sponge_width / sponge_sides / sponge_reflection / damping
• edge_impedance: per-side real impedance [Pa·s/m] / obstacle_mask
sim = simulation.FDTD2D(343, 0.01, shape=(200, 300))
sim.add_source(src); sim.step(); sim.run(400, record_every=10)
• sim.p / sim.vx / sim.vy / sim.dt / sim.time / sim.energy()
• sim.plot_geometry(probes=...): draw the configured domain before running
• sim.add_plane_wave(direction, center=..., width=..., wavelength=...): one-way plane packet initial condition
• sim.add_contour_probe(ix0, ix1, iy0, iy1, frequencies=...): on-the-fly p/v_n phasor capture on a closed contour
GaussianPulsedataclassGaussian pulse source for the FDTD solver.
• ix / iy: source cell
• width [s] / t0 [s] (Default: 4*width) / amplitude [Pa]
GaussianPulse(ix=60, iy=100, half_width_s=3e-4)
PlaneWaveSourcedataclassSustained one-way plane wave injected on a line (TF/SF style).
• direction: 'down'/'up'/'left'/'right' (travel)
• waveform: callable t → p_inc(t) [Pa] (reuse a point source's .value)
• offset: line position in cells from the launch edge (place it just inside a sponge)
• amplitude (Default: 1.0)
sim.add_source(simulation.PlaneWaveSource('down', simulation.CWSource(0, 0, frequency=1000.0).value, offset=22))

• Transversely plane to machine precision; ~1e-4 residual behind the line
CWSourcedataclassContinuous sine source with raised-cosine onset for the FDTD solver.
• ix / iy: source cell
• frequency [Hz] / amplitude [Pa] / ramp_cycles
CWSource(ix=25, iy=25, frequency=170)
SignalSourcedataclassArbitrary sampled waveform source for the FDTD solver.
• ix / iy: source cell
• samples [Pa] / fs [Hz] / amplitude
Linearly interpolated onto the simulation time steps
SignalSource(ix=60, iy=100, samples=sig, fs=48000)
ContourProbeclassOn-the-fly DFT of p and v_n on a closed rectangular contour.
Created by FDTD2D.add_contour_probe; complex accumulators per point and frequency, so CW runs store no time histories
• positions / normals / frequencies / samples
• .reset(): restart accumulation once the field is steady
• .phasors(frequency): the captured ContourPhasors
probe = sim.add_contour_probe(90, 470, 90, 345, frequencies=[2000.0])
sim.run(steps); probe.reset(); sim.run(window)
ph = probe.phasors(2000.0)
ContourPhasorsdataclassSteady-state p and v_n phasors on a closed contour (exp(+jωt)).
• frequency [Hz] / positions (n, 2) [m] / normals (outward)
• pressure [Pa] / normal_velocity [m/s] (complex) / segment [m]
• .subtract(reference): scattered = total − incident phasors
scattered = total.subtract(reference)
far_field_from_contourfunction2D near-to-far-field transformation (Kirchhoff-Helmholtz integral).
• contour: ContourPhasors
• angles_deg [deg]: observation directions (cos a, sin a) in grid axes
• distance: None (far-field pattern F(a), p → F e^{−jkr}/√r) or a radius [m] for the exact Hankel evaluation
• origin: phase-reference point
• fluid: Fluid (Default: SIMULATION_AIR, the medium the solver runs in)
F = simulation.far_field_from_contour(ph, np.arange(-180, 180, 2), origin=(xc, yc))

• Complex pattern, one value per angle_deg
elastic_fdtd_simulationfunction2D elastic P-SV FDTD wave simulation (velocity-stress, Virieux staggered grid).
• c_p / c_s: wave-speed maps [m/s], (ny, nx) arrays or scalars with shape (c_s = 0 marks fluid cells)
• dx: grid spacing [m] / duration [s] / rho: density map [kg/m³]
• sources: ExplosionSource | ForceSource list
• recording: ElasticRecording (probe cells and fields, snapshot cadence and field)
• boundaries: ElasticBoundaries (the four sides and the sponge thickness)
• obstacle_mask / cfl / damping
res = simulation.elastic_fdtd_simulation(6320, 3130, 0.001, 5e-5, rho=2700, shape=(300, 600), sources=[simulation.ForceSource(ix=300, iy=0, direction='y', waveform=simulation.GaussianPulse(0, 0, half_width_s=8e-6).value)], boundaries=simulation.ElasticBoundaries({'top': 'free'}))

• ElasticFDTDResult
ElasticFDTDResultdataclassElastic FDTD simulation result.
• times [s] / signals (n_probes, n_fields, n_steps+1) / probe_fields / probes / probe_positions [m]
• dx / dt / shape / size [m] / sources / snapshots / snapshot_times / snapshot_field / obstacle_mask / free_sides
• .plot(): probe histories; .plot(kind="snapshot"): recorded field
res.signals, res.times
res.plot()
ElasticRecordingdataclassWhat an elastic FDTD run records.
• probes: (ix, iy) cells (Default: none)
• probe_fields: ("p" | "vx" | "vy", ...) (Default: ("vy",))
• snapshot_every steps (Default: None)
• snapshot_field (Default: "p")
ElasticRecording(probes=[(300, 0)], snapshot_every=50, snapshot_field='vy')
ElasticBoundariesdataclassHow the four edges of the elastic domain end.
• sides: "rigid" (Default) | "absorbing" | "free" (stress-imaging surface) | per-side mapping
• absorbing_layer_cells (Default: 20)
ElasticBoundaries({'top': 'free'}, absorbing_layer_cells=40)
ElasticFDTD2DclassElastic P-SV stepping engine (frame-by-frame access).
• c_p / c_s [m/s] / dx [m] / rho [kg/m³] / cfl / shape
• free_sides: traction-free surfaces (stress imaging)
• sponge_width / sponge_sides / sponge_reflection / damping / obstacle_mask
sim = simulation.ElasticFDTD2D(6320, 3130, 0.001, rho=2700, shape=(300, 600), free_sides='top')
sim.add_source(src); sim.step(); sim.run(400, record_every=10)
• sim.txx / sim.tyy / sim.txy / sim.vx / sim.vy / sim.p / sim.lam / sim.mu / sim.dt / sim.time / sim.energy()
• sim.collocated(field): one field interpolated to cell centres
ElasticFDTD2D.from_regionsclassmethodLayered/embedded set-ups from named materials (no manual maps).
• shape: (ny, nx) / dx [m]
• background: Material or (c_p, c_s, rho) filling the grid
• regions: (where, material) pairs painted in order (where: boolean mask or numpy index)
• remaining kwargs forwarded to the constructor
sim = ElasticFDTD2D.from_regions((300, 600), 0.001, background=WATER, regions=[(np.s_[150:, :], STEEL)])
MaterialdataclassIsotropic medium as wave speeds and density (frozen).
• c_p [m/s] / c_s [m/s] (0 marks a fluid) / rho [kg/m³]
• is_fluid: c_s == 0
Must satisfy c_p² ≥ 2 c_s² (non-negative λ)
Material(c_p=5958, c_s=3184.7, rho=7850)
SIMULATION_AIRFluidThe air the acoustic solvers run in.
343.0 m/s, 1.2 kg/m³, the AIR Material written as a fluid
• the fluid default of far_field_from_contour
• a phonometry.fluids.Fluid: pass a computed one, or a water, to transform out of the medium the run actually used
simulation.SIMULATION_AIR.density # 1.2
AIR / WATER / STEEL / ALUMINIUM / CONCRETEMaterialNamed media, the three solids read off Bies 5e Table C.1.
air 343/0/1.2, water 1480/0/1000, steel 5958/3184.7/7850, aluminium 6450.5/3098.7/2700, concrete 3726.8/2282.2/2400 (c_p/c_s/ρ)
• each solid's density is printed and its two speeds follow from the modulus and Poisson ratio beside it
ElasticFDTD2D.from_regions((240, 480), 0.005, background=WATER, regions=[(np.s_[120:, :], STEEL)])
scholte_speedfunctionExact Scholte interface-wave speed of a fluid over an elastic half-space.
• fluid: Material with c_s = 0 (or triple)
• solid: Material with c_s > 0
Root of the exact characteristic equation (Brekhovskikh & Godin Eq. 4.4.20); non-dispersive, below both the fluid speed and the solid shear speed
scholte_speed(WATER, STEEL) # 1479.6

• v [m/s]
ExplosionSourcedataclassIsotropic (explosive) stress source for the elastic solver.
• ix / iy: source cell
• waveform: callable t → injected pressure [Pa] (reuse a point source's .value)
• amplitude (Default: 1.0)
Pressure-like sign: equal -s(t) increments on both normal stresses
ExplosionSource(ix=250, iy=250, waveform=simulation.GaussianPulse(0, 0, half_width_s=8e-6).value)
ForceSourcedataclassDirectional body-force source for the elastic solver.
• ix / iy: staggered velocity node
• direction: 'x' | 'y'
• waveform: callable t → line force [N/m] / amplitude
A vertical force under a free surface reproduces Lamb's problem
ForceSource(ix=300, iy=0, direction='y', amplitude=1e6, waveform=simulation.GaussianPulse(0, 0, half_width_s=8e-6).value)
PhonometryWarningwarning classBase class for all phonometry warnings.
Emitted by every module through the subclass of its own domain, so catching this one catches every library advisory at once
warnings.simplefilter('error', PhonometryWarning)
FilterBankWarningwarning classFractional-octave filter-bank advisory.
Emitted for filter-bank processing pitfalls
warnings.simplefilter('error', FilterBankWarning)
TonalityWarningwarning classTonality advisory.
Emitted for biased tonality estimates (e.g. coarse FFT resolution)
warnings.simplefilter('error', TonalityWarning)
STIWarningwarning classSTI/STIPA advisory.
Emitted for suspect speech-intelligibility measurements or inputs
warnings.simplefilter('error', STIWarning)
__version__strPackage version string.
(no parameters)
phonometry.__version__ # '4.0.0rc1'
.plot()methodOne-line canonical figure on every result object (soft matplotlib dependency).
Available on ZwickerLoudness, MooreGlasbergLoudness, MooreGlasbergTimeVaryingLoudness, EcmaLoudness, EcmaTonality, EcmaRoughness, PsychoacousticAnnoyanceResult, FluctuationStrengthResult, ProgramLoudnessResult, KWeightingResponse, STIResult, SIIResult, SIIProcedure, StandardSpeechSpectrum, NCResult, RCResult, AgeThresholdResult, NiptsResult, HtlanResult, ImpulseProminenceResult, ImpulsiveSoundResult, SelDistribution, DirectivityFactor, RandomIncidenceSensitivity, DiffuseFieldSensitivity, AdjustmentValue, FreeFieldCorrection, CorrectionUncertaintyBudget, CorrectionUncertaintyVerification, MultipleShockResult, ImpulseResponseResult, DecayCurve, RoomAcousticsResult, ReverberationResult, ReverberationModelResult, DynamicStiffnessResult, MobilityResult, TransferStiffnessResult, BandAveragedStiffness, LevelDifferenceCheck, OutputMassCheck, EffectiveBlockingMass, DrivingPointStiffnessResult, DrivingPointUncertainty, VibrationSoundPowerResult, StructureBornePowerResult, InstalledSourceResult, WeightedRatingResult, ImpactRatingResult, FacadeInsulationResult, LabAirborneInsulationResult, LabImpactInsulationResult, SoundPowerResult, SoundEnergyResult, ReverberationSoundPowerResult, ReverberationSoundEnergyResult, InSituSoundPowerResult, InDuctSoundPowerResult, HighFrequencySoundPowerResult, SoundPowerIntensityResult, DiscretePointIntensityResult, PrecisionSoundPowerResult, PrecisionIntensityResult, IntensityResult, UncertaintyResult, AbsorptionRatingResult, ScatteringResult, DiffusionResult, DiffusionSpectrum, InsituAbsorptionResult, WeightingResponse, WeightedSpectrum, Signal and DailyVibrationExposure.
• ax: existing Axes, or None to build a fresh figure (Default: None)
• returns the Matplotlib Axes (an array of Axes for multi-panel figures); never calls plt.show()
• needs matplotlib (pip install phonometry[plot])
res.plot()
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.
  • 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.
  • The 3.1 aliases are gone, as their notices said they would be in 4.0: octavefilter, getansifrequencies, normalizedfreq, calculate_sensitivity, the bare coverage_factor and expanded_uncertainty of ISO 12999-1, the OCTAVE_BANDS_HZ, THIRD_OCTAVE_BANDS_HZ and BASE_PLATE_BANDS_HZ constants, BAND_CENTRES, ExposureWarning, and the sample_rate, humidity and room_volume keywords. Use octave_filter, nominal_frequencies, normalized_frequencies, sensitivity, insulation_coverage_factor, insulation_expanded_uncertainty, OCTAVE_BANDS, THIRD_OCTAVE_BANDS, BASE_PLATE_BANDS, phonometry.speech.sii.BAND_CENTERS, OccupationalExposureWarning, fs, relative_humidity_percent and volume.