Skip to content

room.room_acoustics

Room acoustic parameters from impulse responses per ISO 3382-1:2009 (performance spaces) and ISO 3382-2:2008 (ordinary rooms).

The measured impulse response (acquired e.g. with the swept-sine or MLS front end of phonometry.room_ir, ISO 18233) is filtered into fractional-octave bands (IEC 61260) and converted to a decay curve by Schroeder backward integration of the squared impulse response (ISO 3382-1:2009, 5.3.3, Equation (1)). To limit the influence of background noise, the integration is truncated at the crossing point between the background-noise level and a sloping line fitted to the squared impulse response, and the missing tail is compensated assuming an exponential decay with the fitted rate (5.3.3, Equation (3)).

From the decay curve the reverberation times are evaluated by least-squares line fits (ISO 3382-2:2008, Clause 6 and Annex C): EDT over 0 dB to -10 dB (ISO 3382-1:2009, A.2.2), T20 over -5 dB to -25 dB and T30 over -5 dB to -35 dB, each extrapolated to a 60 dB decay (T = -60/slope). The energy parameters follow ISO 3382-1:2009 Annex A: clarity C50/C80 (Equation (A.10)), definition D50 (Equation (A.11)) and centre time Ts (Equation (A.13)), with t = 0 at the start of the direct sound (A.2.1).

Validity flags implement the dynamic-range criterion of ISO 3382-1:2009, 5.3.3: the background noise must lie at least the evaluation range plus 15 dB below the maximum of the (squared) impulse response - 25 dB for EDT (equivalently, the noise floor sits at least 10 dB below the lowest evaluation point). The +15 dB rule is derived for finite forward integration without tail compensation (C = 0), which under-estimates T; because this module compensates the truncated tail (5.3.3, Equation (3), C != 0) with a residual positive bias, the T20 and T30 flags add extra headroom (46 dB for T20, 54 dB for T30) so that a flagged-valid decay time stays within the 5 % just-noticeable difference of ISO 3382-1:2009, Table A.1. The curvature indicator C = 100*(T30/T20 - 1) follows ISO 3382-2:2008, B.3; values above 10 % flag a decay curve that is far from a straight line.

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

decay_curve(
ir: list[float] | np.ndarray,
fs: int,
band: float | None = None,
fraction: int = 1,
zero_phase: bool = False,
) -> DecayCurve

Schroeder decay curve of an impulse response.

Backward integration of the squared impulse response (ISO 3382-1:2009, 5.3.3, Equation (1)), with noise truncation at the crossing of the background-noise level with the fitted decay slope and exponential compensation of the missing tail (Equation (3)). Time zero is the start of the direct sound (A.2.1) and the level is referenced to the steady-state level (the total energy of the integrated impulse response, Clause 6).

Parameters

NameDescription
irMeasured impulse response (1D), e.g. from phonometry.impulse_response (ISO 18233).
fsSample rate in Hz.
bandOptional band centre frequency in Hz. When given, the impulse response is first filtered with the matching IEC 61260 fractional-octave filter; when None the broadband response is integrated directly.
fractionBandwidth fraction of the band filter (1 = octave, 3 = one-third octave). Only used when band is not None.
zero_phaseIf True, filter the band with forward-backward (zero-phase) filtering, removing the octave filter’s group delay before the backward integration. ISO 3382-2:2008 Clause 7.3 NOTE permits time-reversed filtering (it relaxes the B*T > 16 rule to B*T > 4); it roughly halves the low-frequency short-decay bias at 125 Hz. Only used when band is not None. Default False (causal).

Returns: A DecayCurve with time in seconds from the direct sound and level in dB (0 dB at time zero), up to the noise truncation point. It unpacks as time, level = decay_curve(...) for backward compatibility and exposes DecayCurve.plot.

DecayCurve(time: np.ndarray, level: np.ndarray, band: float | None = None)

Schroeder backward-integrated decay curve of an impulse response.

time holds the sample times in seconds from the direct sound and level the decay levels in dB (0 dB at time zero), up to the noise truncation point (ISO 3382-1:2009, 5.3.3). band is the octave/third-octave band centre in Hz, or None for a broadband decay.

For backward compatibility with the previous (time, level) tuple return of decay_curve, the dataclass is iterable and unpacks as time, level = decay_curve(...).

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

Plot the decay curve with optional straight T-fit overlays.

Requires matplotlib (pip install phonometry[plot]); returns the Axes. Pass fits=False to omit the EDT/T20/T30 fit lines.

room_parameters(
ir: list[float] | np.ndarray,
fs: int,
limits: tuple[float, float] | None = (125.0, 4000.0),
fraction: int = 1,
zero_phase: bool = False,
) -> RoomAcousticsResult

Room acoustic parameters per ISO 3382-1:2009 / ISO 3382-2:2008.

The impulse response (e.g. acquired with the ISO 18233 swept-sine or MLS methods of phonometry.room_ir) is filtered into fractional-octave bands (IEC 61260) and each band decay curve is obtained by Schroeder backward integration with noise truncation and tail compensation (ISO 3382-1:2009, 5.3.3). Least-squares line fits (ISO 3382-2:2008, Annex C) yield EDT (0 dB to -10 dB, ISO 3382-1, A.2.2), T20 (-5 dB to -25 dB) and T30 (-5 dB to -35 dB), each extrapolated to 60 dB. Clarity C50/C80, definition D50 and centre time Ts follow ISO 3382-1:2009, Equations (A.10), (A.11) and (A.13), with t = 0 at the start of the direct sound.

