Skip to content

Instantly share code, notes, and snippets.

@endolith
Created August 8, 2010 14:20
Show Gist options
  • Save endolith/514077 to your computer and use it in GitHub Desktop.
Save endolith/514077 to your computer and use it in GitHub Desktop.
Audacity waveform analyzer plug-in

The unit dBFS is ambiguous when applied to RMS levels.

For this plug-in, a full-scale sine wave will measure at -3 dBFS RMS.
The RMS level is relative to a full-scale square wave.

Peak amplitude value and RMS measurements are after removing any constant DC offset.
Peak sample measurement will be before the DC offset removal.

These two should be merged

;nyquist plug-in
;version 1
;type analyze
;name "Amplitude statistics..."
;action "Calculate amplitude statistics..."
; endolith@gmail.com
; 2010-08
; Set the output format (example: 53.3 dB)
(setq *float-format* "%#3.2f");
(defun rms-flat (a) ; compute the RMS of a sound
(sqrt (snd-fetch (snd-avg (mult a a) (round len) (round len) OP-AVERAGE)))
)
(defun analyze (s-in) ; code that does the analysis and returns data as a string
; Measure DC
(setq dc-offset (snd-fetch (snd-avg s-in (round len) (round len) OP-AVERAGE)))
; Remove DC
(setq s-in (diff s-in dc-offset))
; Should peak measurement be before or after removing DC?
; Peak samples should be measured before
; Calculate the maximum and RMS levels
; RMS of full scale square wave is 0 dBFS
(setq lmax (snd-maxsamp s-in))
;(setq lmax (linear-to-db (peak s-in ny:all))
(setq lrms (rms-flat s-in))
; A-weighted version of sound - by Edgar (thanks!)
(setq sa (lp (lp (hp (hp (hp (hp s-in 20.6) 20.6) 107.7) 737.9) 12200) 12200) )
; Calculate the RMS level of the A-weighted signal
; constant is a fudge factor to normalize to 0 dB at 1 kHz
(setq larms (* 1.3363917 (rms-flat sa)))
(format NIL
"DC offset: ~a%~%Peak level: ~a (~a dBFS)~%RMS level: ~a (~a dBFS)~%A-weighted: ~a dBFS(A)"
(* dc-offset 100) lmax (linear-to-db lmax) lrms (linear-to-db lrms) (linear-to-db larms))
)
(defun analyze-mono (input) ; for mono tracks
(format NIL "Mono track properties~%~%~a~%"
(analyze input))
)
(defun analyze-stereo (input) ; for stereo tracks
(format NIL "Stereo track properties~%~%Left channel:~%~a~%~%Right channel:~%~a~%"
(analyze (aref input 0))
(analyze (aref input 1)))
)
(if (arrayp s)(analyze-stereo s)(analyze-mono s))
;nyquist plug-in
;version 1
;type analyze
;name "Wave Stats..."
;action "Gathering Data..."
;info "By Steve Daulton. http://audacity.easyspacepro.com Released under GPL v2.\n\nAttempting to analyse too much data may cause Nyquist to crash.\nIn the unlikey event of Audacity crashing, reduce the\n'Maximum Length' to less than 30 seconds."
;; version 0.3
;; A-weighting curve by Edgar
;; Much of inspiration for this plug-in from endolith.
;control time "Maximum Length to Analyse" real "(seconds)" 10 0 30
(setq time (min 30 (max 0 time))) ; 0 < time < 30
(setq bignum (truncate (* time *sound-srate*)))
(setq step (truncate (min bignum LEN))) ; 'peak' requires blocksize and stepsize as integers
(setq *float-format* "%#1.3f")
(setq msg (format NIL "Length of selection: ~a seconds.~%~a samples at ~a Hz.~%"(get-duration 1)(truncate LEN)(truncate *sound-srate*)))
(setq msg (strcat msg (format NIL "Analysis of first ~a seconds:~%(~a samples)~%" (min time (get-duration 1)) step)))
(setq channels (if (arrayp s) 1 0))
(setq *float-format* "%#1.1f")
(defun a-weight (s-in)
(lp (lp (hp (hp (hp (hp s-in 20.6) 20.6) 107.7) 737.9) 12200) 12200))
(defun s-rms (s-in)
(linear-to-dB (sqrt (peak (snd-avg (mult s-in s-in) step step OP-AVERAGE) bignum))))
(defun test (s-in)
(if (> channels 0)
(setq msg (strcat msg (format NIL "~%CHANNEL ~a~%" channels)))
(setq msg (strcat msg (format NIL "~%Mono Track.~%"))))
(setq msg (strcat msg (format NIL "Peak Level: ~a dBFS~%" (linear-to-db (peak s-in bignum)))))
(setq msg (strcat msg (format NIL "Peak Positive: ~a dBFS~%" (linear-to-db (peak (sum 1 (clip (sum s-in -1) 1)) bignum)))))
(setq msg (strcat msg (format NIL "Peak Negative: ~a dBFS~%" (linear-to-db (peak (sum -1 (clip (sum s-in 1) 1)) bignum)))))
(setq msg (strcat msg (format NIL "DC offset: ~a %~%" (* 100.0 (peak (snd-avg s-in step step op-average) bignum)))))
(setq msg (strcat msg (format NIL "RMS: ~a dBFS~%" (s-rms s-in))))
(setq msg (strcat msg (format NIL "RMS (A-weighted): ~a dBFS~%" (+ 2.5664444 (s-rms (a-weight s-in))))))
(setq channels (1+ channels)))
(multichan-expand #'test s)
(format NIL msg)
@grayspires
Copy link

I want to download Wave Stats Plug in as advised by ACX.com as I am a narrator. Unfortunately Adobe won't allow this as it is unsupported and because it was sent by email. Can anyone kindly advise how to get round this, or provide some other way of monitoring RMS levels.

Thanks

Grayspires in the UK

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment