webAudio API打造体验优良的电子钢琴

一个人长大之后做的每一件事,其实都是在成全我们儿时种下的愿望或未完成的梦想。

《毛诗序》有言:

“情动于中而行于言,言之不足,故嗟叹之,嗟叹之不足,故咏歌之,咏歌之不足,不知手之舞之,足之蹈之也。”

音乐也是一座拉近人与人之间距离的桥梁。

我想从两个方面介绍如何借助 webAudio API 完成基本的在线钢琴:

  • 钢琴的布局
  • webAudio API与点击事件完成按键播放

钢琴布局

钢琴一共有88个按键,其中黑键36个,白键52个。如果从任意白键Do(或者叫C键)开始,每7个白键为一组(Do/Re/Mi/Fa/So/La/Xi 或叫 C/D/E/F/G/A/B),每一组还有五个黑键(命名规则是其前一个白键名前加一个“升”字,或者后一个白键名前加“降”字)有规律的分布在白键上方,所以一组有7个白键和5个黑键,如此一来整个键盘便是该组的拷贝,循环往复。

钢琴中有一个特殊的白键,叫中央C,故名思意,88个键中间一组的12个键的第一个白键。

了解了这些规则就能用代码将键盘布局实现出来了。

我采用JavaScript来实现动态布局,需要预先声明一个变量存储88个键的数据:

之后声明一个函数用于渲染钢琴结构,其中遍历到了前面声明的钢琴88键数据:

几点注意

  • 白键按顺序排列。
  • 黑键根据白键位置定位。
  • 运用事件委托机制和冒泡原理,给88个键的父容器添加事件监听器。

webAudio API与点击事件完成按键播放

首先要解决一个关于88键音源加载平衡的问题,这里有三个方案:

  • 88个键音源一次性加载完毕,点击按键时不会有延迟,牺牲空间复杂度,降低时间复杂度。
  • 首次不加载,点击按键时再加载,会有延迟,牺牲时间复杂度,降低空间复杂度。
  • 首次加载中央C键及两侧的常用按键适量个并缓存,此后如果按到未加载银色的按键时那么加载该音色并缓存。

显然,我选择了第三种方案,平衡了时间复杂度与空间复杂度。

据此,我需要几个封装的函数处理这些过程:

  • 用来加载音色文件(这里用到的钢琴音色时ogg格式)。
  • 解码音色文件为 web audio api 能识别的编码(当然也是用到webAudio提供的接口)。
  • 检查按键音色是否存在(也就是按了初次没加载的音色,需要加载并解码音色)。
  • 尝试播放音色。

下面是部分代码片段,完整的示例代码就在你的指间,请动起你发财的小手,不要照抄哦,你会收获更多。


本篇完,小弟不才,文中不妥之处望指出批评。

其实我一直很同意《小王子》的这句台词:

最本质的东西肉眼是看不见的。

对于程序员,写代码的时间可能只占整个实现过程的三分之一不到,更多的时间是用来考虑安全、算法、性能甚至个人习惯的养成等等用户肉眼看不到的时刻。

对于设计师,PS作图的时间可能只占整个设计过程的三分之一不到,更多的时间是来自想灵感,灵感来自平时的大作赏析、经验积累、生活感悟、读书等等用户肉眼看不到的时刻。

参考资料 : Web_Audio_API

版权声明 » 自由转载-署名-非商用-相同方式共享

作者署名 » 陈帅华-探索技术艺术与国学之美

发布日期 » 2017年11月22日 星期三

我要留言