2013-04-08 78 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