FMOD Ex文档前两章翻译(转)

Posted on 2009-12-27 15:47 hyf 阅读(3293) 评论(2)  编辑 收藏 引用 所属分类: Game Design

Firelight Technologies FMOD Ex

术语 / 基本原理

导言

下文中的术语和原理将贯穿整个FMOD文档,本节对部分术语和原理进行解释,以免混淆。

Samples vs bytes vs milliseconds

在很多FMOD函数中都会提到PCMsamplesbytesmilliseconds
要理解它们有什么区别,请看下图。下图描述了原始PCM采样数据在FMOD缓冲中的存储方式:

从图中可以看出立体声音频由左/右声道的数据交替组成。

. 一对左/右声道(声道)数据称为一个sample

. 因为是16bit的数据,所以1 sample = 4 bytes

. 如果采样率是44.1khz或者或回放频率是44100 采样/秒,那么1个采样是1/44100,或者1/44毫秒。因此44100个采样就等于1秒钟的数据。

下面的公式可以用来在不同的术语间进行转换:

. ms = samples * 1000 / samplerate.

. samples = ms * samplerate / 1000.

. samplerate = samples * 1000 / ms.

. bytes = samples * bits * channels / 8.

. samples = bytes * 8 / bits / channels.

一些函数如Sound::getLength 提供了以毫秒、字节和采样为单位的长度值,这样就不必再使用上述公式计算了。

声音——采样 vs 压缩采样 vs

加载声音有三种方式:一是将静态帧解压后以PCM格式装入内存;二是以其原始格式装入内存,并在运行时解压;三是将声音流化后并从外部媒介(如硬盘或CD)实时(in chunks)解码。

. "Samples" 适合那些需要多次播放的小的声音片段,例如音效。它播放时占用很少的CPU,并且能使用硬件加速。参见FMOD_CREATESAMPLE

. "Streams" 适合那些因为太大而无法载入内存的声音,声音会被流化并装入到一小段由FMOD管理的环形缓冲中。这会占用少量CPU和硬盘带宽,具体视文件格式而定。举个例子,实时解码MP3会比播放一个PCM(未压缩WAV)文件占用更多的CPU。一个流式的声音只能播放一次,因为一个流只有一个文件句柄和一个环形缓冲。参见FMOD_CREATESTREAM.

. "Compressed samples" 是一个新的高级选项,它允许用户将一个确定格式的压缩文件装载到内存中,并且不需要对其解压。用CPU进行软件混合,没有stream的只能播放一次的限制。它比标准的PCM采样占用更多的CPU,但由于不需要访问硬盘且使用更少的缓冲,因此比streamCPU的占用更少。参见FMOD_CREATECOMPRESSEDSAMPLE.

你可能注意到术语"Sample""Stream"都没有对应的类名,那是因为所有的FMOD APIs 都统一使用"Sound"类型。
默认情况下,System::createSound 会将整个声音文件解码到内存中
要使用流进行实时播放且节约内存的话,创建声音时使用FMOD_CREATESTREAM标记,或者使用helper函数System::createStream,其本质和System::createSound相同,只是自动使用了FMOD_CREATESTREAM标记。
要创建一个压缩采样则在System::createSound中使用FMOD_CREATECOMPRESSEDSAMPLE标记。

硬件 vs 软件

FMOD Ex支持通过DirectSound或者控制台硬件API对音频回放使用硬件加速,但也可以使用自己的软件混合机制。
由于基于硬件和软件的音频回放的某些特征,所以通常硬件和软件交替使用。
Hardware sounds(
使用FMOD_HARDWARE创建,CPU占用率低,响应时间短,可以访问硬件混响),例如EAX4
Hardware sounds
在某些方式下也有其局限性,例如DirecSound就仅限于Windows,静态采样不支持任意位置的循环点(循环播放整个sound或者不循环), 不能播放非混响音效(例如chorus, distortion, lowpass etc)

Software sounds (
使用FMOD_SOFTWARE创建,虽然有时会占用更多的CPU,但它能做更多的事,如复杂循环、实时解析、音效和采样精确同步)

Hardware vs Software.

Hardware
优点

. Usually lower latency. (Although on consoles or ASIO output in windows, using FMOD_SOFTWARE can have extremely low latency as low as 2-5ms)

