Old 06-11-2019, 09:13 AM   #1
DarkStar
Human being with feelings
 
DarkStar's Avatar
 
Join Date: May 2006
Location: Surrey, UK
Posts: 19,677
Default JSFX: convert amplitude to dB?

I thought that I would use
Code:
dB_level = floor(20 * log10((abs(spl0) + abs(spl1))/2));
to convert the average audio amplitude to dB.

I looked in some other JSFX and saw:
Code:
sc=6/log(2); // 8.656 
dB_level2 = floor(log((abs(spl0) + abs(spl1))/2)*sc); // dB
What am I getting wrong? If they give the same result, which is more efficient? And why?
__________________
DarkStar ... interesting, if true. . . . Inspired by ...

Last edited by DarkStar; 06-11-2019 at 11:31 AM.
DarkStar is offline   Reply With Quote
Old 06-11-2019, 10:37 AM   #2
sai'ke
Human being with feelings
 
sai'ke's Avatar
 
Join Date: Aug 2009
Location: NL
Posts: 1,453
Default

They're not the same, no.
log10(x) = log(x)/log(10)

So if you want option 2 to match option one, you'd have to do something like:

sc=20/log(10);
dB_level_new = floor(log((abs(spl0) + abs(spl1))/2)*sc);

Not sure about the performance of either. I know that exp is significantly faster than pow($exp, blah); but I don't know if something similar holds for log.
__________________
[Tracker Plugin: Thread|Github|Reapack] | [Routing Plugin: Thread|Reapack] | [More JSFX: Thread|Descriptions|Reapack]
sai'ke is offline   Reply With Quote
Old 06-12-2019, 08:18 AM   #3
DarkStar
Human being with feelings
 
DarkStar's Avatar
 
Join Date: May 2006
Location: Surrey, UK
Posts: 19,677
Default

Ah ha - I see where I was going wrong.

I was reading "log" as "log to the base 10", but it is actually "log to the base e, or natural log". With that understood, the 2 equations yield very similar results. Here they both are in MS Excel, with a range of values:



With amplitudes of 0.50, the equations evaluate to -6.021 and -6.000 respectively, so the second equations looks the better of the two.
__________________
DarkStar ... interesting, if true. . . . Inspired by ...
DarkStar is offline   Reply With Quote
Old 06-12-2019, 08:31 AM   #4
sai'ke
Human being with feelings
 
sai'ke's Avatar
 
Join Date: Aug 2009
Location: NL
Posts: 1,453
Default

sc should be 20/log(10);

That brings your error < 1e-10;
__________________
[Tracker Plugin: Thread|Github|Reapack] | [Routing Plugin: Thread|Reapack] | [More JSFX: Thread|Descriptions|Reapack]
sai'ke is offline   Reply With Quote
Old 06-12-2019, 10:12 AM   #5
DarkStar
Human being with feelings
 
DarkStar's Avatar
 
Join Date: May 2006
Location: Surrey, UK
Posts: 19,677
Default

Even better, thank you. And this is what I am working on:

__________________
DarkStar ... interesting, if true. . . . Inspired by ...
DarkStar is offline   Reply With Quote
Old 06-12-2019, 07:22 PM   #6
ashcat_lt
Human being with feelings
 
Join Date: Dec 2012
Posts: 7,272
Default

Quote:
Originally Posted by DarkStar View Post
With amplitudes of 0.50, the equations evaluate to -6.021 and -6.000 respectively, so the second equations looks the better of the two.
???
-6.021 is closer to correct. 6db for a doubling/halving is an approximation.
ashcat_lt is offline   Reply With Quote
Old 06-18-2019, 07:58 AM   #7
DarkStar
Human being with feelings
 
DarkStar's Avatar
 
Join Date: May 2006
Location: Surrey, UK
Posts: 19,677
Default

OK, thank you. back to my original calculation then,
__________________
DarkStar ... interesting, if true. . . . Inspired by ...
DarkStar is offline   Reply With Quote
Old 11-15-2020, 09:51 PM   #8
IonianStreams
Human being with feelings
 
IonianStreams's Avatar
 
Join Date: May 2019
Location: Front Range Colorado
Posts: 17
Default

I found this thread as I had the same question as DarkStar. From sai'ke and ashcat_lt's comments, it looks like the 20 * log10(spl) approach is more accurate than the 6/log(2) * log(spl) approach. But why? Which is theoretically, physically correct? I looked into it a bit more. I'm no expert -- corrections, clarifications are welcome.

First, clear up log semantics. There are two types of logs here: base-10 log and natural log (base e). As DarkStar notes, it's easy to get confused which is which, especially when dealing with the semantics of differing programming languages. Reaper's JSFX uses "log()" for the natural log and "log10()" for base-10 log (in contrast for example, Microsoft Excel uses "ln()" for natural log).

Base-10 logs deal with powers of 10; e.g. 10^2 = 100 and log10(10^2) = 2. Natural log deals with powers of "e" which is the value 2.7182; e.g. 2.7182^5 = 148.4 and log(2.7182^5) = 5. As sai'ke shows, to convert from natural to base-10 log use log10(x) = log(x)/log(10), (that is, divide by the natural log of the value 10, which illustrates another way to get confused between the two logs!).

