#music #language #command-line-tool #macro #lmml

app lmml-cli

LMML的命令行工具

8 个版本 (5 个重大更改)

0.5.1 2024年5月12日
0.5.0 2023年11月17日
0.4.1 2023年11月17日
0.3.0 2023年11月17日
0.0.0 2023年11月8日

#399 in 音频

Download history 178/week @ 2024-05-11 15/week @ 2024-05-18 1/week @ 2024-05-25 1/week @ 2024-06-08 1/week @ 2024-06-29 4/week @ 2024-07-06 74/week @ 2024-07-27

每月 78 次下载

MIT/Apache

75KB
972

LMML

GitHub Actions Workflow Status

LMML(LMML Music Macro Language)是MML的方言。

演奏示例

https://github.com/yuma140902/lmml/assets/23431077/dfad8777-ade5-4591-8804-a3968a2e14ea

; Bad Apple!! feat. nomico

t320 l4

@0 v15
<ab>cd e.r8ag e.r8<a.r8> edc<b>
<ab>cd e.r8dc <bab>c <bagb>
<ab>cd e.r8ag e.r8<a.r8> edc<b>
<ab>cd e.r8dc <b.r8>c.r8 d.r8e.r8

@1 v10
<ab>cd e.r8ag e.r8<a.r8> edc<b>
<ab>cd e.r8dc <bab>c <bagb>
<ab>cd e.r8ag e.r8<a.r8> edc<b>
<ab>cd e.r8dc <b.r8>c.r8 d.r8e.r8

@3 v25
gaed e.r8de gaed e.r8
dedc <bga.r8 gab>c de<a.r8>
egga ede.r8 dega ede.r8
dedc <bga.r8 gab>c de<a.r8>

@4 v30
egga ede.r8 dega ede.r8
dedc <bga.r8 gab>c de<a.r8>
egga ede.r8 dega ede.r8
ab>c<b age.r8 dedc <bga.r8>

@0 v15
egga ede.r8 dega ede.r8
dedc <bga.r8 gab>c de<a.r8>
egga ede.r8 dega ede.r8
dedc <bga.r8 gab>c de<a.r8>
egga ede.r8 dega ede.r8
dedc <bga.r8 gab>c de<a.r8>
egga ede.r8 dega ede.r8
ab>c<b age.r8 dedc <bga.r8

LMML教程

演奏方法

使用lmml-cli的对话模式是演奏LMML代码最简单的方法。

cargo install lmml-cli

安装lmml-cli,

lmml repl

启动对话模式。

语法

LMML有几个命令。这些命令的组合构成了LMML程序。

如果您想了解严格的语法,请参阅下面的“LMML语言语法”。

音符命令

CB的字符分别代表C到B的音符。+表示升高半音,-表示降低半音。

音符命令之后可以跟一个表示音长数字。例如,四分音符是4,八分音符是8。注意,数字越大,音长越短。

如果省略数字,则使用最后执行的L命令的值。如果不存在L命令,则使用4。

此外,可以在数字后面加上..表示附点音符。

示例

  • c4 - C的4分音符
  • c+8 - C#的8分音符
  • d4. - D的附点4分音符
  • d+4. - D#的附点4分音符

休止符命令

R表示休止符。与音符命令相同,可以跟一个表示音长的数字和.

和弦

通过使用[]括号包围音符来表示和弦。音符应该以根音开头,然后按低到高的顺序书写。

示例

  • [ceg] - C Maj
  • [ace] - Am
  • [ga+df] - Gm7
; カノン進行 C/G - G - Am/E - Em - F/C - C - F/C - G/D
@4t40 [gce][gbd][eac][egb][cfa][ceg][cfa][dgb]

https://github.com/yuma140902/lmml/assets/23431077/9f5b72ed-5317-4cdf-bf3a-d028d05c7cd5

L命令

设置音符的长度。如果没有在音符命令后面跟数字,则使用此命令的值。有关详细信息,请参阅下面的“LMML语言详细规格”。

O命令

设置八度值。初始值为4,值越大,音越高。八度4的A是440Hz。

>命令

将八度值增加1。

<命令

将八度值减少1。

N命令

使用MIDI的音符编号(0~127)来指定音符。

※LMML不依赖于MIDI,但内部以MIDI兼容的格式处理音符。

V命令

设置音量。初始值为20,值越大音量越大。100对应0dB,0对应-∞ dB。

T命令

设置节奏。值表示每分钟四分音符响起的次数。初始值为120。

@命令

使用0~4的数字设置波形。默认值为0。

数字 波形
0 锯齿波
1 矩形波
2 脉冲波
3 三角波
4 正弦波

:命令

LMML有16个通道,可以同时演奏。

:0所示,后面的命令将作用于通道0。

示例

https://github.com/yuma140902/lmml/assets/23431077/6f76011c-c638-4741-a067-14986da3178d

; 少女さとり ~ 3rd eye (東方地霊殿より)
; (最初の2小節のみ)

:0 @3 v20 t60 o4
:1 @3 v20 t60 o3
:2 @3 v30 t60 o2
:3 @4 v50 t60 o2
:4 @4 v20 t60 o4
:5 @4 v40 t60 o1

:0 l8
<b4.>c+16d16f+ <b>df+g<b>c+gf+2

:1 l2
f+1 gf+

:2 l2
f+1 gf+

