How to convert Decibels (dBFS) to real dB SPL

Hi guys!

JUCE provides a way to convert amplitude to dBFS.
I’m currently looking for a way to convert dBFS to dBSPL (and later to dB(a)) for a mobile application.

I’m aware that the best way would be to use a microphone to do the calibration of the current environment.

However, I don’t need a high accuracy and I saw some applications that said “pre calibrated microphone”. So I guess it would be possible to do this conversion without external microphone. But does anybody know how I could do this pre calibration?

There is no such conversion, as they operate in different realms. 0 dBFS could correspond to -80 dBSPL or +10 dBSPL, it entirely depends on how much you crank up the volume on your physical audio device. Only relative differences should be identical, unless your physical audio chain produces significant distortion.

2 Likes

Thanks for the information @siedschl.
So I should found the calibration value of the phone (is it possible to find it for iPhone?) or to always use an external dedicated acoustic microphone, right?

It will also depend on the distance from your iPhone speakers…

1 Like

Do you want to measure SPL (with a microphone) or do you want to produce a prescribed SPL (with speakers)? From the above I guess it’s rather the latter.

If you have everything under control (hardware and room, volume control etc.) you can basically use an SPL meter, play back a test signal with a level (dBFS) of your choice and measure how much SPL you get out of it. With that you can calculate how much dBFS you need to produce a certain SPL.

Sounds simple, but in reality it isn’t, for several reasons. The most important one is the question, where you want to get the desired SPL. That means, distance to the speaker and any influence of the room etc… Also, your mileage may vary depending on the signals involved. If you figure out a conversion dBFS to SPL that works for pink noise, that doesn’t mean that the conversion works the same way for white noise, music or (most fuckup potential) sine tones. Unless you have a really really linear flat response playback system. Worst case is when you don’t know the hardware that’ll be used at all. Then there’s no way around a manual calibration with a microphone.

Can you elaborate a bit more on the application and what problem you want to solve?

Thanks for the detailed answer.

The application will prompt the user to talk and will analyze to calculate the variation of the dB(a) of his speech.

The application will be an iOS and Android application and I cannot tell to the user to buy an external mic. I also try to find the smoothest UX.

So I’m in your “worst case” scenario since I don’t know the hardware that will be used.

I find this project https://github.com/audiojs/a-weighting and it seems like it’s possible to get the dB(a) from the audio data.

//get a-weighted frequencies
var frequencies = ft(waveform).map(function (magnitude, i, data) {
    var frequency = 22050 * i / data;
    return aWeight(frequency) * magnitude;
});

It’s a js code but maybe it could be possible if I tweak it a little.

Is variation of speech level the only thing you need or does the (average) speech level matter as well? If not, you don’t need to calibrate anything, as the variation is the same no matter if dB SPL, dBV or dB SPL or whatever.

As for the A-Weighting, I don’t have something handy right now, but what you need to do is filter the audio with an A-Weighting filter (usually 2 or 3 biquads) before measuring the level.

I just need to take the dB(a) every 100ms so I don’t need the average speech level.
But I’m not sure to understand your last message. Would the code I posted (fft then compute the dB(a)) be good?
I’m sorry my knowledge in acoustics are not really good.

Yep you can do that with FFT as well. It’s just not very efficient to do it like that.

Would you have any guidance for an other way to do it? It’s the only one I found so I’m open for any other one (especially if they’re more efficient).

Yeah, the other way is what I (too shortly) described above. I’ve looked into some old notes and found the rough specifications for an A-Weighting IIR Filter using 3 biquads.

  • A second-order highpass filter with Q=0.5 at 20.6 Hz
  • Another second-order highpass filter with Q=0.33 at 281.9 Hz
  • A second-order lowpass filter with Q=0.5 at 12200 Hz
  • An overall boost of 2 dB

(Don’t ask me how I arrived at these numbers, and I can’t guarantee 100% correctness right now.)

Then you use an RMS follower to track the RMS of this filtered signal. For example you can take slices of 100ms (because that’s what you said above) and for each one add up the squared samples, divide it by the number of samples and take the square root. Convert that value to dB and you probably have what you need.

There’s more advanced ways to build an RMS follower, but that will probably work fine for your application (which I don’t know much about).

Sorry for the delay. Thanks you so much for the explanation.

Finally the project is aborted because it could be too difficult to convert an amplitude (from RMS) to dB(a) because of the mass of device. Every device could have their own microphone calibration and we couldn’t guarantee an exact result without an external microphone.

Ah, what a pity. So you do need the absolute calibration? Because normally, if all that matters to you is the variation of dB(A), the absolute calibration or reference wouldn’t matter at all. It wouldn’t be proper dB(A), but something offset by some constant amount of dB, and it did sound like your application would average out such a constant offset anyway.

Yes things happens…

I would need the exact value, not the variation. If the user speaks, I need to detect if his speech is 35dB(a) or 50 dB(a). (Unfortunately) I’m not an acoustics expert but I guess I definitely need the absolute calibration for this.

Thank you a lot for you help @hugoderwolf

Finally the project changed a little and I can have now a reference sound.
The ambient sound will be recorded few seconds before starting the real time recording analysis.

@hugoderwolf Do you think I’ll be able to generate the dB value with a record of the ambient sound? Was it what you mean with “variation of dB(A)”?

Do you know the true dB(A) level and spectrum of the ambient sound? Otherwise it’s still not possible. If you’d have a reference sound source, with known distance, level, and spectrum, then it would be easier

Thanks for your information @danielrudrich. Unfortunately I won’t have them… It’s supposed to be for casual user…
But I think I may find a “not so bad” solution. I don’t need a great accuracy in the value of the dB and dB(A).
From several project ( CNRS Lab and SoundMeterPro they manage to compute an approximation of the dB. The start from the fact that the microphones are 16bit so the maximum dB value they can record is 96dB. From this application this is not an issue since it records the human voice (and I don’t think someone could speak above 96dB…)
From this the formula to compute the dB from the amplitude would be:
dB = 96 - abs(20*log10( amplitude / 32767.0)
I was only able to test it on iPhone 6 and iPad, the results seemed to be coherent but not very accurate ( something like 5dB difference).
But I’m wondering if it would have a big impact if this code is used for the Android phone.
What do you think about it @danielrudrich and @hugoderwolf ?

Thats not true, it only means that they can record a dynamic of 96dB, not absolute sound levels of 96dB. That’s a difference. The transfer function of the microphone and the preamps will determine what’s the lower and upper limit of that range in terms of absolute level. In modern devices, the there’s an auto-gain feature, which will set the preamps depending on the input levels. That’s why the recording quality of concerts is now way better (no clipping any more) than couple of years ago.

1 Like

Ah… Ok I understand it better. I may look totally ignorant but I’m kind new in the acoustic world.
So the formula dB = 96 - abs(20*log10( amplitude / 32767.0) won’t work if I understand.
I was kind of happy to find something that matched the calibrated sound meter app on iPhone :weary:

Yep, that’s total coincidence, as the scaling has nothing to do with dynamic range of 16bit recording. But the order of magnitude for converting dBFS to dB SPL is often somewhere in the 80-90 range. It depends on sensitivity of the microphone and the preamp/adc. If you see that you’re systematically of by 5dB, just add/subtract those 5dB so you get the reading you want. That’s probably the best kind of “calibration” you can get on such a device. But you need to check if the offset is the same for every device or use device-dependent calibration offset.

That’s not very precise, but it might be just enough for your application.

It’s hard to judge though without knowing what your application actually does in detail.

1 Like