使用一套基于简谱(想必都熟悉,所以不贴wiki链接了)和TeX的标记语言生成MIDI文件。
这个想法最初来自一个播放简谱的Mathematica程序,输入的格式很类似,因为简谱很容易转化成ASCII字符串。这个程序是很早以前我的一个同学在一个论坛上发现的,但现在找不到了。在此感谢该程序的作者。
目前输出的MIDI文件为格式1。
quick-midi <输入字符串> [选项]
或
quick-midi -f <输入文件> [选项]
下面详细介绍输入字符串和输入文件的内容的格式。
首先来看一些例子:
两只老虎:
1231 1231 345- 345- {5654}_31 {5654}_31 15.1- 15.1-
C大调卡农片段:
5{34}_5{34}_ {55.6.7.1234}_ 3{12}_3{3.4.}_ {5.6.5.4.5.17.1}_ 6.{17.}_6.{5.4.}_ {5.4.3.4.5.6.7.1}_ 6.{17.}_1{7.6.}_ {7.1217.16.7.}_ 1---
新年好
1
更多的例子在examples/
目录下。
输入包含多个音轨,每个音轨包含多个声部,声部中为音符序列。音轨和声部都以相应的命令开始,命令中需要给出它们的名字。
[文件选项]
\track{<音轨名>}
[音轨选项]
\v{<声部名>} ... <音符序列> ...
\v{<声部名>} ... <音符序列> ...
\track{<音轨名>}
\v{<声部名>} ... <音符序列> ...
\v{<声部名>} ... <音符序列> ...
...
和TeX一样,命令都是以\
开头的。每个音轨都是单独的通道。当一个音轨或声部第一次出现时就会被创建,之后再次出现就会将该音轨或声部中的音符序列追加到已有的上面。这样就使得可以把一个音轨和声部分成多个部分,增加了可读性。
文件选项和音轨选项部分为一些可选的命令,用于定义MIDI和音轨的各种参数。
为了简便,第一个音轨和每个音轨中的第一个声部的开头命令可以省略,此时它们会被自动命名为Track 1
和1
。所以只包含一个单独的音符序列的输入也是合法的,就像上面的几个例子一样。
音符序列由音符、序列组以及命令组成。每个音符后面可以跟一些修饰符来修改它们的长度和音高。一个音符为数字0到7,其中0为休止符,1到7为自然音阶中的7个音符,和简谱一样。音符1的音高由调号决定,默认为C大调,第四个八度,即1 = C4,可以被命令修改。一个音符如果没有修饰符,那么就为四分音符。
修饰符位于一个音符之后。_
将音符长度减半,n个连续的-
和*
分别将长度增加n和(1 - 1 / 2^n)倍。也就是说这三个修饰符分别相当于简谱中的下划线、横线和附点。另外,为了能表示n连音,增加了修饰符/
,n个/
将音符长度除以(n + 1)。如果有多个这样的修饰符,对音符的总影响为它们的积。下面是一些例子:
- 全音符: 1---
- 二分音符: 1-
- 附点二分音符: 1-- 或 1-*
- 四分音符: 1
- 三连音:1// 2// 3//
- 附点四分音符: 1*
- 八分音符: 1_
- 十六分音符: 1__
音符的长度单位为刻,一个整数。对于四分音符,它的长度等于MIDI文件的division值,该值默认为96,可以通过\div
命令来修改。当一个音符的长度达到允许最小值1或最大值0x7fffffff(虽然不太可能发生)时就会被切断在极限值处。为避免其发生应该在需要的时候修改division的值。
另一种修饰符会改变音高。'
和.
分别将音符升和降八度,#
和b
分别升和降半调。MIDI允许的最低音和最高音分别为C-1(C大调中为1.....
)和G9(C大调中为5'''''
),当音高达到这两个极限值时同样会被切断。
力度是音符的又一个参数。音符被创建时将会被赋予的力度值默认为80,可以用\vel
命令修改。
竖线|
可出现在序列中的任何位置,但相当于虚词,无实意,只是为了增加可读性,如分隔小节。
序列组同样是序列中的元素。一个组即一串用逗号,
隔开并且用{}
包围起来的序列:
{ <序列> [, <序列>]* }
序列组中的各个序列相当于属于一些同时开始的不同声部,会被同时播放,这就提供了一种简单的表示和弦的方式。比如C和弦可以表示为{1,3,5}
。一个组的长度等于组中长度最长的序列的长度。
序列组同样可以跟修饰符,此时这些修饰符会影响组中的所有音符。比如{1231}_
和1_2_3_1_
是等价的。
组同样也是一些命令的作用域。
命令的格式和TeX很类似,命令的参数可以是一个字符或被{}
包围的字符串。所以当参数是不止一个字符的时候应使用{}
括起来,比如应写\bpm{200}
而不是\bpm 200
。
一些命令的作用只在作用域中有影响,当离开作用域时相关的参数就会回到父级作用域的值上。会使得命令的作用进入新作用域的组成部分包括序列组和声部。注意一个声部是一个单独且连续的作用域,即使被分成了多个部分。比如,在下面这个输入中
\v{1} \vel{100} 1
\v{2} \vel{70} 1.
\v{1} ... 2
\v{2} ... 2.
1
和2
的力度为100,而另外两个的为70。
命令可以出现在文件选项、音轨选项、以及音符序列中。命令的用法及功能如下:
\tempo <速度值>
:设置速度值,即每四分音符多少毫秒。可以出现在文件选项和序列中。此命令会产生一个设置速度值的元事件。\bpm <拍每分>
:通过指定每分钟多少拍来设置速度值。这是更常用的设置速度的方法。\track <音轨名>
:开始编辑给定名称的音轨。如果该音轨不存在则会被创建。\v <声部名>
:开始编辑给定名称的声部。如果不存在就会被创建。\instrument <乐器编号>
:设置或改变音轨的乐器,可出现在音轨选项和序列中,会产生一个程序(乐器)改变事件。乐器编号和乐器的对应关系可在MIDI文件说明上查得。\times <分子> <分母>
:设置或改变拍号,可出现在文件选项和序列中。这个命令会产生一个拍号改变的元事件,在需要将输出的MIDI文件导入到其他软件时可能有用,但对播放没有影响。\div <division的值>
:设置division的值。只能出现在文件选项部分中。\major <调名>
,\minor <调名>
:用大调调名或小调调名设置或改变调号,可出现在文件选项和序列中。调名中的#
和b
应出现在调名字母的后面。这个命令不仅会产生一个调号改变的元事件,而且会改变该作用域中之后1的音高。有效的调名如下图所示。\vel <力度值>
:设置或改变该作用域中音符被创建时的力度值。
和TeX一样,在输入文件中的任何地方可以用\def
定义宏并使用。但由于#
已被用作升半调的符号,宏参数的字符被改为了$
。如果对TeX不是很熟悉的话,定义宏的格式为\def\<宏名><参数列表>{<宏内容>}
,其中宏名只能由字母组成,参数列表是包含宏参数的字符串。下面是使用宏的例子:
\def\repeat$1{$1$1}
1155665- 4433221- \repeat{5544332-}
宏展开后序列应为1155665- 4433221- 5544332- 5544332-
MIT.