måndag 31 maj 2010

A-weighting in Audacity



A while ago (in 2007) I wrote the following Nyquist plug-in for Audacity that calculates the A-weighted equivalent and maximum level with time weighting FAST and appends them in a label track below the selected audio.

It only works for mono audio tracks and for a sampling frequency of 44.1 kHz (the equivalent level is OK for higher frequencies but the maximum is not).

The A-weighting solution was posted by Edgar to the Audacity-nyquist mailing list.

Place the file in the plug-in directory of Audacity and restart it (Audacity that is..).

Any improvements or comments are welcome.

There is also an Audacity forum post where the plug-in is included.




;nyquist plug-in
;version 1
;type analyze
;name "Equivalent and maximum dB(A)..."
;action "Calc. A-weighted equivalent level (LAeq) and maximum level with time weighting FAST (LAFmax)..."

; Mikael Ogren, mr.ogren@gmail.com
; 2007-01-12
; Licensed under GPL, no warranty, use at your own risk...

; Calibration so that a 1000 Hz tone with amplitude 1.0 gives 94 dB
(setq calibration (+ 94 28.2))

; A-weighting by Edgar (thanks!)
(setq sa (lp (lp (hp (hp (hp (hp s 20.6) 20.6) 107.7) 737.9) 12200) 12200) )

; Exponential time-weighting filter FAST (125 ms)
; snd-avg is used to downsample to 100 Hz (by averaging over 441 samples)
; This only works for 44.1 kHz sampling frequency, perhaps someone can help out here
; by making a more general approach that works for all sampl. frq?
; The filtering part is OK for all frequencies, but the "441" constant is not.
; -
; The constant 0.000001 is to avoid clipping at filtered squared pressure > 1.0
(setq saf2
(mult 0.000001
(snd-avg (snd-biquad (mult sa sa ) 1 0 0 (exp (/ 1 (mult (snd-srate sa) -0.125))) 0 0 0) 441 441 OP-AVERAGE)
)
)

; Length of the downsampled pressure squared signal
(setq mlength
(snd-length saf2 99999999999)
)

; Calc. the equivalent level
(setq leq
(+ calibration (* 0.5 (linear-to-db (snd-maxsamp (snd-avg saf2 mlength mlength OP-AVERAGE) ))))
);

; Calc. the maximum level
(setq lmax
(+ calibration (* 0.5 (linear-to-db (snd-maxsamp saf2))))
);

; Set the output format to 3 digits (example: 53.3 dB)
(setq *float-format* "%#3.3g");

; Output result as a label track (or append into existing label track)
(setq u (format NIL "LAeq= ~A LAFmax= ~A" leq lmax))
(list (list 0.0 u))