游戏开发论坛

 找回密码
 立即注册
搜索
查看: 9657|回复: 5

VB DirectSound详细说明

[复制链接]

68

主题

228

帖子

241

积分

中级会员

Rank: 3Rank: 3

积分
241
QQ
发表于 2003-10-10 00:38:00 | 显示全部楼层 |阅读模式
'在使用 DirectX 之前必须先“引用”DirectX 库函数。
'dtx为 DirectX 的对象简码

Option Explicit
Dim objDtxDirectX7 As New DirectX7                          '声明一个 DirectX7 对象,并使用New来创建新 DirectX7 对象。
Dim objDtxDirectSound As DirectSound                        '声明一个 DirectSound 对象
Dim objDtxSoundBuffer As DirectSoundBuffer                  '声明一个声音缓存区对象
Dim dtxSoundEnum As DirectSoundEnum                         '声明一个声音驱动设备列表

Dim dscPoint As DSCURSORS                                   '声明一个 DSCURSORS 类数据,用来存放声音缓存指针

Private Sub cboSoundDrive_Change()

    '<修改声音驱动设备>
    Set objDtxDirectSound = Nothing                             '清空DirectSound
    Set objDtxSoundBuffer = Nothing                             '清空SoundBuffer
    '更改声音驱动程序
    Set objDtxDirectSound = objDtxDirectX7.DirectSoundCreate(dtxSoundEnum.GetGuid(cboSoundDrive.ListIndex + 1))

End Sub

Private Sub cmdPlay_Click()

    objDtxSoundBuffer.Play DSBPLAY_LOOPING                  '循环播放音乐
    'objDtxSoundBuffer.Play DSBPLAY_DEFAULT                  '只播放一遍音乐

End Sub

Private Sub cmdRestart_Click()

    objDtxSoundBuffer.SetCurrentPosition 0                  '重新播放

End Sub

Private Sub cmdStop_Click()

    objDtxSoundBuffer.Stop                                  '停止播放音乐

End Sub

Private Sub Form_Load()

Dim intTemp As Integer

On Error Resume Next

    '<获取声音驱动设备信息,若不考虑更改可以省略此部分>
    'DirectSoundEnum 声音设备列表,方法详解:
        'GetCount           声音驱动设备数量
        'GetDescription     声音驱动设备描述
        'GetGuid            声音驱动设备Guid
        'GetName            声音驱动设备名称
    Set dtxSoundEnum = objDtxDirectX7.GetDSEnum                     '获取声音驱动设备列表
   
    For intTemp = 1 To dtxSoundEnum.GetCount
        cboSoundDrive.AddItem dtxSoundEnum.GetDescription(intTemp)  '写入下拉列表框
        cboSoundDrive.ListIndex = 0
    Next intTemp

    '<创建 DirectSound 对象>
    '使用 DirectSoundCreate 函数来创建 DirectSound 对象:
    '代码 object.DirectSoundCreate(guid As String) As DirectSound
    '其中的参数 Guid 为相应设备的全局独有标志符(Guid)。您可以通过上一段代码列举声音设备得到Guid,
    '或使用空字符串来为缺省设备创建对象。
    Set objDtxDirectSound = objDtxDirectX7.DirectSoundCreate("")
   
    '若创建失败则会触发 Err 事件,Err事件的参数为
    'DSERR_ALLOCATED        设备已经被其他独享程序使用中,请求失败。
    'DSERR_INVALIDPARAM     使用参数错误。
    'DSERR_NOAGGREGATION    这个对象不是 COM 构架下的系统。
    'DSERR_NODRIVER         对象已经被创建,没有可用的驱动。
    'DSERR_OUTOFMEMORY      没有足够的内存创建 DirectSound 对象。
    If Err.Number <> 0 Then
        If Err.Description = DSERR_INVALIDPARAM Then
            MsgBox ("调用DirectX对象时出错,错误原因:" & Err.Description), 16, "错误"
            End
        End If
    End If
   
    '<初期化DirectSound>
    '[1]使用 SetCooperativeLevel 方法来设置 DirectSound 的优先级。
    '代码 object.SetCooperativeLevel(hwnd As Long, level As CONST_DSSCLFLAGS)
    '参数 hwnd 是窗口的句柄,即指定需要设置优先级的窗口;
    '关于 CONST_DSSCLFLAGS 参数的说明(这里用枚举类型代码来作说明):
    'Enum CONST_DSSCLFLAGS
    '    DSSCL_EXCLUSIVE = 3        允许独占声音设备,会使所有后台应用程序都不发声;
    '    DSSCL_NORMAL = 1           与其它应用程序调节到最佳协作方式的工作方式;
    '    DSSCL_PRIORITY = 2         允许改变主缓冲区声音格式,音质效果较佳;
    '    DSSCL_WRITEPRIMARY = 4     允许直接存取。
    'End Enum
    objDtxDirectSound.SetCooperativeLevel Me.hWnd, DSSCL_PRIORITY
   
    '[2]创建一个DirectSoundBuffer二级缓冲
    '在创建二级缓冲之前,首先要声明两个数据类型即:DSBUFFERDESC 和 WAVEFORMATEX
   
    'DSBUFFERDESC 数据结构包含 DirectSoundBuffer 的信息,下面使用 Type 来加以说明。
    'Type DSBUFFERDESC
    '    lBufferBytes As Long           设定缓冲区的大小,以字节为单位;
    '    lFlags As CONST_DSBCAPSFLAGS   (见以下说明)
    'End Type
    'lFlags 建立音效缓冲区的标记,CONST_DSBCAPSFLAGS 的枚举参数如下:
    'Enum CONST_DSBCAPSFLAGS
    '    DSBCAPS_CTRL3D = 16            缓冲区具有控制3D音效的能力;
    '    DSBCAPS_CTRLFREQUENCY = 32     缓冲区具有控制频率的能力;
    '    DSBCAPS_CTRLPAN = 64           缓冲区具有控制左右声道的能力;
    '    DSBCAPS_CTRLPOSITIONNOTIFY = 256       缓冲区具有控制位置的能力。
    '    DSBCAPS_CTRLVOLUME = 128       缓冲区具有控制音量的能力;
    '    DSBCAPS_GETCURRENTPOSITION2 = 65536    该参数标志来保证当前可以写数据的位置是正确的。
    '    DSBCAPS_GLOBALFOCUS = 32768
    '    DSBCAPS_LOCHARDWARE = 4        当声卡上有足够的内存时,在声卡上建立缓冲区并作为混音区;
    '    DSBCAPS_LOCSOFTWARE = 8        强制缓冲区设置在程序缓冲内,并利用该缓冲来混音,此方法将不考虑声卡上的资源;
    '    DSBCAPS_MUTE3DATMAXDISTANCE = 131072   如果超出缓冲区的容量,声音播放将停止,且不再消耗处理时间。
    '    DSBCAPS_PRIMARYBUFFER = 1      指定缓冲区为首要声音缓冲区,当它不被指定时,将被默认为是二级缓存。
    '    DSBCAPS_STATIC = 2             缓冲区的数据为静态数据,若有可能会将缓冲区建立在声卡上;
    '    DSBCAPS_STICKYFOCUS = 16384
    'End Enum

    '其实现多重功能调用的功能实现代码为 lFlags = DSBCAPS_CTRLPAN Or DSBCAPS_CTRLVOLUME
   
    'WAVEFORMATEX 数据结构是对声音的定义,下面使用 Type 来加以说明。
    'Type WAVEFORMATEX
    '    lAvgBytesPerSec As Long        平均传输率,每秒的数据流量
    '    lExtra As Long                 不作设定,默认值为0。
    '    lSamplesPerSec As Long         采样率(单位:赫兹)典型值:11025、22050、44100Hz
    '    nBitsPerSample As Integer      每个采样点数;8-bit或16-bit;
    '    nBlockAlign As Integer         每个采样点字节数
    '    nChannels As Integer           声道的设置,当其值为1时是单声道,为2时是双声道;
    '    nFormatTag As Integer          声音的格式,通常使用WAVE_FORMAT_PCM来设定,因为PCM是比较常用的声音格式。
    '    nSize As Integer               追加信息,可不作设定。
    'End Type
    Dim typBufferDesc As DSBUFFERDESC   '声明一个 DSBUFFERDESC 数据结构变量
    Dim typWaveFormat As WAVEFORMATEX   '声明一个 WAVEFORMATEX 数据结构变量
   
    '判断声音文件是否存在
    Dim strWaveFilePath As String       '声明一个存储文件位置的字符串变量;
    strWaveFilePath = App.Path + "\1.wav"
    If Dir(strWaveFilePath) = "" Then
        MsgBox ("未找到文件:" & strWaveFilePath), 16, "错误"
        End
    End If
      
    '调整缓冲区功能,使其具有调整左右声道、音量、频率的功能
    typBufferDesc.lFlags = DSBCAPS_CTRLPAN Or DSBCAPS_CTRLVOLUME Or DSBCAPS_CTRLFREQUENCY
   
    '创建DirectSoundBuffer二级缓冲
    '代码 object.CreateSoundBuffer(bufferDesc As DSBUFFERDESC, format As WAVEFORMATEX) As DirectSoundBuffer
    Set objDtxSoundBuffer = objDtxDirectSound.CreateSoundBufferFromFile(strWaveFilePath, typBufferDesc, typWaveFormat)
   
    If Err.Number <> 0 Then
        If Err.Description = DSERR_INVALIDPARAM Then
            MsgBox ("调用DirectX对象时出错,错误原因:" & Err.Description), 16, "错误"
            End
        End If
    End If
   
    'SoundBuffer对象方法详解
   
    '信息类
    '   GetCaps     检查硬件支持能力
    '   GetFormat   获取 WAVEFORMATEX 类型数据
    '   GetStatus   获取状态参数
    '   SetFormat   设置 WAVEFORMATEX 类型数据
   
    '内存管理类
    '   restore     将设置重新装入内存
   
    '其他类
    '   SaveToFile  保存缓存中的声音
   
    '获取 GetDirectSound3DBuffer 对象信息
    '   GetDirectSound3DBuffer      获取GetDirectSound3DBuffer信息
    '   GetDirectSound3DListener    获取GetDirectSound3DListener信息
   
    '再生管理
    '   GetCurrentPosition          获取文件播放指针位置,需要使用 DSCURSORS 数据来获取
    '       Type DSCURSORS
    '           lPlay As Long       当前播放指针位置
    '           lWrite As Long      当前数据读取指针的位置,一般都是先读取在播放,因此该指针位置比lPlay靠后
    '       End Type

    '   Play                        播放音乐;
    '       DSBPLAY_LOOPING 循环播放音乐;
    '       DSBPLAY_DEFAULT 只播放一遍音乐。
    '   ReadBuffer                  获取缓冲区的数据
    '   SetCurrentPosition          设置播放文件位置
    '   SetNotificationPositions    设置缓冲的通知点
    '   Stop                        停止播放
    '   WriteBuffer                 写入缓冲区的数据
    '属性管理
    '   GetFrequency                获取声音的频率
    '   GetPan                      获取左右声道的强度数值
    '   GetVolume                   获取音量强度数值
    '   SetFrequency                设置声音的频率;100到100000之间
            'DSBFREQUENCY_MIN           '最慢速度
            'DSBFREQUENCY_ORIGINAL      '原始速度
            'DSBFREQUENCY_MAX           '最快速
    '   SetPan                      设置左右声道的强度数值;-10000到10000之间(左右)
    '   SetVolume                   设置音量强度数值;0到-10000之间
   
    '<调整频率调节滚动条属性>
    sldFre.Max = 100000
    sldFre.Min = 100
    sldFre.TickStyle = sldNoTicks
    sldFre.LargeChange = 1000
   
    sldFre.Value = objDtxSoundBuffer.GetFrequency           '获取默认频率
   
