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: string
:basic_string指定要播放的声音。必须为在sounds.json中被定义的一个声音项目(例如,
entity.pig.ambient
)。一个声音项目可被多个不同的声音关联,而实际产生的声音为从中随机挑选的结果,被选中的概率由其权重决定,与正常游戏中相同。例如,声音项目
entity.pig.ambient
会随机播放多种猪音效之一,因为有多个声音关联于该项目。资源包可能会向sounds.json中添加额外的声音项目;此命令可以正常播放这些项目。该命令使用的声音名称不是文件名;而是严格使用sounds.json内定义的项目(项目名称可能与实际音频文件的文件名和目录相差甚远),因此资源包在添加新声音时必须为这些音频文件定义声音事件项目(但当资源包替换原有的已被定义的音频文件时,不必为其重新定义)。
player: target
:CommandSelector Player指定播放声音的目标。
必须为玩家名、目标选择器或UUID。且目标选择器只允许玩家。
position: x y z
:CommandPositionFloat指定声音发出的方位。
必须为三维坐标,元素为浮点数。允许波浪号与脱字号标记。
volume: float
:float指定声音能被听见的距离。必须至少为0.0。对小于1.0的值,声音会相对减轻,球状可闻范围会相对小。对大于1.0的值,声音不会实际上增大,但其可闻范围(1.0时半径为16米)会与_音量_相乘。声音总会基于与球体中心的距离逐渐衰减至无声。默认为1.0。
pitch: float
:float指定声音的音调。若未指定,默认为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的值会导致听不到该声音。
minimumVolume: float
:float指定在声音可闻范围外的目标能听到的音量。若目标在可闻范围外,作为补偿,声源会被放置在距离目标较近的位置(距离小于4格),而
_最小音量_
会决定补偿声源的音量。如果此数值等于0,则正常可闻范围外的目标听不到声音。如果未指定,则默认为0.0。
有这三要素基本就满足了声音构成的条件,但是把范围缩小到 音乐
当中,光有这基本三要素是不够的,关于 音调
的使用范围至关重要,而在乐理中基本的音调构成范围就不得不提到 十二平均律 了:
十二平均律(12-equal temperament)又称十二等程律,是世界上通用的一组音(八度)分成十二个半音音程的律制,各相邻两律之间的波长之比完全相等。 十二平均律是由中国明朝皇族世子朱载堉发现。
十二平均律是指八度的音程按波长比例平均分成十二等份,每一等份称为一个半音(小二度)。一个大二度则是两等份,称为全音。将一个八度分成12等份有着惊人的一些巧合。这是因为它的纯五度音程的两个音的波长比(即1/2的7/12次方)约为0.6674,与2/3,约为0.6667,非常接近。
可能有人会问为什么要拘泥于十二平均律?使用微分音创作音乐不是也很新吗?其实这么想也不是不可以,不过截至目前,人类的基本音乐创作理论体系 (俗称乐理) 还“局限”于基于十二平均律中,因此,想要作出“给人听”的音乐十二平均律的存在是不可或缺的。当然科技发展至今,使用微分音创作的电子音乐也不算少数,这个就因人而异咯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之类的办法。
但是通过 /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)~~:
其中 代表的是 [pitch: float]
中的数值,而 则是十二平均律中的数值关系, 的整数之间都是半音关系,比如在音色 note.pling
中, 的时候对应 ,对应的 F#3 , 的时候对应 对应的 F#4, 的时候对应 ...... 以此类推,便能得到钢琴八十八键对应的音符音调了。
值得一提的是,MC中所有可以使用的音效对应的基准因,也就是 p=1 对应的音,并不一定都是 F# ,但是就目前来看,所有 Note
类型的音色对应的基准音都是 F#,所以以 F# 为基准音的基础上去测试以及记录对应的88音平均律的基本关系,如果有基准因不是 F# 的,也可以通过参考这个基准音对应关系来进行平移得到相对应的平均律谱表。
88音平均律谱表
以 note.pling
音色为基准,通过 p=1 F#3 的基本音关系延伸,根据 p=2^((n-12)/12) 的关系式,测试计算出来的平均律谱表如下(p取值为小数点后四位数):
测试指令:
1 | /playsound note.harp @a ~~~ 1 p |
n | p | 音符 | 音域 |
---|---|---|---|
-33 | 0.0743 | A | 0 |
-32 | 0.0787 | A# | |
-31 | 0.0834 | B | |
-30 | 0.0884 | C | 1 |
-29 | 0.0936 | C# | |
-28 | 0.0992 | D | |
-27 | 0.1051 | D# | |
-26 | 0.1114 | E | |
-25 | 0.1180 | F | |
-24 | 0.1250 | F# | |
-23 | 0.1324 | G | |
-22 | 0.1403 | G# | |
-21 | 0.1487 | A | |
-20 | 0.1575 | A# | |
-19 | 0.1669 | B | |
-18 | 0.1768 | C | 2 |
-17 | 0.1873 | C# | |
-16 | 0.1984 | D | |
-15 | 0.2102 | D# | |
-14 | 0.2227 | E | |
-13 | 0.2360 | F | |
-12 | 0.2500 | F# | |
-11 | 0.2649 | G | |
-10 | 0.2806 | G# | |
-9 | 0.2973 | A | |
-8 | 0.3150 | A# | |
-7 | 0.3337 | B | |
-6 | 0.3536 | C | 3 |
-5 | 0.3746 | C# | |
-4 | 0.3969 | D | |
-3 | 0.4204 | D# | |
-2 | 0.4454 | E | |
-1 | 0.4719 | F | |
0 | 0.5000 | F# | |
1 | 0.5297 | G | |
2 | 0.5612 | G# | |
3 | 0.5946 | A | |
4 | 0.6300 | A# | |
5 | 0.6674 | B | |
6 | 0.7071 | C | 4 |
7 | 0.7492 | C# | |
8 | 0.7937 | D | |
9 | 0.8409 | D# | |
10 | 0.8909 | E | |
11 | 0.9439 | F | |
12 | 1.0000 | F# | |
13 | 1.0595 | G | |
14 | 1.1225 | G# | |
15 | 1.1892 | A | |
16 | 1.2599 | A# | |
17 | 1.3348 | B | |
18 | 1.4142 | C | 5 |
19 | 1.4983 | C# | |
20 | 1.5874 | D | |
21 | 1.6818 | D# | |
22 | 1.7818 | E | |
23 | 1.8877 | F | |
24 | 2.0000 | F# | |
25 | 2.1189 | G | |
26 | 2.2449 | G# | |
27 | 2.3784 | A | |
28 | 2.5198 | A# | |
29 | 2.6697 | B | |
30 | 2.8284 | C | 6 |
31 | 2.9966 | C# | |
32 | 3.1748 | D | |
33 | 3.3636 | D# | |
34 | 3.5636 | E | |
35 | 3.7755 | F | |
36 | 4.0000 | F# | |
37 | 4.2379 | G | |
38 | 4.4898 | G# | |
39 | 4.7568 | A | |
40 | 5.0397 | A# | |
41 | 5.3394 | B | |
42 | 5.6569 | C | 7 |
43 | 5.9932 | C# | |
44 | 6.3496 | D | |
45 | 6.7272 | D# | |
46 | 7.1272 | E | |
47 | 7.5510 | F | |
48 | 8.0000 | F# | |
49 | 8.4757 | G | |
50 | 8.9797 | G# | |
51 | 9.5137 | A | |
52 | 10.0794 | A# | |
53 | 10.6787 | B | |
54 | 11.3137 | C | 8 |
以上表格使用Excel计算 原文件 (懒人一个xd) :【腾讯文档】MC音律表
结语
从未设想过的道路)如果能加上midi转换的话,那么直接在MC里制作音乐也是完全有可能的了(确信。虽然有了nbs音乐,但是nbs本身并不支持在原版MC中直接播放,虽然可以用NBS Studio进行转换,但是目前NBS Studio也不支持MC基岩版,以及原版适配中目前似乎并没有支持到用命令扩展音域的地步(不过高版本mcfunction似乎可行。?)能在原生的MC里实现88音律表,也方便以后创作红石音乐的人们。
简单的一次尝试,也学到了不少东西,xd