2013-04-08 80 views
1

我正在用DirectX.DirectSound开发音乐播放器。我的音量有问题。直接音量是对数。这意味着在无声的情况下,对幅度的微小变化比对响亮的声音要敏感得多。这也意味着,对于线性音量滑块,我们会有音量变化的对数感觉,并且感觉不对。我的问题是:我怎样才能使它线性? 我的代码,直到这里是:Directsound对数音量到线性音量滑块

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)); 
      } 
+0

“trkBalance.Value”的范围是多少?如果你想恢复对数标度,你必须使用反函数('Math.Exp')。 DS.Volume.Min/Max是什么值?你需要找到一个函数'v(t)= c * Math.Exp(t)',其中'v(minValue)== DS.Volume.Min'和'v(maxValue)== DS.Volume.Max'。 – 2013-04-08 16:00:13

+0

@NicoSchertler它用于-10000 Min和0 for Maximum,我的轨迹栏是0-100。我正在尝试'foreGroundSound.Volume = Math.Exp(((trkBalance.Value * 100) - 10000)',但没有运气。 – 2013-04-08 16:07:20

回答

2

有一个经验法则来确定感知响度:

10分贝(的doubleValue)导致声音的差异两倍/一半响亮原始来源。

考虑到这一点,我们可以创建一个将衰减映射到声压级的公式。

但是起初我们必须计算实际衰减(作为一个分数)。 DirectSound可以将声音衰减100 dB,这是1/2^(100/doubleValue)的衰减。这是最小轨迹栏值的值。最大值是1(不变)。总体来说:

doubleValue = 10; 
minimumAttenuation = 1/2^(100/doubleValue) 
attenuation = minimumAttenuation + trkBalance.Value/100 * (1 - minimumAttenuation); 

现在我们有一个有效范围内的值。现在我们需要找到这个衰减的声压级。

我们知道,响度每10 DB(的doubleValue)双打:

attenuation = 2^(db/doubleValue) //ln 
ln(attenuation) = db/doubleValue * ln(2) 
db = doubleValue * ln(attenuation)/ln(2) 

而且因为DirectSound的需要hundreths分贝,你可以使用

foreGroundSound.Volume = db * 100; 

这些只是一些理论基于维基百科信息的想法。它可能会或可能不会工作。去尝试一下。

+0

'int attenuation = 1/1024 + trkBalance.Value/100 * 1023/1024; double db = 10 * Math.Log10(attenuation)/ Math.Log10(2); label8.Text =(db * 100).ToString();' 你的意思是这样的?不幸的是,这个公式给出了无限的。 – 2013-04-09 09:04:25

+0

您应该考虑语言特定类型的安全性。即使用1f等来避免截断为int。 – 2013-04-09 09:10:15

+0

不,我的问题是如果ln =与基数2对数。Thanxs – 2013-04-09 12:57:15