<!-- canonical: https://jmrplens.github.io/phonometry/reference/api/materials/road-absorption/ -->
Source: https://jmrplens.github.io/phonometry/reference/api/materials/road-absorption/

In-situ sound absorption of road surfaces (ISO 13472-1 / ISO 13472-2).

Two complementary standardised in-situ methods are supported here. They target
opposite ends of the absorption scale and are **not** interchangeable:

* **BS ISO 13472-1:2002** - *extended surface method*. A free-field impulse
  response is measured over the road, the direct (incident) and surface
  (reflected) components are separated in the time domain by the subtraction
  technique and an **Adrienne-type temporal window** (Clause 6.4), transformed
  to frequency, and ratioed. The normal-incidence sound absorption coefficient
  is (Clause 4.1):

```text
alpha(f) = 1 - QW(f) = 1 - (1 / Kr^2) * | Hr(f) / Hi(f) |^2
```

  with `Hi`/`Hr` the incident/reflected transfer functions and `Kr` the
  geometrical-spreading factor `Kr = (ds - dm) / (ds + dm)` for the mandatory
  geometry `ds = 1.25 m` (source-to-plane) and `dm = 0.25 m` (mic-to-plane),
  giving `Kr = 2/3` (Clause 4.2 / Annex C). The complex pressure reflection
  factor `Qp = (1/Kr)(Hr/Hi) exp(+j 2 pi f dtau)` with `dtau = 2 dm / c`
  (Annex C) is available for theory comparison. A highly reflective reference
  surface removes the electro-acoustic chain error and the geometry factor by a
  ratio (Annex B), and non-normal incidence uses `Kr,theta` (Annex F).

* **BS ISO 13472-2:2010** - *spot method*. This is an **in-situ application of
  the ISO 10534-2 two-microphone impedance tube** for reflective surfaces
  (measured `alpha` below ~0.15). Part 2 does not restate the
  transfer-function / reflection-factor / absorption mathematics; Clauses 4,
  5.7 and 6.6 defer it to ISO 10534-2. The core computation therefore lives in
  [`phonometry.impedance_tube.two_microphone_impedance`](/phonometry/reference/api/materials/impedance-tube/#two_microphone_impedance) and is **not**
  reimplemented here. This module contributes only the Part-2 tube
  geometry/validity helpers (upper usable frequency, microphone-spacing bounds,
  the 250-1600 Hz one-third-octave working range) and the Annex A internal-loss
  system correction `alpha ~ alpha_measured - alpha_system`.

Sign / normalisation convention (ISO 13472-1): the forward transform is
NumPy's `rfft` with kernel `e^{-j 2 pi f t}` (unnormalised); every quantity
here is a ratio of two transforms from the same processing chain, so the
transform normalisation cancels (Clause 6.1). A pure time delay `tau` of the
reflected path scales its spectrum by `e^{-j 2 pi f tau}`; the optional phase
restoration multiplies by `e^{+j 2 pi f tau}` to recover `Qp` (Annex C /
Annex G, resolving the Clause 4.1 NOTE shorthand to the frequency-dependent
form).

The window durations of the Adrienne window are **not** fixed by the standard:
Clause 6.4 mandates only a sharp leading edge, a 5 ms flat portion and a
cosine-squared or Blackman-Harris trailing edge, with the shape and lengths
**reported per measurement**. They are therefore configurable here and default
to a short leading edge, a 5 ms flat top and a Blackman-Harris trailing edge
(the Annex E example report); the historical fixed edge timings are **not**
hard-coded as if normative.

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

## absorption_reference_corrected

```python
absorption_reference_corrected(
    road_reflection: ArrayLike,
    reference_reflection: ArrayLike,
) -> Real
```

Reference-corrected road absorption (ISO 13472-1:2002, Annex B).

Dividing the road and reference measured pressure reflection factors removes
both the electro-acoustic chain error `e(f)` and, because the geometry is
identical, the `Kr` factor:

```text
Qp,road(f) = Qp,road,meas(f) / Qp,ref,meas(f)
alpha_road(f) = 1 - |Qp,road,meas(f) / Qp,ref,meas(f)|^2
```

The reference surface is assumed totally reflecting (`|Qp,ref| = 1`,
checked in an impedance tube to have absorption \< 0.05, Annex B).

**Parameters**

| Name | Description |
| :--- | :--- |
| `road_reflection` | Measured road pressure reflection factor `Qp,road,meas` (complex; the `1 / Kr` scaling need not be removed as it cancels). |
| `reference_reflection` | Measured reference pressure reflection factor `Qp,ref,meas` (complex, same geometry and chain). |

**Returns:** Reference-corrected road absorption coefficient `alpha_road(f)`.

## adrienne_window

```python
adrienne_window(
    fs: float | None = None,
    *,
    flat_duration: float = 0.005,
    leading_duration: float = 0.0005,
    trailing_duration: float = 0.005,
    leading_edge: str = 'blackman-harris',
    trailing_edge: str = 'blackman-harris',
    sample_rate: float | str = 'deprecated',
) -> Real
```

Adrienne-type temporal window (ISO 13472-1:2002, Clause 6.4).

Clause 6.4 mandates a **sharp leading edge**, a **5 ms flat portion** and a
**cosine-squared or Blackman-Harris trailing edge** so as to suppress
frequency-domain oscillations (Figure 4); the shape and the durations are
*reported per measurement* rather than fixed by the standard. All three
durations are therefore configurable. The window is the concatenation of a
rising leading half-taper, a unit-valued flat portion and a falling trailing
half-taper:

```text
w = [ rising_edge (0 -> 1) | flat (== 1) | trailing_edge (1 -> 0) ]
```

The defaults (short 0.5 ms leading edge, 5 ms flat top, 5 ms Blackman-Harris
trailing edge) follow the Annex E example report; they are **not** a
normative fixed set of timings. The lower usable frequency scales as
`~ 1 / T_window` (Clause 6.4), so report the durations used.

**Parameters**

| Name | Description |
| :--- | :--- |
| `fs` | Sampling frequency, in hertz (ISO 13472-1 Clause 6.2 requires `fs > 40 kHz` in practice). |
| `flat_duration` | Flat-portion duration, in seconds (default 5 ms). |
| `leading_duration` | Leading-edge (rise) duration, in seconds; 0 gives a sharp step onset. |
| `trailing_duration` | Trailing-edge (fall) duration, in seconds. |
| `leading_edge` | Leading-edge shape, `"blackman-harris"` or `"cosine-squared"`. |
| `trailing_edge` | Trailing-edge shape, `"blackman-harris"` or `"cosine-squared"`. |
| `sample_rate` | Deprecated alias of `fs` (remove in 4.0). |

**Returns:** The time-domain window, one sample per `1 / fs` (length `round((leading + flat + trailing) * fs)` samples).

**Raises**

| Exception | When |
| :--- | :--- |
| ValueError | If `fs` is missing or not positive, a duration is negative, the flat duration is not positive, or an edge shape is unknown. |

## check_spot_frequency_range

```python
check_spot_frequency_range(frequency: ArrayLike) -> None
```

Advise when a spot-method frequency is out of range (ISO 13472-2, Scope).

The spot method is valid over the one-third-octave bands 250-1600 Hz
(narrow-band 220-1800 Hz). Frequencies outside [`SPOT_FREQUENCY_RANGE`](/phonometry/reference/api/materials/road-absorption/#spot_frequency_range)
raise a [`RoadAbsorptionWarning`](/phonometry/reference/api/materials/road-absorption/#roadabsorptionwarning); results there are advisory.

**Parameters**

| Name | Description |
| :--- | :--- |
| `frequency` | Frequencies to check, in hertz. |

**Raises**

| Exception | When |
| :--- | :--- |
| ValueError | If any frequency is negative. |

## DEFAULT_MIC_HEIGHT

*Constant* (`float`).

```python
DEFAULT_MIC_HEIGHT = 0.25
```

## DEFAULT_SOURCE_HEIGHT

*Constant* (`float`).

```python
DEFAULT_SOURCE_HEIGHT = 1.25
```

## DEFAULT_SPEED_OF_SOUND

*Constant* (`float`).

```python
DEFAULT_SPEED_OF_SOUND = 340.0
```

## geometric_spreading_factor

```python
geometric_spreading_factor(
    source_height: float = 1.25,
    mic_height: float = 0.25,
) -> float
```

Geometrical-spreading factor `Kr` (ISO 13472-1:2002, Clause 4.1).

`Kr = (ds - dm) / (ds + dm)`. It corrects the reflected path for the
extra spherical spreading over the image-source distance `ds + dm`
relative to the direct distance `ds - dm` (Annex C). The mandatory
geometry `ds = 1.25 m`, `dm = 0.25 m` gives `Kr = 2/3` (Clause 4.2).

**Parameters**

| Name | Description |
| :--- | :--- |
| `source_height` | Source-to-reference-plane distance `ds`, in metres. |
| `mic_height` | Microphone-to-reference-plane distance `dm`, in metres. |

**Returns:** Geometrical-spreading factor `Kr` (dimensionless, `0 < Kr < 1`).

**Raises**

| Exception | When |
| :--- | :--- |
| ValueError | If `ds` or `dm` is not positive or `ds <= dm`. |

## geometric_spreading_factor_angle

```python
geometric_spreading_factor_angle(
    incidence_angle: float,
    source_height: float = 1.25,
    mic_height: float = 0.25,
) -> float
```

Oblique geometrical-spreading factor `Kr,theta` (ISO 13472-1, Annex F).

`Kr,theta^2 = 1 - cos^2(theta) * (1 - Kr^2)` with `Kr` the normal-
incidence factor of [`geometric_spreading_factor`](/phonometry/reference/api/materials/road-absorption/#geometric_spreading_factor). At `theta = 0` the
cosine is unity and `Kr,theta` collapses to `Kr` (Clause 4.1).

**Parameters**

| Name | Description |
| :--- | :--- |
| `incidence_angle` | Incidence angle `theta`, in **radians**. |
| `source_height` | Source-to-reference-plane distance `ds`, in metres. |
| `mic_height` | Microphone-to-reference-plane distance `dm`, in metres. |

**Returns:** Oblique factor `Kr,theta` (positive root, dimensionless).

## insitu_absorption_coefficient

```python
insitu_absorption_coefficient(
    incident_ir: ArrayLike,
    reflected_ir: ArrayLike,
    *,
    source_height: float = 1.25,
    mic_height: float = 0.25,
    incidence_angle: float = 0.0,
    n: int | None = None,
) -> Real
```

Normal-incidence absorption coefficient `alpha(f)` (ISO 13472-1, 4.1).

`alpha(f) = 1 - QW(f) = 1 - (1 / Kr^2) * |Hr(f) / Hi(f)|^2` (the direct
energy route via [`power_reflection_coefficient`](/phonometry/reference/api/materials/road-absorption/#power_reflection_coefficient); for oblique incidence
`Kr` is replaced by `Kr,theta`, Annex F). Non-specularly reflected energy
is treated as absorbed, so `alpha` may be slightly overestimated
(Clause 4.1).

**Parameters**

| Name | Description |
| :--- | :--- |
| `incident_ir` | Windowed incident impulse response `hi(t)`, real. |
| `reflected_ir` | Windowed reflected impulse response `hr(t)`, real. |
| `source_height` | Source-to-plane distance `ds`, in metres. |
| `mic_height` | Microphone-to-plane distance `dm`, in metres. |
| `incidence_angle` | Incidence angle `theta`, in radians (0 = normal). |
| `n` | FFT length; defaults to the longer input. |

**Returns:** Absorption coefficient `alpha(f)` at the `rfft` frequency bins.

## insitu_absorption_from_reflection

```python
insitu_absorption_from_reflection(reflection: ArrayLike) -> Real
```

Absorption coefficient from the reflection factor (ISO 13472-1, 4.1).

`alpha = 1 - |r|^2`. With `r` already carrying the `1 / Kr` factor
(see [`insitu_reflection_factor`](/phonometry/reference/api/materials/road-absorption/#insitu_reflection_factor)) this is the **reflection-factor route** to
`alpha` and equals the direct energy route of
[`insitu_absorption_coefficient`](/phonometry/reference/api/materials/road-absorption/#insitu_absorption_coefficient).

**Parameters**

| Name | Description |
| :--- | :--- |
| `reflection` | Complex reflection factor `r`. |

**Returns:** Absorption coefficient `alpha` (real).

## insitu_absorption_spectrum

```python
insitu_absorption_spectrum(
    incident_ir: ArrayLike,
    reflected_ir: ArrayLike,
    fs: float | None = None,
    *,
    source_height: float = 1.25,
    mic_height: float = 0.25,
    incidence_angle: float = 0.0,
    n: int | None = None,
    f_min: float = 250.0,
    f_max: float = 4000.0,
    clip_negative: bool = True,
    sample_rate: float | str = 'deprecated',
) -> InsituAbsorptionResult
```

In-situ one-third-octave absorption spectrum (ISO 13472-1, Clause 4.1).

End-to-end convenience: the windowed incident and reflected impulse
responses give the narrow-band absorption via
[`insitu_absorption_coefficient`](/phonometry/reference/api/materials/road-absorption/#insitu_absorption_coefficient), which is then reduced to
one-third-octave bands with [`one_third_octave_absorption`](/phonometry/reference/api/materials/road-absorption/#one_third_octave_absorption) and wrapped
in a plottable [`InsituAbsorptionResult`](/phonometry/reference/api/materials/road-absorption/#insituabsorptionresult).

**Parameters**

| Name | Description |
| :--- | :--- |
| `incident_ir` | Windowed incident (direct-path) impulse response `hi`. |
| `reflected_ir` | Windowed reflected-path impulse response `hr`. |
| `fs` | Sampling frequency, in hertz. |
| `source_height` | Source-to-plane distance `ds`, in metres. |
| `mic_height` | Microphone-to-plane distance `dm`, in metres. |
| `incidence_angle` | Incidence angle `theta`, in radians (0 = normal). |
| `n` | FFT length; defaults to the longer of the two impulse responses. |
| `f_min` | Lowest band centre to report, in hertz (default 250 Hz). |
| `f_max` | Highest band centre to report, in hertz (default 4000 Hz). |
| `clip_negative` | Clip negative band results to zero (default `True`). |
| `sample_rate` | Deprecated alias of `fs` (remove in 4.0). |

**Returns:** An [`InsituAbsorptionResult`](/phonometry/reference/api/materials/road-absorption/#insituabsorptionresult) with `.plot()`.

**Raises**

| Exception | When |
| :--- | :--- |
| ValueError | On empty inputs, invalid geometry, or a missing or non-positive `fs`. |

## insitu_reflection_factor

```python
insitu_reflection_factor(
    incident_ir: ArrayLike,
    reflected_ir: ArrayLike,
    *,
    source_height: float = 1.25,
    mic_height: float = 0.25,
    incidence_angle: float = 0.0,
    fs: float | None = None,
    delay: float | None = None,
    n: int | None = None,
    sample_rate: float | str = 'deprecated',
) -> Complex
```

Complex pressure reflection factor `r(f)` (ISO 13472-1, Clause 4.1).

`r(f) = (1 / Kr) * Hr(f) / Hi(f)` from the windowed reflected and incident
impulse responses, with `Hr`/`Hi` their real FFTs and `Kr` the
geometrical-spreading factor (or `Kr,theta` when `incidence_angle` is
given, Annex F). When both `fs` and `delay` are supplied the
reflected-path time offset is undone by `exp(+j 2 pi f * delay)`, yielding
the complex `Qp` of the Clause 4.1 NOTE (with `delay = dtau = 2 dm / c`,
Annex C; the frequency-dependent form of Annex G).

**Parameters**

| Name | Description |
| :--- | :--- |
| `incident_ir` | Windowed incident (direct-path) impulse response `hi(t)`, real, one sample per `1 / fs`. |
| `reflected_ir` | Windowed reflected-path impulse response `hr(t)`, real, same sampling as `incident_ir`. |
| `source_height` | Source-to-plane distance `ds`, in metres. |
| `mic_height` | Microphone-to-plane distance `dm`, in metres. |
| `incidence_angle` | Incidence angle `theta`, in radians (0 = normal). |
| `fs` | Sampling frequency, in hertz; required with `delay` for phase restoration. |
| `delay` | Reflected-path delay `dtau` to undo, in seconds; `None` returns the raw spectral ratio. |
| `n` | FFT length; defaults to the longer of the two impulse responses. |
| `sample_rate` | Deprecated alias of `fs` (remove in 4.0). |

**Returns:** Complex reflection factor `r(f)` at the `rfft` frequency bins.

**Raises**

| Exception | When |
| :--- | :--- |
| ValueError | On empty inputs, invalid geometry, or `delay` given without `fs`. |

## InsituAbsorptionResult

```python
InsituAbsorptionResult(frequencies: Real, absorption: Real)
```

An in-situ one-third-octave absorption spectrum (ISO 13472-1).

**Attributes**

| Name | Description |
| :--- | :--- |
| `frequencies` | One-third-octave band centre frequencies, in hertz. |
| `absorption` | Sound-absorption coefficient `alpha` per band (a band with no contributing narrow-band samples is `nan`). |

### InsituAbsorptionResult.plot()

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

Plot the in-situ absorption spectrum `alpha(f)`.

Requires matplotlib (`pip install phonometry[plot]`); returns the
`Axes` and never calls `plt.show`.

## max_sampled_area_radius

```python
max_sampled_area_radius(
    window_width: float,
    *,
    source_height: float = 1.25,
    mic_height: float = 0.25,
    speed_of_sound: float = 340.0,
) -> float
```

Radius of the maximum sampled area (ISO 13472-1:2002, Annex A).

For normal incidence the maximum sampled area is a circle of radius (m):

```text
r = (1 / (ds + dm + c Tw))
    * sqrt[ (ds + dm + c Tw/2)(ds + c Tw/2)(2 dm + c Tw)(c Tw) ]
```

with `Tw` the width of the temporal window isolating the reflected wave.
The Annex A worked example (`ds = 1.25`, `dm = 0.25`, `c = 340` m/s,
and the 5 ms flat window) gives `r ~ 1.34 m`.

**Parameters**

| Name | Description |
| :--- | :--- |
| `window_width` | Temporal-window width `Tw` (reflected wave), seconds. |
| `source_height` | Source-to-plane distance `ds`, in metres. |
| `mic_height` | Microphone-to-plane distance `dm`, in metres. |
| `speed_of_sound` | Speed of sound `c`, in metres per second. |

**Returns:** Maximum-sampled-area radius `r`, in metres.

**Raises**

| Exception | When |
| :--- | :--- |
| ValueError | On non-positive geometry or window width. |

## msa_major_axis

```python
msa_major_axis(
    window_width: float,
    projected_distance: float,
    *,
    source_height: float = 1.25,
    mic_height: float = 0.25,
    speed_of_sound: float = 340.0,
) -> float
```

Major axis of the oblique sampled-area ellipsoid (ISO 13472-1, Annex F).

`a = c Tw + sqrt((ds + dm)^2 + dp^2)` for the ellipsoid of revolution with
the source and microphone at its foci; `dp` is the source-to-microphone
distance projected on the reference plane.

**Parameters**

| Name | Description |
| :--- | :--- |
| `window_width` | Temporal-window width `Tw`, in seconds. |
| `projected_distance` | Projected source-to-mic distance `dp`, in metres. |
| `source_height` | Source-to-plane distance `ds`, in metres. |
| `mic_height` | Microphone-to-plane distance `dm`, in metres. |
| `speed_of_sound` | Speed of sound `c`, in metres per second. |

**Returns:** Major axis `a`, in metres.

**Raises**

| Exception | When |
| :--- | :--- |
| ValueError | On non-positive window width, speed, or negative `dp`. |

## one_third_octave_absorption

```python
one_third_octave_absorption(
    frequency: ArrayLike,
    absorption: ArrayLike,
    *,
    f_min: float = 250.0,
    f_max: float = 4000.0,
    clip_negative: bool = True,
) -> tuple[Real, Real]
```

Aggregate narrow-band absorption into one-third-octave bands.

Both parts require a **linear average** of the narrow-band absorption over
each one-third-octave band (ISO 13472-1 Clause 4.1; ISO 13472-2 Clause 6.6),
keeping negative narrow-band values during the averaging. The band edges are
the IEC base-two limits `fc * 2^(+/-1/6)`. Negative one-third-octave
results are set to zero when `clip_negative` is true (ISO 13472-2
Clause 6.6 step 5); Part 1 does not mandate clipping, so pass
`clip_negative=False` to reproduce its raw output.

**Parameters**

| Name | Description |
| :--- | :--- |
| `frequency` | Narrow-band frequencies, in hertz. |
| `absorption` | Narrow-band absorption values aligned with `frequency`. |
| `f_min` | Lowest band centre to report, in hertz (default 250 Hz). |
| `f_max` | Highest band centre to report, in hertz (4000 Hz for Part 1; pass 1600 Hz for the Part-2 range). |
| `clip_negative` | Set negative band results to zero (default `True`). |

**Returns:** Tuple `(band_centres, band_absorption)`; a band with no narrow-band samples yields `nan`.

**Raises**

| Exception | When |
| :--- | :--- |
| ValueError | If `frequency` and `absorption` differ in length or are empty. |

## PART1_FREQUENCY_RANGE

*Constant* (`tuple`).

```python
PART1_FREQUENCY_RANGE = (250.0, 4000.0)
```

## power_reflection_coefficient

```python
power_reflection_coefficient(
    incident_ir: ArrayLike,
    reflected_ir: ArrayLike,
    *,
    source_height: float = 1.25,
    mic_height: float = 0.25,
    incidence_angle: float = 0.0,
    n: int | None = None,
) -> Real
```

Sound-power reflection factor `QW(f)` (ISO 13472-1, Clause 4.1 / Annex C).

The **direct energy route** `QW(f) = (1 / Kr^2) * |Hr(f) / Hi(f)|^2`
(`Kr,theta` for oblique incidence). It equals `|r|^2` from
[`insitu_reflection_factor`](/phonometry/reference/api/materials/road-absorption/#insitu_reflection_factor) but is formed from magnitudes only, so it is
independent of any reflected-path time offset.

**Parameters**

| Name | Description |
| :--- | :--- |
| `incident_ir` | Windowed incident impulse response `hi(t)`, real. |
| `reflected_ir` | Windowed reflected impulse response `hr(t)`, real. |
| `source_height` | Source-to-plane distance `ds`, in metres. |
| `mic_height` | Microphone-to-plane distance `dm`, in metres. |
| `incidence_angle` | Incidence angle `theta`, in radians. |
| `n` | FFT length; defaults to the longer input. |

**Returns:** Sound-power reflection factor `QW(f)` (real).

## reflected_path_delay

```python
reflected_path_delay(
    mic_height: float = 0.25,
    speed_of_sound: float = 340.0,
) -> float
```

Reflected-path arrival delay `dtau` (ISO 13472-1:2002, Annex C).

`dtau = 2 dm / c` is the time difference between the direct and the
surface-reflected impulses for the normal-incidence geometry; it is the
delay undone by the phase-restoration term of [`insitu_reflection_factor`](/phonometry/reference/api/materials/road-absorption/#insitu_reflection_factor).

**Parameters**

| Name | Description |
| :--- | :--- |
| `mic_height` | Microphone-to-reference-plane distance `dm`, in metres. |
| `speed_of_sound` | Speed of sound `c`, in metres per second. |

**Returns:** Delay `dtau`, in seconds.

**Raises**

| Exception | When |
| :--- | :--- |
| ValueError | If `dm` or `c` is not positive. |

## RoadAbsorptionWarning

Advisory for out-of-range in-situ road-absorption frequencies.

## SPOT_FREQUENCY_RANGE

*Constant* (`tuple`).

```python
SPOT_FREQUENCY_RANGE = (250.0, 1600.0)
```

## spot_internal_loss_correction

```python
spot_internal_loss_correction(
    measured_absorption: ArrayLike,
    system_absorption: ArrayLike,
    *,
    clip_negative: bool = True,
) -> Real
```

Internal-loss (system) correction (ISO 13472-2:2010, Annex A).

The tube reads all thermal/viscous losses between the microphones and the
surface as absorption. For reflective surfaces this is removed by
subtracting the reading on a totally reflecting reference plate:

```text
alpha(f) ~ alpha_measured(f) - alpha_system(f)
```

Valid because both terms are small (measured \< 0.15, internal \< 0.03). This
is the **subtractive** Part-2 correction and must not be confused with the
Part-1 ratio correction ([`absorption_reference_corrected`](/phonometry/reference/api/materials/road-absorption/#absorption_reference_corrected)). Negative
one-third-octave results are set to zero when `clip_negative` is true
(Clause 6.6 step 5).

**Parameters**

| Name | Description |
| :--- | :--- |
| `measured_absorption` | Measured road absorption `alpha_m(f)`. |
| `system_absorption` | Reference-plate (system) absorption `alpha_system(f)`, same bands. |
| `clip_negative` | Set negative corrected values to zero (default `True`). |

**Returns:** Corrected absorption coefficient `alpha(f)`.

**Raises**

| Exception | When |
| :--- | :--- |
| ValueError | If the two inputs differ in shape. |

## spot_microphone_spacing_bounds

```python
spot_microphone_spacing_bounds(
    speed_of_sound: float = 340.0,
    *,
    f_min: float = 220.0,
    f_max: float = 1800.0,
) -> tuple[float, float]
```

Microphone-spacing bounds `(s_min, s_max)` (ISO 13472-2:2010, 5.4.2).

`s_max < 0.45 c0 / f_max` avoids spacing approaching half a wavelength at
the top frequency, and `s_min > 0.05 c0 / f_min` keeps the spacing above
5 % of a wavelength at the bottom frequency. For the narrow band
220-1800 Hz (`c0 ~ 340 m/s`) these give `s_max ~ 85 mm` and
`s_min ~ 77 mm`, bracketing the nominal `s = (81 +/- 4) mm`.

**Parameters**

| Name | Description |
| :--- | :--- |
| `speed_of_sound` | Speed of sound `c0`, in metres per second. |
| `f_min` | Lowest frequency of interest `f_min`, in hertz. |
| `f_max` | Highest frequency of interest `f_max`, in hertz. |

**Returns:** Tuple `(s_min, s_max)` of the lower and upper spacing limits, m.

**Raises**

| Exception | When |
| :--- | :--- |
| ValueError | On non-positive speed or frequency, or `f_min >= f_max`. |

## SPOT_NARROW_BAND_RANGE

*Constant* (`tuple`).

```python
SPOT_NARROW_BAND_RANGE = (220.0, 1800.0)
```

## spot_tube_upper_frequency

```python
spot_tube_upper_frequency(
    diameter: float,
    speed_of_sound: float = 340.0,
) -> float
```

Upper usable frequency of the spot tube (ISO 13472-2:2010, Clause 5.4.1).

`f_u = 0.58 c0 / d` (circular tube), the highest frequency at which only
plane waves propagate. A 100 mm tube at `c0 = 340 m/s` gives
`f_u ~ 1972 Hz`, comfortably above the 1800 Hz narrow-band top.

**Parameters**

| Name | Description |
| :--- | :--- |
| `diameter` | Tube diameter `d`, in metres. |
| `speed_of_sound` | Speed of sound `c0`, in metres per second. |

**Returns:** Upper usable frequency `f_u`, in hertz.

**Raises**

| Exception | When |
| :--- | :--- |
| ValueError | If `d` or `c0` is not positive. |
