AutoCAD 3DMAX C语言 Pro/E UG JAVA编程 PHP编程 Maya动画 Matlab应用 Android
Photoshop Word Excel flash VB编程 VC编程 Coreldraw SolidWorks A Designer Unity3D
 首页 > VC编程

使用DirectX 优化声音特性

51自学网 2015-08-30 http://www.51zixue.net

 

二.在主缓冲区中使用相同的数据格式

DirectSound合成器将每个从缓冲区中的数据转换为主缓冲区的数据格式,这种数据的转换是在数据进入主缓冲区的合成过程中实现的,它也将占用CPU周期。你可以在保证从缓冲区(例如波形文件)和主缓冲区具有相同的数据格式的前提下消除这笔开销。事实上,正是由于DirecSound的这种格式转换方式,你所要做的仅仅是对比样例速率和声道数,即使样例速率(8位或16位)存在一些差别也没有关系,因为它唯一的后果只是降低主缓冲区的数据存取速率。

到目前为止,大多数声卡都是ISA总线卡, 它通过DMA方式将声音数据从系统内存移动到当地缓冲区中,处理器在进行内存读写之前将被迫等待DMA的数据传输结束,这势必会影响到CPU的运行速度。对于ISA总线声卡,上述的数据传送方式无疑将对系统的运行产生不可回避的影响,但并不会对新型的32位PCI卡产生任何影响。

对于DirectSound,DMA数据传输的影响直接关系到数据的输出速率以及主缓冲区的访问速率。我曾听说过这样的趣事:在一台主频为90Mhz的奔腾机上运行基本格式为44.1Khz,16位的立体声音乐程序,DMA将占用多达30%的CPU指令周期!DMA数据传输正是影响DirectSound运行的最大因素。值得庆幸的是,上述问题在你无法顺利执行时非常容易处理。实验表明,减少数据存取速率的最好办法是改变主缓冲区中的数据格式。这里的转换十分明显,运行改变了声音的品质,要改变主缓冲区中的数据格式,只需调用方法IDirectSoundBuffer::Setformat,但不要忘记:你的协作层设置成DSSCL.PRIORITY或DSSCL_EXCLUSIVE,以避免主缓冲区的耗费。

三.在无声时间间隔中连续使用主缓冲区

DMA同时从另一个方面影响着系统的运行。当没有声音播放时,DirectSound停止了合成器的工作和DMA的活动。如果你的程序中存在着短促频繁的无声时间间隔,在每次声音播放时使合成随声音播放时的间断而起起停停,将比你让合成器一直处于连续的工作状态的情况更糟。在这种情况下,你可以在主缓冲区中强制性的调用方法PLAY使合成器处于激活状态。这样,即使在没有声音播放时,合成器也将连续工作。此时,为了恢复停止合成器的缺省方式,我们可以在主缓冲区中调用方法STOP。

四.使用硬件进行声音合成

如果系统中装配了支持声卡的DirectSound驱动器,大多数声卡都支持一定水平的硬件合成。下面的一段小窍门将允许你尽量使用硬件合成。


在你进行硬件声音合成时使用静态缓冲区。DirectSound将试图在静态缓冲中 进行声音合成。


为你用得最多的声音文件建立声音缓冲区(可用来进行声音硬件合成的合成器是有一定的限度的。


在声音文件运行时,使用方法IDirectSound::GetCaps决定声音加速硬件支持何种格式,并尽可能的采用这些格式(一些声卡只能合成特定格式的声音文件。例如:SoundBlaster AWE32声卡只能合成单16位格式的声音文件)。

当你调用CreatSoundBuffer建立从缓冲区时,你得建立静态缓冲区,在结构DSBUFFERDESC的dwPlag区域设定DSBCAPS_LOCHARDWARE标志。你也可以通过设定 DSBCAPS_LOCHARDWARE标志将缓冲区的数据进行强制性的硬件合成。但是,硬件合成所要使用的资源不可用时,CreatSoundBuffer就将出错。

方法IDirectSound::GetCaps为我们提供了关于声音加速能力的详尽描述,这对于我们进行存取操作有很大的邦助。我们在其工作时间内可以调用GetCaps,调整音频系统以最佳方式使用硬件资源。在 DirectX 文档中查看结构 DSAPS和标志DSCAPS.dwFlags可使我们准确了解到一些系统的有用信息。

五.最低限度的进行声音控制变换

在从合成器中改变均衡、音量或频率也将影响到应用程序的运行。为了防止声音输出时的中断的产生,DirectSound合成器必须提前20到100毫秒,甚至更多的时间进行声音合成。当你进行声音控制变换时,合成器不得不刷新正在进行的声音合成的缓冲区的信息,重新合成以适应适应的变化。比较好的方法是尽量减少送入系统的控制改变次数。这在按流或群输入时显得尤为重要。同时,我们应尽量减少日常的调用SetVolume、SetPn、SetFrequency的不连续操作。例如:如果你进行帧同步的定期检测,需要将适应从左声道扬声器移动到右声道扬声器时,你就应该每帧调用SetPan一次,而不是每帧两次。

注意: 三维控制变换 (方向、位置、速度、多普勒因子等等) 也将引起DirectSound合成器在其先前进行合成的缓冲区中重新合成。但是,你也可以将一系列三维控制变换集合在一组中,这将只使DirectSound合成器只进行一次重新合成。请仔细阅读以下关于延时控制变换详细说明的章节。

六.使用延时三维进程命令

正如我在前面所说的那样,三维声音将比常规声音花费更多的CPU指令周期。这是因为在每一个合成周期内,为计算出三维立体声音效将占用更多的CPU指令周期。你应该尽可能地减少使用三维立体声,最好不要使用那些并不对你真正有用的三维声音。这是通过实践得出的在你运行程序时影响整个系统工作的另一因素。在设计你的应用程序时,你应该尽早进行尝试,使其更加容易使声音具有或没有三维效果。你也可以调用具有 DS3DMODE_DISABLE标志的方法IDirectSound::SetMode,使得三维进程能够在三维缓冲区中运行。

改变三维声音缓冲区以及听众进行的诸如对方位、速度、多普勒因子的操作,都将引起DirectSound合成器重新合成先前合成缓冲区中的信息,当然,这将浪费一定的CPU指令周期。为了使三维设置的改变对系统运行的影响降低到最小程度,你就应该使用延时三维进程命令。这是DirectSound三维声音组件所特有的特征为了使用三维延时进程命令,请设定每个三维设置变换(SetPosition,SetVelocity等等)中的方法IDirect3DListener或 Direct3DSoundBuffer的dwApply 参数的DS3DMODE_DISABLE 标志,并且将所有的这些变化制成一帧,随后,再调用IDirect3DListener::CommitDeferredSettings去执行所有的延时命令,在先前的合成缓冲区中进行一次重新合成。


 

结 论


我已经为读者罗列了一系列利用DirectX优化音频媒体的特殊工具。我所能给予你的最好的建议是:设计你的支持运行、监视和音量调节的音频子系统。毫无疑问,你必须保证你有充足的时间等待你的程序的运行!如果你从一开始就将程序运行的协调性考虑进去,这个任务将变得更加容易。

 
 
说明
:本教程来源互联网或网友上传或出版商,仅为学习研究或媒体推广,51zixue.net不保证资料的完整性。

上一篇:如何通过崩溃地址找到出错的代码行  下一篇:程序中嵌入汇编的实例