VB下利用DirectX處理聲音文件
前言
微軟提供的DirectX技術不僅可以實現圖形圖像的處理,而且DirectX提供了DirectSound和DirectMusic類以分別支持聲音(WAVE)文件和音樂(MIDI)文件,筆者結合自己的學習體會,介紹如何在Visual Basic環境下利用DirectX技術實現WAVE和MIDI文件的處理,和廣大編程愛好者一起交流,希望能夠互相學習,共同進步。
一、DirectSound聲音處理技術
DirectSound類對象是DirectX提供的實現播放、捕捉數字聲音文件的對象,它不僅可以播放聲音文件,還可以實現聲音在虛擬的三維空間的定位。它包括以下的幾個對象:DirectSound、DirectSoundBuffer、DirectSound3Dbuffer、Direct3DsoundListner、DirectSoundCapture、DirectSoundCaptureBuffer。其中DirectSound對象和DirectSoundCapture對象是DirectSound類對象的基本對象,利用DirectX7對象的DirectSoundCreate()方法和DirectSoundCaptureCreate()方法可以分別建立DirectSound對象和DirectSoundCapture對象。DirectSoundBuffer對象和DirectSound3Dbuffer是音頻播放緩沖對象,顧名思義,前者是音頻播放對象,而后者是三維音頻播放對象。DirectSound對象實現聲音文件的播放,而DirectSoundCapture對象是用來捕捉聲音數據的基本對象。Direct3DSoundListner對象用于設置播放三維聲音效果時收聽者所處的位置。
下面通過一個程序來介紹DirectSound的應用,這個程序可以利用DirectSound3DBuffer播放文件并可以動態的設置聲音位置。首先建立一個工程文件,在其中加入DirectX7說明庫,然后在Form1中加入一個PictureBox控件和兩個CommandButton控件。將Picture1的Width和Height屬性都設置為3000;將Picture1的Scale屬性設置為3-Pixel。保存工程文件,并在工程所在的目錄下放置一個名為 Demo.wav 的聲音文件。在Form1的代碼窗口加入以下代碼:
| Dim m_dx As New DirectX7 Dim m_ds As DirectSound Dim m_dsBuffer As DirectSoundBuffer Dim m_ds3dBuffer As DirectSound3DBuffer Dim m_dsPrimaryBuffer As DirectSoundBuffer Dim m_dsListener As DirectSound3DListener Dim m_pos As D3DVECTOR Sub DrawPositions() Dim X As Integer Dim z As Integer Picture1.Cls '以黑色圈標出收聽者所在的位置 Picture1.Circle (Picture1.ScaleWidth / 2, Picture1.ScaleHeight / 2), 4 '以紅色圈標出聲音所在的位置 X = CInt(m_pos.X) + Picture1.ScaleWidth / 2 z = CInt(m_pos.z) + Picture1.ScaleHeight / 2 Picture1.Circle (X, z), 4, RGB(255, 0, 0) End Sub Sub Load(sFile As String) Dim bufferDesc1 As DSBUFFERDESC Dim waveFormat1 As WAVEFORMATEX '設置將建立的DirectSoundBuffer對象的屬性 bufferDesc1.lFlags = (DSBCAPS_CTRL3D Or DSBCAPS_CTRLFREQUENCY Or _ DSBCAPS_CTRLPAN Or DSBCAPS_CTRLVOLUME) Or DSBCAPS_STATIC '建立DirectSoundBuffer對象 Set m_dsBuffer = m_ds.CreateSoundBufferFromFile(sFile, bufferDesc1, _ waveFormat1) '設置DirectSoundBuffer對象的聲音(0為最大) m_dsBuffer.SetVolume 0 '設置DirectSoundBuffer對象 Set m_ds3dBuffer = m_dsBuffer.GetDirectSound3DBuffer '設置DirectSoundBuffer對象的播放方向屬性 m_ds3dBuffer.SetConeOrientation 1, 1, 1, DS3D_IMMEDIATE m_ds3dBuffer.SetConeAngles DS3D_MINCONEANGLE, 100, DS3D_IMMEDIATE m_ds3dBuffer.SetConeOutsideVolume -100, DS3D_IMMEDIATE '設置DirectSoundBuffer對象的播放位置屬性 m_ds3dBuffer.SetPosition m_pos.X / 50, 0, m_pos.z / 50, DS3D_IMMEDIATE End Sub Sub UpdatePosition(X As Single, z As Single) m_pos.X = X - Picture1.ScaleWidth / 2 m_pos.z = z - Picture1.ScaleHeight / 2 DrawPositions If m_ds3dBuffer Is Nothing Then Exit Sub '重新設置DirectSoundBuffer對象的播放位置屬性 m_ds3dBuffer.SetPosition m_pos.X / 50, 0, m_pos.z / 50, DS3D_IMMEDIATE End Sub Private Sub Command1_Click() If m_dsBuffer Is Nothing Then Call Load(App.Path + "demo.wav") End If '循環播放聲音文件 m_dsBuffer.Play 1 End Sub Private Sub Command2_Click() If m_dsBuffer Is Nothing Then Exit Sub m_dsBuffer.Stop m_dsBuffer.SetCurrentPosition 0 End Sub Private Sub Form_Load() Dim i As Integer Command1.Caption = "播放" Command2.Caption = "停止" Me.Show DoEvents On Local Error Resume Next '建立DirectSound對象 Set m_ds = m_dx.DirectSoundCreate(vbNullString) If Err.Number <> 0 Then MsgBox "無法建立DirectSound對象,請查看聲卡或驅動程序是否安裝正確" End End If '設置DirectSound對象的協作模式 m_ds.SetCooperativeLevel Me.hWnd, DSSCL_PRIORITY Dim primDesc As DSBUFFERDESC, format As WAVEFORMATEX primDesc.lFlags = DSBCAPS_CTRL3D Or DSBCAPS_PRIMARYBUFFER '建立主聲音緩沖對象 Set m_dsPrimaryBuffer = m_ds.CreateSoundBuffer(primDesc, format) '建立DirectSound3DListener對象 Set m_dsListener = m_dsPrimaryBuffer.GetDirectSound3DListener() m_pos.X = 10: m_pos.z = 50 UpdatePosition m_pos.X, m_pos.z End Sub Private Sub Picture1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) If Button = 1 Then UpdatePosition X, Y End If End Sub Private Sub Picture1_Paint() |
運行程序,在PictureBox中回出現一個黑色和一個紅色的小圓圈。黑色的代表虛擬的收聽者的位置,紅色的代表音源的位置。點擊"播放"按鈕即可以播放wav文件,你可以點擊PictureBox中的不同位置來設置音源的位置,然后再聽一下聲音發生的改變,由于本人機器上安裝的只是普通雙聲道聲卡,所以效果不是很明顯,有高檔多聲道聲卡的朋友可以使用上面的程序感受一下你的聲卡的三維效果。