PS2音频简介,以及《蚊》的语音汉化
aikika
2025年01月26日 15:09

用PS2的《蚊》来尝试下语音汉化的可能性

PS2音频文件的处理

PS2平台大多数游戏的音频格式都是基于ADPCM这种编码方式。ADPCM属于有损压缩,可以快速地被机器处理。

实际应用中,ADPCM又分很多种,在游戏机上就按照厂商分为几类,索尼PS的和任天堂,XBOX都有各种的ADPCM样式。在通用领域,也有IMA-ADPCM这种常见额ADPCM音频。

PS ADPCM领域,又存在很多格式,ADPCM用于编码波形数据,而各种格式则套上不同文件头,用扩展名区分,比如PS2的VAG等,PS2的常用视频格式PSS,其音频部分也是adpcm,视频则是mpeg2。 波形数据方面,PS ADPCM有个十分显著的特征,其数据是16个字节为一块,大多数16进制编辑器默认即16个字节为一行,因此PS ADPCM数据在编辑器里面看来非常规整。

如何快速的辨别PS ADPCM呢,只需要观察hex编辑器的第二列,即0x1、0x11、0x21这样的位置,对于PS ADPCM来说,这里要么都是00,要么都是02。

一列全是02或者00,而其他部分则是不同的数据,那这个很可能就是ADPCM音频。

这里以《蚊》为例,在这游戏的根目录存在ADPCM和ADPCM2两个子目录,其中装的都是扩展名为INT的文件:

用编辑器打开,可以观察第二列都是02或者00,并且从第一行开始就是这样,说明这种数据没有文件头,是纯ADPCM波形数据。

想对音频做一个快速验证,一开始是查看到PS 的VAG格式的文档:https://problemkaputt.de/psxspx-cdrom-file-audio-single-samples-vag-sony.htm 这种格式 PS1, PSP, PS2, PS3, PS4都在用,其实就是给ADPCM纯波形数据加了个简单的文件头指定播放参数。给INT加上文件头并改格式为VAG,拿FOOBAR 2000(装了vgmstream插件)就能播放了,当然如果参数不对,播放也不正常。 事实证明,这么手动验证太麻烦,所以介绍一个20多年前的神器:MFAudio,这个带GUI的工具可以读取任何PS ADPCM并播放,当然需要手动指定播放参数,充当文件头

主要指定采样率、声道数(双声道还需要额外指定一个交错值interleave),格式选RAW Compressed ADPCM,然后点击play听能不能播放正常的声音,如果过快或者过慢,或者机器人声音,就调整参数,一直调整,直到得到正确播放的参数。

对于PS2来说,采样率一般就是16000/32000/22050/24000/44100/48000这么几种,声道就单声道或双声道。BGM一般都是44100hz,即CD音质,而语音数据可能要低点,因为要频繁读取,可能只有16000hz。 比如《蚊》的旁白语言是单声道44100hz,而剧情对话是双声道44100hz,400交错,任务中的短音频则是16000hz单声道。如果一直是纯噪音那就要考虑这东西到底是不是ADPCM了。 一些打包到一个大文件里面的ADPCM音频,则需要设置起始offset,MFAudio会直接从这里播放,就和一些未知的位图数据一样,需要手动指定调色板和像素数据的位置,才能正常查看。 对于找到了正确播放参数的音频,MFAudio可以使用这组参数导出为WAV,同样的,WAV也能按照确定的参数,使用AFaudio转换成ADPCM。在此基础上,就能实现对游戏里面的音频的修改。 当然,并不是所有游戏都会用这种无头ADPCM音频,vgmstream这个项目解析了成百上千的游戏音频格式,其中包括大量PS ADPCM类型的,而且很多都可以转换到WAV,所以分析音频之前可以先看看是否在vgmstream的支持列表里面: https://github.com/vgmstream/vgmstream/blob/master/doc/FORMATS.md

播放器FOOBAR2000可以使用vgmstream的插件,实现对这些被支持格式的直接播放,非常方便。

扩展

PS2游戏(包括很多PSP游戏也是)中,一些封装了若干条adpcm音频段的音频容器文件里面,能找到ADPCM音频段首尾标识:开头是00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00, 结尾是00 07 77 77 77 77 77 77 77 77 77 77 77 77 77 77,可以视为PS ADPCM音频片段的普遍特征标识,两段音频的交界处就是一串777777,然后一串000000,很容易辨别。 比如很多SCE发行的游戏会用到的XV格式:

一些游戏的音频打包数据,名为sound的档案文件,虽然封包方式不同,但这种原始音频的数据仍然能被看到:

对于这些音频,都可以尝试用MFAudio,手动输入参数和offset去播放试试,找到正确的参数,就能导出为wav。 而对应一些单独存放的大段连续音频,如BGM,或者大段背景音或长对话,可能就没上面说的标志数据,通过文件头,或者观察音频部分连续的第二列也能够辨别他们是不是音频。 不过以上都是说的标准的PS ADPCM,而实际游戏开发时,一些公司会用一些其他开发套件,比如CRI Middleware的开发工具,它的音频格式则是adx、aix、aax之类的,也属于adpcm,在很多PS2/PSP游戏里面都能见到,它的数据特征就和PS ADPCM不同了。 如果游戏开始会显示这个logo(相信大家都见过)

那么这游戏就是用的adx音频格式。adx的相关工具倒是挺成熟,和wav互转很简单。 ADPCM属于有损压缩,那有没有无损的音频格式在PS2游戏中使用呢,当然有,某些PS2游戏的音频是用的PCM(一种未压缩的音频编码方法),比如KONAMI的《全职猎人 龙脉的祭坛》,它根目录有个SOUND.CD文件,直接把扩展名改成RAW...拿FB 2000可以直接播放,都是一段段的BGM。

在PS1游戏里面,这种情况更常见,因为PS1 CD很多自带CD-DA(属于PCM),就是CD唱片的格式,翻录的镜像是多个BIN+CUE的方式,大部分情况下,只有一个BIN是游戏数据,其他BIN都是音轨,只要把这些BIN改成RAW,也能被FB2000播放(可能要装vgmstream插件),而且FB2000可以把这些音频也转为WAV(右键->Convert)。 例如,PS1的《苍穹红莲队 黄武出击》、《皇牌空战1》,把那些容量小一点的BIN改成RAW播放,可以听到都是各个关卡前后的任务播报语音,以及BGM。

PS2《蚊》修改配音的实现

无头ADPCM数据

上面已经提到了,《蚊》使用了无头ADPCM,这些音频的播放参数直接写在了启动文件里面。但是对于替换配音来说,无需关注程序具体怎么实现播放的,只需要按照原始播放参数,拿MFAudio把中文音频wav转成ADPCM音频数据,最后把扩展名改成INT就能被游戏识别并正常播放。 不过一个个在GUI界面选择输入输出路径,指定参数效率很差,好在MFAudio支持命令行,因此可以实现批处理,比如: MFAudio.exe /IF44100 /IC2 /OTRAWC /OF44100 /OC2 /OI400 "START_01.WAV" "START_01.adpcm"

这个命令是把一个44100hz,双声道的WAV转换成44100hz,双声道,400交错的ADPCM文件。具体参数看MFAudio的命令行说明 'MFAudio /?' 。

封装的音频片段

《蚊》的任务中的短语音,都放在VOICE文件夹,里面的文件一组一组的BD+HD文件:

这里的HD是header,文件头,BD是body,里面装了若干adpcm片段,是一个容器,查到了PS2上面的这种HD+BD格式的简介:https://w.atwiki.jp/soundfile/pages/9.html

HD文件的开始是写的IECSsreV,但是蚊的HD文件打开不是这样:

不过BD文件如之前所说,每个音频段开头都是16个00,结尾是00 07 77 77 77 77 77 77 77 77 77 77 77 77 77 77,这是明显的adpcm音频段的标志。 没有细致分析蚊的HD文件头到底是怎么记录BD里面音频段播放方法的,但是只要搞清除BD里面的音频存放方法就可以了。随便导出一段,通过MFaudio得出了BD里面的这些语音的参数都是16000hz单声道。 把一个个BD文件,按照音频片段首尾的标识逐个导出来。用MFAudio进一步转换成wav文件,可以拿来做音频转文字,为翻译做准备。 把配音好的wav音频(和原始音频一模一样的长度),转成adpcm。由于没有去解析HD文件头,搞清楚具体的编排方式,只能粗暴一点,把修改得到的adpcm音频通过裁剪或填充,把字节数也弄得和原始的一样,(因为考虑到同样一句话,中文大多数情况都比日文短,所以的确可以这么搞)。最后导入BD,进入游戏测试,播放也是OK。

弄了个GUI 工具来专门处理BD文件里面的音频片段的替换,可以批量换成配音好的音频片段,效率UP。

处理wav文件我是用的剪映,这软件的确很傻瓜化,很多操作符合直觉,拿来处理音频也很方便。不过有个问题,剪映导出的wav不能被MFAudio识别,原因是包括剪映在内一些软件生成的WAV,会在文件头写入版本INFO数据:

而MFAudio似乎会从固定地址读取音频头(标识为data),找不到就报错,能读取的wav形式如下,0x24开始即为音频数据开头(data):

把剪映生成的wav的0x24到data之间的内容全删了,就能被MFAudio识别,保证从0x24开始是data就好。可以写个简单的程序专门做这事,直接批量改。

用AI进行声音处理和配音

声音分离和转文字

由于《蚊》中很多长对话音频有背景音,比如蝉鸣,狗叫之类的,需要先分离出声音,虽然剪映也有这种功能,但是要会员,其实免费的开源项目完全可以搞定,这种技术叫做UVR..抱脸上面直接有大佬部署好的,在线用 https://huggingface.co/spaces/TheStinger/UVR5_UI 分离模型也分很多,有的负责处理人声分离,有些可以分离音乐中的元素,比如鼓点什么的,搞不清楚就用第一种,效果也很好。 对于音频片段的语音转文字,用OpenAI开源的Whisper就行了,抱脸上面依然有现成的应用,https://huggingface.co/spaces/hf-audio/whisper-large-v3-turbo 你也可以接他们的API。

不过识别的文字必须要全部校对一遍,一条条音频听一下,在对比下识别结果,虽然总体效果很好,但还是会存在问题,比如把角色在打拳时喊的“上段”,识别成“冗談!”,“正拳”识别成“圣剑”,虽然这两组词发音确实一样,但对应的汉字完全不同,意思也不同,所以结合使用场景来做校对是必须的。

AI生成语音 对于用计算机合成一段说话的声音,技术很早就有了,早期是用录制好的单字语音,进行拼接合成的技术相信大家都听过,路边大喇叭常有这种。 不过随着基于神经网络的TTS(文字to声音)的兴起,以及不断发展,各种TTS项目的效果越来越好,完全可以拿来试试投入生产环境,做做AI配音。 对于《蚊》的AI中文配音,我主要用了两个开源项目:GPT-SOVITSCosyVoice2和CV2,GSV实现大部分剧情对话和旁白的语音生成,而CV2则实现了一些强烈语气的表现,比如大喊招式,呵斥,愤怒等强烈情感的表现。 其实我首先想到的是直接复刻原始角色的声线,方法是用常用的TTS,比微软的azure tts(就是营销号用烂了的哪些AI声音)生成声音,再用RVC训练一个游戏里面角色的变声处理模型,把AZURE TTS的声音变成游戏里面角色音色,但是效果不行。 于是把思路还是转向了直接TTS生成语音,找一些觉得比较合适的语音素材做训练,用作游戏里面角色的中文配音声线。直接训练日文原版声优的声音也可以,也可以说中文,但是有一股日本人说中文的所谓“大佐味” 之所以选择GSV,是因为之前就对这个有过了解,并且实际用过,最重要的是,它可以在开发者提供的预训练权重之上进行微调,得到一个专属音色的权重(模型),音色的还原度很高。

GSV的训练很快,我全程是在Google的 colab上面使用TESLA T4这个比较老的GPU进行训练(优点是显存比较大16GB,而且,免费),把batch_size拉到可以吃满显存的地步,十分钟的音频数据,训练10个epoch,大概不到20分钟吧。而某个角色音频素材只有3分钟,学习率拉高点,于是训练了15个epoch,也就10分钟不到。

在推理时,可以提供原始素材作为语气参考,这样就能比较容易控制一些语气表现。但是GSV的缺点也有,一个是电音,即某些生成的音频带有电音,一个是强烈语气的表现并不算太高,但是一般语气的表现非常棒。 在使用时,我是直接部署到抱脸上面,作为一个在线应用,缺点当然是用CPU推理慢了点。

对于强烈语气,我使用的是CosyVoice2,这个项目缺点是,没有放出训练方法,因此,也就不能在预训练权重上面进行微调,让它在我们指定的音色基础上表现的更好。只能用官方宣传的0样本三秒克隆音色,不过这个功能效果一般。 CV2的优势是可以文字去描述生成的语音,比如“愤怒”、“大喊”,然后上传一段语音作为音色参考,即可开始生成,对于情绪的控制想对来说容易一些。 因为CV这个项目是基于扩展模型的,就是AI绘画常用的那种技术,生成语音的过程即反向扩散过程(去噪),这过程的随机性非常非常非常大,一点生成按钮有上亿种可能性吧,因此想得到一段比较合心意的语音需要反复尝试生成,就和抽卡一样,一段不到一秒是发招叫喊抽个几十次很正常。 最后得到的语音都是WAV格式,转换成ADPCM导入游戏就能播放了。 当然,以上的语音生成时的缺点都是技术还不成熟的体现,相信一两年之内会有更好更易用的解决办法,那时候搞语音汉化会更容易。 END