编写一个网页版的音高识别软件
经常使用安卓手机📱上面的一个叫做VocalPitchMonitor的APP,它的软件界面是这样的:
我想更加方便的使用这个功能,所以有了一个制作网页版音高🗣️识别软件的想法。有了想法之后,就开始上网上搜索。在GitHub上有多个音高识别的软件库,为我的这个想法提供了底层能力,我只需要做好想要的交互就可以了。
我选择了PitchDetect,与我最终想要的外观最接近。首先要添加左侧的音符🎵坐标,我在代码中找到了freq和note的转换方法,找资料重温了十二平均律后大概有了思路。开始沿着开源代码的方法路线,使用画布实现,后来发现在高分辨率屏幕上会发虚,所以改为使用 CSS实现。
第二是我想实现一个瀑布图🌊。一开始的方案是实时绘制整个瀑布图数据,每次刷新重新绘制。这种方法的性能很差,所以改为了只渲染最新的一个像素宽度的画面,之前的画面保留,并向右平移一个像素。主要代码如下:
...
//初始化
waveCanvas = document.getElementById("waveform");
ctx = waveCanvas.getContext("2d");
//缓冲画布比主画布窄一个像素。
tmpCanvas = new OffscreenCanvas(waveCanvas.width - 1, waveCanvas.height);
tmpCtx = tmpCanvas.getContext('2d');
...
function updatePitch(time) {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
//主画布1像素后绘制之前缓存的画面
ctx.drawImage(tmpCanvas, 1, 0);
//这里在第0列绘制最新的频谱数据
//必须清空临时画布
tmpCtx.clearRect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height);
//将主画布本次图形存储到缓冲画布
tmpCtx.drawImage(ctx.canvas, 0, 0);
}
下面是我最终完成⌛的界面: