主要观点:介绍了一个用 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 的感谢。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。