HarpScore:我做了一个开源的布鲁斯口琴乐谱软件
古董级程序员,前百度/微博工程师,现在关注 AI 工程化与开发者工具。
微信公众号「字与码」,记录技术思考与行业观察。
本文同步发布于 zicode.com
最近整理抽屉时翻出两把十孔布鲁斯口琴,又恰好想做一个「小而美」的开源项目。于是就有了 HarpScore——一个跨平台的布鲁斯口琴乐谱软件,能同时显示简谱和十孔口琴演奏标记。这篇文章把从规划到上线的全过程记录下来,包括我当时的完整 Prompt、技术方案取舍,以及几张正式的运行截图。
2026-08-31 更新:上线后我对全部内置曲谱做了一次音高校验:发现原
octaveShift机制只在孔位计算时生效,简谱八度点渲染仍以未移位的八度为准,导致 5 首曲谱的高低音点全部低了一个八度;同时校正了《欢乐颂》第 3 段、《友谊地久天长》全曲、《爱尔兰画眉》的简谱错误。随后又补充了 6 首可完整演奏的入门曲目(两只老虎、玛丽有只小羊羔、祝你生日快乐、西班牙划船歌、平安夜、奇异恩典),内置曲库达到 14 首,并在分析面板增加来源与核对日期标注。所有曲谱已重新生成、截图已替换,GitHub 仓库已同步更新。

一、一切从这条 Prompt 开始
下面就是我对 WorkBuddy 说的原始指令,一字未改:
新建一个跨平台的布鲁斯口琴乐谱软件,开源,MIT协议,选一个合适的项目名称(需要我确认),放到github的ax2组织下,代码在本地ax2用户的work目录下,主要功能包括布鲁斯口琴的琴谱展示、管理、导出,琴谱的展示需要美观、专业、包含简谱和口琴吹奏的专业标记。需要内置若干的曲谱,为此需要在workbuddy创建skill,在网上搜索指定的乐曲的简谱,判断是否满足布鲁斯口琴的演奏,如果不合适就不要导入,合适的话转换成专业的布鲁斯口琴的曲谱导入到软件中作为内置曲谱。
这条 Prompt 很典型:目标明确、约束清楚,对失败条件也有交代。接下来就变成了一场从命名到架构再到自动化技能的完整开发。
二、命名与技术方案
HarpScore 是四个候选名里挑中的。备选有 HarpScore、HarpTab、BendNote、BlueHarp,最终 HarpScore 胜出:Harp + Score,既点出十孔口琴(Harmonica 昵称 harp),又强调乐谱属性,GitHub 和 npm 上重名率也低。
跨平台方案选了 Vite + React + TypeScript 的 Web 应用。理由很简单:浏览器即开即用,PWA 可安装到桌面和手机,未来再用 Tauri 打包成原生安装包也不冲突。Electron 太重,Tauri 现阶段还不想引入 Rust 构建链,Web 是最快能跑起来的路径。
三、曲谱数据模型与十孔口琴音阶引擎
曲谱核心数据结构设计成这样:
- 音符:简谱度数 degree、八度 octave、时值 beats、附点 dotted、升降 accidental
- 口琴标记:孔位 hole、吹/吸 direction、压音级别 bend、颤音/超吹技巧
- 小节 line / measure、反复记号、调号、拍号、歌词
十孔口琴用 C 调 Richter 音阶表,覆盖自然音和压音 / 超吹。引擎负责两件事:把调内简谱度数换算成 MIDI 音高,再把 MIDI 音高映射到具体孔位与吹吸方向,同时标记是否需要压音或超吹。任何超出口琴能力范围的音都会被识别为 error,并在分析面板里标红。
四、专业乐谱渲染:上行简谱,下行孔位
渲染层全部用 SVG 手写,没有依赖现成乐谱库。原因有两个:口琴标记是自定义符号体系,现有库不会原生支持;SVG 导出和打印都方便。
一页谱面包含:标题 / 副标题 / 词曲作者、调号与拍号、小节线、反复记号;上行是简谱数字、八度点、节奏下划线、附点、延音线、歌词;下行是口琴孔位——↑ 吹气(暖红)、↓ 吸气(深蓝),压音用单引号数量表示半音级数,比如 3' 是 3 孔吸气压半音,3'' 是压全音。

《送别》详情页:上行简谱,下行孔位,红色吹气、蓝色吸气

《12 小节布鲁斯练习曲》大量使用了 3' / 3'' / 4' 压音标记
五、曲谱管理与导出
应用左侧是曲库列表,分内置曲谱和用户曲谱;右侧是详情。搜索支持曲名、副标题、标签。

曲库列表:内置 14 首验证通过的曲目,难度星级和标签一目了然
导出按钮提供四种格式:
- PNG:高清位图,适合发朋友圈或打印
- SVG:矢量,可二次编辑
- 打印 / PDF:调用浏览器打印转 PDF
- JSON:原始曲谱数据,可分享给其他 HarpScore 用户导入

JSON 导入弹窗:粘贴或选择文件即可加入个人曲谱库
六、让 WorkBuddy 自动搜谱:harpscore-import 技能
内置曲谱不是随便塞进去的。我专门写了一个用户级 WorkBuddy 技能 harpscore-import,流程如下:
- 联网搜索指定曲目的简谱(C 调优先)
- 把旋律转写成自定义 DSL 输入文件
- 脚本硬性验证:音域是否在 C4–C7、是否出现超吹、压音占比是否过高
- 如果所有调里都找不到可完整演奏的版本,直接拒绝并说明原因
- 通过验证后,自动转换为 HarpScore JSON 并写入
src/data/scores/,同时重建索引
验证过程中发现一个关键细节:很多旋律写在低八度时会在口琴上压音扎堆,比如《小星星》低八度需要 12 个压音,但按口琴实际演奏惯例移到中音区后,全部变成自然音,零压音。这个「八度移位」经验已经被写进技能文档,并且被 bake 进曲谱生成与导入逻辑:生成阶段就把移位后的八度写入每个音符,输出数据里不再保留 octaveShift 字段,让简谱八度点、孔位计算、音域分析三者完全一致,避免运行时只改一处导致显示与实际音高对不上。
每首内置曲谱现在还在分析面板标注来源、原始链接、核对日期,方便演奏者自己回溯简谱出处,也方便社区核查。
七、首批内置曲谱
最终进入内置库的 14 首曲目全部通过了可吹性验证:
0 压音,纯自然音入门
《小星星》《欢乐颂》《爱尔兰画眉》《铃儿响叮当》《两只老虎》《玛丽有只小羊羔》《祝你生日快乐》《西班牙划船歌》《平安夜》《奇异恩典》
带压音的进阶教材
- 《送别》:3 处低音压音,经典的压音入门教材,难度 ★★
- 《友谊地久天长》:4 处低音压音,民歌中常见的弱起与级进,难度 ★★
- 《压音入门练习曲》:14 处压音,专门练习 2–6 孔的音准控制,难度 ★★★
- 《12 小节布鲁斯练习曲》:G 调第二把位,集中训练
3' / 3'' / 4'压音,难度 ★★★★
八、未来路线图
HarpScore 现在能看谱、管谱、导谱,但离「完整工具」还有一段路。接下来打算按这个顺序迭代:
- 近期(1–2 周):曲谱可视化编辑器,直接点选音符输入;支持歌词逐字对齐;夜间模式适配。
- 中期(1–3 个月):播放功能(Web Audio / MIDI 试听)、节拍器、移调;支持 A / D / G 等更多调号口琴。
- 长期(3–6 个月):社区曲谱库(云端分享 + 本地缓存);Tauri 桌面封装,导出独立安装包;移动触控优化。
另外,harpscore-import 技能会继续扩展:未来想让它能直接识别图片简谱或网页里的数字谱,进一步减少手工转写。
九、开源与贡献
HarpScore 采用 MIT 协议,代码已托管在 GitHub:
如果你也吹十孔口琴,或者对乐谱渲染、音乐数据模型感兴趣,欢迎提 Issue、PR,或者直接 fork 一份改成自己想要的样子。乐谱格式本身还在早期,后续可能会随编辑器一起定型 v1。
做这个小项目最大的收获不是代码,而是把「口琴怎么吹」这件事真正结构化了一遍。原来压音、超吹、把位这些概念,落到数据模型里反而更清晰了。
— 本文由 WorkBuddy 辅助整理,HarpScore 项目持续更新中 —
微信公众号
欢迎关注「字与码」
如果这篇文章对你有用,也欢迎在微信里继续关注后续更新。
X / Twitter
关注 @ax2_zicode
更即时的技术观察、新文章提醒和一些短想法会发在 X 上。