Keywords: VB. NET DirectX DirectSound 3D Author: Dong Hanjun
After an afternoon of hard work, I made several detours and finally I was able to play the 3D sound.
Moved ~ ~
Follow these steps:
1. SetCooperativeLevel
2. Set the 3D hardware effect DSoundHelper. Guid3DAlgorithmHrtfFull
3. SoundFormat must be a single channel, not a stereo
4 main buffer description
5. Create a Listenner.
6. Auxiliary buffer reading wav
7. Create a 3D Buffer
8. Play
9 control the spatial location and set the Doppler effect factor and Attenuation Factor
10 stop playing
The following code is fully annotated, and the order is much simpler than Microsoft's example.
Because CSDN blogs cannot upload textures and RAR files, they can only post code. There are two buttons, one Picturebox, and several labels.
========================================================== ========================================================== =
Imports Microsoft. DirectX
Imports Microsoft. DirectX. DirectSound
Imports System. Drawing
Imports System. Drawing. Graphics
Public Class Form1
Inherits System. Windows. Forms. Form
Dim Dev As device' Device
Dim Buff As Buffer
Dim SBuff As SecondaryBuffer 'second-level Buffer
Dim Buff3D As Buffer3D '3d Buffering
Dim descBuff As BufferDescription 'buffer description
Dim Buff3DSet As Buffer3DSettings '3d buffer settings
Dim Listenner As Listener3D 'listener
Dim ListennerSet As Listener3DSettings 'listener settings
Dim Pic As Graphics
Dim BMP As Bitmap
Const FN = "g: \ media \ wav \ rod2m.wav" 'the file to be played must be a single channel
# Region "code generated by Windows Form Designer"
Public Sub New ()
MyBase. New ()
'The call is required by the Windows Form Designer.
InitializeComponent ()
'Add any initialization after InitializeComponent () is called.
End Sub
'Form override dispose to clear the component list.
Protected Overloads Overrides Sub Dispose (ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
Components. Dispose ()
End If
End If
MyBase. Dispose (disposing)
End Sub
'Windows forms designer required
Private components As System. ComponentModel. IContainer
'Note: The following procedure is required by the Windows Forms designer
'You can use the Windows Form Designer to modify this process.
'Do not use the code editor to modify it.
Friend WithEvents Button1 As System. Windows. Forms. Button
Friend WithEvents Button2 As System. Windows. Forms. Button
Friend WithEvents PictureBox1 As System. Windows. Forms. PictureBox
Friend WithEvents Label1 As System. Windows. Forms. Label
Friend WithEvents Label2 As System. Windows. Forms. Label
Friend WithEvents Label3 As System. Windows. Forms. Label
Friend WithEvents Label4 As System. Windows. Forms. Label
Friend WithEvents TextBox1 As System. Windows. Forms. TextBox
Friend WithEvents TextBox2 As System. Windows. Forms. TextBox
Friend WithEvents TextBox3 As System. Windows. Forms. TextBox
Friend WithEvents TextBox4 As System. Windows. Forms. TextBox
Friend WithEvents Label5 As System. Windows. Forms. Label
Friend WithEvents TextBox5 As System. Windows. Forms. TextBox
Friend WithEvents Label6 As System. Windows. Forms. Label
<System. Diagnostics. DebuggerStepThrough ()> Private Sub InitializeComponent ()
Me. Button1 = New System. Windows. Forms. Button
Me. Button2 = New System. Windows. Forms. Button
Me. PictureBox1 = New System. Windows. Forms. PictureBox
Me. Label1 = New System. Windows. Forms. Label
Me. Label2 = New System. Windows. Forms. Label
Me. Label3 = New System. Windows. Forms. Label
Me. Label4 = New System. Windows. Forms. Label
Me. TextBox1 = New System. Windows. Forms. TextBox
Me. TextBox2 = New System. Windows. Forms. TextBox
Me. TextBox3 = New System. Windows. Forms. TextBox
Me. TextBox4 = New System. Windows. Forms. TextBox
Me. Label5 = New System. Windows. Forms. Label
Me. TextBox5 = New System. Windows. Forms. TextBox
Me. Label6 = New System. Windows. Forms. Label
Me. SuspendLayout ()
'
'Button1
'
Me. Button1.Location = New System. Drawing. Point (24, 8)
Me. Button1.Name = "Button1"
Me. Button1.Size = New System. Drawing. Size (88, 32)
Me. Button1.TabIndex = 0
Me. Button1.Text = "initialization"
'
'Button2
'
Me. Button2.Location = New System. Drawing. Point (24, 48)
Me. Button2.Name = "Button2"
Me. Button2.Size = New System. Drawing. Size (88, 32)
Me. Button2.TabIndex = 1
Me. Button2.Text = "play"
'
'Picturebox1
'
Me. PictureBox1.BorderStyle = System. Windows. Forms. BorderStyle. FixedSingle
Me. PictureBox1.Location = New System. Drawing. Point (152, 48)
Me. PictureBox1.Name = "PictureBox1"
Me. PictureBox1.Size = New System. Drawing. Size (552,432)
Me. PictureBox1.TabIndex = 2
Me. PictureBox1.TabStop = False
'
'Label1
'
Me. Label1.Location = New System. Drawing. Point (8,104)
Me. Label1.Name = "Label1"
Me. Label1.TabIndex = 3
Me. Label1.Text = "Doppler effect 0 ~ 10"
'
'Label2
'
Me. Label2.Location = New System. Drawing. Point (8,160)
Me. Label2.Name = "Label2"
Me. Label2.TabIndex = 4
Me. Label2.Text = "attenuation factor 0 ~ 10"
'
'Label3
'
Me. Label3.Location = New System. Drawing. Point (8,216)
Me. Label3.Name = "Label3"
Me. Label3.TabIndex = 5
Me. Label3.Text = "Maximum Distance: 0 ~ 100"
'
'Label4
'
Me. Label4.Location = New System. Drawing. Point (8,272)
Me. Label4.Name = "Label4"
Me. Label4.TabIndex = 6
Me. Label4.Text = "minimum distance 0 ~ 100"
'
'Textbox1
'
Me. TextBox1.Location = New System. Drawing. Point (24,128)
Me. TextBox1.Name = "TextBox1"
Me. TextBox1.TabIndex = 7
Me. TextBox1.Text = "0.0"
'
'Textbox2
'
Me. TextBox2.Location = New System. Drawing. Point (24,184)
Me. TextBox2.Name = "TextBox2"
Me. TextBox2.TabIndex = 8
Me. TextBox2.Text = "0.0"
'
'Textbox3
'
Me. TextBox3.Location = New System. Drawing. Point (24,240)
Me. TextBox3.Name = "TextBox3"
Me. TextBox3.TabIndex = 9
I. TextBox3.Text = "0.9"
'
'Textbox4
'
Me. TextBox4.Location = New System. Drawing. Point (24,296)
Me. TextBox4.Name = "TextBox4"
Me. TextBox4.TabIndex = 10
I. TextBox4.Text = "20.0"
'
'Label5
'
Me. Label5.Location = New System. Drawing. Point (8,328)
Me. Label5.Name = "Label5"
Me. Label5.TabIndex = 11
Me. Label5.Text = "Y axis"
'
'Textbox5
'
Me. TextBox5.Location = New System. Drawing. Point (24,352)
Me. TextBox5.Name = "TextBox5"
Me. TextBox5.TabIndex = 12
I. TextBox5.Text = "0.0"
'
'Label6
'
Me. Label6.Location = New System. Drawing. Point (152, 16)
Me. Label6.Name = "Label6"
Me. Label6.Size = New System. Drawing. Size (424, 24)
Me. Label6.TabIndex = 13
Me. Label6.Text = "Label6"
'
'Form1
'
Me. AutoScaleBaseSize = New System. Drawing. Size (6, 14)
Me. ClientSize = New System. Drawing. Size (720,501)
Me. Controls. Add (Me. Label6)
Me. Controls. Add (Me. TextBox5)
Me. Controls. Add (Me. Label5)
Me. Controls. Add (Me. TextBox4)
Me. Controls. Add (Me. TextBox3)
Me. Controls. Add (Me. TextBox2)
Me. Controls. Add (Me. TextBox1)
Me. Controls. Add (Me. Label4)
Me. Controls. Add (Me. Label3)
Me. Controls. Add (Me. Label2)
Me. Controls. Add (Me. Label1)
Me. Controls. Add (Me. PictureBox1)
Me. Controls. Add (Me. Button2)
Me. Controls. Add (Me. Button1)
Me. Name = "Form1"
Me. Text = "Form1"
Me. ResumeLayout (False)
End Sub
# End Region
Private Sub Form1_Load (ByVal sender As System. Object, ByVal e As System. EventArgs) Handles MyBase. Load
'''Initialize PictureBox during loading and change it to Black (no color)
Picturebox#doubleclick (0, Nothing)
End Sub
Sub initDirectSound ()
''Load the DirectSound device and read wav Files
'Set 3D Mode
Dim DSMode As Guid
DSMode = DSoundHelper. Guid3DAlgorithmHrtfFull
'Join form
Dev = New Device
Dev. SetCooperativeLevel (Me. Handle, CooperativeLevel. Priority)
''Load wav ''' commented out. The original test uses
'Dim TmpDesc As New BufferDescription
'Tmpdesc. Guid3DAlgorithm = DSMode
'Tmpdesc. Control3D = True
'Sbuff = New SecondaryBuffer (FN, TmpDesc, Dev)
'The format has strict restrictions
Dim fmt As New WaveFormat
Fmt. FormatTag = WaveFormatTag. Pcm
Fmt. Channels = 2
Fmt. SamplesPerSecond = 22050
Fmt. BitsPerSample = 16
Fmt. BlockAlign = CShort (fmt. BitsPerSample/8 * fmt. Channels)
Fmt. AverageBytesPerSecond = fmt. SamplesPerSecond * fmt. BlockAlign
'Create description
DescBuff = New BufferDescription
'Scbuff. ControlVolume = True
DescBuff. Control3D = True
'Scbuff. GlobalFocus = True
'Scbuff. StaticBuffer = True
'Scbuff. LocateInHardware = True
DescBuff. PrimaryBuffer = True
DescBuff. Format = fmt
'Scbuff. Guid3DAlgorithm = DSMode
'''Above, you can remove the comment and try again. In some cases, when the Primary is opened, others cannot be used and there is a conflict, especially the following
'Create a primary buffer
Try
''' Capture to prevent incorrect descript descriptions (that is, the parameter settings are incorrect)
Buff = New Buffer (descBuff, Dev)
Catch ex As Exception
MsgBox (ex. Message)
If 'end' is incorrect, there is no need to continue.
End Try
'Create an audience
Listenner = New Listener3D (Buff)
ListennerSet = Listenner. AllParameters
''Wav
Dim tmpDesc2 As New BufferDescription
TmpDesc2.Guid3DAlgorithm = DSMode
TmpDesc2.Control3D = True
'''Here, you must use the auxiliary buffer to provide instances for the master buffer. I don't know what Microsoft thinks, or I may have learned how to use it like this.
Buff = New SecondaryBuffer (FN, tmpDesc2, Dev)
'Create a 3D Buffer
Buff3D = New Buffer3D (Buff)
Buff3DSet = Buff3D. AllParameters use the default settings
Buff3DSet. Mode = Mode3D. HeadRelative 'change a parameter.
Buff3D. AllParameters = Buff3DSet 'apply new settings
MsgBox ("read" + FN)
'OK, Initialization is complete
End Sub
Private Sub Button2_Click (ByVal sender As System. Object, ByVal e As System. EventArgs) Handles Button2.Click
Buff. Play (0, BufferPlayFlags. Looping)
End Sub
Private Sub button#click (ByVal sender As System. Object, ByVal e As System. EventArgs) Handles Button1.Click
InitDirectSound ()
End Sub
Private Sub PictureBox1_MouseMove (ByVal sender As Object, ByVal e As System. Windows. Forms. MouseEventArgs) Handles PictureBox1.MouseMove
''' Is valid when you press the left mouse button.
If e. Button <> MouseButtons. Left Then Exit Sub
Dim r = New Rectangle (e. X, e. Y, 3, 3)
Pic = PictureBox1.CreateGraphics ()
Me. Text = e. X. ToString + "," + e. Y. ToString
Pic. DrawImage (BMP, 1, 1)
Pic. DrawEllipse (New Pen (Color. Red), r)
SetSoundPos (Convert. ToSingle (e. X), Convert. ToSingle (TextBox5.Text), Convert. ToSingle (e. Y ))
'''Here, the coordinate is changed. Because the Y axis is up, we need the distance, so the negative value is given to the Z axis (down from above)
End Sub
Private Sub PictureBox1_DoubleClick (ByVal sender As Object, ByVal e As System. EventArgs) Handles PictureBox1.DoubleClick
'''Clear the canvas. You only need to double-click it to avoid confusion.
BMP = New Bitmap (400,300)
PictureBox1.BackgroundImage = BMP
End Sub
Sub SetSoundPos (ByVal x As Single, ByVal y As Single, ByVal z As Single)
''' Code for Buff adjustment after the user changes the location and speed
'''Is simple, just change the parameter.
''' Definition is between-1 and 1.
Dim POS As Vector3
Dim Speed As Vector3
POS. X = (x-PictureBox1.Width/2)/100
POS. Y = y/100
POS. Z = (z-PictureBox1.Height/2)/100
Speed. X = 1
Speed. Y = 1
Speed. Z = 1
Buff3D. Position = POS
Buff3D. Velocity = Speed
Label6.Text = "relative coordinates: (x, y) =" + x. ToString + "," + z. ToString
End Sub
End Class
========================================================== ==========================================================
There are not many operations on the Y axis here. I cannot use Picturebox to describe the 3D effect. I may have learned D3D to describe the image.
And there is not much use of Doppler (my speaker is difficult to tell), it is best to use that car's single sound is the best
There is also a need for speed changes to detect the location of the mouse twice (the formula needs to be studied, lazy) otherwise the Doppler is not true enough
This example is not perfect for the performance of DirectSound3D, but I still want
Let's just go. You can complete other parts on your own.
Next is the last part. Use DirectSound for sound mixing to implement special effects.
I thought about making an encapsulation for the sound engine, but it seems that D3D must be understood in 3D, so DS is generally included in the game engine.
It doesn't make much sense to take it out independently (unless 3D is not used)