天天看點

DirectSound 3D聲音世界轉自:http://blog.sina.com.cn/s/blog_4de8abbb01000atp.html3D中的聲音

轉自:http://blog.sina.com.cn/s/blog_4de8abbb01000atp.html

3D中的聲音

使用DSound,可以為聲音建立一個3D世界與3D圖形結合。可以在空間定位聲音資源和收聽者的位置,允許使用多普勒變換移動聲音,控制實體參數,例如在距離遠時聲音削弱的頻率。

DSound可以在兩個揚聲器或者耳機裝置上建立虛拟的3D效果。如果使用者已經在控制台中選擇了環繞聲音揚聲器,也可以利用WDM驅動的多聲道。更多的資訊參考DSBUFFERDESC。

3D空間的坐标

聲音資源和收聽者的位置,速率和方向在3D空間中是以笛卡爾坐标系表示的。坐标是與程式建立的視點有關系的。X軸從左到右,Y軸從小到上,Z軸從近到遠。

D3DVECTOR結構包含了在3向坐标系上描述聲音,速率和方向的值。

友善地,向量如下表示(x,y,z)。

位置,預設的機關是米。如果程式的3D圖形沒有使用米作為機關,可以設定一個距離因數,表示每一個制定機關是多少米。例如,如果程式使用尺作機關,可以制定距離因數為.3048,即.3048米是一尺。更多的資訊,參看Distance Factor。

速率,是描述每秒鐘沿每個坐标軸移動速率的向量。同樣的,預設的機關是米,但是可以被程式改變。

方向,可以是任意機關,因為都是成比例的。如果基本3D坐标系預設方向向北,收聽者的方向是(-1,0,1),那麼收聽者面向西北方。這個方向也可以表示為(-5,0,5)或者(-.25,0,.25)。

可以在紙上畫出它們以便觀察向量是怎樣在2D空間工作的。從(0,0)畫到(1,1)和從(0,0)畫到(5,5)是具有相同的方向的,但是後者代表更遠的距離或者更快的速率。

聲音位置的了解

在真實的世界裡,空間中聲音位置的了解是被幾個因素影響的。不是所有的這些因素都是聲學方面的,另一個重點是視覺。聲音本身的線索包括以下幾個方面:

1)  聲音減弱。當一個聲音資源遠離收聽者時,被感覺到的聲音以一個固定的速率遞減。

2)  耳間的音強差别。從收聽者右面傳來的聲音在右耳的聲音會比在左耳的聲音大。

3)  兩耳間的時間差别。聲源在收聽者右邊發出時到達右耳的時間會比到達左耳的時間略微早一點,這些時間大概為1毫秒。

4)  遮擋。耳朵的形狀和位置保證了從收聽者後面傳來的聲音和從前面傳來聲音相比是有一定遮擋的。另外,如果一個聲音從右邊傳來,聲音到達左耳的時候會被收聽者的頭部遮擋。

5)  耳垂的效果。耳朵和它的褶皺導緻了從不同方向傳來聲音的細微差别。數學上将這種效果視作頭部反應傳送函數(head-related transfer function (HRTF))

頭部反應傳送函數(head-related transfer function (HRTF) )

HRTF:是一種音效定位算法,它的實際作用在于欺騙我們的耳朵。簡單說這就是個頭部反應傳送函數(Head-Response Transfer Function)。要具體點呢,可以分成幾個主要的步驟來描述其功用。第一步:制作一個頭部模型并安裝一支麥克風到耳膜的位置;第二步:從固定的位置發出一些聲音;第三步:分析從麥克風中得到聲音并得出被模型所改變的具體資料;第四步:設計一個音頻過濾器來模仿那個效果;第五步:當你需要模仿某個位置所發出的聲音的時候就使用上述過濾器來模仿即可。過濾器的回應就被認為是一個HRTF,你需要為每個可能存在聲源的地方來設定一個HRTF。其實我們并不需要無限多個HRTF。這裡的原因也很簡單,我們的大腦并不能如此精确。對于從我們的頭部為原點的半球形表面上大約分布1000個這樣的函數就足夠了,而另一半應該是對稱的。至于距離感應該由回響、響度等資料變化來實作。