. Less CPU time. (Although on Windows software is a lot faster due to bad hardware sound card driver design, and inefficiencies in the DirectSound API).

. On Windows, access to EAX2, EAX3, EAX4, I3DL2 reverb per voice. (FMOD Ex has its own high quality I3DL2 reverb solution in software, but may not be as flexible or have the quality of EAX4 for example.).

. Free hardware obstruction / occlusion (this is usually equivalent to a lowpass filter or reverb attenuation which can also be performed in software at some expense to the CPU), but only on EAX compatible sound cards on Windows. FMOD_SOFTWARE is cross platform.

. On PS2, PSP, XBox, GameCube, Wii, hardware voices can play back ADPCM compressed sound data with no cpu hit.

. On a limited number of soundcards, hardware 3d sounds will be realtime encoded into an AC3 Dolby Digital stream via a digital / optical output on the card so an amplifier can play it in 3D surround sound. FMOD software mixing now supports 5.1 and 7.1 mixing at slightly higher CPU expense, and will work via analog outputs such as soundcards with 3 stereo jacks to run to a 5.1 speaker setup.

Hardware
缺点

. Win32平台上不支持点到点循环,XBoxGameCube平台支持点到点循环,而PS2上仅支持循环起点,所以不具有跨平台兼容性。

. No access to hardware effects per voice. 大多数PC声卡和控制台都不支持如lowpassdistortionflangechorus etc.等硬件加速音效。

. 没有循环计数控制。一个声音要么被无限次地循环,要么就不循环。

. 特性支持不一致。例如PS2不支持EAX混响,且3D音效的执行通常听上去不同。

. 有时比FOMDWindows上的软件混合速度慢许多。虚拟声音在换进/出时导致的大量状态变化会带来很大的硬件开销(明显的帧率下降),而软件却不会。

Software
优点

. Consistent sound on every platform, there is no variation in playback.

. Sample accurate synchronization callbacks and events.

. Compressed sample playback support without using streams.

. Cross platform reverb.

. Complex looping and loop counts.

. Reverse sample playback.

. Spectrum analysis.

. Filters per channel or for the global mix, to perform effects such as lowpass, distortion, flange, chorus etc.

. Complex DSP network construction for realtime sound synthesis.

. Access to final mix buffer to allow analyzing, drawing to screen, or saving to file.

Software
缺点

. 某些音频设备的响应时间(win32waveout输出)可能会很长。

. 内存占用量更大(分配混合单元和混合缓冲,或将声音储存在主存而非声卡缓存中)

Channels and sounds.

当你加载完你的声音后就须要播放,这时会用到System::playSound函数,它返回一个Channel / FMOD_CHANNEL句柄。
参数channelid通常设为FMOD_CHANNEL_FREE,表示FMOD将自动选择一个未使用的通道来播放。

2D vs 3D.

A 3D sound source is a channel that has a position and a velocity. When a 3D channel is playing, its volume, speaker placement and pitch will be affected automatically based on the relation to the listener.
A listener is the player, or the game camera. It has a position, velocity like a sound source, but it also has an orientation.

listener
source间的相对距离决定音量
listener
source 间的相对速度决定音调(多普勒现象)
listener
相对于source 的方位决定左右声道平衡扬声器位置

2D sound
不受3D soundlistener的影响 ,没有多普勒现象,不衰减,也不受扬声器位置影响。
创建2D sound可以调用Channel::setSpeakerMixChannel::setSpeakerLevelsChannel::setPan
创建3D sound可以调用所有函数名中含有3D的函数.

For a more detailed description of 3D sound, read the tutorial in the documentation on 3D sound.

 

 

 

 

 

 

 

 

 

 

 

()[FMOD编程指南]2.GETTING STARTED

 

GETTING STARTED.

导言

FMOD Ex API被设计得非常直观和灵活,本教程将简要介绍引擎的使用方法,并对使用中涉及的相关问题做出解释。

配置——What to include and what to link.

查阅文档中的"Platform specific issues",找出指定平台上要使用FMOD Ex函数所需链接的文件。

