声音前沿:Linux 音乐制谱软件,第二部分
上个月我介绍了 ABC 音乐制谱系统。本月,我将继续我们的 Linux 制谱程序之旅,了解作曲家/程序员 Bill Schottstaedt 的 Common Music Notation 系统。
Common Music Notation (CMN) 是一种基于 Lisp 的语言,用于创建和编辑乐谱。它提供了完整的音乐符号和其他乐谱便利功能,例如乐谱尺寸调整和文本衬底。CMN 的输出为 Encapsulated PostScript (EPS) 格式,可由任何兼容 PostScript 的打印机打印。此外,您的输出文件可以使用标准的 Linux PostScript 查看器查看,例如 GhostView 和 GhostScript。
CMN 是一种强大的音乐制谱规范语言。虽然它缺乏鼠标驱动的图形界面,但对于熟悉常用音乐符号(以及一些不太常用的音乐符号)命名约定的用户来说,其语言元素将立即变得熟悉。CMN 能够处理几乎任何制谱要求,包括 20 世纪对标准乐谱符号调色板的许多补充。
要使用 CMN,您必须安装可用的 Lisp 编程语言版本。大多数 Linux 发行版都包含某个版本的 Lisp 作为标准软件包。请查看您的软件包管理软件以确定您的系统上安装了哪个版本(如果有)。大多数 Lisp 版本都应该可以与 Common Music Notation 良好配合,但我推荐 Carnegie-Mellon University Common Lisp (CMUCL),可在此处 获取。同样,请查看您的发行版文档以了解是否有 CMUCL 软件包可用。
接下来,下载最新版本的 Common Music Notation(请参阅“资源”部分)并使用以下命令解压 tarball:
tar xzvf cmn.tar.gz
然后移动到新创建的 $HOME/cmn 目录。调用您的 Lisp 解释器——输入lisp在提示符下应该足够了——然后在 Lisp 解释器提示符下输入以下命令
(load "cmn-all.lisp")
在 Lisp 构建 Common Music Notation fasl(快速加载)文件时,喝一杯您喜欢的饮料。在较慢的机器上首次构建文件时,此步骤可能需要一段时间才能完成。但是,一旦构建了 fasl 文件,后续加载将更快完成。在 CMN 构建并加载其各种文件后,在 Lisp 提示符下输入此命令
(in-package :cmn)
现在您可以尽情使用和享受 Common Music Notation 的全部功能了。
源代码包包含用于构建 xcmnw 的代码,xcmnw 是 CMN 自己的 EPS 文件查看器。xcmnw 不以二进制形式分发,因此您必须自行构建。但是,CMN 不要求您使用 xcmnw,它仅作为在 X 窗口系统下使用 CMN 时自动预览的便利工具提供。
xcmnw 使用 Motif 或 LessTif 图形工具包。这些工具包和其他必需的 X 库是大多数主流 Linux 发行版中的标准软件包。如果您在编译 xcmnw 时收到有关 X 或 Motif 的错误,请查阅您的发行版文档以获取有关安装必要开发软件包的说明。假设您已安装了必需的组件,请打开一个 xterm,进入 CMN 源代码目录并在提示符下运行此命令
gcc xcmnw.c -o xcmnw -I/usr/X11R6/include -L/usr/X11R6/lib -lXm -lXp -lXt -lXext -lX11 -lm
恭喜,您已编译了 xcmnw 查看器。成为 root 用户,然后将 xcmnw 二进制文件复制到 /usr/local/bin 或 /usr/X11R6/bin,以使查看器在系统范围内可用。
加载 cmn-all.lisp 并运行 in-package 命令(见上文)后,Lisp 解释器将准备好处理 Common Music Notation 代码。在解释器提示符下输入此命令
(cmn staff treble c4 q)
此示例创建一个带有高音谱号的单行谱表,并在中央 C 音符处有一个四分音符。要在 X 会话中查看生成的输出文件(名为 aaa.eps,默认输出文件名),请使用 GhostView 等查看器。或者,您可以添加输出类型指示符,以便使用 xcmnw 查看,如下例所示
(cmn (output-type :x) staff treble c4 q)
xcmnw 窗口应该打开,显示如图 1 所示。使用此命令关闭它
(x-close)
务必使用此命令关闭 xcmnw 查看器。如果您使用 X 的“关闭”或“杀死客户端”功能,您可能无法运行后续对 xcmnw 的调用。

图 1. xcmnw 查看器
现在,让我们在基本示例中添加更多音符。在解释器中输入此行
(cmn (output-type :x) staff treble c4 q d4 e e4 e f4 h)
然后 xcmnw 查看器显示如图 2 所示的屏幕截图。

图 2. xcmnw 中更多的活动
您可以随时通过在 Lisp 提示符下输入此命令来保存您的工作
(cmn-store)
默认情况下,文件保存为 hi.cmn。如果您想在保存期间重命名它,请使用此命令语法
(cmn-store *cmn-score* "my_new.cmn")
这是在后续会话中加载 my_new.cmn 的命令
(load "my_new.cmn")
恭喜,您已掌握 Common Music Notation 的基本用法。
对于输入上面的简单示例,如果您不需要查看器,我们可以从 xterm 中的命令提示符或 Linux 控制台工作。对于以下示例,我们使用 Xemacs 文本编辑器。如果您的系统上没有 Xemacs,请查阅您的发行版文档以获取有关安装编辑器的说明。
Xemacs 特别适合与任何基于 Lisp 的系统一起工作。在 Xemacs 中,编辑和评估(Lisp 术语,指运行您的代码)周期要容易得多、速度也快得多,我建议对于任何超出上一节简单示例大小的工作都使用它。
还有一件事:您需要将 此处 找到的代码复制到您的 $HOME/.xemacs/init.el 文件中。请注意,该代码中的可执行文件名特定于 Planet CCRMA 软件包。您应该根据您的系统更改它们。
启动 Xemacs 并使用以下 Xemacs 命令将 CMUCL 加载为“inferior lisp” (ilisp)
<Esc>-x cmucl
现在您可以在 Xemacs 中完全编辑、评估和显示您的 CMN 乐谱。键入或复制并粘贴以下示例代码到 Xemacs ilisp-send 缓冲区中
;;; This code is a slightly altered version of an example from the excellent Common Music Notation documentation. (cmn (output-type :x) (size 40) (system brace (staff treble (meter 6 8) (c4 e. tenuto) (d4 s) (ef4 e sf) (c4 e) (d4 s) (en4 s) (fs4 e (fingering 3))) (staff treble (meter 3 4) (c5 e. marcato) (d5 s bartok-pizzicato) (ef5 e) (c5 e staccato tenuto) (d5 s down-bow) (en5 s) (fs5 e))) (system bracket (staff bar bass (meter 6 16) (c4 e. wedge) (d4 s staccato) (ef4 e left-hand-pizzicato) (c4 e tenuto accent rfz) (d4 s mordent) (en4 s pp) (fs4 e fermata))))
将其另存为 example-01.cmn。现在,按 Ctrl-x-h 选择整个代码块,然后按 Ctrl-c-r 评估所选区域。图 3 显示了评估结果,由 GhostView 显示。
example-01.cmn 中看到的代码说明了 CMN 符合标准音乐制谱术语,使用了制谱符号的通用名称,例如 brace、staff、meter、tenuto、marcato 等等。熟悉标准制谱符号的音乐家应该会发现理解 CMN 乐谱规范文件相对容易。
图 3 还展示了 CMN 出色的音乐符号字体。该系统提供了全方位的音符类型、休止符和其他音乐符号,以及各种乐器演奏技巧指示符。您可以几乎以任何方式自由排列这些符号,这赋予了 CMN 创建非常复杂乐谱的能力,如图 4 所示。
这是(Bill Schottstaedt 编写的)生成图 4 中显示的画面的代码
;;; -*- syntax: common-lisp; package: cmn; base: 10; mode: lisp -*- ;;; This example shows uses of invisible notes (a note with (scale 0 0)) ;;; to attach slurs to, and the dy message to an explicit beam. (cmn (output-file "ghosting.eps") (size 35) (automatic-ties nil) (automatic-rests nil) (system brace (setf stf1 (staff treble (a3 (rq 1/16) (scale 0 0) (setf slur1 (begin-slur (dy0 -.5)))) (cs4 (rq 1/16) (onset 1/16) (setf ib1 (beam- (dy .25))) (setf sl1 (tie-))) (e4 (rq 1/16) (-beam- ib1) (setf sl2 (tie-))) (b4 (rq 1/16) (-beam- ib1) (setf sl3 (tie- (tie-curvature .33)))) (as4 (rq 1/16) (-beam- ib1) (setf sl4 (tie-))) (ds5 (rq 1/16) (-beam- ib1) (setf sl5 (tie- (tie-direction :down)))) (g5 (rq 1/16) (-beam- ib1) (setf sl6 (tie- (tie-direction :down)))) (as5 (rq 1/16) (-beam- ib1) (setf sl7 (tie-))) (d6 (onset .5) (scale 0 0) (end-slur slur1)) (chord (notes (c4 (-tie sl1)) (e4 (-tie sl2)) (a4 (-tie sl3)) (b4 (-tie sl4)) (d5 (-tie sl5)) (g5 (-tie sl6)) (a5 (-tie sl7))) h (onset .5) stem-down (diminuendo (onset-offset .25) (duration 1.25))) (cs4 e (onset (+ 2.5 .25)) stem-down begin-beam) (cn4 s (onset (+ 2.5 .75)) stem-down end-beam (begin-tie (tie-direction :down))) (c4 q (pp (dy -.75)) stem-down end-tie))) (staff treble (tied-to stf1) (eighth-rest (scale 0 0)) (d6 begin-beam stem-up s) (cs6 s stem-up (begin-slur (slur-direction :up))) (ef6 s stem-up) (cn6 end-beam s (begin-tie (tie-direction :up)) stem-up) (c6 q stem-up end-slur end-tie) (d4 s begin-beam (begin-slur (slur-direction :up))) (cs4 s) (ds4 s) (cn4 s end-beam end-slur) (fs4 s. begin-beam (begin-slur (slur-direction :up))) (dn4 (rq 1/8)) (d4 e end-beam end-slur)) (setf stf2 (staff (dy -1.0) bass (a3 e stem-down (begin-tie (tie-direction :down) (tie-curvature .25))) (a3 h end-tie) (sixteenth-rest (onset 1.5)) (fs3 s (begin-beam (dy .25)) stem-up (onset 1.75) (begin-slur (slur-direction :up)) (setf sl8 (tie- (tie-curvature .25)))) (es3 s stem-up (onset 2.0) (setf sl9 (tie- (tie-direction :down)))) (g3 s end-beam (onset 2.25) end-slur) (chord (onset 2.5) (notes g3 (f3 (-tie sl8)) (e3 (-tie sl9))) q. stem-down))) (staff bass (tied-to stf2) bar (a3 (rq 1/16) stem-up (-beam ib1)) (fs3 e no-beam (onset 1.75) (begin-slur (dy -.25) (slur-direction :down))) (es3 e no-beam (onset 2.0)) (g3 q stem-down (scale 0 0) end-slur))))
研究此代码的流程揭示了其逻辑。声明了渲染大小,然后是一些配置指令。然后,谱表被括起来并定义——stf1 和 stf2,高音和低音。其余代码定义了音高、时值、连线、符杠和乐句。
给 GhostView 用户的提示:您可以在生成新版本的工作时调用查看器来更新自身。以下是我启动 GhostView 以自动更新 example-01.cmn 的方式
gv -watch ghosting.eps &
现在我可以更改我的代码并重新评估它,正在运行的 GhostView 实例会自动显示更新后的输出。
CMN 已经开发多年,因此几乎没有什么可批评的。对于新用户来说,主要的缺点可能是它缺乏图形界面,但更有经验的用户可能会认为这种缺乏更像是一种祝福(请参阅本系列文章的第一篇)。用户还必须了解 CMN 是制谱的“最后阶段”。也就是说,它的输出文件仅为 EPS 格式,并且没有用于将 CMN 输出转换为 MIDI 或任何其他格式的实用程序。
图 4 很好地展示了 Common Music Notation 的灵活性。但是,我们这里的示例仅仅触及其可能性的皮毛。CMN 允许您衬托文本、着色符号、添加新图形并广泛自定义乐谱的外观。它还与 CCRMA“Common”软件家族的其他成员接口,包括 Common Music 作曲环境和 Common Lisp Music 声音合成语言。提供了广泛的基于 HTML 的帮助,并且源代码包中包含许多示例。此外,如果您遇到问题,可以在活跃的 CMN 邮件列表中联系程序员 Bill Schottstaedt。他会很快帮助您解决您可能遇到的任何他称之为“简单小技巧”的困难。
Dave Phillips 是一位音乐家、教师和作家,居住在俄亥俄州芬德利。自 1995 年首次接触 Linux 以来,他一直是 Linux 音频社区的活跃成员。他是 The Book of Linux Music & Sound 的作者,以及 Linux Journal 中的众多文章的作者。