I am developing an music player with DirectX.DirectSound. I have a problem with the volume. The directsound volume is logarithm. This means that with silent sounds, is much more sensitive to small variations in amplitude than with loud sounds. It also means that with a linear volume slider we have a logarithmic sensation of volume variations, and that just doesn't feel right. My question is: How can I make it linear? My code until here is:
if (trkBalance.Value == trkBalance.Minimum)
{
foreGroundSound.Volume = (int)DS.Volume.Min;
}
else if (trkBalance.Value == trkBalance.Maximum)
{
foreGroundSound.Volume = (int)DS.Volume.Max;
}
else
{
foreGroundSound.Volume = (int)(-5000 * Math.Log10(100 - trkBalance.Value));
}
There is a rule of thumb to determine the perceived loudness:
A difference of 10 dB (doubleValue) results in a sound twice / half as loud as the original source.
With that in mind we can create a formula that maps the attenuation to the sound pressure level.
But at first we have to calculate the actual attenuation (as a fraction). DirectSound can attenuate a sound by 100 dB, which is an attenuation of 1/2^(100/doubleValue)
. This is the value for the minimum trackbar value. The maximum value is 1 (no change). So overall:
doubleValue = 10;
minimumAttenuation = 1/2^(100/doubleValue)
attenuation = minimumAttenuation + trkBalance.Value / 100 * (1 - minimumAttenuation);
Now we have a value within valid range. Now we need to find the sound pressure level for this attenuation.
And we know that the loudness doubles every 10 db (doubleValue):
attenuation = 2^(db/doubleValue) //ln
ln(attenuation) = db / doubleValue * ln(2)
db = doubleValue * ln(attenuation) / ln(2)
And since DirectSound takes hundreths dB, you can use
foreGroundSound.Volume = db * 100;
Those are just some theoretical thoughts based on wikipedia information. It might or might not work. Just try it.
来源:https://stackoverflow.com/questions/15883611/directsound-logarithm-volume-to-linear-volume-slider