Skip to content

Muse 乐谱数据结构解析

前言

本文提出了一个支持 Muse 乐谱语法的数据结构方案。该方案以 abcjs 的 abc 乐谱数据结构为基础进行了部分优化,并扩展支持了 Tab 谱(六线谱、四线谱)与简谱。

一、描述信息

乐谱的元信息包含标题、副标题和作者等字段,对应关系如下:

主标题

语法:T: 单身情歌   (第一个 T 字段)
字段:metaText.title

副标题

语法:T: 演唱 林志炫  (第 n 个,n ≥ 2)
字段:metaText.subtitle

作者

语法:C: 陈耀川
字段:metaText.composer

当有多个 C 字段出现时,所有作者信息在 composer 字段中以换行符分隔。

二、调号、拍号和速度

调号

语法:K: C
字段:key
json
{
    "acc": "",          // 升降调(# / b)
    "accidentals": [],  // 忽略
    "mode": "",         // 忽略
    "root": "C"         // 调名
}

拍号

语法:M: 3/8
字段:meter
json
{
    "type": "specified",
    "value": [
        { "num": "3", "den": "8" }
    ]
}

速度

语法:Q: 1/4=120 "Slowly"
字段:metaText.tempo
json
{
    "bpm": 120,
    "duration": [0.25],
    "postString": "Slowly"
}

上面的例子表示:一分钟演奏 120 个四分音符,速度标记为 "Slowly"。

三、音符与和弦

完整数据结构

一个音符节点位于 staffs[i].voices[i] 数组中,其完整结构如下:

json
{
    "chord": [
        {
            "name": "C/E",   // 和弦名称,查询和弦表
            "position": ""   // 忽略
        }
    ],
    "duration": 0.0625,      // 音长
    "el_type": "note",
    "pitches": [
        {
            "fret": 1,           // 品数,或者 'x'
            "string": 5,         // 第几弦:{a:1, b:2, c:3, d:4, e:5, f:6}
            "pitch": 2,          // 简谱使用
            "accidental": "sharp" // 升半音:sharp,降半音:flat
        }
    ],
    // 多个 pitches 时表示和声,需在同一谱线上绘制
    "startBeam": true,    // 连音符开始
    "endBeam": true,      // 连音符结束
    "startSlur": [],      // slur 开始
    "endSlur": [],        // slur 结束
    "startTie": [],       // tie 开始
    "endTie": [],         // tie 结束(与 startTie 配合使用)
    "startTriplet": 0,    // 连音开始标识
    "endTriplet": true,   // 连音结束标识
    "tripletMultiplier": 0.6667, // 每个音的音长倍数
    "decoration": ["staccato"]   // 装饰音列表
}

说明:

  • tie 表示相同音高的延音线
  • slur 表示两个不同音高之间的连音线
  • triplet 表示三连音、n 连音等,在音长计算上较为特殊

3.1 音高

四线谱 / 六线谱(Tab 谱)

json
{
    "fret": 1,    // 品数,或者 'x'(表示不弹)
    "string": 5   // 第几弦:{a:1, b:2, c:3, d:4, e:5, f:6}
}
  • a 对应谱线最上面的一根弦,以此类推。
  • 如果是扫弦或琶音,只需关注最上面和最下面的弦即可。

简谱

在 Muse 中,中央 C 代表简谱的 1,小写 c 代表高八度的 1C' 表示低八度的 1,依此类推。

音从低到高的顺序与五线谱一致:

C'', C', C, c, c', c''

各音名对应 pitch 字段的编码值:

json
{
    "A": 5,  "B": 6,  "C": 0,  "D": 1,  "E": 2,  "F": 3,  "G": 4,
    "a": 12, "b": 13, "c": 7,  "d": 8,  "e": 9,  "f": 10, "g": 11
}

八度推算规则:

  • C' = C(0) - 7 = -7
  • c' = c(7) + 7 = 14
  • 依此类推……

变音记号

示例:^b1

符号名称含义
^sharp升半音
=natural还原音
_flat降半音
^^double sharp升全音(暂不支持)

3.2 音长

默认音长:L: 1/4

音长修饰符的含义:

