如有游戏背景音乐外包需求,请联系。专注制作真正的游戏背景音乐。

作者:Einsphoton (任江枫)
Email:rjflx@hotmail.com
个人博客:http://blog.sina.com.cn/u/2673256031
个人微博:http://weibo.com/u/2673256031
关注以获得更多内容
版权所有,转载须注明出处以及作者
欢迎加入游戏设计群 http://q.weibo.com/1543457


前言

有关于本文内容,作者想说的太多。

还记得小的时候玩《最终幻想》系列以及《Chrono Trigger》,第一印象就是哪美妙的背景音乐以及整体音效的流畅度。这种体验至关重要,它可以直接吸引你深入游戏,引导你跟随着剧情的情感起伏。紧张激烈,舒缓柔情,飘渺悠扬。至今那些熟悉而又令人感动的旋律依然徘徊在脑中。那个年代,FC、SFC中的各种神级作品,至今未曾被人们遗忘。

然而技术发展到如今,我们国内的游戏产品,用着比以往优越几百倍的技术以及性能,缺没能做出以前国外产品十分之一的游戏体验。其中涉及到的原因多种,诸如设计理念落后、缺乏游戏文化以及内涵、游戏内容趋之若鹜、极致的商业化等、不尊重用户实际的游戏需求体验而想方设法的骗取留存率等。但我们今天只探讨其中一点,关于游戏体验中的音乐音效问题。

纵观国内各种游戏产品并与国外游戏产品比较,我们不难发现,在游戏背景音乐和音效上我们严重缺乏关注。至今仍有多数厂家的产品显得光秃宁静。余下的虽然有背景音乐但没能有条件在这里给予过多的关注,至少现在来看,多数游戏背景音乐不但没有增益反而影响体验,以至于好长一段时间玩家都是关闭声音来游戏的。这相比国外游戏公司单独设立音效部门的这一状况,我们着实气力不足。尽管没有这种条件,但我们也要做足了功课。

目前国内游戏背景音乐方面,通常大家是通过外包的形式,然而国内的各种知名音乐外包团队,尽管有着很多项目经验,但是终究缺乏做【游戏背景音乐】的理念以及技术。于是导致了国内游戏作品中的背景音乐都是4分钟多的一整段,最后来个结束乐句然后等着重新播放,或者更甚者直接30s一小段并且没有无缝衔接,这都会对玩家造成审美疲劳降低体验。游戏背景音乐还是和其他背景音乐有区别的,所以不能一整段的播放然后循环,除非像上古卷轴5那样,多个音乐根据场景算法来播放。

首先我们先来看看背景音乐的无缝循环会给我们带来什么好处:

①增强游戏体验,不会出现断续的尴尬局面,让玩家有种“有头无尾”“一段无限长的音乐”的感觉。避免断断续续造 成的审美疲劳。

②减少外包成本,现在多数音乐外包都是按时间来计算的,然后一段音乐不可能内容完全不一样持续4分多种,多数都是在循环主体乐句。这样浪费了好多资源。如果可以采用“前奏+主循环体+主循环体……”的形式,这样外包只要交付不超过2分钟的“前奏+主循环体”就可以了。而且也大大节省了资源大小。

这两条每一条都是足够分量的优化点,而并不是某些眼里可大可小的部分。所以本文将会致力于提出一种游戏背景音乐无缝循环的解决方案。

想要实现游戏背景音乐无缝循环,我们必须做好3方面的准备:音乐创作上需要Loop形式、音频格式的限制需求、技术上的准备。其中音乐创作层面上的准备,本文不做过多讲解,能看到这篇文章的人基本上都是做技术的:)如果需要音乐创作方面的讲解,请联系作者。

下面就后两方面做出详细讲解。

音频格式的需求

可能会有一些读者体验过这一情况,当我们使用播放器循环播放我们喜欢的音乐或者已经在游戏作品中尝试循环播放的时候,总会在循环衔接处听到短促有力的“pang”的一声或者一阵停顿亦或者有种循环体没有播放完就被重新循环的感觉,这会让我们从音乐的沉静中惊醒,造成不好的体验。而出现这一现象的情况多数存在于低品质音频文件或压缩过的MP3文件。这是因为音频文件在被压缩过之后会在音频波形的前后产生一小段“空白”或者整段音频波形长度被压缩的原因。通过下图我们可以观察出问题所在:

--tv lt;id=valuegt; user-defined frame specified by id and value (v2.3 tag) 自定义标签
--add-id3v2 force addition of version 2 tag
--id3v1-only add only a version 1 tag
--id3v2-only add only a version 2 tag
--id3v2-utf16 add following options in unicode text encoding 使用unicode字符集,推荐
--id3v2-latin1 add following options in latin-1 text encoding 使用latin-1字符集,慎用
--space-id3v1 pad version 1 tag with spaces instead of nulls
--pad-id3v2 same as --pad-id3v2-size 128
--pad-id3v2-size lt;valuegt; adds version 2 tag, pad with extra lt;valuegt; bytes
--genre-list print alphabetically sorted ID3 genre list and exit
--ignore-tag-errors ignore errors in values passed for tags

Note: A version 2 tag will NOT be added unless one of the input fields
wont fit in a version 1 tag (e.g. the title string is longer than 30
characters), or the --add-id3v2 or --id3v2-only options are used,
or output is redirected to stdout.


