其实, 我自己也是小白, 所以只能写个小白教程。
南山南
我们只需要管歌词上面的那一行简谱。注意到:
1 2 3 4 5 6 7
do re mi fa so la si
多 来 米 发 梭 拉 西
上面就是我们需要的音乐基本知识, 其实是很简单的。
MatheMatica中有个SoundNote函数, 可以表示和指定音高相同的一个音符。例如, 南山南中第一个音符6(下划线打不出来), 用MA表示为
SoundNote
6
SoundNote[9,60/68/2,"Guitar"]
9
60/68/2
"Piano", "Violin"
由上面的表示, 我们知道简谱中的一个音可以用两个参数表示出来. 由于4/4拍中有很多八分音符, 故我们将八分音符的时长定义为单位1(主要是减少书写). 这样, 参数化后的简谱为
Melody = {6, 6, 6, {4, 1/2}, {4, 1/2}, {6, 1/2}, {10, 3/2}, {9, 2}, {10, 2}, 9, 5, {8, 2}, {[Infinity], 2}, {[Infinity], 2}, {4, 1/2}, {4, 1/2}, 4, {3, 1/2}, {3, 1/2}, 2, {2, 1/2}, {2, 1/2}, 2, 5, 2, {3, 3}, {[Infinity], 3}, {5, 1/2}, {5, 1/2}};
EqualTempList = {0, 2, 4, 5, 7, 9, 11, 12, 14, 16, 17, 19, 21, 23, 24};
0
2
12
于是要得到中音6, 我们只需取EqualTempList的第6个元素即可。
EqualTempList
尽管MA内置了标准的SoundNote演奏函数, 但是我们的数据并不标准, 例如Melody中有些是一个数字(八分音符), 有些是数列(其他时值)。我们用下面的函数来标准化
Melody
StandardT=60/68/2; MelodyToSound[lis_] := Module[{m, mt}, If[ ListQ[lis], m = lis[[1]]; mt = lis[[2]], m = lis; mt = 1]; If[m == [Infinity], SoundNote[None, mt*StandardT], SoundNote[EqualTempList[[m]], mt*StandardT, "Guitar"]] ]
第一个If判断是否传入的参数为数列, 如果是, 则将第一个参数映射为音符, 第二个参数映射为对应的时值。 否则, 设置时值为1.
If
第二个If判断音符是否为[Infinity], 如果是, 则该音表示空音(不发声), 这时用SoundNote[None, mt*StandardT]来表示时长为mt的空音。
[Infinity]
SoundNote[None, mt*StandardT]
mt
Melody = {6, 6, 6, {4, 1/2}, {4, 1/2}, {6, 1/2}, {10, 3/2}, {9, 2}, {10, 2}, 9, 5, {8, 2}, {[Infinity], 2}, {[Infinity], 2}, {4, 1/2}, {4, 1/2}, 4, {3, 1/2}, {3, 1/2}, 2, {2, 1/2}, {2, 1/2}, 2, 5, 2, {3, 3}, {[Infinity], 3}, {5, 1/2}, {5, 1/2}}; StandardT = 60/68/2; MelodyToSound[lis_] := Module[{m, mt}, If[ListQ[lis], m = lis[[1]]; mt = lis[[2]], m = lis; mt = 1;]; If[m == [Infinity], SoundNote[None, mt*StandardT], SoundNote[EqualTempList[[m]], mt*StandardT, "Guitar"]] ] Sound[MelodyToSound[#] & /@ Melody]// EmitSound
完整的演示音频可以在SoundCloud试听。
还记得在前面我说过数字上方或者下方加点来表示高八度/低八度的音吗?那么具体是怎么回事呢?
首先, 我们所说的音的高低其实是其频率决定的, 例如中音C的频率国际标准定义为440Hz, 即1秒钟震荡440次。我们用正弦波可以非常方便的表示出来:
Sound[Play[Sin[440*2Pi t],{t,0,1}]]
所谓的一个高八度的音就是频率是原来音2倍的那个音, 例如高八度的C, 简谱记为1头上加点, 的频率就是880Hz.而所谓的十二平均律就是说把一个八度平均分成12分(等比地), 每一份就是一个半音。 于是我们很容易得到一个八度中, 12个半音的频率。 例如中音C与高音C这个八度, 其频率表为
所谓的一个高八度的音就是频率是原来音2倍的那个音, 例如高八度的C, 简谱记为1头上加点, 的频率就是880Hz.
八度频率根据7音节的半音/全音(即两个半音)关系, 我们就得到, C调7音节对应的半音如下:
八度频率
音符半音阶个数频率
由此, 不难推出EqualTempList.
参考原文:MA模拟吉他弹奏南山南