I'm a product developer so kind of light on DSP inner workings. I have captured an audio signal - 1024 samples at a time. What I want to know is the amplitude of the wave in dB, and in dBA.


For dB, I've created a 10 deep circular buffer recording data every 100 ms, and averaging the maximum reading over the last 10 reading. Therefore my output looks less jumpy and is more human readable. To get the amplitude I just record the max and min of the signal and take the difference.

Q1: Is this the correct way (or a valid way) to get a dB amplitude from a sample? Analternative is to work out the running average and then do average RMS to get energy in the signal. But I don't think that really corresponds to the maximum audio sound level?


For dBA, I have windowed 512 captured samples with a flat-top window and done an FFT on the data. It all looks fine so far. ( I am resource constrained and can only fit 512 samples into my FFT).

Sampling at 44.1 kHz for standard audio, with 512 samples, I end up with 256 usable frequency bins of 86 Hz, 172 Hz, etc... up to 22 kHz. So far any corrections, please jump in.

Q2: How do I interpret this bin? As representing the band from 0 Hz to 80 Hz? Or as 80 Hz? Since the next step is to apply A-Weighting to the frequency measurements, I need to know what frequency to use.

A-Weighting: I've generated an A weighting table in code based on the values of the bins. In this case, 256 values for 86, 172 ... up to 22 kHz. Clearly the point is to add the weighing on to compensate for the human frequency response - which translates PSL to phons.

What is confusing me is that I have seen some formulae that suggest that the dBA measurement is done by taking only single measurements for each octave starting at a suitable low frequency i.e. 33.25 Hz. Then you create a table with 10 entries in it taking you up to 16 kHz and apply the A-Weighting to those. You basically do an antilog, average, log of the 10 values and bob's your uncle.

Q3: I have 256 bins, and I'd like to make best use of them for improved accuracy. The approach above would suggest that each entire octave contains an equivalent amount of energy for the averaging process. On that basis, if I were to average all 256 bins, the result would be heavily (and incorrectly) weighted towards the highest octave in my sampled set, since it contains half of the bins! Which approach is correct? Is there some magical reason that energy isn't distributed linearly across the frequency domain, albeit that we like to look at frequency in logarithmic scales.

Accepted Answer And Additional Detail

I have accepted @ZR Han 's answer as it succinctly provided the required information to solve the stated problem, deftly sidestepping the misdirection in the errant assumptions I originally made in the question.

Using the formula provided, the time domain approach works perfectly, yielding the answer in dB. I wanted to add that the 2nd order IIR cascaded 3 times with the coefficients taken from jenshee.dk/signalprocessing/aweighting.pdf also works perfectly. I have tested this using a signal generator at various frequencies (old school I know) and the ratio is exactly 1 at 1 kHz, as expected for A Weighting. Problem solved.


2 Answers 2

  1. No, you should calculate the RMS sound pressure. The definition of sound pressure level is

$$ L_p = 20\lg\frac{p}{p_{ref}} $$

where $p$ is the root mean square sound pressure and $p_{ref}$ is the reference sound pressure. For monochromatic sound wave, $p_{rms}= \frac{\sqrt{2}}{2}p_{max}$.

  1. As for dBA, you don't have to go spectral, just use an A-weighting digital filter and then go back to the first step.
  • $\begingroup$ Following yours & @Hilmar 's advice, but drawing a blank on the A weighting filter. I've got a 2-order IIR to fit in my micro (3 coeffs for forward &back), but I can't find coeffs anywhere, and don't use matlab. Any pointers? $\endgroup$
    – monkey
    Commented Feb 5, 2021 at 16:47
  • $\begingroup$ The wiki transfer function is 6th order. Found an interesting post showing three 2nd order IIRs. If I run them in cascade (which I guess is the intent?), the output looks vaguely useful, but I'm literally viewing it in a console using ascii printout - a bit limited. Here's the link jenshee.dk/signalprocessing/aweighting.pdf $\endgroup$
    – monkey
    Commented Feb 5, 2021 at 17:18

Q1: Is this the correct way (or a valid way) to get a dB amplitude from a sample?

Assuming you want to build a sound pressure level meter the answer would be a resounding "no". The correct way is to build a running energy detector with a proper time management as defined in the IEC standard IEC61672. https://webstore.iec.ch/publication/5708. This is actually pretty simple. By far the most difficult part is the calibration of the microphone. As ZR Han in their answer already pointed out: you get to a sound pressure level in dB (dBSPL) by using a reference pressure of $20 \mu Pa$, but that means you have to convert your input signal from Volts or "number" to Pascals as well and this is very device and settings dependent.

Q2: How do I interpret this bin?

That's a complicated question. Each digital bin contains energy from ALL analog frequencies EXCEPT the center frequencies of the other digital bins and the exact relationship isn't trivial. In your case you should just ignore this since there is no reason to do go into the frequency domain in the first place.

Q3: I have 256 bins, ...

Again, that's a very complicated question and I won't get into the answer since its completely unnecessary for what you want to do.

Building a sound level meter is relatively straight forward

  1. Calibrate your input signal to represent actual sound pressure in Pa (Pascal)
  2. Apply time domain weighting filter (A,C, Z, none)
  3. Square the signal
  4. Apply exponential (first order lowpass) averaging with proper time constant
  5. Convert to dB using $p_{ref} = 20 \mu Pa$

Step 1 is by far the most complicated.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.