MS-Windows-specific options:
--priority lt;typegt; sets the process priority:
0,1 = Low priority (IDLE_PRIORITY_CLASS)
2 = normal priority (NORMAL_PRIORITY_CLASS, default)
3,4 = High priority (HIGH_PRIORITY_CLASS))
Note: Calling --priority without a parameter will select priority 0.

Misc:
--license print License information


MPEG-1 layer III sample frequencies (kHz): 32 48 44.1
bitrates (kbps): 32 40 48 56 64 80 96 112 128 160 192 224 256 320

MP3可用的采样频率和比特率:
32 KHz, 44.1 KHz, 48 KHz
32 kbps, 8=40, 48, 56, 64; 16=80,96,112,128; 32=160,192,224,256; 64=320


代码上的优化

正如各位游戏开发者所意识到的,游戏背景音乐是游戏的一个重要部分,它可以使得游戏主题更加深刻,来渲染出紧张、愉悦、悲伤等情感。为了应对各种需求我们需要动态配乐,这样我们就需要一种特殊灵活的方法来连接每一段音乐。

如果你曾经尝试过把MP3音乐放入游戏中并且无缝循环,那么你可能已有体验,那其实并不是你预期的那么好做。还有一些问题等待解决。所以本文将会在极大程度上解决这一困惑。

MP3无缝播放技术可以让你实现多个MP3片段之间流畅地无缝地播放。下面我们来看看有一个无缝循环的背景音乐会是什么样子的:



利用无缝播放我们可以做很多事情,例如,我们可以在教程对话框打开的时候播放一个简短的Loop音乐,当教程被关闭后立马流畅的切换到主场景音乐。或者像上古卷轴那样,当遭遇战斗的时候很自然的切换紧张激烈的音乐,当战斗结束后又很自然的回到舒缓的音乐,而其中无任何停顿、Pong~的声音。当然利用MP3无缝播放技术你还可以做出很多丰富精彩的游戏体验。

在上一个章节的准备之下,我们继续我们的代码优化。以下以IOS平台开发为例。

使用“Audio Queue Services”

一般情况下我们使用的是AVAudioPlayer类来播放MP3文件,它可以慢慢的从硬盘中缓冲式的播放MP3而不是把Mp3数据全部读取到内存中。由于其性能以及使用方便,而广泛被开发者使用,而且是硬解码。

另一种方法,就是使用“Audio Queue Services”,基于AVAudioPlayer的底层。Audio Queue Services使用起来不是很方便,但是却给你提供很大的利用空间。但即使是使用这个方法,也会存在一些问题:

★无论是AVAudioPlayer还是Audio Queue Service都会存在一定的延迟,虽然微小到300毫秒,但却足以辨析,且延迟效果明显。

★硬一次只能处理一个音频音频会话(audio queue),如果你在硬繁忙的时候开启了一个新的音频会话,那么系统会调用费电的软,或者对于老型号的机器就干脆就抛出一个“Hardware in use”的错无提示。

★当一个音频会话完成是,需要一定的时间来释放资源,在此期间硬不能开启另一个音频会话。



如果你想通过传统方式播放MP3音乐,那么你需要等待上一个音频片段释放资源才可以下一步的播放,这样在再次播放之前就会有一个很小的延迟。延迟的长度不可预测,并且这一长度在老设备上会更加长。

解决这些问题的唯一办法就是使用同一个音频会话来播放所有的MP3片段,使用Audio Queue Services,就可以做到。



由于Audio Queue的初始化配置,所有的MP3片段必须使用相同的、属性以及参数,所以在一个会话期间没有办法重新配置。

回调函数会帮你完成所有的繁琐事情,从文件中读取音频数据,然后再填入音频缓冲池里。默认情况下,如果没有数据可以读取,则回调函数停止。而我们制定的回调函数则会继续从下一个MP3文件中读取数据并填入缓冲池。

MP3无缝播放器程序

这一解决方案已经应用于Gapless MP3 Audio Player for iOS ,读者们待会可以从附件中下载完整的代码。(来源Github: Gapless-MP3-Player on GitHub)。
Gapless MP3 Player 是完全免费的,并且你也可以运用到你自己的项目中。其中包含一个特别的“SPGAudioPlayer”类可以在游戏引擎中使用。这个类可以操控内部音频系统事件,并且拥有一个简单的接口。

下面的实例将演示添加两个音频片段到队列中进行播放:



第一个片段部分不执行循环,第二个片段无限循环(其中loop参数-1=无限循环,0=不循环,大于0的整数代表循环播放次数)。

如果你想使用同一个播放器对象来播放另一组片段,可以调用“[player clearQueue]”来清空队列。

当当前loop片段播放完成时,你也可以调用“[player breakLoop]”来移除下一个片段的播放。下面将展示另一个实例:



下面的方法也同样可以控制播放:



MP3的无缝循环技术可以使你的游戏体验有着质的提升,并且可以使玩家深入游戏。现在你可以尽情发挥到你的游戏作品中了!。


下载配套文件 (ZIP,1.1MB)

参阅文献:http://gamua.com/blog/2012/05/gapless-mp3-audio-on-ios/

感谢Daniel Sperl以及GitHub的技术提供!
版权所有锐亚教育

锐亚教育,游戏开发论坛|游戏制作人|游戏策划|游戏开发|独立游戏|游戏产业|游戏研发|游戏运营| unity|unity3d|unity3d官网|unity3d 教程|金融帝国3|8k8k8k|mcafee8.5i|游戏蛮牛|蛮牛 unity|蛮牛