首页 时政热点 科技头条 智能AI 安全攻防 数码硬件 开发者生态 归档 标签 关于

Obscure 音频编解码器非常适合 N64

2026-11-06 1 阅读 约6分钟阅读 frostbyte7
分享:
字号:
Dominic Szablewski,@phoboslab — 2026 年 11 月 3 日星期二 为什么这个晦涩的音频编解码器非常适合 N64 抱歉,标题诱饵。我保证这篇文章将提供:44100 Hz 立体声,接近 Opus 比特率,使用 N64 大约 4% 的 CPU 时间。但首先,回顾一下历史:在 N64 上播放和存储音频数据的选项非常糟糕。 PlayStation 可以直接从 CD 传输未压缩的红皮书音频。在 N64 上,盒式磁带空间非常宝贵,而 93 MHz CPU 的时间也很有限。更糟糕的是,矢量协处理器 RSP 的访问权限被任天堂保护了很长时间。任天堂自己的平台库 Libultra 在内部使用 RSP 来执行各种图形和声音相关的任务,但任天堂不允许第三方开发者直接为其编写代码。 Libultra 提供了一些使用 ADPCM 方案(自适应差分脉冲编码调制)透明播放压缩音频的功能。 RSP 在音频发送到输出缓冲区之前即时处理解压缩。这工作得很好,并将样本所需的空间减少了 4 倍。不过,44100 Hz 的 5 分钟立体声音轨将达到约 12MB,这对于 N64 盒式磁带来说太大了,即使您将采样率降低一半也是如此。整个 Mario 64 ROM 总共只有 8MB。最大的 N64 游戏有 64MB。因此,N64 游戏产生的音乐类似于跟踪器:安排了简短的样本,并在正确的时间以一些有限的效果进行播放。由于盒带上的空间限制,完全“录制”音频几乎是不可能的。在 N64 的后期,任天堂允许一些幸运的开发者直接访问 RSP。最著名的是,Conker's Bad Fur Day 使用它来解压缩游戏中无数语音样本的 MP3 音频。解码 MP3 的成本相当高,而且游戏的帧速率也会受到影响。对于过场动画来说已经足够了,但对于游戏过程中的连续背景音乐或声音效果来说就太过分了。开源 Libdragon 中的音频 与任天堂的 Libultra 类似,开源替代方案 Libdragon 具有在 RSP 上运行的实时 ADPCM 解码器。因此,现在 ROM 空间越来越便宜,我只是用 ADPCM 压缩了 Xibalba 64 的所有音乐。 32MB ROM 中大约有 31MB 用于声音和音乐。请记住,Mario 64 仅使用 8MB ROM,而 Xibalba 64 是一款简单得多的游戏,只有 15 分钟的音乐。它确实有效,但是以这种方式存储音乐是一种无端的空间浪费。现在,Libdragon 还拥有实时、RSP 加速的 Opus 解码器。这本身就是一个奇迹。 Opus 格式在 N64 发布 16 年后发布,但 Giovanni Bajo 设法使其在这种“过时”的硬件上运行。压缩和音频质量非常出色,但同样,它太慢,无法在游戏过程中使用。那还有什么选择呢?我们可以构建一个 RSP 加速的 MP3 解码器,但相对于 Opus 的性能增益会很小,而且质量和压缩会更差。 QOA 比 ADPCM 略有改进,但它不太适合矢量协处理器:每个样本都依赖于先前解码的样本。很难矢量化。一个简单的转换编解码器,比如 MP3,但没有所有联盟设计的包袱,可能会起作用……超低复杂性编解码器在一些深夜“研究”期间,我偶然发现了一个旧的 Game Boy Advance 演示,它仅以 70kbps 的速度播放录制的音乐。这比典型的 MP3 要小,但质量相当。我再说一遍:在 GBA 上。配备 16 MHz ARM CPU。没有矢量指令,并且根据 GitHub 页面,还有一些剩余空间。 Aikku93 的 ulcplayer-gba,在 Game Boy Advance 模拟器中录制 时域编解码器(例如 ADPCM)需要明显更高的比特率才能达到此质量。子带编解码器(例如 MP2)在可比比特率下的质量要差得多,而更“现代”的变换编解码器(例如 MP3)通常至少需要 80-100 MHz CPU。对于这个 GBA 演示,现有的编解码器都无法满足要求。所以Aikku93不仅用ARM汇编编写了解码器,而且还创建了一个全新的编解码器:超低复杂度编解码器(ULC)。 ULC 是一种变换编解码器,有点类似于 MP3。 ULC 将 PCM 数据片段变换到频域。与 MP3 一样,它使用改进的离散余弦变换 (MDCT) 来实现此目的。但与 MP3 不同的是,它不会将信号分成多个频段(ULC 的 MDCT 是“全频段”)。 MP3 使用经典的熵编码(特别是霍夫曼),而 ULC 则……不使用。相反,变换后的系数使用非常简单的基于半字节的语法来存储。简而言之:ULC 就是 MP3 的样子。相同的核心思想,但没有任何多余的东西。 “超低复杂度”并非来自不同的算法,而是通过精心应用和封装而实现的。基于半字节的封装可能是 ULC 最优雅的想法。每个系数仅存储在 4 位中,解释为有符号整数。保留一些值来指示零填充、噪声填充或准填充
这篇文章对您有帮助吗?

订阅66必读

每日精选科技资讯,直达你的邮箱