End Sub

Private Sub Form_Unload(Cancel As Integer)

    '清空对象;
    '若不清空对象,对象将会占用过多的内存,使系统运行速度减慢;
    Set objDtxDirectX7 = Nothing
    Set objDtxDirectSound = Nothing
    Set objDtxSoundBuffer = Nothing
    Set dtxSoundEnum = Nothing

End Sub

Private Sub hscPan_Change()

    '<调整左右声道强度>
    objDtxSoundBuffer.SetPan hscPan.Value

End Sub

Private Sub hscVol_Change()

    '<调整左右声道强度>
    objDtxSoundBuffer.SetVolume hscVol.Value

End Sub

Private Sub sldFre_Change()

    '<调整频率>
    objDtxSoundBuffer.SetFrequency sldFre.Value
    'DSBFREQUENCY_MIN                   '最慢速度
    'DSBFREQUENCY_ORIGINAL              '原始速度
    'DSBFREQUENCY_MAX                   '最快速

End Sub

Private Sub Timer_Timer()

    '<获取指针位置>
    objDtxSoundBuffer.GetCurrentPosition dscPoint               '获取缓存内的两个指针位置
    labPlayPoint.Caption = dscPoint.lPlay                       '显示播放指针
    labReadPoint.Caption = dscPoint.lWrite                      '显示读取指针
    labFre.Caption = objDtxSoundBuffer.GetFrequency             '显示频率
   
End Sub