Values that cannot be evaluated (evaluation range unreachable, or reaching below the noise floor + 10 dB) are NaN. The validity flags apply the dynamic-range criterion of ISO 3382-1:2009, 5.3.3 (noise at least evaluation range + 15 dB below the maximum of the impulse response: 25 dB for EDT), with T20 and T30 raised to 46 dB and 54 dB to absorb the positive bias of the tail compensation and keep a flagged-valid decay time within the 5 % JND (ISO 3382-1:2009, Table A.1).

Parameters

NameDescription
irMeasured impulse response (1D).
fsSample rate in Hz.
limits(f_min, f_max) band-centre limits in Hz; default octave bands 125 Hz to 4 kHz (ISO 3382-1:2009, 5.1). Use (100.0, 5000.0) with fraction=3 for the one-third-octave engineering/precision range. None analyses the broadband response as a single band (frequency is then None).
fractionBandwidth fraction (1 = octave, 3 = one-third octave). Default 1.
zero_phaseIf True, use forward-backward (zero-phase) octave filtering, removing the filter group delay before the backward integration. ISO 3382-2:2008 Clause 7.3 NOTE permits time-reversed filtering (relaxing B*T > 16 to B*T > 4); it roughly halves the 125 Hz short-decay T30 bias (about +4.9 % -> +2.4 % at T = 0.2 s). The benefit is small next to the ~10 % measurement variance but is free and standards-sanctioned. Default False (causal filtering).

Returns: RoomAcousticsResult with one entry per band.

RoomAcousticsResult(
frequency: np.ndarray | None,
edt: np.ndarray,
t20: np.ndarray,
t30: np.ndarray,
c50: np.ndarray,
c80: np.ndarray,
d50: np.ndarray,
ts: np.ndarray,
dynamic_range: np.ndarray,
edt_valid: np.ndarray,
t20_valid: np.ndarray,
t30_valid: np.ndarray,
curvature: np.ndarray,
)

Per-band room acoustic parameters from one impulse response.

All arrays have one entry per analysis band (frequency holds the exact band centre frequencies; it is None for a broadband analysis, in which case the arrays have length 1). edt, t20 and t30 are decay times in seconds extrapolated to 60 dB (ISO 3382-1:2009, A.2.2; ISO 3382-2:2008, Clause 6); c50/c80 are early-to-late indices in dB (Equation (A.10)), d50 the definition ratio (Equation (A.11)) and ts the centre time in seconds (Equation (A.13); the Table A.1 JND is 10 ms).

dynamic_range is the peak-to-noise-floor distance of the squared band impulse response in dB. edt_valid, t20_valid and t30_valid apply the ISO 3382-1:2009, 5.3.3 criterion (noise at least evaluation range + 15 dB below the maximum: 25 dB for EDT), with T20 and T30 tightened to 46 dB and 54 dB to absorb the positive bias of the tail compensation (5.3.3, Eq. (3)) and keep a flagged-valid value within the 5 % JND (ISO 3382-1:2009, Table A.1); they are False when the value could not be evaluated. curvature is C = 100*(T30/T20 - 1) in percent (ISO 3382-2:2008, B.3); values above 10 % indicate an unreliable, non-straight decay.

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

Plot per-band decay times (EDT/T20/T30) and clarity (C50/C80).

Invalid bands are hatched and greyed. With ax given, only the decay-times panel is drawn on it. Requires matplotlib (pip install phonometry[plot]); returns the Axes (or array thereof).

RoomAcousticsResult.report(
path: str,
*,
metadata: ReportMetadata | None = None,
engine: str = 'reportlab',
verbose: bool = False,
language: str = 'en',
) -> str

Render a room acoustic parameters fiche to a PDF (ISO 3382-1/-2).

Writes a one-page report laid out like a room-acoustics measurement report: the standard-basis line, an optional metadata header block (room, volume, source/receiver positions, climate …), the full-width per-band parameter table (T20/T30/EDT and C50/C80/D50/Ts) above the result’s own per-band decay-time plot (plot), the boxed mid-frequency reverberation time T_mid (the mean of the 500 Hz and 1000 Hz band T30; a one-third-octave analysis averages the 500 Hz and 1 kHz one-third-octave bands and labels them as such), an optional verdict row and a footer with the fixed disclaimer. ISO 3382-1/-2 are characterisation standards with no intrinsic pass/fail, so the verdict row appears only when a target mid-frequency T is supplied through metadata.requirement (read as the maximum acceptable T_mid). A broadband result (frequency is None) has no 500 Hz and 1000 Hz bands to average, so the box and the verdict fall back to the plain broadband T30 instead of a mid-frequency average, with no “500-1000 Hz” label; a band range without both mid bands boxes its first finite T30 band, named explicitly.

Parameters

NameDescription
pathDestination path of the PDF file.
metadataOptional ReportMetadata; None produces a bare characterisation fiche (body, result and disclaimer only). The room-specific fields room_volume, source_positions and receiver_positions populate the header; requirement is read as the maximum mid-frequency reverberation time.
engineRendering back end; only "reportlab" is supported.
verboseAccepted for parity with the other fiches; the room table already shows every computed parameter, so it has no effect.
languageFiche language: "en" (default, English) or "es" (Spanish, with a comma decimal separator).

Returns: The written path as a str.

Raises

ExceptionWhen
ValueErrorIf engine is not "reportlab".
ImportErrorIf reportlab is not installed (pip install phonometry[report]).
Created and maintained by· GitHub· PyPI· All projects