Solved

# Need equation for converting decibels (dB) to standard scale 0 to 10000

Posted on 2001-09-11
1,690 Views
I need to fade volume of a DirectSound buffer but IDirectSoundBuffer:SetVolume wants the volume level
specified in in hundredths of decibels (dB). Allowable values are between DSBVOLUME_MAX (no attenuation)
and DSBVOLUME_MIN (silence). These values are currently defined in Dsound.h as 0 and -10,000 respectively.
The value DSBVOLUME_MAX represents the original, unadjusted volume of the stream. The value DSBVOLUME_MIN
indicates an audio volume attenuated by 100 dB, which, for all practical purposes, is silence.

Ramping SetVolume between -10000 and 0 (to fade in) results in a audibility between about -4000 and
0 and gives me a quick fade at the end of my ramp. I need a steady fade throughough. How do I convert
say 0 to 10000 to necessary SetVolume argument that gives me a steady ramp? Thanks!!

I found two leads that may help but unsure how to translate into c:

http://picard.coma.sbg.ac.at/coma/docu/AF/docs/man3/AFdBtoLin.html

http://picard.coma.sbg.ac.at/coma/docu/AF/docs/man3/AFLintodB.html
0
Question by:mortonsw
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• Learn & ask questions

LVL 2

Expert Comment

ID: 6475910
I'm not sure this is the right forum however, if
I'm not mistaken then 2DB means that the volume will be
3 time louder:
10log2 = 3

And therefor if you perform a loop on N then the value
in DB will be:
pow(10, (N/10))

However I don't think the volume is a function of the
distance raised to the power of 2 and in that case:
pow(10, (pow(N, 2)/10))

If it wont work, try to ask a forum which is more
oriented to Physics or Electrical-Engineering people.
0

LVL 2

Expert Comment

ID: 6476044
You should check out the following link (these guys are good):
http://music.calarts.edu/~glmrboy/musicdsp/music-dsp.html
0

LVL 3

Expert Comment

ID: 6476550
And it's worse than you think;
At a simple level you just need to do a log conversion, ie.
if the user wants 1/2 volume lower it 6 dB, if he wants
1/4 volume thats 12 dB, 1/8 = 18 db, etc.

But, people don't hear quite that way, and if you have an
old style radio the volume control will be made so that
it uses a different scale ( called weighting).

You might develop a lookup table to translate from
"volume control position" to ::SetVolume
0

LVL 1

Author Comment

ID: 6476803
I know very little C (I write in ASM and interface) but my func to call DirectX SetVolume is in C and
accepts arg (0 to 10000) which it subtracts 10000 from in order to pass to SetVolume (since it wants
-10000 to 0).

extern "C" BOOL FAR PASCAL DXSBSetVolume( LPDIRECTSOUNDBUFFER lpBuffObj , DWORD Volume)
{
dsrval = lpBuffObj->SetVolume( Volume-10000 );
if(dsrval == DS_OK) return TRUE;
return FALSE;
}

What's the necessary code to use to handle calling argument as 100ths of percent (ie, 10000 = 100.00%),
convert to decibel scale and pass to SetVolume as -10000 to 0?
0

LVL 1

Expert Comment

ID: 6478166
Your question contain the following:
DSBVOLUME_MAX (no attenuation) =0
DSBVOLUME_MIN=-10000
DSBVOLUME_MAX - DSBVOLUME_MIN = 100 db

lpBuffObj->SetVolume( the argument from DSBVOLUME_MIN to DSBVOLUME_MAX);

What's the necessary code to use to handle calling argument as
100ths of percent (ie, 10000 = 100.00%),
convert to decibel scale and pass to SetVolume as -10000 to 0?

------------------------------------------------------------------
As i see, lpBuffObj->SetVolume( Volume - 10000) - is correct decision.
The decibell scale there represented as explanation and
additional calculation not reqired.
To get db scale simply devide by 100 value of Volume argument,
Volume in db =Volume/100;

In Remarks section of SetVolume() function eplanation:
The volume is specified in hundredths of decibels (dB), i.e. lVolume in
HRESULT SetVolume(LONG lVolume);
Alex
0

LVL 1

Author Comment

ID: 6480379
dB is logarithmic and I need linear. ramping setvolume with -10000 to 0 doesn't give me a linear fade. It gives me a logarithmic one. dividing the steps up doesn't change things.
0

LVL 2

Accepted Solution

LoungeLizard earned 100 total points
ID: 6481279
for your function above, use:

DWORD ScaledVolume;

if(Volume <= 1)
ScaledVolume = -10000;
else if(Volume > 10000)
ScaledVolume = 0;
else
ScaledVolume = log10(Volume)/4*10000 - 10000;

dsrval = lpBuffObj->SetVolume( ScaledVolume );

This should give you a percieved linear fade.
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

### Suggested Solutions

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base classâ€¦
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there isâ€¦
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
###### Suggested Courses
Course of the Month3 days, 13 hours left to enroll

#### 751 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.