A weighting again

Using Nyquist scripts in Audacity.
Post and download new plug-ins.

If you require help using Audacity, please post on the forum board relevant to your operating system:
Windows
Mac OS X
GNU/Linux and Unix-like

A weighting again

Permanent link to this post Posted by dulciepercy » Wed Oct 01, 2014 2:07 am

Hello, my first post on the forum.

Some years ago on the mailing list I made some analysis plugins based on Mikael O's A weighting plugin. But I've lost them and I'm recreating them from old emails..

But this base plugin that started it all no longer works - it should return two labels with Leq and LMax, but instead it applies the a-weighting filter to the audio. I've been through it line by line with a two channel version that works, but I can't work out what's going on.

If you've set "type analyze:" it shouldn't return audio at all anyway, should it? Can anyone help me?



Code: Select all
;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, [email protected]
; 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))
dulciepercy
 
Posts: 2
Joined: Wed Oct 01, 2014 1:46 am
Operating System: Please select

Re: A weighting again

Permanent link to this post Posted by steve » Wed Oct 01, 2014 3:35 am

Line 24
Code: Select all
(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)))


it should have:
Code: Select all
-0.125

not
Code: Select all
- 0.125
(there should be no space between the "-" and "0.125")

That particular expression would be better written as:
Code: Select all
(exp (/ (* -0.125 (snd-srate sa))))


It's really quite bad style to write huge long lines like that which then require a paragraph of explanation, and, as you've found, it makes the code difficult to debug.
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)
steve
Site Admin
 
Posts: 45396
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: A weighting again

Permanent link to this post Posted by steve » Wed Oct 01, 2014 3:50 am

To answer a question in the code comment:
The 441 could be replaced by
Code: Select all
(setf step (round (/ *sound-srate* 100.0)))

Then use "step" instead of 441.
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)
steve
Site Admin
 
Posts: 45396
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: A weighting again

Permanent link to this post Posted by dulciepercy » Wed Oct 01, 2014 6:17 am

Thank you so much, it's working again.

Yes the long lines also make it difficult to understand what's going on.
dulciepercy
 
Posts: 2
Joined: Wed Oct 01, 2014 1:46 am
Operating System: Please select

Re: A weighting again

Permanent link to this post Posted by Robert J. H. » Wed Oct 01, 2014 7:41 am

The code should also look like this:
Code: Select all
;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, [email protected]
; 2007-01-12
; Licensed under GPL, no warranty, use at your own risk...
;
; Set the output format to 3 digits (example: 53.3 dB)
(setq *float-format* "%#3.3g");
; A-Weighting Filter
(defun cascade (s freqs &aux (f (car freqs)))
  (cond
    ((null f) s)
    ((minusp f) (cascade (lp s (- f)) (cdr freqs)))
    (t (cascade (hp s f) (cdr freqs)))))
;;
;; Main
(let* (
   ; Calibration so that a 1000 Hz tone with amplitude 1.0
   ; gives 94 dB
   (calibration (+ 94 28.2))
   ; A-weighting frequencies by Edgar (thanks!)
   (freqs '(20.6 20.6 107.7 737.9 -12200 -12200))
   (sa (cascade s freqs))
   (step (round (/ *sound-srate* 100.0)))
   (saf2 (snd-avg (biquad (prod sa sa)
                          1e-6   0 0 1   (exp (/ -8 (snd-srate sa))) 0)
                  step step OP-AVERAGE))
   ; Length of the downsampled pressure squared signal
   (mlength(snd-length saf2 ny:all))
   ; Calc. the equivalent level
   (leq (+ calibration (* 0.5 (linear-to-db (snd-maxsamp (snd-avg saf2 mlength mlength OP-AVERAGE))))))
   ; Calc. the maximum level
   (lmax (+ calibration (* 0.5 (linear-to-db (snd-maxsamp saf2)))));
   ; Output result as a label track (or append into existing label track)
   (u (format nil "LAeq= ~A  LAFmax= ~A" leq lmax)))
 u; Sends output to message box if next is commented out
; (list (list 0.0 u))
); end let*


The 0.000001 gain is completely in the biquad section and the exp term is also simplified.
The filtering is "out-sourced".
Is the filter correct, has any one checked against all frequencies?
(lp and hp are not "normal" filter types)
I think mlength can get too high for long audio and snd-avg won't therefore return a valuable result for LAeq.
Robert J. H.
 
Posts: 1813
Joined: Thu May 31, 2012 8:33 am
Operating System: Windows 7

Re: A weighting again

Permanent link to this post Posted by steve » Wed Oct 01, 2014 3:56 pm

Robert J. H. wrote:The code should also look like this:

Thanks Robert, that is much more readable :)

Also to mention, it helps a lot if variable names are meaningful. For example, what are "SA" and "SAF2"?
It is good to keep variable names reasonably brief, but sufficiently long to be clear what they are.

Robert J. H. wrote:Is the filter correct, has any one checked against all frequencies?

I've previously checked the A-weighting filter from Edgar-rft and it is a reasonably close approximation. I've not checked the biquad expression.
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)
steve
Site Admin
 
Posts: 45396
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu


Return to Nyquist



Who is online

Users browsing this forum: No registered users and 3 guests