# DirectSound sucks?

This topic is 4717 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I probably suck, not the API. But I cannot get the volume control to work, there are pops and cracks as the sound starts, and panning seems all screwed up. I just switched from using FMod, but I'm not using 3D sound. Just calculating the pan and volume relative to the camera to do my own type of 3D effect. The problem with the volume is that 0 decibels is extremely loud and -500 decibels is much more quiet. Yet the docs say silence is at -10000? Do I need to make my own silence at a much higher level, or is it more likely that I'm doing something wrong? I've always used a percentage of volume - a float from 0 to 1 representing percentage. And that was multiplied with 255 to send FMod the value. Now I changed that to (1 - volume) * -10000 to send DirectSound the value. I can barely hear the sounds unless they play at 1.0 volume. Any advice on this? As for panning, DirectSound seems to impliment panning in a different way than FMod. Specifically, it seems to put full volume into both speakers when the sound is centered. I'm not a sound expert, but shouldn't the volume be normalized between the speakers? Is there an option for this somewhere, or do I need to modify the volume any time I mess with panning? Then the pops and cracks. I'm hoping this is a side effect from the other problems. Maybe the sound is just too loud at 100% volume in both speakers? All of the buffer formats match, and the popping is present with no panning or frequency changes. Thanks much for help edit: Does this look correct?
FLOAT pan_change = 1.0f - positive( Panning );
FLOAT vol_perc = 1.0f / sqrtf( 1.0f + (pan_change * pan_change) );
Volume *= vol_perc;
Volume is 0 to 1. Panning is -1 to +1 [Edited by - Jiia on March 26, 2005 10:17:18 PM]

##### Share on other sites
Read the official DirectSound API reference documentation that comes with the SDK. It explains how volume and panning work in DirectSound. (Try looking up the sound buffer interface and then getting a link from that to the SetVolume() and SetPan() methods or whatever they're called.) I haven't used FMod, but if I understand your description of how FMod handles volume and panning, then yes, DirectSound handles it very differently. Personally I don't like the way DirectSound handles it, but you can process your input for the SetVolume() and SetPan() functions so that it behaves more logically without too much trouble.

##### Share on other sites
Quote:
 Original post by mumpoRead the official DirectSound API reference documentation that comes with the SDK. It explains how volume and panning work in DirectSound.

Like I said, I'm not a sound expert. But why isn't -5000 decibals 50% volume? I would say it's more like 15% or less?

Quote:
 Original post by mumpo(Try looking up the sound buffer interface and then getting a link from that to the SetVolume() and SetPan() methods or whatever they're called.)

No offense, but isn't it obvious from my original post that I've already found these?

Quote:
 Original post by mumpoI haven't used FMod, but if I understand your description of how FMod handles volume and panning, then yes, DirectSound handles it very differently. Personally I don't like the way DirectSound handles it, but you can process your input for the SetVolume() and SetPan() functions so that it behaves more logically without too much trouble.

This is the area I need help with. Processing my input. I want volume control to be percentage of volume. The DirectSound docs say -10000 is silence, and 0 is original volume. But if this were linear changes, -5000 would be 50% volume, and it's not even close. So how do I "process my input" to calculate 50% volume?

##### Share on other sites
I just found this link on this issue. It's in VB, but still give it a try:

Quote:
 DsBuffer.SetVolume 5000 '50% volume

So try just using +5000. There are also examples of values and such for panning, position, pitch, and volume. See if that helps any. Oh and you will have to go to the "DirectSound: Modifying Sounds" section of that link, I just realized it's quite large [lol].

##### Share on other sites
Huh? But that doesn't even make sense. It must be a typo.

My guess (that's if MS isn't just crazy) is that decibels have some special range of values that need translated to make them linear. Does anyone know if this is true? I'll keep searching.

Thanks again

##### Share on other sites
Did you try using a positive 5000 and seeing if it worked though? I've never worked with DS before but I have an example from a book I will look at to see how they did it. Ok I am sending you a PM [lol] this is werid - stupid VB examples...

##### Share on other sites
Yeah, I tried it, but only because I'm desperate [smile]

It played at full volume.

##### Share on other sites
This is what I did, I really haven't tested it though.

	bool cSoundBuffer::SetVolume(short percent)	{		long Volume;		if(m_buffer == NULL)			return false;		if(!percent)			Volume = DSBVOLUME_MIN;		else 			Volume = -20 * (100 - (percent % 101));		if(FAILED(m_buffer->SetVolume(Volume)))			return false;		return true;		};	bool cSoundBuffer::SetPan(signed long level)	{		signed long Pan;		if(m_buffer == NULL)			return false;		if(level < 0) 			Pan = DSBPAN_LEFT / 100 * ((-level) % 101);		else			Pan = DSBPAN_RIGHT / 100 * (level % 101);		if(FAILED(m_buffer->SetPan(Pan)))			return false;		return true;  	};

##### Share on other sites
Sound professionals measure sound in decibels (dB) and that's why DirectSound uses hundreths of decibels as the units. They are NOT linear like the method in FMOD. An attenuation of -3 dB (i.e. -300 DirectSound units) should be percieved as about half the full volume, since log 3 is approximately 1/2. The negative sign is there to indicate that the value is an attenuation and not an amplification. To the normal human, the sound will be inaudible long before the -100 dB point.

##### Share on other sites
Ahhh, this is the information I need, except in a more variable form. Any idea how to convert a percentage into decibels or vice versa?

##### Share on other sites
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

##### Share on other sites
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.

##### Share on other sites
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.

##### Share on other sites
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.

##### Share on other sites
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

##### Share on other sites
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.

##### Share on other sites
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

##### Share on other sites
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);}

##### Share on other sites
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.

##### Share on other sites
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]

##### Share on other sites
vol_mag = ..0.0f to 1.0f..FLOAT decibels = 100.0f * 10.0f * log10( vol_mag );DOUBLE b = 0.0000000001;DOUBLE m = 1.0 - b;DOUBLE alt_dec = 100.0 * 10.0 * log10( m * DOUBLE(vol_mag) + b );

decibels and alt_dec are pretty much identical in all situations I tested. I don't think the 0.0000000001 difference is a difference at all within float scale.

Thanks for the info