今天我们要讲的是之前一个研究项目当中的偶然发现。可惜最终未能得偿所愿,过程听起来也有些曲折。别着急,听我慢慢说。总的来说,在进行历史研究的时候,这种意外发现并不少见。《Conker's Bad Fur Day》研究项目就是个典型的例子(如果没接触过这款游戏,不妨点击此处了解详情)。这要从我当时写的一篇关于 Nintendo 64 声音系统的推文说起。带着最初的疑问,我开始着手研究。后来牵出了很多问题,最后险些以灾难收场。当然,说“灾难”有点夸张了。不过,在看完本文之后,各位可能也会心有戚戚。
意外发现
N64 的声音系统操作起来非常复杂。硬件本身不带专用声卡、芯片或处理器。为此,开发者只能各显神通从头开始构建整套东西,以便使用 RCP 和 RSP 处理器播放音乐、音效和配音。为了维持 N64 系统在声音、图形、AI、数据存储等方面的脆弱平衡,当时大家想出了各种各样的技术解决方案。就声音而言,这种脆弱的平衡反过来也塑造了 N64 的发展历史。然而,这段历史并没有多少人了解。所以,要想弄清其中的来龙去脉绝非易事。在研究过程中,我发现 Rare Limited 很可能是第一个在像《Conker》和《Perfect Dark》这样的游戏中使用 MP3 有损音频压缩格式的游戏开发商。于是,我就忍不住想“他们是怎么做的?”。要知道,当时 MP3 还是一种很新的格式,90 年代末的时候远没有像之后那样流行。在对游戏的文件格式进行整合时肯定会有所取舍,这可能会让人更加难以理清游戏音频的发展脉络。在搜集材料的时候,我发觉当中只有对白使用了 MP3 格式。说来倒也合情合理,换做音乐的话,这种程度的压缩率估计没法听。
我在浏览一个技术爱好者论坛的时候偶然间发现了一篇旧帖,有人居然提取了《Conker》中的所有 MP3 文件。这些音频片段涵盖了游戏中所有的角色语音。提取出来的其他文件听起来都跟游戏中一样,唯独 Conker 有所不同。这位主角的语音好像被加快了,而且当中包含很多杂音。帖子中上传了不少文件,不妨从里面随便挑几个,看看是否每个都是如此。我们不知道作者到底用什么工具提取的文件,很难说这些奇怪的杂音就是提取不当造成的。这样假设未免太过牵强。别的文件怎么好好的呢,对吧?我看了一些混有 Conker 和其他角色语音的文件,偏偏只有 Conker 的语音存在前面说的加速问题。凭我有限的技术水平,实在想不出其中缘由。于是,我就请我的朋友 @Percight 前来帮忙。结果他也不清楚怎么回事,最后只好通过测试来查证。
在 @Percight 做完测试之后,我们还是没搞明白具体什么原因。不过,好在慢慢摸索出了其中的一些门道。我们之所以无法弄清究竟为什么存在这一奇怪的音频现象,关键在于不知道当时使用了哪些反编译、提取和解压工具[存档人员注:知道使用了哪些工具很重要,对非官方工具来说更是如此。我们可以猜测使用了哪些工具提取文件,但没有办法确定具体使用的是哪个版本,这样的话就不好排除与版本有关的问题]。我们发现,在使用不同的 MP3 读取工具时,Conker 的语音听起来会有区别。为此,我将 MP3 文件转码为了 WAV 格式,以在 Acousmographe 工具中运行频谱分析。在使用 Windows 的默认播放器时,MP3 充满了杂音和静电干扰,根本听不清 Conker 在说什么。WAV 版本听起来还行,只不过速度加快了。这个时候,我们想到了论坛原帖中提到的大胆设想。会不会是为了节省存储空间而有意将 Conker 的语音加快了?这个角色是游戏当中话最多的,其对白会占用大量的数据空间。所以,这么做有没有可能是想避免占用 N64 卡带空间呢(当时最大只有 64 MB)?
那么问题来了:如果是为了节省空间,为什么不把所有角色的语音都加快呢?要知道,不管对于哪种假设,各种可能都要想到。
听听下面的片段,注意 Conker 的声音效果。CW: Language。
历史线索
经过技术分析,我们做出了大胆的猜测。难道真的是为了节省空间才把游戏中的语音加快了?然而我们并没有办法证实自己的这一猜测,于是便试着查了查之前有没有类似的先例。现在研究电子游戏历史有一点好处,就是目前很多游戏开发人员还健在。我们可以面对面跟创作者进行交流,从专业的角度了解当时的一些情况。对各位来说可能听起来很简单,尤其游戏行业有那么多研讨会。但有些问题最好还是趁早查实,因为时间长了很容易记不清楚。随后,我们试着通过 Twitter 与《Conker》的作曲家罗宾•宾兰 (Robin Beanland) 进行联系,没想到很快就得到了答复。他表示,如果只有对白使用了 MP3 格式,降到像 24 ~ 40 kb/s 这么低的比特率,何况乐曲还采用了品质更高的格式,最终会很难确保角色语音清晰可辨。所以,他并不赞同我们关于节省空间的猜测,而且他也没听说过有这样的事情。据我们所知,《Conker》是 Rare Limited 运用 MP3 格式的第一款游戏。不过,在发布之前,代码交给了《Perfect Dark》的开发团队,所以他们也可以使用。能得知这些内情实属难得,至少让我们有了一些眉目。
除此之外,我们还了解到了更多与声音有关的细节。比如,当时没法在游戏过程中将 MP3 与 ADPCM 一起解压和运行。这就导致在游戏中专注播放音乐(如《Great Mighty Poo》乐曲)时格式总是在变(Great Mighty Poo 角色由 Chris Marlow 配音)。这段过场动画使用的是 MP3 格式,而游戏过程中使用的却是 ADPCM。所以,我们需要知道乐曲什么时候开始播放。说回奇怪的语音加快问题,除了确认并非出于节省内存空间的目的,宾兰对此也没有更多的见解。有了这一新的认识,@Percight 决定更进一步。为此,@Percight 用 Foobar2000 做了转码,并用 Checkmate MP3 Checker 进行分析。不过,老是报告 unidentified bytes 和 invalid header values 错误。由此可见,这是某种自定义 MP3。而且,Conker 说话时所用的标头也很奇怪。事情本来就要到此为止了。几周后我在 Interactive Audio Montreal (IAM) 月会上谈到了这个研究项目,然后跟 Plogue 的创立者大卫•维恩斯 (David Viens) 交流了一下。没想到峰回路转,又有了新的收获。
在遇到想不明白的问题时,最好向有关人员虚心求教。我之所以在 IAM 大会上谈这个项目,是为了强调如果试图脱离游戏这一大背景、没有音频团队的中肯解答,在对音频的了解上就可能会犯很大的错误。在演讲结束之后,有几位音频专业人士跟我反馈了业内的一些现实状况。事实上,几年前确实有为了节省内存空间而将对白加快的做法。而且,在作品移交之后,作曲家并不知道接下来会发生什么,以及整体上会达到怎样的声音效果。整合人员的各种技术处理他们都不知情,自然很难解释清楚整件事情的前因后果。这些反馈是偶然间得到的,也给我留下了更多的疑问。碰巧,没多久法国技术杂志《Canard PC Hardware》便邀请我写一篇关于 N64 声音系统的文章。我心想,太好了,正好可以把这件事拿出来说说。
技术细节
对于执着于技术细节的人,不妨看看下面 @Percight 对从 Great Mighty Poo 对白中提取的一个 MP3 文件 (MyButt.mp3) 的分析。在 Great Mighty Poo 和 Conker 之间的这段对话中,语音加快问题更为明显一些。在这当中,与 Conker 语音对应的一些帧使用了特定的标头。正常语音所用的标头为 0xFF 0xF3 0x50 0xC0,Conker 语音所用的标头为 0xFF 0xF3 0x50 0xC8(两者的最后一个字节不同)。这表示在理应分配给 Copyright 信息的位上将 0000 改为了 1000。就目前来看,这个位不太可能是为此目的而存在的。由下图可见,1 表示在该帧的结尾和下一标头的开头之间添加了数据。不过,这段信息未必带有版权内容。
奇怪的是,除了配音演员可能用了不同的话筒,从声谱图上也没看出有什么特别的。
另外他还惊讶地发现,并不是每个与 Conker 语音关联的帧都使用了这一标头。其他文件里有所不同,所以需要进一步验证。为此,@Percight 尝试删除了源自少数标头的帧以使文件更加稳定,但声音效果实在太差了,听起来就跟音频播放器选择忽略默认帧而非加速读取一样。我们慢慢发现,在把声音的一部分剪掉并将 Conker 的对白改成乱语时,有些数据被抹掉了。于是,@Percight 又试着将所有标头由 0xC8 改为了 0xC0,使文件看起来像个固定比特率的正常 MP3。可惜,最终也没得到设想的结果。不过嘛,试试还是值得的。
最后还有一点有待查明:不知为何,与 Great Mighty Poo 对应的帧使文件更大了。Conker 文件比使用不同标头的文件长了 9 个字节。为此,他尝试消除了其各自的 9 字节分组,结果文件居然可以正常读取了。到此,关于节省空间的猜测算是被推翻了。
拨云见日
经过一番努力,@Percight 总算找到了 Conker 语音加快的原因,接下来只需要弄清这些附加字节的用途。从其独有的模式 (0x4C 0x3A 0x01 0xXX 0x80 0x80/0x81 0xXX 0xXX 0x00) 来看,这些标头显然不是无缘无故出现的。基于音频解码器无法正常读取这一情况,我们开始琢磨这会不会与声音本身无关。这个问题只能由参与过该项目的人来回答,因为背后的原因可能远没表面上那么简单。随着这篇研究文章的截稿日期越来越近,我们设法与当时的音频软件工程师麦克•卡灵顿 (Mike Currington) 取得了联系。他非常爽快地回答了我们的所有问题,并且道出了揭开这一谜题缺失的一环。
他表示,主角 Conker 除了是一只满口脏话的松鼠,还有我们所没有注意到的特点。事实确实如此。游戏中所有其他角色在对话过程中的口型都是随机的,但我们这位主角在动画制作当中却进行了特殊的处理。他有很多不同的面部和嘴部表情。这就需要创建各种各样的面部混合形状,而设计师必须在对话当中同步予以实现。为了方便在过场动画中对口型,麦克•卡灵顿才在 MP3 文件中插入了前面所说的附加字节。经过数月的研究,我们终于揭开了困扰自己的谜题!我的研究文章总算可以收尾了。
这项研究最初是通过另一推文以法语形式发表的。多亏 Rare 团队,我们了解到了更多的信息。Conker 卡通语音的音高被调制了两个半音,但整套处理和渲染都是在整合之前完成的。在这个过程中,罗宾•宾兰确保了语音时长保持不变。所以,绝对不存在为了节省存储空间而将语音加快的情况。
克里斯•西弗 (Chris Seavor) 最近在他的 Twitter 帐户上分享了关卡设计草图。各位不妨借此看看游戏在开发当中是如何演变的(图片来源:https://twitter.com/conkerhimself/status/1359160911769010183)(经克里斯•西弗友好授权使用)
最后总结
在此,我要感谢有关人员的默默努力、无私分享和热心帮助。正是因为他们,我们才得以揭开 Conker 语音加快背后的谜题。在这当中,假如没有 @Percight 的分析和原创游戏音频团队的解答,我可能会错误地以为 Conker 语音加快是为了节省存储空间。这听起来好像不是什么大问题,但却可能给人造成严重的误导。首先来说,读者得到的信息将是错误的。其次,我们也有必要澄清背后的事实。好在我们没有放弃,找到对的人寻根究底,让大家知道了 90 年代的游戏是如何运作的。
最终,我们明白了一个道理:显而易见的答案并不总是正确的,有些信息可能会在倏忽之间丢失。而且,声音文件有时还会包含声音以外的数据。那么,我们不禁要问:作为一名存档人员,应当如何统筹兼顾地处理这些数据呢?不可否认,它们将会改变我们的音频存档方式。在从声音文件中提取数据时,就算如实还原了游戏里的声音,还是有可能会丢掉一部分信息。MP3 文件并不能说明一切,脱离背景注定会顾此失彼。
遗憾的是,程序员和音频整合人员到现在也没有记录和分享相关技巧和流程的习惯。当然,对此秘而不宣确实有一定的现实原因,比如个人职业道德、公司保密要求等。通常,一旦游戏发布,大家马上便会转向新的游戏、硬件和技术。随后,工具慢慢被淘汰,技巧不久便过时。要是没有妥善存档,很快就会被人遗忘。正如前文所说,从游戏中提取的数据并不足以说明所有问题。逆向工程存在一定局限,只能填补部分信息空白。到最后只能管中窥豹,难以了解事情的全貌。而且,有些游戏并没有多少人在意,时间一长很可能会无证可考。想想本文所说研究项目中的偶然发现,该有多少类似情形是我们没注意到的。
总的来说,收获还是很大的。虽然“节省空间”之说在这是错的,但之前的确有人采取过类似的做法。在研究当中,我们发现有些游戏确实存在为了优化存储而将音频加快的情形。据说,直到 PlayStation3 问世,这种做法才被摈弃。不过,对此我们并没有确凿的证据和例子。拿《Rainbow Six 3》来说,曾有玩家问过语音加快的问题,答案是很多 Ubisoft 游戏都这么做过。还有一些早期的 N64 游戏(如《Super Mario》和《Mario Kart 64》)可能也采取过这种做法。然而,除非有关人员出面证实,否则无法断定是否如此。也许读者当中就有人亲身参与过相关项目。有兴趣的话可以跟我联系,说说自己都有怎样的经历,告诉大家曾经发生过什么,以免有些事情就此被遗忘。
评论