用python告诉你为什么十二平均律有12个音

作为一名学音乐的艺术生,为什么平均律现行的是12个音而不是其他的选择,我们需要一个合理的解释。后现代解构主义喜欢把所有的锅都甩给“文化上下文”跟“历史的偶然性”,这是很不负责任的表现。

本文的目的是通过简单的数学和python可视化工具来解释为什么平均律是12个音。以下是正文。

任何数学工具都要从人的需求开始,因此我们先从音乐的角度说人话。

从听感的角度,我们将音程分为两种:

这里我们有了第一个需求:协和音程比不协和音程有更高的优先级,也就是说我们优先考虑让协和音程尽量协和

因为我们的生理构造以及各种神秘的原因,协和音程对应的都是这种形式的比例:

k+1k,k={1,2,3,...}

例如:

因此我们想要一个n-平均律,使得这一平均律最好地照顾到这些协和音程。

本文的目的就是解释为什么当n=12的时候是最优解。

定义损失函数

怎么样算“照顾到这些协和音程”?我们需要找到一种衡量n-平均律跟这些协和音程之间的“距离”,来判定n-平均律的优劣。

当我们定义了一个n-平均律,我们将八度分为了n等份,同时也生成了n个音程:

我们想要的就是:对于任何一个协和音程,存在一个n平均律中的音程,使得这两个音程之间的距离尽量小

例如,我们熟悉的12平均律(n=12),对于纯五度,我们可以找到12平均律中的第7个音程:

2712=1.4983070768766815

而这跟理想中的纯五度

32=1.5

非常接近。

因此定义损失函数非常简单:遍历上文枚举出的协和音程,对于任何一个协和音程,找出在n-平均律中离这一协和音程“距离”最近的一个音程然后计算“距离”。

既然上文提到了“距离”,我们可以很直观地直接用欧氏距离(毕竟从几何到统计学的MSE都在用这个):

d(x,y)=(x1y1)2+...+(xkyk)2

也就是说

损失函数(n-平均律)=(纯八度跟最接近的音程的距离)2+(纯五度跟最接近的音程的距离)2+...

我们现在来看一下效果。

进阶:两个可以考虑的问题

从上面已经可以看出来12对应着一个极小值,这也解释了为什么我们会选择12。

然而美中不足的是:19一样也很小,也就是说,19这一竞争者的存在让我们看不到12独特的光辉。

接下来我们可以用一个邪恶的招数:通过修改“比赛规则”让12成为内定的冠军

不同的音程并非生而平等

我们可以提出第二个(伪)需求:不同的协和音程重要程度也不一样。例如,或许我们觉得顾及纯五度比顾及小三度更加重要,也就是说我们更需要P5精准而不是m3。

从数学的角度来说,我们需要的是加入权重α1,...,αk

损失函数(n-平均律)=α1(纯八度跟最接近的音程的距离)2+α2(纯五度跟最接近的音程的距离)2+...

权重该如何取值?一个很heuristic也是最为自然的办法就是直接用音程自身的值,因为我们发现协和音程的大小跟重要性呈正比

例如纯五度比小三度重要,恰好纯五度对应的32比小三度对应的65要大。

因此公式就成了

损失函数(n-平均律)=21(纯八度跟最接近的音程的距离)2+32(纯五度跟最接近的音程的距离)2+...

看一下效果:

n的取值

另外一个直觉则是,n-平均律,n越大越不现实,毕竟作曲家和听众都会懵逼:比如如果一个八度有100万个音,那么我们大家都会集体懵逼。因此从regularization的角度来讲,我们可以加入对n的penalty:我们想要的是小的损失函数,但是n也最好不要大

所以一个最简单的方式就是把这个对n的regularization penalty放到损失函数中,n越大损失越大

一个最简单且自然的选择就是选择n本身当做系数相乘

损失函数(n-平均律)=n21(纯八度跟最接近的音程的距离)2+32(纯五度跟最接近的音程的距离)2+...

看一下效果:

如上,12这个数字成了唯一的最优解。

后记:剩下的最后一种损失函数

上文我们考虑了三种情况的损失函数:

剩下的最后一种情况:

也就是

损失函数(n-平均律)=n(纯八度跟最接近的音程的距离)2+(纯五度跟最接近的音程的距离)2+...

长得是这个样子: