翻译:Panda3D Manual/V. Programming with Panda/F. Sound

声音(Sound

开源的Panda3D使用一个商业声音库FMOD,但如果你的程序不用于商业目的,可以免费使用FMOD

FMOD是一个强大的跨平台声音引擎,支持多种声音文件——MP3WAVAIFFMIDIMODWMAOGG Vorbis。详情见http://www.fmod.org

如果不想用FMOD,在pandabin文件夹下删除fmod.dlllibfmod_audio.dll文件即可,这样Panda就不会发出任何声音了。但你可以使用另外的声音库,如PygamePyOpenAL

 

载入、播放声音和音乐(Loading and Playing Sounds and Music

结构

Panda3D声音系统把声音分成两种——音效( Sound Effect)和音乐(Music)。这种分组方式只为方便程序员的工作,因为Panda3D2种声音分别处理。它们的区别稍后介绍。

基础

载入声音

我们通过Loader类载入声音。(不提倡通过“base builtin”来载入,它只用于兼容旧版本),在常规的Panda3D环境下,当你如下导入DirectStart时,loader就是一个builtin

import direct.directbase.DirectStart

载入声音需要提供声音的路径,如下:

mySound1 = loader.loadSfx("SoundFile.wav")

这句代码将返回一个AudioSound类对象。声音文件的扩展名是必要的。

播放声音

mySound.play()

停止播放

mySound.stop()

查询声音状态

mySound.status()

如果该声音当前没有在播放,status()返回1,如果正在播放返回2

音量

音量大小从01线性增长:

mySound.setVolume(0.5)

平衡

可以改变声音的平衡,设置的值在-1.01.0之间,-1.0只有左声道,1.0为右声道:

mySound.setBalance(-0.5)

注意!!!

如果在交互提示符下运行Panda,必须在播放一个声音之后用Update()命令。

base.sfxManagerList[n].update()

因为每一帧都会调用Update()命令来重置声道,在交互模式下Panda停止了帧刷新,所以不会自动运行。

 

操控声音(Manipulating Sounds

基础

声音循环

要使一个声音循环播放(播放完后重新播放),可以这样做:

mySound.setLoop(True)
mySound.play()

要停止声音的循环,把False传给setLoop()函数:

mySound.setLoop(False)

也可以指定循环的次数:

mySound.setLoopCount(n)

n”为大于0的任意整数,0表示无限循环。1只播放一次,>1播放数次。

注意设定循环次数为0>1的数将自动将循环标志setLoop()TRUE

无缝循环注意事项:

无缝循环一段声音其实很简单——载入声音然后调用setLoopplay。但是,Panda初级用户经常感到很难做到无缝循环,问题的根源在于:

1、某些MP3编码器有bug,会在声音的末尾添加一段空白,因此循环时就产生间断。试试用wav来代替。

2、有些人尝试通过Sound Interval来创造循环。不幸的是,sound interval依赖Panda线程来重启声音,如果CPU忙碌的话就会产生停顿。一般来说,我们使用setLoop方法。

3Miles声音系统有一个bug,需要在Panda3D中的一个workaround,这个workaround曾经和fmod产生冲突,直到我们做出一个新的workaround。这个bug已经不复存在了,你可以不管它。

综上可知,得到一个可靠的声音循环最简单的办法就是使用wav文件和setLoop方法,不要使用interval。当然,在游戏发布前可以把你的声音转化为mp3格式,但要确保mp3编码器不会添加空白段。

提示时间

对声音panda提供getTime()setTime()length()函数,它们分别报告当前的时间位置、设置当前的时间位置、报告声音时长。单位全都是秒。

mySound.length() 返回声音文件的长度,以秒为单位。

mySound.getTime() 得到当前播放的时间。

mySound.setTime(n) 设定播放时间为第n秒。

注意,声音在这些命令后立即播放,调用play()将重头开始播放声音。

改变播放速度

改变声音播放的速度使用:

mySound.setPlayRate(N)

N为任意浮点数。注意!!!负数将倒着播放,0将暂停播放。可以用

mySound.getPlayRate()

得到声音播放速度。

 

DSP效果(DSP Effects

Panda3D 1.3.0 开始支持FMOD-EX的音频效果,目前提供的效果有:

Panda3D ID

效果

DSPChorus

Chorus 齐声

DSPCompressor

Compression 压缩

DSPDistortion

Distortion 扭曲

DSPEcho

Echo [Delay] 回音[延迟]

DSPFlange

Flange

DSPHighpass

Highpass Filter 高通滤波

DSPItecho

Echo 回音
[For Mod/Tracker Files]

DSPItlowpass

Lowpass Filter低通滤波
[For Mod/Tracker Files]

DSPLowpass

Lowpass Filter

DSPNormalize

Noramlize

DSPParameq

Parametric EQ

DSPPitchshift

Pitchshifter

DSPReverb

Reverb

如何使用效果

首先创建一个效果对象(我们以一个回音效果为例)

echo = base.sfxManagerList[0].createDsp(base.sfxManagerList[0].DSPEcho)

这个效果在sound manager类里是一个常量,因此需要指定base.sfxManagerList[n].<effect> n代表某个音频manager0为声音,1为音乐),<effect>为上面的表格里列出的某种效果。

得到一个DSP对象后,就可以把它附(attach)到一个声音上

mySound.addDsp(echo)

回音效果这样就准备好了。

一些有用的DSP命令

在交互提示符下得到DSP类型的参数:

dspEffect.listParameterInfo()

它列出所有的DSP参数以及你可以编辑的值。可以在代码中编辑参数:

dspEffect.setParameter("nameOfParameter", value)

参数名必须被引用。

可以取回当前的参数:

dspEffect.getParameter("nameOfParameter")

你可以打开或关掉一个参数:

dspEffect.setBypass(n)

n为一个布尔值。

重置一种效果的参数为默认值:

dspEffect.reset(n)

把效果从声音上卸下来(detach):

mySound.removeDsp(effect)

也可以在某个音频Manager下把一个效果附到所有的声音:

base.sfxManagerList[n].addDsp(effect)

注意!!!对一个Manager附上一个效果将影响这个manager的全部声音。

 

3D音效

正如前文所说,音效(Sound Effect)和音乐(Music)在Panda3D里是分开处理的。对每一种类,Panda都可以处理16个不同的声音。这个值在配置文件config.prc中由audio-cache-limit变量指定,可以修改。有时我们只需要音效,有时只需要音乐,有时两者都需要。下面这些命令影响所有的同类声音,后两个函数将根据参数值TureFalse来打开或关闭某类声音:

base.disableAllAudio()
base.enableAllAudio()
base.enableMusic(bEnableMusic)
base.enableSoundEffects(bEnableSoundEffects)

下面介绍一些高级的声音处理程序。在编程中,音效和音乐由AudioManager对象实现。可以通过下面的代码访问这2manager

soundEffectsMgr = base.sfxManagerList[0]
musicMgr = base.sfxManagerList[1]

注意音效是sfxManagerList第一个成员,音乐为第二个。

通过AudioManager对象,我们可以设置doppler因子和dropoff因子,位置相关声音就是由这些因子实现。Panda封装了一个Audio3DManager类帮助我们实现位置相关声音。Audio3DManager的输入参数是一个audioManager和一个listenerlistener代表接收声音的位置,对Panda3D的玩家来说,该位置就是摄影机的位置。距离摄影机远的声音小,近的声音大。

from direct.showbase import Audio3DManager
audio3d = Audio3DManager.Audio3DManager(base.sfxManagerList[0], camera)

我们需要使用Audio3DManager里的loadSfx()函数创建一个位置相关的声音,而不是常规的loader.loadSfx()方法,后者用于与位置无关的声音,如:

mySound = audio3d.loadSfx('blue.wav')

声音可以附在物体上,随物体的移动而移动:

audio3d.attachSoundToObject( mySound, teapot )

你可以使用Audio3DManager提供的setSoundVelocity()setListenerVelocity()来设定声源或接收者的速度,得到一个doppler pitch shifting(多普勒效应,音调变化)。如果想让Audio3DManager自动调整运动物体的速度,调用setSoundVelocityAuto()setListenerVelocityAuto()

audio3d.setSoundVelocity(sound,velocityVector)
audio3d.setListenerVelocity(velocityVector)

base.cTrav = CollisionTraverser()
audio3d.setSoundVelocityAuto(sound)
audio3d.setListenerVelocityAuto()

如上面代码所示,CollisionTraverser必须附到base.cTrav上,如果已经分配了一个用于碰撞检测,那么就足够了。

声音随着距离衰减是基于现实世界的声音传播方式。默认情况下,panda1个单位等同于现实的 1 英尺 。如果使用别的比例尺的话需要用setDistanceFactor来调整比例。如果想让某个位置发出的声音不受距离的影响,可以将它的距离因子设为0

audio3d.setDistanceFactor(scale)

 

多声道(Multi-Channel

(暂无内容)

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值