Given an audio file (WAV), I need to find the $\rm L_{A_{eq}}$ (continuous A-weighted equivalent sound pressure level) of the audio file. For this purpose, I am following this workflow:

  1. Get a frame of audio (say $0.125$ seconds of samples)
  2. Scale the samples to find the $\rm SPL \ re \ 20 \ \mu Pa$ based on calibration factor obtained from a calibration tone.
  3. Apply A weighting to the frame of audio data.
  4. For each frame of audio data, find the SPL (dB) as:

$$ \begin{align} \textrm{pressure}_{\rm Ref} &= 20\times10^{-6};\\ \textrm{amplitude}_{\rm rms} &= \sqrt{\rm mean( audData_1frame.^2 )};\\ \textrm{dBspl}_{\rm perFrame} &= 20\times \log_{10}\left(\frac{\rm amplitude_{rms}}{\rm pressure_{Ref }}\right);\\ \end{align} $$

This gives the $\rm SPL \ re \ 20 \ \mu Pa$ of a frame of data. This would be the Short $\rm L_{eq}$.

How do I proceed further to get these 3 quantities:

  • $\rm L_{eq}$ = The total continuous equivalent sound pressure level. This wold be a scalar value for the entire audio file. If it has to be updated in a plot, how do we integrate the SPL of each frame with the previous frames?

  • $\rm L_{eq_{fast}}$ = Sound pressure level with $125\ ms$ time weighting

  • $\rm L_{eq_{slow}}$ = SPL with $1\ s$ time weighting

  • $\begingroup$ Note that A-weighting filter is loosely defined near 20 kHz, and bilinear transform warps the response, so it's probably best to oversample before filtering or use an equi-ripple type filter instead of BLT. I have an accurate A-weighting filter based on standards here github.com/endolith/waveform_analysis/blob/master/… $\endgroup$ – endolith Jul 26 '17 at 19:35
  • $\begingroup$ @endolith : Thanks for sharing the link. Currently, I am using the weighting filters from MathWork's Audio System Toolbox and they are giving pretty good initial results. I will test it out with your code too $\endgroup$ – Arnav Mendiratta Jul 26 '17 at 19:41
  • $\begingroup$ Oh, I didn't know they had that. Theirs should be fine, they're using the same tolerance limits as mine $\endgroup$ – endolith Jul 26 '17 at 19:47


You're measuring the RMS value of the (filtered) samples, which is sqrt(average(samples^2)), so if you're finding the RMS value in multiple chunks, it would just be sqrt(weighted_average(chunk1^2, chunk2^2, chunk3^2, ...)) where the average is weighted by the number of samples in each chunk (typically they are all the same length, but maybe a recording is not an exact multiple of chunk size, for instance).

To find the time weighting, the signal flow is:

  1. Apply A-weighting filter
  2. Square the samples
  3. Apply a low-pass filter with a real pole at 1/τ (where τ is 125 ms or 1 s in your case)
  4. Square root
  5. 20*log10() of the signal to convert to dB

It's the same as the RMS of the weighted signal, above, except that instead of an unweighted average over the whole signal, you're using a sliding-time average (same as https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average I think).

The time-weighted SPL will be a signal, not a scalar for each frame.

  • $\begingroup$ Thanks, your suggestion worked. I had to do some clever math because I'm calculating streaming LAeq values in real-time, but the sqrt(mean(frame1.^2, ..., frameN.^2)) gives me good results. Can you point me to some theoretical background of using low-pass filter with a real pole at 1/τ for this purpose. $\endgroup$ – Arnav Mendiratta Jul 26 '17 at 20:52
  • $\begingroup$ @ArnavMendiratta It's in the IEC 61672 standard (which happens to be identical to Indian Standard 15575), section 3.5 "time-weighted sound level" and 3.9 "time-average sound level" $\endgroup$ – endolith Jul 26 '17 at 21:02

Your Answer

