apply_weighting — ACOUSTICS level op

資料種類:signalsignal

呼叫:import acoustics; acoustics.apply_weighting(x, rate, kind='A')(或 opsacoustics.get("apply_weighting"))

用法

對訊號施加 A / C / Z 頻率加權,零相位。

> 以下的詳細說明為原文 —— 摘要與標題已翻譯。

The weighting is applied as a real, even gain in the frequency domain, so it

introduces no phase distortion and no group delay — the result is aligned

sample-for-sample with the input, which a recursive filter implementation

would not be.

Measured: a 1 kHz sine at 16 kHz (16000 samples, exactly 1000 periods) is

returned unchanged by both A and C weighting — max absolute difference

1.078e-13 for A and 1.225e-13 for C — because both curves are exactly 0 dB

at 1 kHz by construction. A 100 Hz sine of amplitude 1.0 comes back with

amplitude 0.110373 under A weighting, against the closed form

`10**(-19.1428/20) = 0.110373`.

`kind="Z"` returns a copy, unchanged.

**A tone that is not a whole number of periods in the record reads too

loud, by up to 17 dB, and nothing raises.** The multiplication is over the

record's own DFT, which treats it as periodic; a tone that does not close

on itself leaks across every bin. That leakage would be harmless if the

weighting were flat, but A weighting spans about 40 dB between 20 Hz and

1 kHz, so a sidelobe 40 dB below a 31.5 Hz tone arrives at 1 kHz weighted

40 dB *higher* and takes over the sum. Measured, 0.5 s at 48 kHz, error

against the closed-form `A(f)` for a pure tone:

========== ============= ========== ==============

f (Hz) periods error (dB) bin-centred?

========== ============= ========== ==============

22.0 11.0 +0.0000 yes

31.5 15.75 +7.7986 no

20.5 10.25 +17.2116 no (worst, 20-200 Hz)

63.0 31.5 +0.1121 no

100.0 50.0 +0.0000 yes

1000.0 500.0 -0.0000 yes

========== ============= ========== ==============

31.5 Hz is a nominal one-third-octave centre, so this is a path a real

measurement walks into rather than a contrived one. The error is always

*positive* — leakage only ever adds power at frequencies the curve favours.

Two things confirm the diagnosis is dynamic range and not arithmetic. The

same 31.5 Hz tone under C weighting, whose tilt over the same span is a

few dB rather than forty, is off by only +0.0493 dB. And lengthening the

record to where the tone *does* close on itself removes it entirely: at

31.5 Hz the error is +7.7524 dB over 0.25 s, +7.7986 over 0.5 s, +0.4615

over 1 s, and -0.0000 over 2 s and 4 s (63 and 126 whole periods).

Two candidate cures were measured (error in dB against the closed form,

0.5 s at 48 kHz):

=================================== ======== ======== ========

treatment 31.5 Hz 20.5 Hz 22.0 Hz

=================================== ======== ======== ========

as implemented (rectangular) +7.7986 +17.2116 +0.0000

zero-pad x4 (linear convolution) +5.5620 +14.3352 +0.7969

Hann window, corrected for its gain +0.0534 +0.1841 +0.1505

=================================== ======== ======== ========

Padding barely helps — zero-padding a tone puts an abrupt edge into the

record and an edge is broadband. A Hann window does essentially cure it,

turning +17 dB into +0.18 dB, at the cost of the bin-centred columns which

go from exactly 0 to about 0.15 dB. So why is it not the default?

Because it would trade a loud error for a quiet one. `L_eq` is an

*energy average over the record*, and a window is not energy-preserving for

anything that is not stationary. Measured with Z weighting (so the window is

the only thing acting) on a 50 ms 1 kHz burst inside a 0.5 s record, all

three placements being `-13.0103` dB unwindowed as they must be:

============== ============ ===========

burst position Hann (dB) difference

============== ============ ===========

start -36.0587 -23.05

centre -8.8218 +4.19

end -36.0587 -23.05

============== ============ ===========

A window makes the answer depend on *where in the record the sound happened*,

which is precisely the "plausible wrong number" this module refuses to ship

by default. So the rectangular behaviour stays, and the Hann estimate is

available by asking for it: `equivalent_level(..., window="hann")`. Use it

when the record is stationary and tonal — which is exactly when the leakage

bites — and never when the level of a transient is the point.

A cure with neither cost is a different implementation entirely: the

standard cascade of A-weighting biquads in the time domain, which would give

up the exact-0-dB-at-1-kHz-by-construction property this function is built

on, and the zero group delay promised above.

Also worth doing: give the analysis enough record that the content is

many periods long, prefer durations that are whole multiples of the period

you care about, and read a low-frequency A-weighted level from

:func:octave_spectrum (which reports per-band power, so leakage is visible

as energy in bands where none belongs) rather than from a single number.

Raises `ValueError: everything :func:_as_signal` refuses, an unknown

`kind, rate <= 0`.

詳細使用指南

acoustic_condition_monitoring 族使用指南

參考(範例資料・文獻)

• 範例資料目錄(下載 URL / 授權) —— 2-D 用 skimage.data(BSD/公有領域)加合成圖,3-D 給出真實資料源(Stanford/PDS 等)的下載 URL。

• 運算子來歷與參考文獻 —— 該運算子族所依據的研究/方法出處。

• 演算法的正典(作者・年份)與用途見上面的族使用指南

可執行的範例(實際呼叫該運算子並已驗證的樣例)

acoustic_condition_monitoringpy -3.11 examples/acoustic_condition_monitoring.py

型別可銜接的下一個運算子(可接受 signal 作為輸入)

stft · envelope_spectrum · spectral_kurtosis · cepstrum · angular_resample · order_spectrum · octave_spectrum · weighting_response

同類別(level)

octave_bands · octave_spectrum · weighting_response · equivalent_level · percentile_level


*Provenance: acoustics.py — ACOUSTICS 運算子登記表。本條目由 tools/opdocs.py md 自動產生(請勿手動編輯)。*

© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.