DirectSound sucks?

Started by
19 comments, last by Jiia 19 years ago
This is based empirical testing and my (poor) memory.

Take your percentage and put it in the range 0-1, i.e. 50% = 0.5
take it's logarithm.
Multiply that number by 10
Take it's absolute value.

That's the number of decibels you'll be attenuating by. Now you just need to fix it up so you have that in hundredths of a decibel, and you can pass that to SetVolume().

By the way, incase you didn't already know - you can't increase sound volume in DirectSound, 0 attenuation is as loud as it gets.

-Mezz
Advertisement
That's absolutely correct, Mezz. I shamelessly asked about decibels in the math forum. But you just seconded the only reasonable answer I've gotten.

Thanks much.
static int LinearToLogVol(double fLevel){	// Clamp the value	if(fLevel <= 0.0f)		return DSBVOLUME_MIN;	else if(fLevel >= 1.0f)		return 0;    return (long) (-2000.0 * log10(1.0f / fLevel));}static float LogToLinearVol(int iLevel){	// Clamp the value	if(iLevel <= -9600)		return 0.0f;	else if(iLevel >= 0)		return 1.0f;    return pow(10, double(iLevel + 2000) / 2000.0f) / 10.0f;}static int VolumeToDecibels(float vol) {	if (vol>=1.0F) 		return 0;	if (vol<=0.0F) 		return DSBVOLUME_MIN;	static const float adj=3321.928094887F;  // 1000/log10(2)	return int(float(log10(vol)) * adj);}


The first function converts the default DirectSound range (0 - -10000) to a floating point value between 0.0f and 1.0f. The second converts back. The third converts the converted value to decibels. Enjoy.
Anthony Rufrano
RealityFactory 2 Programmer
Well, I'm not sure if this is useful, but a sound editing program (Sound Forge) lists percentages along with db levels. That doesn't mean it's correct, but it is a quality sound editor. Here are some values..

10.00% = -20.00db (wow, even numbers)
20.00% = -13.98db
30.03% = -10.45db
50.00% = -06.02db
54.70% = -05.24db
70.79% = -03.00db
79.43% = -02.00db
88.82% = -01.03db

I'm not completely sure, but none of the proposed routines seem to match. Unless I'm not using them correctly. 10.0f * log10( 0.5f ) is -3.010, not -6.02. And VolumeToDecibels(0.5) is -9.990, if I'm using it correctly.

I might be screwing something up, but something about everything seems way off.

edit: forgot to mention that I divided the VolumeToDecibels routine by 100.
Well, I don't want to sound rightous, but I think what I suggested is reasonably correct :)
I did check on the internet for a source just before I posted it, and it confirmed that -3dB is half volume. However, I've lost that page now.
So I went looking for another one and found Wikipedia's which does confirm (near the bottom) that a 3dB reduction is half power.

Hope that helps.

-Mezz
Your method sounds correct too Mezz. Like I said, I don't know how SoundForge is coming up with their values. Just mentioning the fact.

I appreciate the help.
I know, I've looked them over and can't figure out how they come up with those values in SoundForge. Maybe you could email the company that makes it and ask them. I'm not a sound engineer or anything, perhaps they have a good reason for it.

-Mezz
Just for my two cents :)

Here's how I do my volume:
//--Volume from 0-100if(Volume > 0){    SBuffer->SetVolume((50 * Volume) - 5000);}else{    SBuffer->SetVolume(-10000);}
Here is a good doc explaining the confusion about 6db vs 3db: clicky

In summary: Taking a single sound and making it twice as loud is 6db where combining two different sounds of the same level results in an increase of 3db. It has to do with the two sounds being similar enough (i.e., phase correlated). Thus "twice as loud" is between 3db to 6db depending on the similarity of the two sounds. Since we are talking about adjusting the volume of one sound, I'd assume 6db is the value to use here.

You will find a summary of the general rules about half way down that page.
Easy. Soundforge is using dB for sound pressure, and DirectSound is using dB for sound power. If you wanted to use a linear scale where 0 is silence and 1 is full volume, then:
long ConvertLinearLevelToDirectSoundLevel(double level){    const double b=pow(10,-10);    const double m=1-pow(10,-10);    return static_cast<long>(1000*log10(m*level+b));}


[Edited by - Mastaba on March 27, 2005 12:43:45 PM]
.

This topic is closed to new replies.

Advertisement