写法含义
//2默认音长的 1/2(0.5 倍)
//默认音长的 1/4(0.25 倍)
2默认音长的 2 倍
>前付点:前音 ×3/2,后音 ×1/2
<后付点:前音缩短,后音延长

示例:

弹唱谱:c1/, c1/2, cx//, a2*2
简谱:  A/, C//, c1

弹唱谱需要表示把位,因此用 / 表示倍减,* 表示倍增。

音长计算公式:

音长值=默认音长×音长倍数

3.3 和弦图

所有和弦(包括默认和弦)存储在全局的 gchords 和弦表中。若某和弦不在和弦表中,则仅绘制和弦名称文字即可。

语法:

%%gchord <和弦名>=<起始品数>;<第n弦品位>(手指),<第n-1弦品位>(手指),...<第1弦品位>(手指)

示例:%%gchord C=1;X,3,2,0,1,0

其中,手指编号为可选项,X 代表和弦外音(不弹该弦)。

数据结构:

json
{
    "name": "C",
    "chord": [
        [1, 0], [2, 1], [3, 0], [4, 2], [5, 3], [6, "X"]
    ],
    // 每项格式:[品位, 手指],数组下标按弦从上到下(从粗到细)
    // "X" 代表和弦外音
    "position": 3,  // 起始品数(可选,无此字段则不需绘制位置标记)
    "bars": [
        { "from_string": 5, "to_string": 1, "fret": 1 }
    ]
    // bars:大横按信息(扩展字段,无声明则不绘制)
    // from_string:起始弦,to_string:结束弦,fret:相对 position 的品数
}

3.4 装饰音

装饰音符号添加在音符前面

示例:u[b1*2-e3/]

符号名称含义
.staccato断音、切音
Vupstrum上扫弦
Udownstrum下扫弦
Auparpeggio上琶音
Bdownarpeggio下琶音
'accent加重音
Ttrill颤音
Hfermata延长音(停顿)
Ppralltriller短颤音

3.5 倚音

倚音同样添加在音符前面,使用花括号包裹。

示例:{a1b1}[c2//d2//]

倚音的数据结构与普通音符完全相同:

json
{
    "accidental": "sharp",
    "duration": 0.5,
    "el_type": "note",
    "pitch": 12,
    "fret": 1,
    "string": 1
}

3.6 连音(二连音、三连音、n 连音)

语法:

简单连音:(n
示例:(2aC1

复杂连音:(p:q:r
示例:(3:2:4G2A2B1

数据字段:

字段含义
startTriplet连音开始标识
endTriplet连音结束标识
tripletMultiplier每个音的音长倍数

3.7 休止符

表示符号:zZ,音长写法与音符相同。

  • z:普通休止符(rest)
  • Z:多小节休止符(multimeasure),暂不支持

3.8 连音线(滑弦、敲弦、勾弦)

Tie(延音线) — 连接相同音高,表示延音:

ex-ex
[^b1*2-e3/]-S-[b2*5/2e4*5/2]

Slur(连线) — 连接不同音高,表示连奏,可以嵌套:

((a3b2d2)b1)

四、小节线与重复线

数据结构:

json
{
    "el_type": "bar",
    "type": "bar_thin",     // bar 类型
    "startEnding": "",      // 重复段落数字及开始标志
    "endEnding": "",        // 重复结束标志
    "barNumber": ""         // 忽略
}

常见小节线类型示意:

类型名符号示意说明
bar_thin|普通小节线
bar_thin_thin||双细线(段落分隔)
bar_thin_thick|]终止线(细线 + 粗线)
bar_thick_thin[|开始线(粗线 + 细线)
bar_left_repeat|:左重复线
bar_right_repeat:|右重复线
bar_dbl_repeat::双重复线
bar_invisible[:]隐形小节线(仅用于换行)

五、歌词

英文歌词以空格断字,中文歌词以单字断字。

符号含义
-英文单词断开(连字符)
*跳过一个音符
~连接两个字,对齐同一个音符

参考资料

  1. abcjs:用于渲染 abc 乐谱记谱法的 JavaScript 库。
  2. Muse 2.7 制谱软件帮助文档。

本文初发于2018年,当时在研究吉他谱在网页上渲染的相关技术,重新发表在这个新博客上,仅作记录。

评论