发布于 

MCBE 88音平均律

前言

今天修IMC Geyser的时候看到冲田在烷MC,随便试了试Xbox联机没想到进去了)然后冲田似乎在研究playsound的调音,我才知道原来MCBE的playsound命令还有微分音的用法(红石音乐人狂喜x)通过微分音的调教,理论上突破原版材质包里自带的音符盒音域,实现88音的完整钢琴音域就可能实现了,如果再搭配上midi文件的转化就可以实现在MC游戏里不依靠任何材质包,mod等就能实现音乐的播放!

虽然已经有相关的项目了,比如 Open Note Block Studio 就已经实现了nbs音乐相关的编辑,以及midi文件的转换。不过这个工具目前只支持MCJE,并不支持MCBE,扩展音域似乎也是通过扩展音符包来实现的,相对繁琐。本文主要记录一下MCBE的playsound调音对应88键平均律的对应数值以及方法,虽然不一定在MCJE适用,但是基本方法应该是差不多的,可以作为参考留档。

基本知识

让我们先来复习一下初中基本物理知识——声音的基本三要素:

  • 音色:波形决定了声音的音调。由于不同对象材料的特点,声音具有不同的特性,音色本身就是抽象的东西,但波形就是把这种抽象和直观的性能。波形因音调而异,不同的音调可以通过波形来区分。
  • 音调:声音的高低由频率决定,频率越高音调越高,人耳听觉范围20—20000Hz;20Hz以下称为次声波,20000Hz以上称为超声波。
  • 响度:指人耳感觉到的声音强弱,即声音响亮的程度,根据它可以把声音排成由轻到响的序列。响度的大小主要依赖于声强和频率,振幅越大响度越大,人和声源的距离越小,响度越大。

而这三要素在Minecraft的 /playsound 指令里基本算是都齐活了,声音的基本三要素和MC指令的信息对应还是需要说明一下(毕竟wiki没提):

MCBE的 /playsound 指令:

1
/playsound <sound: string> [player: target] [position: x y z] [volume: float] [pitch: float] [minimumVolume: float]

示例指令:音色为 note.pling ,音调为 中央C(C4) ,播放给全局玩家。

1
/playsound note.pling @a ~~~ 9999 0.7

指令预览

简单说明:

  • 音色:对应的 <sound: string> ,只能调用 sounds.json 里的项目,具体的可以去Minecraft Wiki或者自行拆包查看,有预览表,也可以使用自制的材质包实现自定义音色。值得一提的是MC中所有的音效都可以使用。这里列几个常用的Note音色:
    • note.harp 音符盒音色,算是MC红石音乐比较标志性的音色。类似音色: note.pling ,声音比较洪亮,音长相对较长。
    • note.guitar 音符盒吉他音色,拨弦乐器声音采样比较短促,类似音色: note.banjo 班卓琴音色
    • note.bass 音符盒贝斯音色,低音必备。类似音色: note.bassattack
    • note.hat 音符盒打击音色,可以当鼓点使用。类似音色: note.bd note.snare
    • note.flute 音符盒笛声音色,使用高频播放的话可以达到延音的效果(吹奏类乐器音色的好处,采样出来的音色首尾相接基本不会有违和感,《光遇》里的乐器演奏也能用类似的方法实现延音。)类似音色: note.didgeridoo 有点低音号的感觉,但是高频播放不是很连贯。
    • note.bit bit音乐采样音色,算是电子音乐比较经典的音色。类似音色: note.bell 八音盒感觉的音色, note.cow_bell 相对低沉的八音盒感觉的音色
  • 音调:对应的 [pitch: float] ,以数值的形式表现,默认是 1 ,在 note.pling 中对应十二平均律中的 F# 。这种对应关系也是本文的重点,大概是通过程序将音色移调的参数,通过这种方式即便不把所有音符采样塞进游戏里理论上也能实现十二平均律,以及对应的钢琴八十八键的复原
  • 响度:响度有些特殊,决定响度的是 [player: target] [position: x y z] [volume: float] [minimumVolume: float] 这三个参数决定,依次是玩家目标,声音发生的位置,能够听到声音的范围,和补偿范围。没有直接影响响度的变量,不过可以通过这些参数间歇性的实现响度的控制,甚至环绕音的混响实现也是有可能的。

详细参数说明:

sound: stringbasic_string

指定要播放的声音。必须为在sounds.json中被定义的一个声音项目(例如,entity.pig.ambient)。

一个声音项目可被多个不同的声音关联,而实际产生的声音为从中随机挑选的结果,被选中的概率由其权重决定,与正常游戏中相同。例如,声音项目entity.pig.ambient会随机播放多种猪音效之一,因为有多个声音关联于该项目。

资源包可能会向sounds.json中添加额外的声音项目;此命令可以正常播放这些项目。该命令使用的声音名称不是文件名;而是严格使用sounds.json内定义的项目(项目名称可能与实际音频文件的文件名和目录相差甚远),因此资源包在添加新声音时必须为这些音频文件定义声音事件项目(但当资源包替换原有的已被定义的音频文件时,不必为其重新定义)。

player: targetCommandSelector Player

指定播放声音的目标。

必须为玩家名、目标选择器或UUID。且目标选择器只允许玩家。

position: x y zCommandPositionFloat

指定声音发出的方位。

必须为三维坐标,元素为浮点数。允许波浪号与脱字号标记

volume: floatfloat

指定声音能被听见的距离。必须至少为0.0。对小于1.0的值,声音会相对减轻,球状可闻范围会相对小。对大于1.0的值,声音不会实际上增大,但其可闻范围(1.0时半径为16米)会与_音量_相乘。声音总会基于与球体中心的距离逐渐衰减至无声。默认为1.0。

必须为单精度浮点数。在Java版中,必须大于等于0.0。

pitch: floatfloat

指定声音的音调。若未指定,默认为1.0。

Java版中,该数值必须在0.0至2.0间(含),而小于0.5的值与0.5等价。小于1.0的值降低音调而提升持续时间;大于1.0的值提升音调而降低持续时间。音调值是乘在声音频率上的一个倍率,因此若将0.5-1.0(含)区间内的音调值乘以2,所得的新音调便会高一个八度。

基岩版中,该数字没有特别限制,但是必须要在0.0至256.0之间才有对应效果。高于256.0的值与默认值的效果相同。小于等于0.0的值会导致听不到该声音。

  • 对于音符盒的声音,如果你希望将其他音符转换为音调数值,请参阅相关内容。但请注意1.0的音调值对于每种声音并不一定都是F♯。

minimumVolume: floatfloat

指定在声音可闻范围外的目标能听到的音量。若目标在可闻范围外,作为补偿,声源会被放置在距离目标较近的位置(距离小于4格),而_最小音量_会决定补偿声源的音量。

如果此数值等于0,则正常可闻范围外的目标听不到声音。如果未指定,则默认为0.0。

必须为单精度浮点数。在Java版中,必须在0.0和1.0(含)之间。

——《命令/playsound - Minecraft Wiki》

有这三要素基本就满足了声音构成的条件,但是把范围缩小到 音乐 当中,光有这基本三要素是不够的,关于 音调 的使用范围至关重要,而在乐理中基本的音调构成范围就不得不提到 十二平均律 了:

十二平均律(12-equal temperament)又称十二等程律,是世界上通用的一组音(八度)分成十二个半音音程律制,各相邻两律之间的波长之比完全相等。 十二平均律是由中国明朝皇族世子朱载堉发现。

十二平均律是指八度的音程按波长比例平均分成十二等份,每一等份称为一个半音(小二度)。一个大二度则是两等份,称为全音。将一个八度分成12等份有着惊人的一些巧合。这是因为它的纯五度音程的两个音的波长比(即1/2的7/12次方)约为0.6674,与2/3,约为0.6667,非常接近。

十二平均律在交响乐队键盘乐器中得到广泛使用,钢琴即是根据十二平均律来定音的。

——十二平均律_百度百科 (baidu.com)

十二平均律图表

可能有人会问为什么要拘泥于十二平均律?使用微分音创作音乐不是也很新吗?其实这么想也不是不可以,不过截至目前,人类的基本音乐创作理论体系 (俗称乐理) 还“局限”于基于十二平均律中,因此,想要作出“给人听”的音乐十二平均律的存在是不可或缺的。当然科技发展至今,使用微分音创作的电子音乐也不算少数,这个就因人而异咯xd 借用《海上钢琴师》里我印象深刻的经典台词来说:

Take a piano. The keys begin, the keys end. You know there are eightyeight of them, nobody can tell you any different. They are not infinite. You are infinite. And on these keys the music that you can make is infinite. I like that. That I can live by.

译:拿一架钢琴来说,从琴键开始,又结束。**你知道钢琴只有88个键,随便什么琴都没差。它们不是无限的。你才是无限的,在琴键上制作出的音乐是无限的。**我喜欢这样,我活的惯。


MC中的平均律

理论成立,实践开始!Minecraft原版中的音符盒的音域只有F#3到F#5的25个键,想要还原钢琴八十八键的音域一般来说只有扩展材质包,mod之类的办法。