C/C++中,如果只须使用C接口,则包含"fmod.h",要使用C++接口则须包含"fmod.hpp"
注意:常量、回调函数、宏定义和枚举类型都在fmod.h中,所以fmod.hpp也包含fmod.h,如果你使用C++的话就必须交叉使用。

对于DelphiC#Visual Basic,都有其对应的头文件可供在程序中使用。

初始化

要初始化fmod,最简单的方法就是调用System::init函数,FMOD会使用默认参数来配置声卡和其他设置。

在查看文档中的System::init函数时,要记住maxchannels参数是你在游戏中可以同时播放声音的最大数量,该数与声卡或软件混合器无关。

这些声音是 虚拟声音(virtual voices)。这意味着你可以同时播放任意多的声音,而不用担心硬件或软件资源问题。
你可以在游戏中安全地播放每个声音,而无须担心System::playSound超出播放上限或抢占其它声音。因此只要你喜欢,你可以将maxchannels设置为任意大的数,如11002001000
注意:同时播放1000个声音并不会音像性能,因为它们中的大部分是听不见的 (听不见的声音被虚拟化)。而FMOD Ex虚拟声音管理器决定哪些声音能听见,哪些听不见只需要很小的系统开销。
下面我们看一个初始化FMOD Ex的例子。

FMOD_RESULT result;

FMOD::System *system;

result =system); // 创建主system对象

if (result != FMOD_OK)

