音符·代码·脑洞

不想当程序员的歌手不是好指挥。

0%

使用AI辅助开发练耳助手应用

距离上一篇blog已经过去了一年半,在写上一篇文章时,我确实没有想过这个Idea真的能够成功。可以说,在这一年半中,AI的发展确实是非常迅猛的。

尤其是AI Agent的出现,确实可以帮助我完成一些重复的工作。比如说,在多个excel表中综合查询、整理数据,按照已有模板生成word和pdf等等。这些工作如果人工操作,就是需要手动把数据从一个表格复制到另一个表格,调整顺序和格式……现在只需要一段提示词,然后等待一段时间就可以完成了。AI Agent会分析数据格式、分析需求、生成对应的处理代码,运行并验证输出是否正确并符合要求。

回归正题,本次开发的是练耳助手H5 App。选用的AI Agent为WorkBuddy。

Demo演示:练耳助手

UI设计

首先,我先让workbuddy帮我解决了最让我头疼的UI设计环节。AI设计的并不好看,但比我强。我连用什么软件做UI设计都不知道。

1
帮我设计app“练耳助手”的页面。主页:欢迎页面,显示logo、欢迎语、按钮“开始练习”模式选择页面:选项有“单音”、“音程”、“和弦”、“节奏”、“旋律“、“综合练习”选择题目数量页面:快捷选项“5” “10”“20” 可以自行输入 做题页面:有播放按钮,点击后播放音频,显示答案的按钮,点击切换答案的显示状态,还有为答案预留的位置(请帮我设计显示和隐藏答案两种状态的页面),页面的下方有按钮让用户标记此题是否回答正确。完成练习页面:显示本次练习的正确率和评语。这几个页面要保持UI风格统一,简洁,重点突出。

有了这段提示词,AI给了我用ardot设计的几个页面的初稿。
pasted-image-1785738489273.webp

Workbuddy还可以直接由设计稿生成代码,我试了下,生成的页面可以用作demo演示,但页面当中的逻辑并不是十分符合需求。希望有一天AI能继续发展,在提示词中分析出所需要的前后端逻辑,直接生成出完整的项目代码。

框架选型与前端代码实现

这个软件定位是H5 App,所以我进行了一番搜索,决定使用Vue+Vite来实现,前端组件库选择轻量的Vant。

题库设计与生成

因为想做一个轻量的软件,杜绝使用数据库。但是又不想直接把题库信息写在前端页面中,所以折中选择,把题目保存为musicxml文件,从前端直接读取musicxml文件,生成对应的题目音频进行播放,显示答案时也直接从musicxml中的数据渲染乐谱显示。

这里涉及到3个问题:

1. 从musicxml将乐谱显示出来

这一部分相对好解决,有现成的包OpenSheetMuicDisplay能够解析musicxml数据并显示为乐谱。

2. 从musicxml中读取音乐信息,播放对应的音频

这部分没有合适的库可以直接套用。大部分musicxml播放库都聚焦于乐谱和音频同步播放显示,但我并不需要这个功能。我只需要读取文件中的音高节奏数据播放出来就可以。

我看了下之前AI生成的Demo代码,这部分的实现是用到了Web Audio API。我读了下文档,觉得这个东西不是两三天能弄明白的。于是就让AI帮我来解决这个问题吧!

1
尝试开发nodejs package。功能:读取musicxml文件,转化成音频数据,并在h5中播放出来。所有musicxml文件已经控制格式,只有一个乐器一种音色(钢琴)。

Workbuddy真的给我写了一个包,甚至还给我生成了demo页面和使用说明。

后面的调整过程就真是调模型了。

1
2
3
完善代码,考虑xml文件中不同音符不同时出现的情况。例如intervalsample.musicxml

发现生成的音频有点问题,音符节奏衔接较近时,后一个音播放结束后还能听到前一个音。分析一下原因,尝试优化代码,解决这个问题

pasted-image-1785739705335.webp

(还给我可视化汇报了一下优化逻辑)

这才算是在这个项目中真正体验到了ai编程,真好用啊。到现在我还是不会用Web Audio API,但我能借助AI写出用Web Audio API实现的包。

3. musicxml题库生成

尝到甜头了,这个问题也扔给AI。

1
参照各艺术院校、音乐学院的艺考、考研视唱练耳考试标准,完善题库(单音听辨、音程听辨、和弦听辨)。生成对应的musicxml文件,对应文件夹中已有模板。并完善index.js中的3个questionList。

上线

最后手动build一下,打包上传服务器,配置nginx、DNS一条龙,这部分就自己来吧,感觉直接把服务器的root权限直接给AI实在是不放心。

总之,玩了一下AI Agent,还是很快乐的。有点想买付费版了,不过目前每天签到领的积分还是很够用的,先把羊毛薅了再说。