🌞

10分钟纯前端实现音准检测(WASM算法运算)

背景在工作群中,偶然看到这样一种场景:在乐谱演奏中,实时分析演奏的音准并进行评分。在这种场景下,一般性的做法,无非是进行音频采集,再通过音频处理(降噪等),最后通过算法分析得到预测的音准。流程很清楚,

文链接在语雀:https://www.yuque.com/wumingshi/rkh1qq/

背景

在工作群中,偶然看到这样一种场景:在乐谱演奏中,实时分析演奏的音准并进行评分。

在这种场景下,一般性的做法,无非是进行音频采集,再通过音频处理(降噪等),最后通过算法分析得到预测的音准。流程很清楚,现实很骨感,这里涉及到很多链路,那在纯前(zi)端(ji)领(hui)域的领域,目前可以尝试做到一个什么程度呢?

这便产生了以下的demo:

http://demo.onehacker.top/pitch-detection-app/

原理分析

step1:音频采样

无非不过两种

  • 录音
  • 音频文件

在浏览器侧不管实现哪种音频的采集,都是很方便的,这里为了防止环境噪音的干扰,采用音频文件的方式,基本实现也很简单:

    const context = new AudioContext();
    const mediaStreamSource = context.createMediaElementSource(
      stream as HTMLMediaElement
    );
    const analyser = context.createAnalyser();
    mediaStreamSource.connect(pitchSetup.analyser);
    analyser.connect(pitchSetup.audioContext.destination)

通过这种方式实现音频到自己的处理通道,这样就可以拿到音频的二进制数据。拿到的数据通过做法进行数据分析

step2: 数据分析

提取的数据需要进行基因检测,检测的算法五花八门,比如最基础的自相关检测。关于这个算法的优劣这里不做赘述,毕竟也不是本文重点。

获取的数据是一串离线的数字信号,简易设置一个滤波器,在超出范围的数据进行过滤,过滤后的数字进行进行傅里叶频谱转换,这里包含傅里叶正变换、逆变换等一些复杂的数学算法。最终可以得出当前声音的频率和清晰度。

总之使用 service worker + wasm 完成复杂算法的结果运算。

具体的算法可以参考:https://github.com/alesgenova/pitch-detection

step3:将分析的结果进行展示

总结

通过以上的方式,即可实现前端进行音频采集,前端进行算法运算,最终前端进行音频展示的能力。整体的效果还很粗糙,但借助于WASM,相信在前端领域内的直接算法运算会变得越来越可为。

updatedupdated2022-08-022022-08-02