B 站鬼畜区有一类作品:把歌曲的每个音替换成动漫角色的台词音效,让长崎素世"唱"《春日影》。做得好的全靠 up 主手搓,一首歌要磨很多天。这个项目想回答一个问题:这件事能不能全自动,而且机器能不能找到人想不到的贴法?
先听成品。下面这首《春日影》,没有一个音是乐器,全部 659 个音都是长崎素世的台词原句:
鬼畜版(素世台词 × 659 句,连带伴奏拟合)
原曲对照
直觉做法是把旋律拆成一个个音符,每个音符找一个音高最接近的音效填进去。我们的前七个版本就是这么做的,全部失败:几千个 0.1 秒的碎片拼起来像"近似傅里叶变换",音效听不清、旋律也糊掉了。
最后的方案退回一步,反而成立了:不切碎,整句往上贴。素材库里每句台词(1–4 秒的完整句子,带基频轮廓)是一个"token";渲染变成一个有约束的搜索问题——
几条关键设计,每条都来自一次失败:
不用 AI 声码器。试过 VQ-VAE 式生成路线,音质上去了,但"听得出这是素世那句话"的感觉没了——鬼畜的灵魂是 meme 本身。所以码本只能是真实台词原句,一句都不能合成。
拟合可以作弊,播放必须完整。搜索时允许算法裁剪句子(这样才知道哪句的哪个片段最贴旋律),但播放时永远从句首放完整、零掐断,句与句自然叠加。这是 v10.1 的 "play-full" 模式:之前版本里那些 0.1 秒的碎 glitch 由此从机制上消失,剩下的短音都是"あっ"这类天然短句。
一个人把整首哼完。伴奏不另建声部:主旋律唱到长间隙,同一条流自动切去接贝斯线(贝斯升两个八度进入人声可唱音域)。听感像一个人边唱边在换气间隙哼 bass。
只允许降调,最多 4 个半音。升调会让音色变得不像本人;降一点还有"压嗓子"的节目效果。音域够不到的高音宁可空着也不硬掰。
| 曲目 | 鬼畜版 | 原曲 |
|---|---|---|
| Ave Mujica | ||
| Bloody Stream(JOJO) | ||
| Roundabout(JOJO) |
已知的短板也直说:Bloody Stream 副歌的拖长高音超出素世音域,52% 的高音区找不到合适的句子,只能空着或大幅降调——这是"不许硬掰音高"原则的直接代价。解决办法不是放宽原则,而是补码本(换一个音域更高的角色)。
同一首歌、同一搜索配置,只换素材库:原神丽莎 533 句 vs 长崎素世 2381 句。丽莎的语音更"大制作",但音域和语气跟这首歌不合:±50 音分音准 50% vs 65%,高音区覆盖 4% vs 78%,"该唱的时候在唱"42% vs 82%。结论:素材和歌的匹配度远比素材数量重要——这让我们省下了下载原神 95G 全量语音包的开销。
我们拆了 B 站 88 万播放的同类标杆《春日影,但是用素世扣出来》(纯手搓)做对照:
标杆正歌段(手搓,人工作品)
实测差距最大的一项不在算法,在混音:标杆的人声压过伴奏 +11~13 dB,我们的人声比伴奏还低 5.6 dB——18 dB 的落差,这就是"机器版旋律不够突出"的主因。另外标杆会先放 10 秒无伴奏名场面台词"交代梗的场景",唱完再收一句 punchline,本质上是个带音乐的小剧场;我们目前只做了音乐部分。这两条的修复都已在排队。
也有接近的地方:标杆 42% 的台词起音卡在 ±30ms 节拍网格上,我们的引擎在慢歌上做到 44–59%;标杆靠选句贴旋律、基本不变调,和我们"只允许小幅度降调"的原则不谋而合。
春日影:±50 音分音准 59%,"该唱在唱" 82%,659 个音效、最多 5 句同响;八首歌全部在 A100 集群 8 卡并行渲染,单首分钟级。所有逐句对照(每个音效配原句 + 原曲片段)都在仓库的 review 页里可查。
代码、引擎、全部指标:github.com/guoshaoyang-pku/kichiku-voice-mad(MIT)。