image-20230514173645051

但是通过 /playsound 指令中的 [pitch: float] 调音参数就能实现原版MC不使用任何外部资源加持的前提下实现88键钢琴音域的还原! (甚至超出88键都有可能xd)那么在这其中需要实现各个键位的音调还原,Minecraft中 pitch参数和十二平均律的对应关系是必不可少的。

本来以为是很简单的正比线性对应关系,但是试了几个数之后感觉有点不对。。比如 p=1 的时候音色 note.pling 对应的是 F#4, p=2 的时候对应的是 F#5,但是到 F#3的时候对应的 p=0.5 ,并不是一般的一次函数线性关系。

通过冲田分享的文章 【我的世界】playsound钢琴全键音调值 - 哔哩哔哩 (bilibili.com) 知道了基本的对应关系式~~(不知道是怎么来的,不过随机抽样了几个数试了试大概是对的,就按这个公式来看吧x)~~:

p=2(n12)12p=2^{\frac{\left(n-12\right)}{12}}

image.png

其中 pp 代表的是 [pitch: float] 中的数值,而 nn 则是十二平均律中的数值关系, nn 的整数之间都是半音关系,比如在音色 note.pling 中, n=0n=0 的时候对应 p=0.5p=0.5 ,对应的 F#3 , n=12n=12 的时候对应 p=1p=1 对应的 F#4,n=24n=24 的时候对应 p=2p=2 ...... 以此类推,便能得到钢琴八十八键对应的音符音调了。

钢琴频谱

值得一提的是,MC中所有可以使用的音效对应的基准因,也就是 p=1 对应的音,并不一定都是 F# ,但是就目前来看,所有 Note 类型的音色对应的基准音都是 F#,所以以 F# 为基准音的基础上去测试以及记录对应的88音平均律的基本关系,如果有基准因不是 F# 的,也可以通过参考这个基准音对应关系来进行平移得到相对应的平均律谱表。

88音平均律谱表

note.pling 音色为基准,通过 p=1 F#3 的基本音关系延伸,根据 p=2^((n-12)/12) 的关系式,测试计算出来的平均律谱表如下(p取值为小数点后四位数):

p=2(n12)12p=2^{\frac{\left(n-12\right)}{12}}

测试指令:

1
/playsound note.harp @a ~~~ 1 p
np音符音域
-330.0743A0
-320.0787A#
-310.0834B
-300.0884C1
-290.0936C#
-280.0992D
-270.1051D#
-260.1114E
-250.1180F
-240.1250F#
-230.1324G
-220.1403G#
-210.1487A
-200.1575A#
-190.1669B
-180.1768C2
-170.1873C#
-160.1984D
-150.2102D#
-140.2227E
-130.2360F
-120.2500F#
-110.2649G
-100.2806G#
-90.2973A
-80.3150A#
-70.3337B
-60.3536C3
-50.3746C#
-40.3969D
-30.4204D#
-20.4454E
-10.4719F
00.5000F#
10.5297G
20.5612G#
30.5946A
40.6300A#
50.6674B
60.7071C4
70.7492C#
80.7937D
90.8409D#
100.8909E
110.9439F
121.0000F#
131.0595G
141.1225G#
151.1892A
161.2599A#
171.3348B
181.4142C5
191.4983C#
201.5874D
211.6818D#
221.7818E
231.8877F
242.0000F#
252.1189G
262.2449G#
272.3784A
282.5198A#
292.6697B
302.8284C6
312.9966C#
323.1748D
333.3636D#
343.5636E
353.7755F
364.0000F#
374.2379G
384.4898G#
394.7568A
405.0397A#
415.3394B
425.6569C7
435.9932C#
446.3496D
456.7272D#
467.1272E
477.5510F
488.0000F#
498.4757G
508.9797G#
519.5137A
5210.0794A#
5310.6787B
5411.3137C8

以上表格使用Excel计算 原文件 (懒人一个xd)【腾讯文档】MC音律表


结语

从未设想过的道路)如果能加上midi转换的话,那么直接在MC里制作音乐也是完全有可能的了(确信。虽然有了nbs音乐,但是nbs本身并不支持在原版MC中直接播放,虽然可以用NBS Studio进行转换,但是目前NBS Studio也不支持MC基岩版,以及原版适配中目前似乎并没有支持到用命令扩展音域的地步(不过高版本mcfunction似乎可行。?)能在原生的MC里实现88音律表,也方便以后创作红石音乐的人们。

简单的一次尝试,也学到了不少东西,xd