用 Rust 演奏吉他指板标记法

主要观点:介绍了一个用 Rust 编写的吉他指板乐谱播放器 Ruxguitar,包括其解析乐谱、构建 UI、合成 MIDI 事件、音频循环等方面的实现,还提到了未来的工作方向和项目总结。

关键信息:

  • 使用 ASCII 字符表示吉他弦和品位的吉他指板乐谱(tablature),以替代乐谱,如“Smoke on the Water”的示例。
  • Ruxguitar 项目仍处于早期阶段,可在 GitHub 上找到源代码和预构建二进制文件,其命名为“Ruxguitar”,是“Rust”和“Guitar”的组合。
  • 解析乐谱时使用 nom 库处理不同版本的.gp4 文件格式,重点关注.gp5 版本,还写了单元测试确保解析器工作正常。
  • 选择 Iced 库构建 UI,它是一个基于事件的库,用于处理播放同步和绘制乐谱,遇到过版本 0.12.0 的 bug 并升级到 0.13.0 的 main 分支。
  • 绘制乐谱时要精心处理每个字符串、节拍、音符和效果,使用 iced-aw crate 的 wrap 小部件组装成响应式网格布局。
  • 使用 MIDI 合成器将乐谱转换为声音,选择 rustysynth 库,需要 soundfont 文件,可在编译时包含或通过命令行参数提供。
  • 音频输出流由 cpal 库管理,通过计算时间增量和使用二进制搜索找到下一个要播放的 MIDI 事件,实现音频循环。
  • 实现音频播放器与 UI 的完美集成,使用 iced::Subscription 机制,通过键盘、按钮等触发消息更新 UI。
  • 未来工作包括支持更多文件格式、显示更多乐谱信息、支持重复节拍和调整播放速度等。

重要细节:

  • 介绍了不同的 MIDI 事件(NoteOn、NoteOff 等)及其包含的信息,如音符编号、速度等。
  • 展示了音频循环的代码示例,包括设置音频设备、构建音频流、处理 MIDI 事件和合成音频等步骤。
  • 说明了如何通过 tokio::sync::watch 通道实现音频线程与 UI 的通信,更新当前时间戳和播放位置。
  • 提到在项目开发过程中遇到的困难,如处理复杂的文件格式、遇到 cryptic 错误等,以及对 TuxGuitar 的感谢。
阅读 36
0 条评论