Sign in to follow this  
Jiia

DirectSound sucks?

Recommended Posts

Jiia    592
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 this post


Link to post
Share on other sites
mumpo    534
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 this post


Link to post
Share on other sites
Jiia    592
Quote:
Original post by mumpo
Read 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 mumpo
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.

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?

Thanks for your help

Share this post


Link to post
Share on other sites
Drew_Benton    1861
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 this post


Link to post
Share on other sites
Jiia    592
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 this post


Link to post
Share on other sites
Drew_Benton    1861
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 this post


Link to post
Share on other sites
PumpkinPieman    382
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 this post


Link to post
Share on other sites
Mastaba    761
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 this post


Link to post
Share on other sites
Jiia    592
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?

Thanks for your time.

Share this post


Link to post
Share on other sites
Mezz    571
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 this post


Link to post
Share on other sites
Jiia    592
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 this post


Link to post
Share on other sites
paradoxnj    208

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 this post


Link to post
Share on other sites
Jiia    592
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 this post


Link to post
Share on other sites
Mezz    571
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 this post


Link to post
Share on other sites
Jiia    592
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 this post


Link to post
Share on other sites
Mezz    571
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 this post


Link to post
Share on other sites
UltimaX    468
Just for my two cents :)

Here's how I do my volume:

//--Volume from 0-100
if(Volume > 0)
{
SBuffer->SetVolume((50 * Volume) - 5000);
}
else
{
SBuffer->SetVolume(-10000);
}

Share this post


Link to post
Share on other sites
JotDot    146
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 this post


Link to post
Share on other sites
Mastaba    761
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 this post


Link to post
Share on other sites
Jiia    592
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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this