Arnaud Carré 这次做的事很硬:在 Amiga 500 上播放 Atari ST 的 YM2149 音乐,同时把 sin-dots 从 Hannibal 的 6682 个推到 7210 个。
更反常的是,音乐播放几乎不吃 68000 CPU。
这不是“Amiga 原生支持 Atari 声音芯片”。恰好相反。YM2149 和 PAULA 是两套思路:一个生成方波、噪声和包络;一个播放 8-bit PCM 采样。Carré 真正做成的,是把播放任务从 CPU 手里挪走。
难点不是播放音乐,是 CPU 已经不够用了
这事的起点有点 demo scene 老江湖的味道。
Carré 之前在 Amiga 上做过 6405 dots 的 sin-dots 效果。后来 Hannibal 在 3D Demo 3 里做到 6682 dots,还调侃他:你这个 Atari 程序员优化得不错,但按 Amiga 专家的办法,还能再多榨几百个 dots。
这句话就够了。
Carré 的回应很具体:破 sin-dots 记录,同时播放 Atari 音乐。问题也很具体:CPU 时间不够。
他在 2020 年 AmigAtari demo 里做过 YM2149 模拟。要精确复现现代 Atari 音乐里的 SID voices、Sync Buzzer、Digidrums,还要模拟 Atari 定时器,代价大约吃掉 50% 帧时间。
要冲 dots,这条路走不通。
| 问题 | 常规做法 | 这次做法 |
|---|---|---|
| Atari 音乐 | 68000 实时模拟 YM2149 | PC 端离线提取音乐状态 |
| Amiga 发声 | CPU 每帧更新寄存器 | PAULA 播放样本和调制 |
| 定时更新 | 68000 负责调度 | Copper list 写寄存器 |
| 目标 | 尽量模拟得像 | 让 CPU 留给 sin-dots |
这对复古计算机和 chiptune 爱好者的意义很直接:别只听成品音色,要看这首曲子怎么被“翻译”到另一块硬件上。
对写底层优化的人也一样。这里的动作不是换更快算法,而是重新分配任务归属:哪些该 CPU 做,哪些该芯片寄存器做,哪些应该提前算掉。
漂亮的一刀,是把调制关系反过来
第一版方案不复杂。
把方波做成很短的 PCM 样本,让 PAULA 循环播放。PC 工具离线读取 .sndh 音乐,逐帧提取 YM 的周期和音量,再转成 PAULA 寄存器数据。Amiga 端只需要按帧写入。
但纯方波不够。
Atari 音乐里很多好听的“脏劲”,来自 YM 包络被误用。比如 MadMax Buzzer:包络不只是修饰音量,它自己也变成声源,再叠一个略微失谐的方波,声音会扫动、粗粝、有攻击性。
Carré 找到 PAULA 的 attached voice 功能。它可以让一个声部调制另一个声部的音量或周期。
他先让一个 PAULA 声部播放方波,再让另一个声部播放三角包络,去做音量调制。
结果不好。
问题卡在分辨率。attached volume modulation 的数据精度太低,用它调制三角包络时,台阶感很重,声音变粗,不像参考输出。
真正的 Eureka 是角色反转:三角包络不再当低分辨率调制器,改成 8-bit PCM 样本播放;方波去做音量调制。
方波只有高低两档,不怕调制精度低。三角波则交给 8-bit PCM,细节保住了。
这就是老硬件优化最迷人的地方。缺点没有消失,只是被挪到了不敏感的位置。
“因地制宜”在这里不是成语,是寄存器级别的判断。
0 CPU 的边界,比口号更重要
最后一步交给 Copper。
Copper 是 Amiga 的协处理器,可以等待屏幕位置,也可以把立即数写进自定义芯片寄存器。Carré 预生成很多小段 Copper list。每个音乐帧对应一组 PAULA 寄存器写入,Copper 还能自链到下一段 list。
于是播放任务离开 68000。CPU 留给 sin-dots。结果是 7210 dots。
但边界必须说清。
这不是通用 YM2149 实时仿真。也不是 PAULA 天生会唱 Atari。它依赖几件事:离线预计算、特定音乐数据、PAULA attached voice,以及 Copper 对寄存器的驱动。
原文技术验证中也多次使用 WinUAE 输出。真实 Amiga 硬件上的表现当然是关键参照,但模拟器输出和实机边界不能混在一起讲。
接下来最该看的,不是“还能不能再多几个 dots”这么简单,而是三件事:
- 这种方案能覆盖多少类 YM2149 曲目,而不是只服务单一 demo;
- WinUAE 输出和真实 Amiga 硬件在音色、时序上是否一致;
- Copper list 和 PAULA 资源被占用后,会不会挤压别的视觉效果。
这也决定了它的实用层级。
对 chiptune 爱好者,它更像一种跨平台音色移植方法,适合研究,不适合直接当万能播放器。对 demo 程序员,它的启发更强:如果目标是极限画面,就该把音频、调度、数据准备尽量搬出主 CPU。
扯远一点,早期铁路提速也不只靠更强火车头。调度表、信号系统、站场组织,都会改变吞吐量。今天这台 Amiga 也是同一个道理。68000 没变快,工作流被重排了。
我更在意的正是这里。
现代软件太容易把问题扔给 CPU、内存、框架和下一代硬件。老机器不惯着你。资源越硬,工程判断越锋利。
7210 dots 是结果。更有价值的是那条路径:别急着把代码写快,先问它为什么非要由 CPU 执行。
