从真实 MIDI 为 Game Boy “Wario Synth” 发布

发布: (2026年3月14日 GMT+8 21:32)
5 分钟阅读
原文: Dev.to

Source: Dev.to

Cover image for Shipping a Game Boy “Wario Synth” from real MIDI

Wario Synth Logo

Wario 合成引擎 8‑Bit Midi

把任何歌曲变成 Game Boy 版。

在线演示

www.wario.style

关于

WAH! 🎮

随便输入一首歌。我们会在网上找到对应的 MIDI 文件,然后通过在浏览器中运行的自制 Game Boy 声音芯片把它彻底“炸”掉。

  • 准确吗?有时是。
  • 合法吗?大概吧。
  • 酷炫吗?绝对酷

四条辉煌的 chiptune 频道:

  • 🟨 Pulse 1 — 尖叫的主旋律
  • 🟨 Pulse 2 — Pulse 1 忘记的部分
  • 🟩 Wave — 有种不同感觉的厚重低音
  • Noise — 打击乐(嘶嘶 pshh)

零采样。零服务器音频。只有原始振荡器在尽情嗨。

Wario sprite

功能

  • MIDI 搜索,来自 BitMidi 及其他来源
  • 浏览器播放,带音色钢琴预览
  • Wario 合成引擎:基于解析后的 MIDI 结构进行程序化 Game Boy 风格合成
  • 分享链接,带动态社交预览

我们已交付的 MVP

  • MIDI 搜索 + 排名(跨来源后端抓取/代理,带 SSRF 防护)
  • 确定性的 MIDI 解析 + 元数据(稳定、可调试)
  • 可靠的播放,使用 Web Audio + iOS “点击启用音频”交互
  • Motif / 变体模式(角色映射:旋律/低音/和弦/纹理 → 合成层)

让我们卡住的功能:“下载 MP3”

我们添加了一个导出按钮,执行以下步骤:

  1. 离线渲染 (OfflineAudioContext)
  2. 在 JS 中编码 MP3 (lamejs)
  3. 触发 Blob 下载

当时体验很好:

  • “渲染音频中…”
  • “编码 MP3 中…”
  • “MP3 已下载!”

随后浏览器开始阻止它。

真正的问题

现代浏览器经常 在长时间的异步工作(渲染/编码)后默默阻止下载,因为“用户手势”已经失效。没有错误提示,也没有文件,只有… 什么也没有。

我们尝试了常见的变通方案(导致复杂度爆炸):

  • 打包编码器(避免 CDN 全局变量)
  • 两次点击的 “准备 → 下载” 流程
  • 在支持的情况下使用文件保存选择器 (showSaveFilePicker)
  • 点击时预打开一个标签页/窗口,然后再导航到 Blob

最终,导出交互成为整个应用最不可靠的部分,于是我们 移除了下载 MP3 按钮,而不是交付一个不稳定的功能。

我们的收获

  • 可靠性胜过巧妙:不可靠的按钮会破坏用户信任。
  • 浏览器策略是产品约束:自动播放解锁 + 下载手势规则决定了你的用户体验。
  • 确定性让迭代更有趣:稳定的解析/元数据让调试保持理性。

下一步提升方向

  • 构建自己的 MIDI 库:爬取/缓存 “已知良好” 的 MIDI,统一元数据,去重,并按 “在我们的合成器中听起来好” 排序。
  • 更好的音乐智能(仍保持轻量):改进角色映射、基本调式/音阶启发式、更加智能的鼓/噪声处理。
  • 正式恢复导出功能:要么 服务器端渲染/导出,要么采用一种真正跨浏览器可靠的 “保存…” 流程。

把随机的 MIDI 变成酥脆的 Game Boy 表演简直是疯一样的有趣——它也是音频、MIDI 奇思妙想以及快速交付的绝佳练习场。

0 浏览
Back to Blog

相关文章

阅读更多 »