DSound 3D緩沖區

每一個3D環境中的聲音資源都是由IDirectSound3DBuffer8接口描述的。這個接口隻被使用DSBCAPS_CTRL3D标志位建立的聲音緩沖區所支援。

程式在使用DSound的3D相容性的時候必須提供單聲的聲音資源。如果嘗試使用DSBCAPS_CTRL3D标志位建立一個緩沖區并且WAV格式多于1個聲道的話會導緻錯誤。下面的章節描述了怎樣獲得和管理3D緩沖區對象。

獲得3D緩沖區對象

IDirectSound3DBuffer8接口是從一個由DSBCAPS_CTRL3D标志位建立的次緩沖區獲得的。可以通過呼叫QueryInterface在IDirectSoundBuffer8接口上獲得IDirectSound3DBuffer8接口:

LPDIRECTSOUND3DBUFFER8 lpDs3dBuffer;      
HRESULT hr = lpDsbSecondary->QueryInterface(IID_IDirectSound3DBuffer8,      
                (LPVOID *)&lpDs3dBuffer);      

最小和最大距離

當一個收聽者接近一個聲源時,聲音變大;當距離縮小到一半時,聲音加倍。傳遞一個特定的指針,不過音量的增強并不是那麼有規律的。

設定的最小距離決定了聲音以多快速度消失。例如,對一個噴射機可能設定這個值為100米,而對于一隻蜜蜂設定為2厘米。根據這些設定,噴射機在離收聽者200米的時候音量減半,而蜜蜂音量減半的距離僅為4厘米。

SDK幫助文檔中的附圖表示了最小距離和最大距離是怎樣在距離增大的情況下影響噴射機和蜜蜂的音量的。

最小距離:聲音緩沖區預設的最小距離是DS3D_DEFAULTMINDISTANCE,被定義為1個機關或者使用預設距離因數的時候為1米。除非改變這個值,聲音離收聽者1米外的時候聽到的聲音是最大音量的,2米外音量減半,4米外變為四分之一等等。對于大多數的聲音可能需要設定一個大一點的最小距離,這樣當聲音離遠時不至于衰減過快。

最大距離:一個聲源的最大距離是指超過這個距離聲音就不再衰減。預設的最大距離是1billion,這意味着在聽覺範圍外聲音的衰減也會被繼續計算。為了避免不必要的處理,在VXD驅動的軟體緩沖區下,程式可以設定一個合适的最大距離并且在建立緩沖區的時候包含DSBCAPS_MUTE3DATMAXDISTANCE标志位(在DMusic中,這個标志位載3D緩沖區中是被自動設定的)。

最大距離也可以用來組織聲音消失。例如,如果設定了100米的最小距離,那麼可能在1000米以外就聽不到了,通過設定800米為最大距離,可以保證在更遠的距離仍然可以保持最大音量的八分之一。在這種情況下當然就不能設定DSBCAPS_MUTE3DATMAXDISTANCE标志位了。

預設的,距離值使用米來描述。如果想調整距離的影響效果可以改變距離衰減因數。

處理模式

聲音緩沖區有3種處理模式:正常,頭部相關和禁止

普通模式(DS3DMODE_NORMAL)聲源的位置和方向完全依賴世界空間。這個是預設的模式,用于聲源相對于收聽者不移動并且不轉動的情況。

頭部相關模式(DS3DMODE_HEADRELATIVE)聲源的3D屬性和目前收聽者的位置,朝向和速度都是有關系的。當一個收聽者移動或者轉動的時候在世界空間緩沖區重新配置。頭部相關可以用來制作環繞在收聽者頭部的效果。但是,大多數的聲音都不必是3D的。

禁止模式(DS3DMODE_DISABLE)3D聲音處理被禁止,聲音貌似從收聽者的頭部中心傳來

緩沖區的位置和速度

當一個聲源移動時,程式為它的位置和速度指定值。

位置使用三個坐标軸的距離機關表示,和世界空間和收聽者有關,決定于處理模式。

速度使用每秒在三個坐标軸上移動的向量為機關。預設的,距離機關是米。速率隻有在多普勒變換的時候才會被使用。

聲音圓錐

一個沒有方向的聲音在各個方向都具有相同的振幅。有方向的聲音在朝向的方向聲音最響。描述帶方向聲音大小的模型叫做聲音圓錐。聲音圓錐由内錐和外錐組成。外錐的角度必須等于或者大于内錐的角度。

在内錐以内的任何角度,音量的大小都是在考慮基本音量,收聽者距離,收聽者方向等各種因素後沒有圓錐的音量大小。

在外錐以外的任何角度,正常的音量通過程式設定的一個因子衰減。外錐音量使用百分貝表示,并且是負數,因為聲音從0衰減。音量等于内錐音量+定義的外錐音量。

在内錐和外錐之間是聲音從内錐到外錐的裱畫過程。音量随着角度的增加減小。

每一個3D聲音緩沖具有一個聲音圓錐,但是預設的緩沖區是一個全方位的聲源,因為外圍的聲音沒有衰減,并且内錐和外錐的角度都是360度。除非程式改變這些值,聲音表面聽起來沒有任何方向。

恰當的設計聲音圓錐可以為程式增加動态效果。例如:可以在屋子中間放置一個聲源,設定它的方向朝向一個走廊的開着的門。然後設定内錐的角度這樣它可以延伸至,使外錐角度稍微款一點,設定外錐的聲音是聽不見的。一個沿着走廊走的收聽者隻有靠近門的時候才會聽到聲音,并且聲音在收聽者開着的門的時候會最大。

3D緩沖區的一批參數

程式可以單獨或者批量的獲得或者設定3D聲音緩沖區的參數。如果聲源正在移動,可能需要馬上一起設定位置,朝向和速率等很多參數。可以通過調用IDirectSound3DBuffer8::GetAllParameters來獲得目前的參數,改變其中的DS3DBUFFER結構成員的值,然後将修改過的值傳給IDirectSound3DBuffer8::SetAllParameters

參數的改變也可以通過标記他們為延緩執行并且在以後一起執行來提高效率。

DSound3D收聽者

在虛拟的3D環境和在真實世界一樣,聲音的存在隻和接收點有關。在DX程式中3D聲音效果不僅受聲源的位置,方向和速度值的影響,還和虛拟收聽者的位置,方向和速度有關。

預設的,收聽者在原點,鼻子的方向朝向Z軸的方向,頭頂朝Y軸的方向。程式可以改變這些值來影響使用者的移動和朝向。收聽者也控制聲學環境中一般參數,例如多普勒變換和聲音衰減率。

這個章節描述了怎麼獲得并且管理一個全局的3D聲音參數。

獲得3D收聽者

全局聲音參數從主緩沖區的IDirectSound3DListener8表面設定和獲得。在一個程式中隻有一個主緩沖區和一個收聽者。

為了獲得一個收聽者借口,必須首先使用IDirectSound8::CreateSoundBuffer建立一個主緩沖區,定義DSBCAPS_CTRL3D和DSBCAPS_PRIMARYBUFFER标志位。調用QueryInterface方法獲得一個指向IDirectSound3DListener8接口的指針。

下面的例子獲得了一個收聽者的指針:

GetListener(LPDIRECTSOUND8 lpds, LPDIRECTSOUND3DLISTENER8* ppListener)      
{      
  DSBUFFERDESC             dsbd;      
  LPDIRECTSOUNDBUFFER      lpdsbPrimary;  // Cannot be IDirectSoundBuffer8.      
  LPDIRECTSOUND3DLISTENER8 lp3DListener = NULL;      
  HRESULT hr;      
  ZeroMemory(&dsbd, sizeof(DSBUFFERDESC));      
  dsbd.dwSize = sizeof(DSBUFFERDESC);      
  dsbd.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER;      
  if (SUCCEEDED(hr = lpds->CreateSoundBuffer(&dsbd, &lpdsbPrimary, NULL)))      
  {      
    hr = lpdsbPrimary->QueryInterface(IID_IDirectSound3DListener8,      
                                 (LPVOID *)ppListener);      
    lpdsbPrimary->Release();      
  }      
  return hr;      
}      

收聽者的空間參數

收聽者向量預設的,前方向量是(0.0, 0.0, 1.0),上方向量是(0.0, 1.0, 0.0)。兩個向量必須時刻互相保持直角。如果必要,DSound會調整前方向量來使其與上方向量成直角。

位置通過向量的距離機關來衡量。

速度使用沿向量的速率來衡量。預設機關是米。速率隻有多普勒變換才有用。

距離因子

距離因子是在一個向量機關表示多少米。預設的距離因子是1.0。如果一個緩沖區的速度是(2.0, 0.0, 0.0),聲源被認為沿X軸以每秒2米的速度移動。為3D圖形使用不同度量機關的程式可能是以作相應的改變。

假設,例如基本度量機關是英尺,或者.3048米。設定距離因子為.3048。從此就使用英尺作為機關,它們自動被轉換成米。

通過改變通過n度量機關每秒描述的實際速度,距離因子可以影響多普勒變換。它并不直接影響衰減,因為距離的衰減率是在最小距離的基礎上的。如果設定最小距離為2個度量機關,音量在4個度量機關處為一半,不管度量機關是英尺,米或者其它度量衡。更多的資訊,參考Minimum and Maximum Distances。

多普勒效應

DSound自動為擁有速度的緩沖區或者收聽者建立多普勒變換效果。效果是累積的:如果收聽者和緩沖區都在移動,系統自動計算相關速度,進而調整多普勒效果。

為了在程式中擁有真正的多普勒變換效果,必須計算正在移動的任何物體的速度,然後為聲源或者收聽者設定合适的速度。在特殊情況下可以自由的增大或者減小這個值來建立特殊效果,也可以通過改變多普勒因子在全局加強或者減弱多普勒效應。

多普勒效應可以從DS3D_MINDOPPLERFACTOR 到 DS3D_MAXDOPPLERFACTOR,分别被定義為0.0和10.0。0意味着聲音沒有多普勒變換。其它數值表示多少倍的多普勒變換。

衰減因子

衰減因子是作用于聲音的衰減數量,基于收聽者和聲源的距離。DSound可以忽略,增大衰減或者使用和真實世界一樣的效果,這些取決于一個全局的衰減因子。

衰減因子可以從DS3D_MINROLLOFFFACTOR到DS3D_MAXROLLOFFFACTOR,分别被定義為0.0和10.0。DS3D_MINROLLOFFFACTOR 表示無論聲音離收聽者多麼遠都會是最大聲音。任何其它的值表示真實世界的衰減。

衰減因子是全局的。想要為每一個單獨的聲音緩沖區改變距離效果,可以為緩沖區設定最小距離。

3D收聽者的一批參數

程式可以分别或者批量的得到和設定一個3D收聽者對象的參數。如果收聽者在移動,可能希望馬上設定大量的參數例如位置,方向和速率等等。可以通過調用IDirectSound3DListener8::GetAllParameters獲得目前的參數,改變當中DS3DLISTENER結構中的成員變量,傳遞到IDirectSound3DListener8::SetAllParameters.。參數變化可以通過标記它們為延緩處理的,然後一起執行它們來提高效率。獲得更多資訊,參考Deferred Settings

延緩設定

每一次3D聲音的變化都會導緻在消耗CPU周期情況下的重混合。為了最小化改變3D設定對執行性能的影響,在調用IDirectSound3DListener8 或者 IDirectSound3DBuffer8中的方法改變3D聲音的設定時設定DS3D_DEFERRED标志。然後調用IDirectSound3DListener8::CommitDeferredSettings方法立刻執行所有延緩執行的指令。

延緩設定會被立即模式覆寫。例如,如果使用DS3D_DEFERRED設定收聽者的速度是(1.0,0,0)然後使用DS3D_IMMEDIATE設定收聽者的速度為(2.0, 0.0, 0.0),那麼收聽者的速度變為(2.0, 0.0, 0.0),當CommitDeferredSettings被呼叫時也不會被改變

繼續閱讀