''CONST_DSSCLFLAGS 枚举参数:
'Enum CONST_DSSCLFLAGS
'    DSSCL_EXCLUSIVE = 3             '允许独占声音设备,会使所有后台应用程序都不发声;
'    DSSCL_NORMAL = 1                '与其它应用程序调节到最佳协作方式的工作方式;
'    DSSCL_PRIORITY = 2              '允许改变主缓冲区声音格式,音质效果较佳;
'    DSSCL_WRITEPRIMARY = 4          '允许直接存取。
'End Enum
'
''lFlags 建立音效缓冲区的标记,CONST_DSBCAPSFLAGS 的枚举参数
'Enum CONST_DSBCAPSFLAGS
'    DSBCAPS_CTRL3D = 16            '缓冲区具有控制3D音效的能力;
'    DSBCAPS_CTRLFREQUENCY = 32     '缓冲区具有控制频率的能力;
'    DSBCAPS_CTRLPAN = 64           '缓冲区具有控制左右声道的能力;
'    DSBCAPS_CTRLPOSITIONNOTIFY = 256
'    DSBCAPS_CTRLVOLUME = 128       '缓冲区具有控制音量的能力;
'    DSBCAPS_GETCURRENTPOSITION2 = 65536    '该参数标志来保证当前可以写数据的位置是正确的。
'    DSBCAPS_GLOBALFOCUS = 32768
'    DSBCAPS_LOCHARDWARE = 4        '当声卡上有足够的内存时,在声卡上建立缓冲区并作为混音区;
'    DSBCAPS_LOCSOFTWARE = 8        '强制缓冲区设置在程序缓冲内,并利用该缓冲来混音,此方法将不考虑声卡上的资源;
'    DSBCAPS_MUTE3DATMAXDISTANCE = 131072
'    DSBCAPS_PRIMARYBUFFER = 1      '指定缓冲区为首要声音缓冲区。
'    DSBCAPS_STATIC = 2             '缓冲区的数据为静态数据,若有可能会将缓冲区建立在声卡上;
'    DSBCAPS_STICKYFOCUS = 16384
'End Enum
'
''DSBUFFERDESC 数据结构
'Type DSBUFFERDESC
'    lBufferBytes As Long           '设定缓冲区的大小,以字节为单位;
'    lFlags As CONST_DSBCAPSFLAGS   '(见以下说明)
'End Type
'
''WAVEFORMATEX 数据结构是对声音的定义
'Type WAVEFORMATEX
'    lAvgBytesPerSec As Long        '每秒的数据流量,相当于lSamplePerSec * nBlockAlign
'    lExtra As Long                 '不作设定,默认值为0。
'    lSamplesPerSec As Long         '设定声音的频率分别为8.0 kHz、11.025 kHz、22.05 kHz、或者44.1 kHz;
'    nBitsPerSample As Integer      '设定声音为8-bit或16-bit;
'    nBlockAlign As Integer         '资料区所占的byte数,例如mono及8-bit其值为1;若stereo及16-bit其值为4;
'    nChannels As Integer           '声道的设置,当其值为1时是单声道,为2时是双声道;
'    nFormatTag As Integer          '声音的格式,通常使用WAVE_FORMAT_PCM来设定,因为PCM是比较常用的声音格式。
'    nSize As Integer               '追加信息,可不作设定。
'End Type

sf_2003101003853.jpg

25

主题

234

帖子

262

积分

中级会员

Rank: 3Rank: 3

积分
262
发表于 2003-10-10 10:23:00 | 显示全部楼层

Re:VB DirectSound详细说明

我顶。

9

主题

28

帖子

28

积分

注册会员

Rank: 2

积分
28
发表于 2003-10-10 13:11:00 | 显示全部楼层

Re:VB DirectSound详细说明

这样的帖,该置顶的.

0

主题

1

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2006-7-15 23:39:00 | 显示全部楼层

Re:VB DirectSound详细说明

获取声音驱动设备信息后,如何得到设备的能力,如是否可以播放WAV格式文件。
下面我据一个例子:
我有台电脑有如下声音设备(用objDtxDirectX7.GetDSEnum函数得到的)
1、主声音驱动程序
2、Crystal SoundFusion(tm) CS4281
3、调制解调器 #0 线路播放 (仿真)
问题1:如何不显示“主声音驱动程序”?
问题2:如何判断出“调制解调器 #0 线路播放 (仿真)”不能播放WAV格式的文件



19

主题

40

帖子

52

积分

注册会员

Rank: 2

积分
52
发表于 2006-7-17 19:25:00 | 显示全部楼层

Re:VB DirectSound详细说明

一个问题~~~我发现使用VB编写DirectX Sound的程序占用CPU的资源非常严重~~~
我那图拉丁赛扬1.3G的CPU就被耗去了至少36%的资源~~~厉害阿~~~

不知道怎么降低CPU的占用率呢??

26

主题

537

帖子

537

积分

高级会员

Rank: 4

积分
537
发表于 2006-7-21 09:56:00 | 显示全部楼层

Re:VB DirectSound详细说明

我使用静态缓冲似乎没什么问题,但是建立流缓冲却总是失败。
SecondaryBuffer有一种构造方法只使用BufferDescription和Device两个参数。能给出一个调试通过的该构造方法示例吗?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-25 00:08

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表