分享
 
 
 

VB.NET 实现DirectSound9 (5) DS3D2

王朝c#·作者佚名  2006-12-17
窄屏简体版  字體: |||超大  

关键字: VB .NET DirectX DirectSound 3D 作者:董含君

经过一下午的奋战,走了若干弯路,终于可以播放3D声音效果了

感动 ~ ~

大体按照下列的步骤来:

1 关联设备 SetCooperativeLevel

2 设置3D硬件效果 DSoundHelper.Guid3DAlgorithmHrtfFull

3 格式要求 SoundFormat 必须是单声道,不能是立体声

4 主要缓冲区描述

5 创建Listenner

6 辅助缓冲区读取wav

7 创建3D缓冲区

8 播放

9 控制空间位置,以及设置多普勒效应因子,衰减因子

10 停止播放

以下代码注释比较全,顺序比微软的例子简单不少

由于CSDN的Blog不能上传贴图以及RAR,只能帖代码了,有两个Button 一个Picturebox,还有若干Label

==================================================================================

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 '设备

Dim Buff As Buffer '主要缓冲

Dim SBuff As SecondaryBuffer '二级缓冲

Dim Buff3D As Buffer3D '3D缓冲

Dim descBuff As BufferDescription '缓冲区描述

Dim Buff3DSet As Buffer3DSettings '3D缓冲设置

Dim Listenner As Listener3D '听众

Dim ListennerSet As Listener3DSettings '听众设置

Dim Pic As Graphics

Dim BMP As Bitmap

Const FN = "g:\media\wav\rod2m.wav" '要播放的文件,必须是单声道

#Region " Windows 窗体设计器生成的代码 "

Public Sub New()

MyBase.New()

'该调用是 Windows 窗体设计器所必需的。

InitializeComponent()

'在 InitializeComponent() 调用之后添加任何初始化

End Sub

'窗体重写 dispose 以清理组件列表。

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 窗体设计器所必需的

Private components As System.ComponentModel.IContainer

'注意: 以下过程是 Windows 窗体设计器所必需的

'可以使用 Windows 窗体设计器修改此过程。

'不要使用代码编辑器修改它。

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 = "初始化"

'

'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 = "播放"

'

'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 = "多普勒效应0~10"

'

'Label2

'

Me.Label2.Location = New System.Drawing.Point(8, 160)

Me.Label2.Name = "Label2"

Me.Label2.TabIndex = 4

Me.Label2.Text = "衰减因子 0~10"

'

'Label3

'

Me.Label3.Location = New System.Drawing.Point(8, 216)

Me.Label3.Name = "Label3"

Me.Label3.TabIndex = 5

Me.Label3.Text = "最大距离 0~100"

'

'Label4

'

Me.Label4.Location = New System.Drawing.Point(8, 272)

Me.Label4.Name = "Label4"

Me.Label4.TabIndex = 6

Me.Label4.Text = "最小距离 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

Me.TextBox3.Text = "0.9"

'

'TextBox4

'

Me.TextBox4.Location = New System.Drawing.Point(24, 296)

Me.TextBox4.Name = "TextBox4"

Me.TextBox4.TabIndex = 10

Me.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轴"

'

'TextBox5

'

Me.TextBox5.Location = New System.Drawing.Point(24, 352)

Me.TextBox5.Name = "TextBox5"

Me.TextBox5.TabIndex = 12

Me.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

'''加载的时候初始化一下PictureBox,把它变成黑色(没有颜色)

PictureBox1_DoubleClick(0, Nothing)

End Sub

Sub initDirectSound()

''加载DirectSound设备以及读取wav文件

'设置3D模式

Dim DSMode As Guid

DSMode = DSoundHelper.Guid3DAlgorithmHrtfFull '由于为了演示3D效果,所以用最高模式

'关联窗体

Dev = New Device

Dev.SetCooperativeLevel(Me.Handle, CooperativeLevel.Priority)

''加载wav '''注释掉了,原来测试用的

'Dim TmpDesc As New BufferDescription

'TmpDesc.Guid3DAlgorithm = DSMode

'TmpDesc.Control3D = True

'SBuff = New SecondaryBuffer(FN, TmpDesc, Dev)

'格式有比较严格的限制

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

'创建描述

descBuff = New BufferDescription

'descBuff.ControlVolume = True

descBuff.Control3D = True

'descBuff.GlobalFocus = True

'descBuff.StaticBuffer = True

'descBuff.LocateInHardware = True

descBuff.PrimaryBuffer = True

descBuff.Format = fmt

'descBuff.Guid3DAlgorithm = DSMode

'''以上可以自己去掉注释尝试一下,某些时候当Primary打开的时候,其他的不能用,有冲突,尤其是后面几个

'创建主缓冲

Try

'''捕获一下,防止descript的描述不正确(就是参数设置的不对)

Buff = New Buffer(descBuff, Dev)

Catch ex As Exception

MsgBox(ex.Message)

End '不对的话,就没有必要继续了

End Try

'创建听众

Listenner = New Listener3D(Buff)

ListennerSet = Listenner.AllParameters '使用主缓冲听众的设置

''WAV

Dim tmpDesc2 As New BufferDescription

tmpDesc2.Guid3DAlgorithm = DSMode

tmpDesc2.Control3D = True

''' 这里必须借助辅助缓冲给主缓冲提供实例,不知道微软怎么想的,也可能是我学艺不精,怎么尝试都要这样用

Buff = New SecondaryBuffer(FN, tmpDesc2, Dev)

'创建3D缓冲区

Buff3D = New Buffer3D(Buff)

Buff3DSet = Buff3D.AllParameters '使用默认的设置

Buff3DSet.Mode = Mode3D.HeadRelative '改变一个参数

Buff3D.AllParameters = Buff3DSet '应用新的设置

MsgBox("已经读取" + FN)

'ok,初始化完成

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 Button1_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

''' 当鼠标左键按下去的时候有效,我可不希望鼠标经过就改变

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))

'''这里坐标变换一下,因为y轴向上,我们需要的是远近,所以负值给Z轴(从上面俯视)

End Sub

Private Sub PictureBox1_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles PictureBox1.DoubleClick

''' 清除画板,只需双击一下,免得太乱

BMP = New Bitmap(400, 300)

PictureBox1.BackgroundImage = BMP

End Sub

Sub SetSoundPos(ByVal x As Single, ByVal y As Single, ByVal z As Single)

'''''''''用户改变位置以及速度之后,对Buff进行调整的代码

''' 很简单,就是更改参数而已

''' 定义域在-1 到 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 = "相对坐标:(x,y)=" + x.ToString + "," + z.ToString

End Sub

End Class

================================================================================

这里对y轴的操作不多,我无法用Picturebox描述3D的效果,也许学会了D3D就可以比较形象的描述了

而且对于多普勒也没有过多的使用(我的音箱很难分辨),最好用那种汽车的单一的声音最好

还有速度的改变需要检测鼠标两次的位置判断(需要研究公式的,懒)否则多普勒不够真实

对于表现DirectSound3D的性能,这个例子是不够完善的,但是对于介绍使用DS3D的步骤,我想还是

说得过去的.其他的部分大家自己完善就可以了.

下次就是最后的部分了,利用DirectSound进行混音,实现特效.

倒是想过自己做一个封装,用于声音引擎,但是似乎牵扯到3D的地方必须了解D3D,所以DS一般都包含在游戏引擎里面

单独拿出来就没有太大的意义了(除非不使用3D)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有