




已阅读5页,还剩159页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第1章DirectXAudio之DirectSound 1 1DirectXAudio介绍 1 2 3 4 1 2DirectSound介绍 1 5 6 7 8 1 3DirectSound应用程序开发 5 6 7 8 9 1 4本章小结 1 5 6 7 8 1 1DirectXAudio介绍 1 2 3 4 1 1 1DirectX发展历程现在从事DirectX开发的程序员恐怕对DirectX的历史并没有太多了解 也许程序员可能也并不关心其历史 因为这并不会影响程序员现在的工作 但是我仍想在这里用一点篇幅介绍一下DirectX的发展历程 让那些无论是正在进行或是准备进行DirectX开发的朋友们知道DirectX是在什么样的背景下诞生的 它经历了什么 现在正处于什么阶段 以及其它相关背景知识 1 DirectX的诞生众所周知 Windows95是Microsoft在操作系统上的一个最重要的里程碑 DirectX有幸搭上了这趟列车 它是和Windows95同时推出的 当时还不叫DirectX 而是称为GameSDK 我们可以认为GameSDK就是现在DirectX的前身 从GameSDK的字面意思我们就能大概理解它的内容 说白了 GameSDK就是在Windows95下运行的 提供给游戏软件开发商使用的 游戏软件开发包 GamesSoftwareDevelopmentKit 正是这种局面引起的困惑 才使Microsoft着手开发GameSDK 当时GameSDK的设计思想是 1 GameSDK由许多速度很快 低层的库和API组成 这些库和API为游戏开发者提供最大限度的自由和对硬件的操作 2 GameSDK对硬件开发的支持 由原来游戏开发商转移到硬件制造商 即由对硬件最为熟悉的硬件制造商来完成对自己硬件的支持软件 并且将最先进的硬件技术为游戏开发商所知 3 让游戏也成为真正的Windows应用程序 即支持多任务 你可以从一个游戏切换到同时运行的另一个应用程序 然后还可以返回该游戏 4 要有能超过或者达到DOS环境下所能达到的性能 在使用GameSDK的情况下 游戏开发者不必关心游戏要运行在哪个制造商的硬件上 因为Microsoft把这些特性都封装在了硬件驱动程序和一系列API中 当然很多是由硬件制造商完成的 达到了开发时的硬件独立性 2 DirectX的发展DirectX的发展历程如图1 1所示 图1 1DirectX的发展历程 1 DirectX1 0DirectX1 0是Windows下第一个可以直接对硬件信息进行读取的程序接口 与早期的GameSDK相比有本质性的区别 可以令Windows下的图形处理速度与DOS媲美 2 DirectX2 0在这一段时间内 刮起了强烈的3D加速旋风 然而当时的DirectX在这一领域还是空白的 当时市场上出现的高性能3D图形加速卡在当时的DirectX下只能发挥其性能的1 10 3 DirectX3 0完整的Direct3D是随DirectX3 0向公众发布的 当时的Direct3D被公布为 一个视频游戏开发平台 将成为进入视频游戏工业的驱动力 4 DirectX5 0从5 0版开始 没有DirectX4 0 DirectX的多个部件按照应用目的被分为两大层次 DirectXFoundation层和DirectXMedia层 DirectXFoundation层为开发者提供一套 低级 API函数 以便应用程序能够充分利用3D图形加速芯片和声卡的各种高级特性 DirectXMedia层则建立在DirectXFoundation层的基础之上 提供播放动画 播放多媒体数据流和交互控制等高级服务 它也由四个部件组成 DiectShow DirectAnimation Direct3DRetainedMode和DirectPlay DirectXMedia使得应用程序只需使用一套API函数就能处理多种媒体数据 而不像以前那样 声音和图像要分别使用不同软件厂商开发的API函数 另外 DirectXMedia提供一种统一的定时机制来处理多媒体事件 使得开发者可以灵活地控制动画 视频和音频等数据的生成与同步播放 5 DirectX6 01998年推出的DirectX6 0版本相对于5 0新增了DirectMusic部件 DirectMusic由三个子部件组成 DirectMusicCore DirectMuiscInteractive和DirectMusicProducer 在这个新版本中Direct3D功能更强大 运行速度更快 并支持FlexibleVertex 多重材质及模板平面 程序得到大大优化 6 DirectX7 0DirectX7 0在图形功能方面创建的图形多边形数目比以前版本都要多 这使得计算机生成的数字世界的人物和物体的表面更加平滑 DirectX7 0提供高级3D加速支持 使得多边形的变化更快 它所产生的动画效果非常逼真 7 DirectX8 0DirectX8 0是Microsoft公司于2000年11月9日正式推出的一款DirectX的最新版本 它具有多项令人兴奋的功能特性 下面将对它的新增特性进行全面详细的介绍 DirectX8 0是Windows操作系统下的最新的多媒体系统链接库 通过DirectX8 0 其它软件能够尽情发挥系统的效能 并且带给我们最棒的多媒体体验和震撼效果 DirectX8 0的诸多强大功能和特性可以带来游戏与视听多媒体方面更为强大的功能 它可以让游戏在3D真彩模式下运行得更为流畅 在电脑上看VCD或者是欣赏音乐的时候能够看见更为绚丽的画面 也能够体验到环绕音乐的魅力 1 1 2DirectXAudio概述从DirectX6 1开始 DirectXAudio成为DirectMusic的一个扩展功能 而现在DirectX8 0中把DirectSound和DirectMusic合并在一起统称为DirectXAudio 可谓意味深长 一方面 通过合并实现了更为统一的核心API DirectSoundAPI和DirectMusicAPI在某些方面可以互补 DirectMusic可以被当作一种高级音频API用于多种音频流 在DirectX8 0中 DirectSound和DirectMusic这两个名字仍然会继续使用 但实际上DirectSound和DirectMusic之间的区别已经很小了 另一方面 通过加入大量的新特征和新机制 使控制更加灵活 功能更加完善和强大 DirectXAudio的功能并不只是用于播放音乐 它能够充分调用硬件的加速功能 系统可下载功能以及3D特效环境来更好地营造出一个立体氛围的音乐环境 诸如在不同的游戏中会有各种各样的声音效果 脚步声从后面慢慢逼近 蜻蜓的嗡嗡声在你头边环绕 一辆火车从左边飞驰而来 DirectXAudio能够让你感受到空间的声音效果 它能够制造出声音从你身边发出的幻觉效果 DirectX8 0Audio为播放集成的音乐和声音效果提供了新的体系结构 尽管仍然使用名称DirectSound和DirectMusic 但在它们之间已经没有明显的区别 希望将来DirectMusicAPI能够成为创建交互式声音效果的首选API 图1 2DirectX8 0Audio体系结构 Creative公司的部分EAX混响技术也整合进了DirectXAudio体系中 很早Microsoft就已经得到了Creative公司的授权许可使用该公司EAX 环境音效扩展技术 声音技术中的一些声音特效 这些效果包括边缘处理 和声 环境回响等经由DirectSound和DirectMusic被增加到了DirectX8 0中 1 1 3DirectXAudio新特征前面曾提到 在新的DirectXAudio体系结构中加入了不少新的特征 增加了控制的灵活性和功能的完善性 下面对这些新特征予以总结 1 WAV文件和基于消息的声音集成在一个播放机制中 WAV文件和资源现在可以通过DirectMusic加载器加载 并通过DirectMusic演奏器播放 应用程序不再需要分解WAV文件 并将其复制或流入DirectSound缓存 DirectSoundAPI并没有被丢弃 而仍然会得到支持 开发者仍然可以通过DirectSound缓存直接播放WAV文件 见后面的DirectSound部分 DirectSound仍将是用于WAV文件捕获和全双工的API WAV文件和MIDI文件在处理的先后次序上享有同等的地位 并将采用同一机制对两者进行回放 由于DirectXAudio支持了DLS2标准 因此一些MIDI音乐中特有的音效处理也可以用在WAV文件上 2 音轨 AudioTrack 模型更加灵活 强大 在以前版本的DirectMusic中 演奏通道被映射到端口 同时每个端口将其输出发送到一个独自的DirectSound缓存 在新的模型下 段落中的声道被映射到音轨 控制声音数据从演奏器流向最终输出设备 3 可以对段落状态进行独立控制 段落的每个播放实例都有自己的音轨 因此可以单独修改每个段落状态的音量 音质和音调等参数 4 DLS2合成 DirectMusic合成器现在基于DLS2标准 能够提供更高质量的声音合成 DLS2合成器的新特性包括六级封装 语音分层 释放波形和额外的低频振荡器 LFO Low FrequencyOscillators 5 特殊效果 DirectX媒体对象 MediaObjects 可与声音缓冲区连接在一起 以增加各种音效 诸如音乐回声 二级交互式3D音效 I3DL2 Interactive3DAudioLevel2 环境有关的声音回声 扭曲等标准音效和由DirectXAudio提供的回声效果 以及第三方提供的音效等 6 通过段落连接实现更强大的控制 作曲家可以在段落中设置许多点 指定从何处开始播放段落 从而维护段落与时间标志之间的关系 主段落可以包含连接到其它段落的任意点 7 实现了接近静音的通知类型 演奏通知事件现在有一个新的通知类型 这个通知类型的常量标志为DMUS NOTIFICATION MUSICALMOSTEND 它表示队列中的最后一个主段落即将结束 这样 就给应用程序一个机会来安排播放新的段落 8 加强型MIDI控制器支持 现在循环消息支持 已注册的参数数目 RPN RegisteredParameterNumber 和 未注册的参数数目 NRPN NonregisteredParameterNumber 控制器变化 9 可实现段落无限次循环 新的DMUS SEG REPEAT INFINITE标志使得一个段落可以播放无限多次 10 简化音乐波段的加载和卸载 段落对象调用一个简单的方法加载和卸载音乐波段 11 生成动态声轨数据 对于声轨 新的配置和播放标记使得每次播放或循环播放某个段落时 都可以对声轨进行改写 例如 可以配置和弦声轨 使得每次播放该段落时 都建立新的和声进行 12 音乐脚本 先前版本中的音乐脚本 AudioScript 在DirectX8 0中没有改动 音乐脚本使得设计者可以把游戏编程和事件音乐伴奏的插入分割开来 从而让设计者更好地进行游戏编程工作 13 通过音轨实时控制 应用程序可以单独设置各个音轨的配置 禁用播放和参数控制 音轨可以配置为根据时钟时间而不是音乐时间进行操作 14 容器对象 DirectMusicProducer使工程的所有组件都可以放在一个文件中 查找和加载所有对象非常容易 容器也可以嵌在段落中 因此播放一个段落所需要的所有内容都可以放在这个段落中 15 歌词声轨 包含歌词声道的段落可以将时间戳记文字发送到演奏器 16 提高了高速缓存管理性能 应用程序可以更容易释放由其它对象加载的 而现在已用不着的对象 1 2DirectSound介绍 1 5 6 7 8 1 2 1关于DirectSoundDirectSound可以提供快速的混音 硬件加速功能 并且可以直接访问相关设备 当然 最主要的是它提供的功能与现有的设备驱动程序保持兼容 DirectSound允许进行波形声音的捕获 重放 也可以通过控制硬件和相应的驱动来获得更多的服务 DirectSound的优势当然和DirectX的其它组件一样表现在速度上 它提供了低延迟音频控制和处理 允许开发者最大效率地使用硬件 并拥有良好的兼容性 DirectSound允许在与某个有设备无关接口的硬件打交道时 无须知道其具体的细节就可以以最有效的方式来使用它 你的应用程序可以在最简陋的音频设备上工作得很好 而同时又利用到了DirectSound针对其特性所做的优化 DirectSound还可使以下的工作做起来更容易 在运行时检查硬件能力 从而能在给定的个人电脑配置下作出最佳的解决方案 在用C 开发时 通过使用属性设置 可以使那些还不被DirectSound直接支持的新硬件能力得到利用 为得到快速响应 实现了低延迟的音频流混合 实现了3D音效 声音捕获 1 2 2DirectSound的功能组成DirectSound的各个功能部分组成为 声音回放 声音捕获 扩展性能的属性设置 直接硬件设备访问等 DirectSound与其它DirectX内容一样 使用组件对象模型 COM ComponentObjectModel 构造诸如声卡 IDirectSound8 声音缓冲区 IDirectSoundBuffer8 3D声音缓冲区 IDirectSound3DBuffer8 和声音捕获设备 IDirectSoundCapture8 等接口 1 DirectSound的声音回放概述DirectSound的缓冲区对象是一个PCM格式表示的声音数据的缓冲区 缓冲区对象用来启动 停止 暂停声音回放 也可以对频率 格式等属性进行设置 主缓冲区包括收听者可以听到的音频信号 也就是说如果将声音数据写入主缓冲区 这些声音就马上能被听见了 当然前提是必须有音箱 二级缓冲区分别包含了单个声音信号或一个音频信号流 DirectSound自动生成了一个主缓冲区 而让应用程序去创建二级缓冲区 当声音信号在那些二级缓冲区中产生时 DirectSound便把它们在主缓冲区中混合后再由输出设备播放出去 限制DirectSound所能混合的缓冲区个数的 仅仅是可用的处理时间 DirectSound并没有分析声音文件的函数 你必须以正确的格式向二级缓冲区提供音频信号流 2 DirectSound的音频捕获概述DirectSoundCapture对象被用于对声音捕获设备的能力的查询和创建 并用于从一个输入源捕获音频信息的缓冲区 音频捕获函数在Win32中原已存在 早些时候出现在DirectX5 0中的DirectSoundCapture的发行版本并没有比已经存在的WaveIn函数有多大的改进 然而 DirectSoundCaptureAPI允许应用程序开发者们使用统一的音频回放和捕获接口 它同时也使现在开发的应用程序能从将来新的 不断发展的驱动模式及API中得到好处 DirectSoundCapture允许对压缩格式的捕获 在早些时候的版本里 由WaveIn函数或硬件提供对压缩格式的支持 DirectSoundCapture自己并不调用音频压缩管理程序 ACM AudioCompressionManager DirectSoundCaptureBuffer对象生成一个缓冲用来存放从输入设备捕获的数据 这个缓冲区是环型的 也就是说 当输入指针到达缓冲区的尾部时 它又将从头开始 见后续章节的内容 DirectSoundCaptureBuffer对象的方法可以让你获取缓冲区的各种属性 开始或停止音频捕获 查看内存的分配情况 以便你可以安全可靠地取得数据 保存在一个文件中或作别的用途 在音频回放时 DirectSound可以使你在捕获的数据到达缓冲区的某一特定位置时或在捕获停止时得到通知 这个功能是由IDirectSoundNotify8接口来提供的 3 DirectSound的扩展性能的属性设置通过扩展性能的属性设置 DirectSound能支持声卡及其相应的驱动程序的制造商所提供的更多扩充性能 硬件厂商不断使硬件具有新的功能并制订出新的属性规范 应用程序开发者可以使用IksPropertySet接口的各种方法去判断一个特定的属性集是否在某个特定的硬件设备上有效 并且可以设置那些属性 例如打开和关闭特殊音效 属性设置使DirectSound有了无限的可扩展性 你可以只用一个方法 IksProperty Set Set 来改变硬件制造商以任何方式规范的硬件属性值 IksPropertySet接口是WDMKS Win32DriverModelKernelStreaming 体系结构的一部分 4 DirectSound的直接硬件访问DirectSound通过DirectSound硬件抽象层 HAL Hardware AbstractionLayer 一个由音频设备驱动程序所组成的接口 来访问声音硬件设备 DirectSound硬件抽象层提供以下功能 获得或释放对声音硬件的控制 提供对声音设备的功能的描述 当硬件可用时对其执行特定的操作 当硬件不可用时可以作出操作请求失败的报告 DirectSound会自动地使用声音硬件加速功能 包括硬件混音和硬件声音缓冲存储器 你的应用程序无须查询硬件或通过特殊的编程 就可以使用硬件加速 然而 如果你要发挥出硬件资源的最大潜能 则可以在运行时实时查询DirectSound以获得对声音设备能力的一个完整描述 然后通过不同的途径去优化那些给出的或没给出的特性 你也可以指定某些声音缓冲区来接收硬件加速 5 DirectSound和其它系统声音部件之间的关系DirectSound和其它系统声音部件之间的关系如图1 3所示 DirectSound和标准的Windows波形音频函数 WaveOutxxx 提供了对声音硬件的波形音频分配的不同途径 每个设备在同一时间内只能提供通过一条途径的访问 如果波形音频驱动程序申请分配到了一个设备 那么再试图用DirectSound申请分配同一个设备将失败 类似地 如果一个DirectSound分配到了某个设备 也不能再试图用波形音频驱动程序再去申请 图1 3DirectSound和其它系统声音部件之间的关系 MicrosoftWindows视频现在使用了波形音频函数在AVI AudioVisualInterleaved 视频音频交互 文件中播放音轨 因此 当你的应用程序使用DirectSound播放AVI文件时 音轨将会听不到 类似地 如果你在播放AVI文件时试图去创建一个DirectSound对象 创建函数将会返回错误 1 3DirectSound应用程序开发 5 6 7 8 9 1 3 1设置VisualC 编译环境1 DirectSound包含的头文件DirectSound应用程序所包含的头文件如表1 1所示 表1 1DirectSound包含的头文件 2 在工程中加入所需库文件DirectShow所需使用的库文件如表1 2所示 表1 2DirectShow所需使用的库文件 1 3 2创建并初始化DirectSound对象DirectSound对象描述了系统的声音硬件设备 在应用程序中使用DirectX8 0创建一个DirectSound对象 也就是创建IDirectSound8接口的一个实例 IDirectSound8接口可以让你在应用程序中定义并控制声卡 扬声器和内存环境 1 创建DirectSound对象每一个DirectSound对象都是与声音硬件设备 声卡 相关联的 检测声音设备就是找出可用的声音设备并与创建的DirectSound对象关联起来 在DirectX8 0中用DirectSoundCreate8函数创建一个IDirectSound8接口 其语法如下 HRESULTWINAPIDirectSoundCreate8 LPCGUIDlpcGuidDevice LPDIRECTSOUND8 ppDS8 LPUNKNOWNpUnkOuter 这个函数的第一个参数指出与此对象相联系的设备的GUID地址 你可以通过检测声音设备来获得这个GUID 或者简单地传递NULL为缺省的设备创建一个对象 其语法如下 defineSAFE RELEASE p if p p Release p NULL defineFAILED Status HRESULT Status 0 HRESULThr S OK LPDIRECTSOUND8pDS LPDIRECTSOUNDBUFFERpDSBPrimary NULL SAFE RELEASE pDS 如果pDS已与其它设备关联 则先解除这种关联 用缺省的主声音设备创建一个DirectSound对象hr DirectSoundCreate8 NULL 如果系统没有安装声音设备或声音设备正被波形音频 非DirectSound 函数使用 此函数将返回错误 你必须在你的应用程序中为这个调用的失败作出相应的处理 以使应用程序能在没有声音的情况下继续工作 或提醒用户先关闭已占用了声音设备的程序 例如可以用dxerr h中定义的宏DXTRACE ERR hr DirectSoundCreate8 NULL 返回错误信息如下 这里只是举例而已 实际上是不会返回此信息的 也可以用CoCreateInstance函数来创建DirectSound对象 在应用程序一开始就调用CoInitialize来初始化COM if FAILED CoInitialize NULL returnFALSE 下面的代码是使用CoCreateInstance函数和IDirectSound Initialize方法而非DirectSoundCreate8函数创建的DirectSound对象 dsrval CoCreateInstance 其中 CLSID DirectSound8是DirectSound对象驱动程序类的类标识 IID IDirect Sound8是可以使用的DirectSound接口的标识符 pDS参数给出了CoCreateInstance返回的没有被初始化的对象 CoCreateInstance函数创建一个由CLSID指定的 还没有初始化过的类对象 然后用IDirectSound8 Initialize方法对该对象初始化 当然在使用该DirectSound对象前 必须先进行初始化工作 2 设置协作等级由于Windows的多任务机制 同一时间可能有不止一个的应用程序在使用同一个设备的驱动程序 通过协作等级的使用 DirectX保证了每个应用程序不会在错误的时间或以错误的方式取得对设备的访问 每个DirectSound应用程序有一个协作等级决定了它被允许访问设备的范围和程度 在创建好一个DirectSound对象后 你必须在播放声音前用IDirectSound8 SetCoope rativeLevel方法设置好相应设备的协作等级 即HRESULTIDirectSound8 SetCooperativeLevel HWNDhwnd DWORDdwLevel 其中 参数hwnd是应用窗口的句柄 参数dwLevel是由用户指定的优先级 dwLevel取表1 3中所列出的值 表1 3DiredSound设备的协作等级 DirectSound为声音设备定义了四个协作等级 独占的 DSSCL EXCLUSIVE 常规的 DSSCL NORMAL 优先的 DSSCL PRIORITY 和直接写入的 DSSCL WRITEP RIMARY 大多数的应用程序用常规级别使用声音设备 此级别允许在多个使用声卡的应用程序之间按顺序切换 下面的例子是在一个DirectSound对象创建时为DirectSound设备设置常规的协作等级 if FAILED hr pDS SetCooperativeLevel hWnd DSSCL NORMAL return hr 3 设备能力DirectSound允许你的应用程序获得声音设备的硬件能力 大多数应用程序并不需要做这一步 因为DirectSound会自动地使用一切可行的硬件加速功能 然而 高水平的应用程序能使用此功能 以便让硬件发挥应有的性能 例如 当硬件支持混音时 应用程序就可比不支持硬件混音时播放更多的声音 创建了一个DirectSound对象后 调用IDirectSound8 GetCaps方法就能获得声音设备的能力 下面的例子说明了在DirectSound对象创建并初始化以后 如何获得设备的能力 DSCAPSdscaps dscaps dwSize sizeof DSCAPS hr pDS GetCaps DSCAPS结构存放关于声音设备的资源和性能的信息 包括每类的最大资源数和当前可用的资源 注意在调用此方法前 DSCAPS结构的dwSize成员要先被初始化 DSCAPS结构在dsound h中定义如下 typedef DWORDdwSize DWORDdwFlags DWORDdwMinSecondarySampleRate DWORDdwMaxSecondarySampleRate DWORDdwPrimaryBuffers DWORDdwMaxHwMixingAllBuffers DWORDdwMaxHwMixingStaticBuffers DWORDdwMaxHwMixingStreamingBuffers DWORDdwFreeHwMixingAllBuffers DWORDdwFreeHwMixingStaticBuffers DWORDdwFreeHwMixingStreamingBuffers DWORDdwMaxHw3DAllBuffers DWORDdwMaxHw3DStaticBuffers DWORDdwMaxHw3DStreamingBuffers DWORDdwFreeHw3DAllBuffers DWORDdwFreeHw3DStaticBuffers DWORDdwFreeHw3DStreamingBuffers DWORDdwTotalHwMemBytes DWORDdwFreeHwMemBytes DWORDdwMaxContigFreeHwMemBytes DWORDdwUnlockTransferRateHwBuffers DWORDdwPlayCpuOverheadSwBuffers DWORDdwReserved1 DWORDdwReserved2 DSCAPS LPDSCAPS typedefconstDSCAPS LPCDSCAPS 4 扬声器配置DirectSound用扬声器配置 即使用与收听者相关的扬声器定位 来为用户的声音系统优化3D音效 在Windows98和Windows2000中 扬声器配置可以在控制面板中进行 而在一个应用程序中 亦可以用IDirectSound8 GetSpeakerConfig方法得到这些值 也可用IDirectSound8 SetSpeakerConfig来设置这些值 但有时并不能马上生效 而必须重新启动计算机 所以通常建议用控制面板进行配置 5 存储区压缩只要在最小的优先级 应用程序就可以用IDirectSound8 Compact方法将声音内存中的数据转移到内存中连续的存储区域内 以腾出尽可能多的可用存储空间 1 3 3设置DirectSound缓冲区本节讲述DirectSound缓冲区 Buffer 对象的创建和管理 这些操作是声音播放的基础 DirectSoundBuffer对象控制将声音数据从一个地方传输到另一个地方 数据来源可以是声音合成器 其它类型的缓冲区 一个文件或其它资源 1 缓冲区基础知识当你在应用程序中初始化DirectSound时 它自动创建和处理了一个主声音缓冲来进行混音并把声音送往输出设备 应用程序自己必须创建至少一个二级缓冲区用来存储和播放独立的声音信息 一个二级缓冲区可以在应用程序的整个生命周期内存在 或者在不需要时将其销毁 2 创建二级缓冲区为创建一个声音缓冲区 你的应用程序首先要填写一个DSBUFFERDESC结构并调用IDirectSound8 CreateSoundBuffer方法 此方法创建一个DirectSoundBuffer对象并返回指向该接口的指针 应用程序使用这个接口来操纵和播放缓冲区 3 克隆缓冲区应用程序可以用IDirectSound8 DuplicateSoundBuffer方法创建多个拥有相同数据的二级缓冲区 但不能克隆主声音缓冲区 4 缓冲区控制选项当创建一个声音缓冲区时 应用程序需为其指定控制选项 这可通过DSBUFFERDESC结构的dwFlags数据成员来完成 它可以指定一个或更多的DSBCAPS CTRL 标志 5 缓冲区的3D算法如果设置DSBCAPS CTRL3D控制标志创建一个二级缓冲区 并且该缓冲区由软件实现 在应用程序中就可以指定一个用于3D声音空间的算法 缺省时 不采用HRTF处理 并且与收听者有关的声音定位由均衡和音量表示 6 静态声音缓冲区和流式声音缓冲区在创建一个二级声音缓冲区时 需要定义其为静态还是流式缓冲区 静态缓冲区在内存中包含了一段完整的声音 通常只写入数据一次 然后一次播放完 创建一个静态缓冲区不一定要设置DSBCAPS STATIC标志 这一标志用于在声音设备自带的存储器中申请存储空间 1 3 4DirectSound缓冲区回放控制1 主缓冲区访问对那些需要特殊混音的应用程序 或为完成二级缓冲区不支持的 特殊效果的应用程序 DirectSound允许其直接访问主缓冲区 主声音缓冲区必定是被反复播放的 必须保证DSBPLAY LOOPING标志被置位 下面的例子说明了如何获得主声音缓冲区的写操作权 其中LPDIRECTSOUNDBUFFER定义为 typedefstructIDirectSoundBuffer LPDIRECTSOUNDBUFFER HRESULThr LPDIRECTSOUNDBUFFERpDSBPrimary NULL if pDS 得到主缓冲区DSBUFFERDESCdsbd ZeroMemory hr pDS SetCooperativeLevel hwnd DSSCL WRITEPRIMARY if FAILED hr returnDXTRACE ERR TEXT SetCooperativeLevel hr if FAILED hr pDS CreateSoundBuffer 如果硬件中根本不支持缓冲区 你就不能获得一个主缓冲区的写操作权 可以调用IDirectSoundBuffer GetCaps方法并检测返回的DSBCAPS结构的数据成员dwFlags的DSBCAPS LOCHARDWARE标志来进行判断 如果你试图锁住一个用软件模拟的主缓冲区 此调用将失败 2 设置主缓冲区格式在创建二级缓冲区之前 必须要设置主缓冲区的格式 在应用程序中用IDirectSoundBuffer SetFormat成员函数设置主缓冲区的格式 IDirectSoundBuffer SetFormat成员函数并不适用于二级缓冲区 如果需要一个新的格式的缓冲区 则必须重新创建一个DirectSoundBuffer对象 并设置成新的格式 下面的例子说明了如何设置主缓冲区的格式 WAVEFORMATEXwfx ZeroMemory 其中 结构变量wfx记录了主声音缓冲区新的格式 WAVEFORMATEX结构在Mmreg h中定义如下 ypedefstruct WORDwFormatTag 波形声音格式 在此只能是WAVEFORMAT PCM一种格式WORDnChannels 声道数DWORDnSamplesPerSec 采样率DWORDnAvgBytesPerSec 平均每秒数据量WORDnBlockAlign 块对齐WORDwBitsPerSample 量化位数WORDcbSize 多余数据 WAVEFORMATEX 3 向缓冲区写数据并播放1 向静态缓冲区中写数据并播放向静态缓冲区中写数据通常经过以下三个处理步骤 1 把整个缓冲区锁住 用IDirectSoundBuffer8 Lock方法 指定数据写入位置偏移量 通常为0 即从缓冲区起始地址开始写入 并得到该点的内存地址 2 用标准内存拷贝方法 将声音数据写入返回的内存地址 3 缓冲区解锁 用IDirectSoundBuffer8 Unlock方法 IDirectSoundBuffer8 Lock方法接受一个缓冲区的地址偏移量和要锁定的数据量作为参数 它返回了一个指向写入锁定地址开始处的指针 地址的偏移量是从缓冲区的头部开始计算的 其语法如下 HRESULTIDirectSoundBuffer8 Lock DWORDdwOffset DWORDdwBytes LPVOID ppvAudioPtr1 第一个指针LPDWORDpdwAudioBytes1 第一个指针指向的数据大小LPVOID ppvAudioPtr2 第二个指针LPDWORDpdwAudioBytes2 第二个指针指向的数据大小DWORDdwFlags 下面的代码说明了如何锁定缓冲区 并写入数据 其中 lpdsbStatic是一个指向已创建的静态缓冲区对象的指针 pbData是一个已有声音数据源的地址 LPVOIDlpvWrite DWORDdwLength if DS OK lpdsbStatic Lock 0 开始锁定的数据偏移量位置0 锁定的数据大小 因为设置了DSBLOCK ENTIREBUFFER标志 该参数被忽略 lpvWrite 起始锁定的第一部分数据地址 dwLength 锁定的第一部分数据的大小NULL 此处不需要回绕起始地址NULL 此处不需要回绕数据大小 DSBLOCK ENTIREBUFFER 标志位 表示锁定整个缓冲区 memcpy lpvWrite pbData dwLength 将声音数据拷贝到声音缓冲区中lpdsbStatic Unlock lpvWrite 锁定数据的起始地址dwLength 锁定数据大小NULL 没有回绕数据部分0 没有回绕数据大小 下面说明如何播放静态缓冲区中的数据 首先用IDirectSoundBuffer8 SetCurrentPosition方法设置播放游标的位置 然后调用IDirectSoundBuffer8 Play方法播放缓冲区 代码如下 lpdsbStatic SetCurrentPosition 0 HRESULThr lpdsbStatic Play 0 保留参数位0 优先级0 标志位 由于在上述例子中未设置DSBPLAY LOOPING标志 因而当缓冲区数据播放完毕 即播放游标移动到缓冲区结束位置时 缓冲区便会自动停止 在播放过程中 也可以用IDirectSoundBuffer8 Stop方法来强制停止 这时播放游标便停在原位 这就是为什么要用IDirectSoundBuffer8 SetCurrentPosition方法重置播放游标位置的原因 即这样可以确保从缓冲区开始位置播放 2 向流式缓冲区中写数据并播放因为流式缓冲区通常需持续不断地写入数据 并且不断地播放 且其缓冲区是 环 型的 所以DirectSound在对声音缓冲区加锁时就返回了两个写指针 参见 向静态缓冲区中写数据并播放 中的IDirectSoundBuffer8 Lock方法 当然 如果锁定的数据大小没有超过缓冲区的结尾 即锁定开始地址加上锁定数据长度没有超过缓冲区的最大偏移量 只需返回一个地址指针 如果锁定的数据大小超过了缓冲区的结尾数 则返回两个指针 其中第二个指针指向缓冲区的起始地址 例如 如果你要在一个400字节的缓冲区内锁住从缓冲区中部开始 偏移200字节 以后的300字节 则Lock方法返回的一个指针指向缓冲区内的后200个字节处 而第二个指针指向前100个字节处 锁定环形缓冲区结构如图1 4所示 图1 4锁定环形缓冲区结构 下面的代码说明了如何锁定缓冲区 并写入数据 LPDIRECTSOUNDBUFFERpDSBuffer BYTE pWavData DWORDdwWavData WAVEFORMATEX wfx 现在假设pDSBuffer已被创建 并假设我们已从WAV文件中读取数据存放在缓存pWavData中 且读取数据大小为dwWavData WAV文件格式信息存放在结构wfx中VOID pDSLockedBuffer NULL 指向被锁定的DirectSound缓冲区的指针DWORDdwDSLockedBufferSize 0 被锁定的DirectSound缓冲区大小DWORDdwWavDataRead 0 从WAV文件中读取的数据量DWORDdwOffset 300 将要锁定的DirectSound缓冲区大小if pDSBuffer NULL returnCO E NOTINITIALIZED 锁定缓冲区if FAILED hr pDSBuffer Lock 0 dwOffset 若没有数据 即dwWavData 0 则在锁定的缓冲区内放置 静音 数据if dwWavData 0 memset BYTE pDSLockedBuffer BYTE wfx wBitsPerSample 8 128 0 dwDSLockedBufferSize 若读取的数据大小dwWavData小于锁定的DirectSound缓冲区大小 则将数据复制到缓冲 区后 还要用数据填充剩余缓冲区 elseif dwWavDatawBitsPerSample 8 128 0 dwDSLockedBufferSize dwWavData 如果不再需要 则将缓冲区解锁pDSBuffer Unlock pDSLockedBuffer dwDSLockedBufferSize NULL 0 如果应用程序中用IDirectSoundBuffer8 Lock方法锁定缓冲区时返回两个指针 则用IDirectSoundBuffer8 Unlock方法解锁时也必须用相应的两个指针 但传递的缓冲区大小可以小于加锁时的大小 因为它们代表了将要送入声音输出设备的数据量 声音播放时 把解锁后的数据送往主缓冲区 然后用IDirectSoundBuffer8 Play方法将数据送到声音输出设备 通常在到达缓冲区的末尾时播放会自动停止 然而 如果IdirectSoundBuffer8 Play方法的dwFlag参数中的DSBPLAY LOOPING标志被置位 缓冲区就会反复播放直到应用程序调用了IDirectSoundBuffer8 Stop方法 此时播放游标又回到缓冲开始处 对流式缓冲区来说 你的应用程序要确保下一块数据在当前播放点回到缓冲开始处以前就写入到缓冲区中 为此你可设立通知位 以便在当前播放点到达一个特定位置时产生一个信号 应用程序中的数据应该比当前播放点提前1秒写入 以使回放时声音出现断续的可能性最小 4 缓冲区回放控制1 声音音量控制在应用程序中可以用IDirectSoundBuffer8 GetVolume方法得到声音缓冲区的音量 缓冲区的音量范围在dsound h中定义 其中音量最大值DSBVOLUME MAX为0 音量最小值DSBVOLUME MIN为 10000 音量最大值表示了缓冲区中的原始的声音音量 音量最小值表示了在最大值的基础上衰减100dB后的音量 实际上最小值表示静音 在应用程序中还可以用IDirectSoundBuffer8 SetVolume方法设置播放的音量 音量的值只能在音量最大值DSBVOLUME MAX与音量最小值DSBVOLUME MIN之间 该方法不能对声音放大 LONG plVolume LONGlVolume 0 pDSB GetVolume plVolume pDSB SetVolume lVolume 2 声音频率控制在应用程序中可以用IDirectSoundBuffer8 GetFrequency方法得到声音缓冲区播放声音的频率 Hz 缓冲区播放声音的频率范围在dsound h中定义 其中频率最大值DSBFREQUENCY MAX为100000 频率最小值DSBFREQUENCY MIN为100 由软件模拟的缓冲区的声音频率只能在这个范围内 而硬件实现的缓冲区声音频率可能超出这个范围 LPDWORDpdwFrequency pDSB GetVolume pdwFrequency 在应用程序中还可以用IDirectSoundBuffer8 SetFrequency方法设置声音缓冲区播放声音的频率 DWORDdwFrequency pDSB SetVolume dwFrequency 在用IDirectSound8 CreateSoundBuffer方法创建声音缓冲区时 会设置一个缺省的声音频率 在用IDirectSoundBuffer8 SetFrequency方法改变声音频率后 还可以用下面的方法将声音频率设置为缺省值 IDirectSoundBuffer8 SetFrequency DSBFREQUENCY ORIGINAL 3 左右声道均衡控制在应用程序中可以用IDirectSoundBuffer8 GetPan方法得到声音缓冲区左右声道的相对音量 得到的值在DSBPAN LEFT和DSBPAN RIGHT之间 这两个值在Dsound h中分别定义为 10000和10000 其中 DSBPAN LEFT表示在右声道由最大音量衰减100dB时的音量 DSBPAN RIGHT表示在左声道由最大音量衰减100dB时的音量 另外 DSBPAN CENTER的值定义为0 当由IDirectSoundBuffer8 GetPan返回的值为0时 表示两个声道都是最大值 衰减0dB 5 有关播放和写入的位置DirectSound在缓冲区中维护了两个指针 分别指向当前播放位置和写入位置 或者说是写入游标 指针的内容是相对于缓冲区的偏移量而非绝对地址 IDirectSoundBuffer8 Play方法总是从缓冲区的当前播放位置开始播放 缓冲区创建时 当前位置被置为零 当声音被播放时 播放点逐渐移动但总是指向要播放输出的下一个字节 当播放停止时 播放点仍然停在原处 即下一个要输出的字节处 如图1 5所示 把缓冲区看成是一个钟面 顺时针方向写入数据 播放位置与写入位置就像两条等速转动的针 写入位置总是稍微领先于播放位置 如果播放位置是1而写入位置指向2 往2以后写入数据才是安全的 在1和2之间的数据已被DirectSound排好等待输出而不应去改动 图1 5环形缓冲区播放和写入游标位置示意 应用程序可调用IDirectSoundBuffer8 GetCurrentPosition方法获取当前播放和写入游标的位置 HRESULTIDirectSoundBuffer8 GetCurrentPosition LPDWORDpdwCurrentPlayCursor LPDWORDpdwCurrentWriteCursor 6 播放缓冲区通知机制在处理音频流时 若希望应用程序
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 保密培训考试试题及答案
- 2025年济南监狱面试真题及答案
- 2025年中国蓝牙便携式打印机行业市场全景分析及前景机遇研判报告
- 2025年中国拉杆行业市场全景分析及前景机遇研判报告
- 2025年中国可生物降解和可堆肥真空袋行业市场全景分析及前景机遇研判报告
- 浙江省温州市乐清市知临中学2022-2023学年高二上学期期中考试历史试题(含答案)
- 新建氟化工一体化项目(一期)(220kV变电站部分)环境影响报告表
- 家庭农场市场准入与竞争力提升路径
- 幼儿教师心理素质与情感教育能力的提升途径
- 促进钢铁产品多元化与高附加值发展
- 产业园转让协议样本
- 剪式升降台的驱动机构设计
- 脑梗取栓护理查房
- 中国古代社会的发展演变过程
- 山西省中考语文模拟试卷及答案汇总五
- 双高建设背景下高职院校社会服务能力研究
- 25道中国民航航空医生岗位常见面试问题含HR常问问题考察点及参考回答
- 加油站服务承诺书的范文范文精简处理
- SF095广州市社会保险费补缴申请表
- 醉酒驾驶行政复议委托书范本
- 讲故事比赛细则、评分表
评论
0/150
提交评论