:3 l32
crrrrrrr rrrrrrrr [d+g]rrrrr[d+g]r rrrr[d+g]rrr
<<[bg+f]rrrrrrr rrrr[bg+f]rrr >[g+f]<rrrrrrr rrrrrrrr>>

:4 l2
[bf+]1[bg][bf+]

:5 l2
[bf+]1[bg][bf+]

LMML语言语法

<lmml>        := <command>*
<command>     := <note-cmd>
               | <chord>
               | <n-cmd>
               | <rest-cmd>
               | <set-octave>
               | <set-length>
               | <set-volume>
               | <set-tempo>
               | <set-wave>
               | <set-channel>
               | <inc-octave>
               | <dec-octave>
<note-cmd>    := <note-char> <modifier>? <number>? <dot>?
<note-char>   := 'C' | 'D' | 'E' | 'F' | 'G' | 'A' | 'B'
               | 'c' | 'd' | 'e' | 'f' | 'g' | 'a' | 'b'
<modifier>    := '+' | '-'
<rest-cmd>    := 'R' <number>? <dot>? | 'r' <number>? <dot>?
<chord>       := '[' (<note-char> <modifier>?)+ ']' <number>? <dot>?
<dot>         := '.'
<n-cmd>       := 'N' <number> | 'n' <number>
<set-ocatve>  := 'O' <number> | 'o' <number>
<set-length>  := 'L' <number> <dot>? | 'l' <number> <dot>?
<set-volume>  := 'V' <number> | 'v' <number>
<set-tempo>   := 'T' <number> | 't' <number>
<set-wave>    := '@' <number>
<set-channel> := ':' <number>
<inc-octave>  := '>'
<dec-octave>  := '<'
<number>      := <digit>+
<digit>       := '0' | '1' | '2' | '3' | '4'
               | '5' | '6' | '7' | '8' | '9'

基本不区分大小写。空白或换行被忽略。

;开始的行被视为注释并忽略。

LMML语言详细规格

长度指定

音符命令、休止符命令、L命令中省略数字或.时的行为如下表所示。认为行为可能因人而异的部分用粗体表示。

最后一个L命令的数字 .是否存在 音符·休止符命令的数字 .是否存在 长度
L命令无 N/A 省略 四分音符
L命令无 N/A 省略 附点四分音符
L命令无 N/A n n分音符
L命令无 N/A n 附点n分音符
m 省略 m分音符
m 省略 附点m分音符
m n n分音符
m n 附点n分音符
m 省略 附点m分音符
m 省略 附点m分音符
m n n分音符
m n 附点n分音符

音符高度

音符命令转换为频率的过程分为两步。

首先将以下称为音符编号的内部形式进行转换。$n$是音符命令的类型,$m$是升号、降号等指定,$o是当前的八度。

base = if n == C then 0
       if n == D then 2
       if n == E then 4
       if n == F then 5
       if n == G then 7
       if n == A then 9
       if n == B then 11

modifier = if m == '+' then  1
           if m == '-' then -1
           else              0

N = base + modifier + ((o + 1) * 12)

然后将音符编号$N转换为频率$f [Hz]。

f = 440 \times 2 ^ { \frac{N - 69}{12} }

音的衰减

一个音符在响起的瞬间音量最大,然后逐渐减小。具体来说,如果音量由V命令指定为$v_0、音长为$T、从响起到经过的时间为$t,则在$t处的音量$v(t)$是

v(t) = \frac{v_0 (T-t)}{T}

目前无法更改衰减方式。

数值限制

八度的值

上下限均无,但预计在-1到9的范围内使用。另外,由于O命令只能指定非负值,因此如果想要指定负的八度,请使用<命令。

音量的值

下限是0,上限无。但是,由于100对应0dB,因此指定比100更大的值可能会导致音量失真。0时音完全不出。

N命令的值

下限是0,上限无。但预计在0到127的范围内使用。

节奏

下限是1,上限无。

通道编号

下限是0,上限是15。

LMML实现的详细规格

精度

波形合成以44.1kHz、32位浮点进行。

各个crate

lmmlcrate

包含LMML的AST或时间线数据结构和波形合成处理的crate。

lmml-parsercrate

LMML的解析器。

use lmml::{LmmlAst, LmmlCommand, NoteChar, NoteModifier};
use lmml_parser::parse_lmml;

pub fn main() {
    let ast = parse_lmml("t80 c+ d e8. r8").unwrap();

    assert_eq!(ast, LmmlAst(vec![
        LmmlCommand::SetTempo(80),
        LmmlCommand::Note {
            note: NoteChar::C,
            modifier: NoteModifier::Sharp,
            length: None,
            is_tied: false,
        },
        LmmlCommand::Note {
            note: NoteChar::D,
            modifier: NoteModifier::Natural,
            length: None,
            is_tied: false,
        },
        LmmlCommand::Note {
            note: NoteChar::E,
            modifier: NoteModifier::Natural,
            length: Some(8),
            is_tied: true,
        },
        Lmmlcommand::Rest { 
            length: Some(8) 
            is_tied: false,
        },
    ]));
}

lmml-clicrate

用于以交互方式演奏LMML或将其转换为其他格式命令行工具。

安装方法

cargo install lmml-cli

使用方法

播放文件。

lmml load ファイル

启动交互模式。

lmml repl

依赖项

~3–32MB
~479K SLoC