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 패밀리 가이드

참고(샘플 데이터·문헌)

• 샘플 데이터 카탈로그(DL URL / 라이선스) —— 2-D 는 skimage.data(BSD/public)+ 합성, 3-D 는 실데이터 소스(Stanford/PDS 등)의 DL 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 연산자 레지스트리. 이 op 노트는 tools/opdocs.py md 가 자동 생성합니다(직접 편집하지 마세요).*

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