本文要介绍 R 包 gm,你可以用它来生成音乐。
具体来说,gm 有三大特点:
- 它设计了一套非常简单的语言,你可以用这个语言来描述音乐。
- gm 会将你的描述转化成乐谱和音频,你几乎不需要考虑记谱的技术细节。
- gm 可以在 R Markdown 文档或 R Jupyter 笔记本里自动将乐谱嵌入生成的文档中。
先来看一个简单的例子。
小例子
# 加载 gm
library(gm)
# 创建 Music 对象
m <-
# 初始化 Music 对象
Music() +
# 加上 4/4 拍号
Meter(4, 4) +
# 加上一条包含四个音的声部
Line(list("C5", "D5", "E5", "F5"), list(1, 1, 1, 1))
# 转化成乐谱和音频
show(m, c("score", "audio"))
相信这个例子足够让你感受 gm 的简单和直观。深入之前,先来看看如何下载。
下载与设置
从 CRAN 上下载:
install.packages("gm")
从 Github 上下载开发版:
# 请先下载 devtools
# install.packages("devtools")
devtools::install_github("flujoo/gm")
你还需要安装 MuseScore,它是一款开源免费的打谱软件。
MuseScore 有默认的安装路径,如果你安装到其它路径,请在 .Renviron 文件中设置:
- 打开 .Renviron 文件。可以用命令
file.edit("~/.Renviron")
。 - 在其中加入
MUSESCORE_PATH=<MuseScore 可执行文件的路径>
,比如MUSESCORE_PATH="C:/Program Files (x86)/MuseScore 3/bin/MuseScore3.exe"
。 - 重启 R。
深入一点
使用 gm 时,我们通常需要初始化一个 Music
对象:
m <- Music()
我们可以直接打印它来查看它的结构:
m
#> Music
在这个空的 Music
对象之上,我们可以加上其它的成分。比如加上拍号:
m <- m + Meter(4, 4)
m
#> Music
#>
#> Meter 4/4
加上声部:
m <- m + Line(pitches = list("C5"), durations = list("whole"))
m
#> Music
#>
#> Line 1
#>
#> * as part 1 staff 1 voice 1
#> * of length 1
#> * of pitch C5
#> * of duration 4
#>
#> Meter 4/4
当然,更直观的方式是将其转化成乐谱查看:
show(m)
gm 的语法有点像 ggplot2,你可以不断添加新的成分,然后查看,然后再添加,不断反复。
我们还可以加上拍速记号:
m <- m + Tempo(120)
show(m)
加上新的声部:
m <- m + Line(
pitches = list("C3", "G3"),
durations = list("half", "half")
)
show(m)
这个过程可以继续,但我们在此打住。你可以查看完整的文档解锁所有功能。
与其它包的比较
在 R 中,我所知的有类似功能且较为成熟的包只有 tabr. 但两者依然有明显的区别:
- gm 仅用来生成音乐,而 tabr 除了生成音乐,还可以分析音乐。
- 就生成音乐来说,gm 更关注高阶地描述音乐,而 tabr 更关注记谱,比如它可以生成吉他谱,并且支持更多的记谱功能。
- gm 直接将生成的音乐嵌入在 R Markdown 文档或 R Jupyter 笔记本中,tabr 则需要导出查看。
- gm 使用 R 的基本数据结构来表征音乐结构,比如向量和列表,而 tabr 则使用字符串。
- gm 的语言更简单直观,结合上面这点,gm 更适合音乐编程。
Python 有一个非常成熟的库 music21,它提供了非常丰富的工具用来分析和生成音乐。就生成音乐的功能来说,music21 能生成相对更加专业的乐谱,同时支持在 Python Jupyter 笔记本中嵌入生成的音乐。 相比之下,gm 的优势依然是更为简单的语言。比如,在 music21 中,
- 创建音符并组合成旋律线的过程非常繁琐笨重,
- 用户有时候必须关注乐谱的技术细节,哪怕他们只想高阶地描述音乐结构,
- 处理复杂的连音时不够直观。
自动作曲
gm 的一个有趣的应用是算法作曲,也就是用算法来生成音乐。下面是一个例子:
pitches <- as.list(c(64, 65, 69, 71, 72, 76))
durations <- rep(list(1), length(pitches))
m <- Music() + Meter(4, 4) + Tempo(120)
for (i in 0:8) {
m <- m + Line(pitches, durations, offset = 0.5 * i)
}
show(m, to = c("score", "audio"))
上面的代码生成了九条声部,所有声部的音符都是相同的,区别是每条声部加入的时间都比前一条声部慢一点,因此形成了有趣的回音效果。
从这个例子你也可以感受到,gm 利用 R 的基本数据结构来表征音高和时值,语法简单,非常适合用编程的方式产生音乐。
总结
综合来说,gm 的优点是,语言高阶简单,并且适用于常见的 R 工作环境,方便传播生成的音乐。 而如果你想要专业级别的记谱软件,gm 目前还不够。 但在之后的版本中,gm 会实现更多的功能,包括添加乐器、力度记号等。
如果你喜欢 gm 可以在 Github 上点赞。有任何建议或分享,也欢迎联系作者。