The decibel (dB) scale is based on powers of ten (another clue that the 20 * log10(spl) approach is more appropriate). A "decibel" is one-tenth of a "bel". A measurement of a sound in "bels" is the base-10 log of a measure of the sound's "acoustic pressure". This value is then multiplied by 10 to get the equivalent "decibels" value (this 10-factor is solely for the convenience of making the resulting values bigger; it has nothing to do with acoustical physics).

So if P is the sound's "acoustic pressure" (in units such as "watts per square meter") then log10(P) is the pressure in bel units, and 10 * log10(P) is the pressure in decibel (dB) units.

bel = log10(P)
decibel = 10 * log10(P)

But -- if I have this right -- in Reaper we deal with digital samples ("spl") that measure the sound wave's amplitude, not its pressure. These sample values range from -1 to 1 (or 0 to 1 in absolute terms, with the sign indicating phase). To express these amplitude sample values in decibels which depend on pressure, we need to know how amplitude relates to pressure: a sound's pressure relates to the square of the sound's amplitude; that is, P = spl^2.

So...
decibel (dB) = 10 * log10(P)
= 10 * log10(spl^2)
= 10 * [2 * log10(spl)]
= 20 * log10(spl)
[ Math reminder: log(X^n) = n * log(X) ]
in short...
dB = 20 * log10(spl)

There's the origin of the first equation. Reaper gives us a sample of a sound's amplitude. To convert it to dB, we first convert amplitude to pressure, which (ultimately) results in a 2-factor. We take the base-10 log of the pressure to get bels. Then we multiply that by 10 to get decibels dB. The 10 and the 2 combine to form the 20-factor. Only the 2-factor, however, is physically significant as it links amplitude to pressure; the 10-factor is just for convenience.


What about the other equation, 6/log(2) * log(spl)? Converting from the log10 form to a natural log form, we get...

dB = 20 * log10(spl)
dB = 20 * log(spl) / log(10) 'using log10 to log conversion from sai'ke above
dB = 20 * log(spl) / 2.302585
dB = 20 / 2.302585 * log(spl)
dB = 8.68589 * log(spl)
dB = 6.0206/log(2) * log(spl)
dB ~ 6/log(2) * log(spl)

Note that the factor 8.68589 is exact because it's derived directly from the log(10) conversion factor. If we compute 6/log(2) we get 8.65617, which is close but not exact. To get the two equations to agree exactly we should use 6.0206/log(2) which equals 8.68589. This is what sai'ke said above: "sc should be 20/log(10)". This is what ashcat_lt said above: "-6.021 is closer to correct."

Conclusion: Either the log10 or natural log approach can be used. But the log10 approach using 20 * log10(spl) is more accurate and also reflects the underlying nature of the decibel scale. The log approach using 6/log(2) * log(spl) can be used as an approximation; maybe it's needed if the log10 function is unavailable or the natural log is desired for some other reason. To improve its accuracy, use 6.0206/log(2) * log(spl).

[Note: I have ignored the fact that sound pressure is properly treated as a ratio to a "threshold of hearing" reference pressure.]


SIDEBAR: ashcat_lt also said above, "6db for a doubling/halving is an approximation." This refers to the fact that a 6 dB boost corresponds to a doubling of the amplitude, and a 6 dB cut means a halving of the amplitude (note that 20*log10(2)=6.0206). However, that does not mean that our human perception of the volume is doubled or halved (apparently that takes more than a 6 dB change). I'm fuzzy on whether -- and if so how -- the 6/log(2) term represents this relationship.


BUT WAIT, THERE'S MORE...
In some JS programs I've also seen the reverse procedure -- taking a value in dB and converting to a sample "spl" value. The code seen is (e.g. JS Volume Adjustment)...
spl = 2^(dB/6)

Converting backward to confirm that this is the same thing just in reverse...
spl = 2^(dB/6)
log(spl) = log[2^(dB/6)]
log(spl) = dB/6 * log(2)
log(spl) / log(2) = dB/6
log(spl) / log(2) * 6 = dB
dB = 6/log(2) * log(spl)
...which confirms that we're back where we started.

However, we've seen that using "6" is close but not exact. To convert dB to spl exactly use 6.0206...
spl = 2^(dB/6.0206)

...or use the log10 equivalent...
dB = 20 * log10(spl)
dB/20 = log10(spl)
10^(dB/20) = 10^(log10(spl))
spl = 10^(dB/20)


Summary:
Using log10()...
dB = 20 * log10(spl)
spl = 10^(dB/20)
Using natural log()...
dB = 6.0206/log(2) * log(spl)
spl = 2^(dB/6.0206)

Examples:
spl = 0.384
dB = 20 * log10(0.384) = -8.3 dB

spl = 0.9999 'nearly the maximum spl value of 1.0
dB = 20 * log10(0.9999) = -0.00087 dB 'nearly the maximum dB value of 0

spl = 0.0001 'nearly the minimum spl value of 0
dB = 20 * log10(0.0001) = -80 dB 'nearly the minimum dB value; inaudible

Notice that these dB equations yield negative values from 0 dB downward toward -96 dB. This is the "dB Full Scale" or "dBFS".

References:
https://www.dsprelated.com/freebooks/mdft/Decibels.html
http://legacy.earlham.edu/~tobeyfo/m...ibel_edit.html
https://docs.cycling74.com/max5/tuto...italaudio.html
__________________
I understand. At least I think I understand, which is the same thing... I think.
My music made with Reaper: https://www.youtube.com/channel/UC5y...G03G5UQBR22Yfw
IonianStreams is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 01:38 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.