{

printf("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));

exit(-1);

}

result = system->init(100, FMOD_INIT_NORMAL, 0); // 初始化FMOD

if (result != FMOD_OK)

{

printf("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));

exit(-1);

}

这是最基本的初始化FOMD引擎的方法,使用了100个虚拟声音。
注意:mods3mxmitmidi格式的文件播放时只使用一个声音,不要以为在这里增大数量就可以使用多个声音来播放这些格式的文件。这些格式的都使用它们自己的internal pool voices

配置选项

如果你不想使用默认设置的话,可以自行设定输出硬件、FOMD资源使用和其他配置选项。
这些操作都必须在System::init函数调用前进行。
常用配置如下:

. System::setOutput选择输出方式。例如你可以在Windows上选择DirectSoundWinMMASIOno-soundwave-writer或其他输出选项,每个平台都有不同的选择。如果你只是要使用默认配置,就不需要调用它。

. System::setDriver选择用于播放的设备驱动。当你拥有不止一块声卡并且不想使用默认声卡的时候,这个函数就很有用了。你需要用System::getNumDrivers函数来获取设备数,用System::getDriverName函数来获取驱动名称以供用户选择。

. System::setHardwareChannels使用这个函数来限制硬件声音的数量,或设定在reverting to 100% software mixed voice support之前的最小硬件声音数量。“minimum”选项用于保证同时至少能听到的声音数量。

. System::setSoftwareChannels使用这个函数来设定FMOD通道使用的软件混合声音的数量。 This will be purely for polyphony reasons or CPU / memory resource usage reasons. 使用mod/s3m/xm/it/midi这些格式时,不要指望使用它来增加声音的数量,它们不使用通道的pool而使用自己的。

. System::setSoftwareFormat用于改变FMOD软件混合器的设置。包括采样率、输出模式(integer vs float)、输出通道数(multi-output channel ASIO devices)、内存使用和混合质量。

. System::setDSPBufferSize如果在很慢的机器上或非良好的声卡驱动上出现声音抖动,就需要使用这个函数。它可以改变软件混合器的响应时间,但误用的话也可能影响性能。一些人可能想让用户在低响应时间高兼容性两种模式间做出选择,可以通过调整缓冲大小来达到牺牲响应时间换取稳定性的目的。

. System::setSpeakerMode设置扬声器输出模式。此函数只对FMOD软件混合引擎起作用,默认值为stereo (5.1 on xbox and xbox360 and 7.1 on ps3),可以按需要任意更改。注意:声道数越多,占用的内存也越多。

下面的例子使用了一些配置项来初始化FMOD要记住这些选项都是可选的,如果不需要就不用设置,在你没有弄懂其真正含义前,千万不要仅仅将下面的代码复制再粘贴! 例如,如果用户没有5.1声道的系统,你就不能仅仅将扬声器模式设定为5.1

FMOD_RESULT result;

FMOD::System *system;

result =system); //创建主system对象

ERRCHECK(result);

// 设置扬声器模式为5.1声道

result = system->setSpeakerMode(FMOD_SPEAKERMODE_5POINT1); ERRCHECK(result);

// 允许同时播放100个软件混合声音

result = system->setSoftwareChannels(100); ERRCHECK(result);

// 要求声卡至少要有322D3D硬件声音,如果声音数超过64,就限制为64

result = system->setHardwareChannels(32, 64, 32, 64); ERRCHECK(result);

// 初始化FOMD,使用100个虚拟声音

result = system->init(200, FMOD_INIT_NORMAL, 0);

ERRCHECK(result);

加载与播放

要播放声音,你必须先加载!
使用System::createSoundSystem::createStream就可以完成这项工作。
默认情况下,系统会尝试将整个声音解压到内存中(如果使用 System::createSound函数),而和sample不同的是stream(System::createStream创建)是在运行时解码,仅使用很少的内存作为缓冲,这就是为什么大文件最好用stream的原因。
更多请参见术语/基本原理

下面是一个加载MP3文件的例子,默认条件下System::createSound函数将整个MP3解压成16bitPCM格式,这就意味着将占用比文件本身大许多倍的内存。

FMOD::Sound *sound;
// FMOD_DEFAULT
等效于FMOD_LOOP_OFF | FMOD_2D | FMOD_HARDWARE.

result = system->createSound("../media/wave.mp3", FMOD_DEFAULT, 0, &sound);

ERRCHECK(result);

 

下面是一个用stream打开MP3文件的例子。System::createStream函数将打开文件并预缓冲小部分数据,然后就可以在System::playSound调用时直接播放了。

FMOD::Sound *sound;
// FMOD_DEFAULT
等效于FMOD_LOOP_OFF | FMOD_2D | FMOD_HARDWARE.

result = system->createStream("../media/wave.mp3", FMOD_DEFAULT, 0, &sound);

ERRCHECK(result);



指定用软件混合就必须使用FMOD_SOFTWARE标记。如果你想要使用如DSP effectsspectrum analysisgetwavedatapoint to point looping和其它更多的高级技术,就必须使用软件混合。

FMOD::Sound *sound;
//
使用软件混合

result = system->createSound("../media/wave.mp3", FMOD_SOFTWARE, 0, &sound);

ERRCHECK(result);



下一个例子是将MP3sample的形式载入内存而不解压,使用 FMOD_CREATECOMPRESSEDSAMPLE标记。此时如果没有指定FMOD_HARDWAREFMOD_SOFTWARE,将默认为软件混合。硬件声音回放不支持这个标记,除非格式为ADPCM on XboxVAG on PS2/PSPGCADPCM on Gamecube/Wii Platforms like PS3 and Xbox 360 are all done one the cpu (usually a different core to the main cpu so it does not affect performance).

FMOD::Sound *sound;
// FMOD_CREATECOMPRESSEDSAMPLE
标记让sample先尝试直接播放(不解压到内存),但仅限于IMA ADPCMMP2MP3XMA格式

result = system->createSound("../media/wave.mp3", FMOD_CREATECOMPRESSEDSAMPLE, 0, &sound);

ERRCHECK(result);

警告! 必须谨慎使用这种模式,它看上去和PCM sample很相似,但它会在运行时导致巨大CPU开销。FMOD按照声音的压缩格式,在播放时对其进行解码。


现在,要播放soundstream只需简单地调用System::playSound就行了。

FMOD::Channel *channel;

result = system->playSound(FMOD_CHANNEL_FREE, sound, false, &channel);

ERRCHECK(result);

此时,声音已经在后台播放了!而你的程序将继续执行。

关于playSound的注意事项:

. 如果不需要的话,可以不必获取channel句柄,可以将其设为0NULL。如果你不需要更改这个sound实例,或者这个声音很短(不循环),就可以省去它。例如:

result = system->playSound(FMOD_CHANNEL_FREE, sound, false, 0);

ERRCHECK(result);

. 可以在开始播放时暂停,这样就可以更改声音的属性而不会被用户听见,这就是“paused”参数的用处所在。例如,如果你将paused设为true,再设置音量为0.5,然后解除暂停,此时声音就会一一般的音量播放。但如果你是将paused设为false,而其它操作相同的话,你会听见声音开始时瞬间是全音量播放的,用户可不希望听到。

result = system->playSound(FMOD_CHANNEL_FREE, sound, true, &channel);

ERRCHECK(result);

// 暂停时设定音量

result = channel->setVolume(0.5f);

ERRCHECK(result);

// 声音从这里才开始播放

result = channel->setPaused(false);

ERRCHECK(result);

. 一个“channel”就是一个声音的实例。一个声音你可以同时播放多次,每次播放都会得到一个新的channel句柄,stream除外,它只能同时播放一次,如果你尝试多次播放,只会重复播放当前stream并返回同上次一样的channel句柄。这是因为stream只有一个缓冲和一个文件句柄。要同时播放两个stream就必须打开两次再播放两次。

. 始终使用FMOD_CHANNEL_FREEFMOD会使用通道管理器自动为你选择一个未使用的channel。如果希望使用一个现有的channel来播放,就使用FMOD_CHANNEL_REUSE标记,这样可以避免每次调用System::playSound函数都产生一个新的实例。

. 不需要“free”“release”一个channel句柄。所有的channel都位于你使用System::init所创建的一个pool中。当声音停止后,channel可以被复用;如果所有的channel都处于播放状态,那么其中一个优先级最低的会被抢占。其实只需增大System::init中的通道数就可以避免发生这样的情况。

. 一个channel会在播放结束时即刻失效。这意味着你不能再对其进行更改,即使做了也没有实际意义,因为它不可能再播放了。绝大多数情况下,引用一个已失效的channel会导致一个FMOD_ERR_INVALID_HANDLE错误。

Update. (This is important!)

在每一帧中调用System::update函数是很重要的,但不需要多次调用,那样只会影响效率。
该函数用于更新FMOD Ex的以下内容:

. Platform specific routines 例如向PS2IOP发送一个frame command packet。在这个平台上,不调用update的话就听不到声音。

. Virtual voice emulation 不调用update,虚拟声音就不会播放。

. 3D voice calculation 如果不调用update,就算channellistener已经正确设置,也无法听到声音移动的3D音效。

. Geometry engine FMODpolygon/geometry引擎需要通过update来启用。否则用户定义的occlusion/obstruction特性将无法呈现。

. Non realtime output FMOD_OUTPUTTYPE_NOSOUND_NRTFMOD_OUTPUTTYPE_WAVWRITER_NRT标记需要此函数才能更新到输出(如用FMOD_OUTPUTTYPE_WAVWRITER_NRT写出到文件)

. Streaming engine 如果指定了FMOD_INIT_STREAM_FROM_UPDATE标记,如果用户希望在主线程中自己驱动流引擎,就必须有规律地调用update,否则会导致抖动和缓冲溢出。

关闭

调用System::release函数来关闭输出设备并释放对象关联的内存。
你不必人工关闭channelsound,这些都在System::release中自动完成。
当然,你也可以手动关闭它们,这是个很好的编程练习(虽然是多余的)
如果你要释放system对象就不需要调用System::close函数了,在System::release中已经包含了对System::close的调用。

资源使用配制

在程序开发中,一些开发人员希望和其它程序一样用自己的函数来访问所有的磁盘或内存。
FMOD Ex中你可以通过System::setFileSystem函数来设置FMOD文件系统使你自己的文件程序。

要让FMOD使用你的内存系统,或将FMOD限制在一个内存块中,使用Memory_Initialize

注意! XboxXBox 360中,必须给FMOD提供一个块内存。Xbox 360上必须使用XPhysicalAlloc来分配这块内存。更多参见"Platform specific issues"

 

 

 

 

 

 

 

 

 

 

Feedback

# re: FMOD Ex文档前两章翻译(转)  回复  更多评论   

2009-12-28 16:36 by 陈梓瀚(vczh)
几年前就用过FMODEX了,这是个好东西,而且demo也非常好,基本上不用看文档看一眼demo的代码就知道怎么回事了。所以我觉得如果想让文章更有价值的话你可以写教程。

# re: FMOD Ex文档前两章翻译(转)[未登录]  回复  更多评论   

2010-01-02 23:35 by SonicMisora
HYF神牛威武

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理