动听的代码:音乐编程语言Alda

什么是Alda?

Alda是一种强大灵活的音乐编程语言,只需要在编辑器中写一些代码,然后通过软件将其编译成声音,就可以产生各种风格的音乐。它的作者Dave竭尽所能来让这门语言简单易用,对初学者友好。Alda的目标之一就是让编程经验不多甚至没有编程经验的人试用其进行创作。通过它的口号——为音乐家设计的一门音乐编程语言——也能看出它传达出的对无编程经验者友好的价值理念。

尽管Alda语法的目标是至简易用,但是扩展性依然很好,提供给用户的自由度很高。通过音乐编程的方式来带给作曲家最少的限制,或许可以激发创作潜能,这也是作者的一个心愿。

目前,Alda可以使用通用乐器数字接口中的所有乐器来创作曲谱。在不久的将来,Alda将会支持从基本声波、音乐文件中的片段或者其他形式的声音来合成音乐。Dave的初衷是,让所有的程序员和非程序员都可以轻松地创作各种形式的音乐,从古典乐到8位音乐到实验音景——只需要通过一个编辑器和Alda解释器。

这篇文章将会介绍如何安装并使用Alda写一些基本的乐谱。但开始之前,我们要先来了解一些历史。

UNC和MML

Alda的起源可以追溯到2004年。那时Dave在北卡罗来纳大学学习作曲和电子乐的创作方式。他尝试了FruityLoops但是没有什么进展。后来,开始沉迷于音乐编程的世界。敲门砖就是MML,在当时(可能现在依然是)那是创作任天堂的8位数字音乐最佳的方式。读了NullsleepMML指南并开始学习如何创作基本的任天堂音乐之后,Dave就沉迷于凭直觉创作音乐当中。但那时候一颗音乐编程的种子也在他的心里悄悄埋下了。

MML对Alda的影响很大。Dave很痴迷在文本编辑器中创作音乐的过程,但是他想将音乐变成扩展到更广泛地领域中去,他想取代通过MML创作音乐的方式并将其应用到音乐合成、电子乐甚至是古典音乐中去。

古典音乐?

Dave在成为一个职业的程序员之前,他所受的音乐教育使他对各种各样创作音乐的形式产生了兴趣。生活在计算机文化氛围浓厚的环境中,Dave也尝试过使用图形界面的程序来作曲,比如用过Guitar Pro来写吉他谱,对于传统的音乐谱子,他还尝试过CakewalkNoteworthy ComposerFinaleSibelusMuseScore等等。

其中,Sibelius用的比较多,这款软件可以生成乐谱的数字版本,从而得到每一种乐器的乐谱,不同的音乐家就可以方便地了解自己所负责演奏的部分。这个功能非常实用。

像Sibelius这样的音乐谱曲软件对专业的作曲家来说是一种重要的工具。然而对于同样是作曲家和程序员的Dave来说,这种GUI音乐谱曲软件存在很多局限性:

容易使人分心

在软件普及之前音乐是写出来的,所有的科技就是纸和笔。乐谱的布局、音符等等各种东西都是产生自大脑而流于笔尖。但是使用图形界面程序的时候,要选择一个音符就要在一层一层的菜单中查找,注意力就这样被转移了: 1. 找到你想要的东西很不便捷,当你找到的时候,灵感已经走了; 2. 所有的音符都列出来供你查找同样让人分心,Dave使用Sibelius的时候就常常在长时间寻找音符的时候走神。

相比之下,使用文本编辑器编程来创作音乐的方式可以更让人集中尽力。

限制太多

Dave认为作曲家所需要的创作环境应该回归根本——从一张白纸开始。还要可以借助于21世纪科技的力量,电脑应该可以解释乐谱并转化成音频以查看效果。如果可以方便地转化成传统的乐谱供音乐家阅读就更好啦。

图形化的作曲软件在当下已经做得不错了,不过他们走了捷径——跳过了“从白纸开始”。当然,如果你用Sibelius从头开始创作,看起来也像是从白纸开始,但是却比物理上的手稿纸差的多。你不能拿起笔来就开始写下心中的灵感,那些图形界面背后隐藏的数字限制住了你。

所有图形化的音乐编辑器都走了这种捷径。为了将你心中的音符表现出来,这些限制是必须的。音乐编程语言同样有这种限制(从某种意义上说这是所有的软件都避免不了的),但是因为它的可视化需求不高,也不需要维持一个图形用户界面,这种限制就小得多,降到了可以接受的范围之内。Dave作为一个作曲家,觉得这恰到好处,令人鼓舞。

安装

注意:由于Alda还在开发中,所以必须按照下面的过程来安装和运行,Dave尽可能将这些步骤设计的直观,如果发生问题可以通过电子邮件来联系他。相信在将来,Alda一定会更加简单易用。

开始安装之前,你需要两个工具:

  • Clojure的编译工具Boot。如果你的操作系统是Mac OS X,可以选择使用Homebrew安装,命令是brew install boot-clj。其他平台的安装方式可以查看这里
  • Alda执行文件,可以将下面的代码复制到终端运行安装:

现在alda命令行工具就已经安装好了。它可以解释和播放Alda文件,或者接收一行Alda代码来作为命令的参数。你也可以通过Alda的REPL(Read-Evaluate-Play Loop,阅读、评估、播放循环)来迭代创作乐曲。

Alda 101

我们先来通过Alda的REPL来体验一下Alda的语法吧,通过下面这个命令可以在命令行启动REPL:

注意:Alda使用了一个叫做FluidR3的音色库使MIDI听起来更舒服,首次启动的时候需要花几分钟下载一个125M的文件,如果不愿意下载这个文件可以使用alda repl --stock命令使用Java虚拟机内建的MIDI合成器(效果很糟糕)。

FluidR3下载完成之后,你将会看到下面这样的界面:

现在你就可以尝试在REPL中输入一些Alda代码了,按下回车就可以立刻听见效果。

上文已经提到,MML和LilyPond对Alda的影响很大,尤其是它们简单的语法。下面将会描述它们像MarkDown一样简单的语法,基本上可以达到所见即所得的效果。

音符

先从简单的开始,将下面这个形式的乐谱改写成Alda代码:

一共有四个音符:C,D,E,F.相应地Alda代码是:

试着在REPL中输入然后按下回车……什么都没发生对不对?因为没有指定乐器呀!先用钢琴来试试:

这次你应该听到钢琴弹奏的这四个音符了。你会发现提示符从>变成了p>ppiano的缩写,表示目前的乐器是钢琴,除非做出更改,否则接下来的代码都会以钢琴播放。

音阶

让我们来试试更多的音符。

你应该注意到了钢琴声从C大调持续上升。>在Alda语法中表示下一个音阶上升。在科学音调符号中音阶从C大调开始上升至B,一旦超过B,就在一个新的音阶上重新从C开始。在Alda中,每一种乐器都从音阶4开始,知道你告诉它改变音阶它才会变。改变音阶有两种方式:使用><来提高或降低音阶;或者使用o接一个数字直接指定一个音阶。如下例:

变音记号

音调升高或降低可以在后面加+或者-号。

连续使用两个升/降调也可以:

事实上,音符和升/降调在Alda中可以随意组合,虽然两个以上的升/降调没有什么用,但是语法中也没有强制制止这种行为:

上面是代替E调的不必要且笨拙的做法。

音符长度

Adla中音符的默认长度是1/4,可以通过在音符后面接数字来改变,数字代表音符长度类型,例如4代表1/4音符,8代表1/8音符,16代表1/16音符等。当你指定了一个音符的长度之后,接下来的音符都会默认使用这个长度。

上例中使用了|符号。这个符号用来分隔两段音乐,在Alda语言中是可选的,编译器会忽略这个符号。|的作用是让程序可读性更高。

休止符

休止符在Alda中和音符差不多,类似于“听不见”的音符。休止符用r表示。

附点音符

Alda也支持附点音符,使用方法是在音符长度后面加.,可以加一个或多个。

连接符

通过连接符可以将两个音符连接在一起,Alda中的符号是~

和弦

在同一时间用一种乐器演奏不同的音符,这就是和弦。在Alda中,和弦用/分隔多个音符来表示。

注意,就像连续的音符一样,指定了一个和弦的音符会影响后面的音符的长度。

在Alda里一个和弦中不需要所有的音符都用一个长度,这个特性使创作音乐时和弦的使用非常方便。

在和弦中也可以使用><来改变音阶,这样描述和弦的升降音就很方便了。

声部

Alda中多音符同时演奏的另一种表现方式是声部。上面用和弦表达的例子也可以组合和弦和声部来表现:

退出REPL,只需要键入bye然后回车。

写一章乐谱

刚刚,我们已经在Alda里尝试了一些代码,并且听到了效果。这种方式在确认一段音乐之前测试片段非常有用,当确认了曲调的时候,就该把它们写成乐谱了。

在Alda中,乐谱就是文本文件,你可以使用任何你喜欢的文本编辑器来写。按照约定,文件名应该使用.alda结尾。在终端的当前文件夹下建立一个新文件,并命名为test.alda来试一下吧。

然后在文本中键入以下内容:

运行alda play --file test.alda,你将会听到优美的巴松管曲调。

属性

你可能会发现在这里用到了新的语法,下面就解释以下这部分。(quant XX)(XX的范围是0-99)是改变音符的长度,但是不改变它的持续时间。数值表示的是听到的音符长度的百分点。当你听到上面的音乐的时候,F音符和G音符(调整至30%)很短而且是间断的,最后的A音符(调整至99%)就很长而且是连续的。

quant(quantization的缩写)是一种可以在Alda中设置的属性。volume也是一种属性,可以设置音符的声音。像大多数的属性一样,volume(也可以写作vol)的取值也是0-100.可以通过逗号分隔多种属性。

试一下编辑test.alda如下:

运行alda play --file test.alda你将会听到前两个音符和后三个音符的不同。

说句题外话,你可能会发现每次运行alda命令都会等上一段时间。这是选择使用Clojure的一个坏处:Clojure有一个众所周知的毛病就是启动很慢。你也可以通过REPL来测试——只要启动一次,之后的使用中就不会受到影响了。

在不久的将来,Alda会实现提前编译,单独运行,速度将会得到提升。

乐器合奏

终于,到了最好玩的地方了:写多个乐器合奏的乐谱。

Alda乐谱支持无限多的乐器同时合奏,可以在test.alda文件中尝试下面的代码:

在这里两种乐器是单独谱曲,小号和长号,但是当播放乐谱的时候,两种乐器会同时和谐地一起演奏。

也可以一次只写一部分,像下面这样:

这段代码和上面的例子效果完全一样。值得一提的是,当你切换成另一种乐器的时候,之前使用的乐器部分依然存在,只不过处于一种“暂停”的状态,当你切换回来的时候,可以从上次的地方继续写。

全局属性

上文中介绍了改变volume属性,tempo(节奏)是另一个可以改变的属性,下面就来试一下:

听见了吗?小号的声音变成了200bpm的速度,但是长号依然没有变,是默认的120bpm。这不是bug,而是一项特性。Alda中tempo是基于每一项乐器来设置的,这样就可以给两件乐器设置不同的节奏。

设置全局属性可以更改所有的乐器设定,方法如下:

tempo!属性通过加一个!改变全局乐器的节奏,可以试一下(tempo! 200)等。

标记

接下来要介绍的是Alda的特殊功能——它可以使乐器完美的互相配合。

标记的概念是,给一个音乐段标注一个名字。名字可以包含数字、字母、撇号、破折号、加号、圆括号,前两个符号必须是字母。下面是一些合法的例子:

  • chorus
  • voiceIn
  • last-note
  • verse(2)
  • bass+drums

使用标记功能需要两步。第一步,在一个名字的开头加一个%给音乐段命名;第二步,使用@接名字来将乐器插入这个音乐段。如下例,可以将大号(tuba)插入到小号(trumpet)的last-note部分。

到这里,目前Alda的所有功能就介绍完了,如果有任何问题和建议通过邮件来和Dave联系。这个项目是开源的,如果你是一个Clojure程序员,可以通过PR来贡献代码

Leave a comment

电子邮件地址不会被公开。 必填项已用*标注