我学不会任何乐器。试过不止一次,每次都只能勉强发出大致正确的声响,却始终不明白为什么这些声响是对的。

问题从来不在练习。而是音乐理论的每一种解释,似乎都跳过了事物之所以如此的根本原因。这里是五线谱,这是谱上的音符,这是大调音阶,记住这个模式。为什么是这些音符?为什么是那个模式?因为这就是惯例。

打开网易新闻 查看精彩图片

这种教法,对一个本质上源于物理和算术的系统来说,实在奇怪。十二个音符的存在有其原因,大调音阶的形状有其原因,好听的和弦之所以好听也有其原因,而这些原因都是可以计算出来的。

所以我决定从零开始,用第一性原理学习音乐。我的起点,是写代码。

声音是一个随时间变化的数字

声音就是气压的波动。扬声器通过振膜前后推动来发声,你的电脑处理音频的一切操作,归根结底是生成一串数字,描述振膜每秒四万四千次应该处在什么位置。

音频文件就是把这串数字记录下来。合成器则边运行边生成这串数字,只要你告诉它想要的波形,浏览器就能帮你完成这部分工作。最简单的波形是正弦波,下面这个例子每秒重复440次:

const osc = ctx.createOscillator();osc.frequency.value = 440;osc.connect(out);osc.start();osc.stop(ctx.currentTime + 1);

其中ctxout是我自己定义的,其余都是Web Audio API的原生接口。要在别处运行这段代码,需要先加上:

const ctx = new AudioContext();const out = ctx.destination;

数字440是这里唯一带有音乐意义的元素,而它本身也是任意的。这是大家约定俗成称为"A"的频率,是整个系统校准的基准音叉。把它改成300再运行一次,你会得到不同的音高,一切照常工作——因为在这个层面还没有音符的概念,只有数字。

频率就是音高:数字越大,音符越高。这就是全部的映射关系,也是音乐里最后一件这么简单的事。

为什么那个音符会"咔哒"一声

你可能注意到刚才播放结束时有一声轻微的咔哒。这不是浏览器的bug,而是物理学的无情。

振荡器在波形中途被停止,扬声器振膜正处于行程边缘的某个位置,然后瞬间弹回。气压的瞬时跳变,就是咔哒声的本质。