Crates.io | sakuramml |
lib.rs | sakuramml |
version | 0.1.42 |
source | src |
created_at | 2022-11-15 07:01:46.239911+00 |
updated_at | 2025-02-18 01:45:49.927925+00 |
description | MML(Music Macro Language) compiler, MML to MIDI |
homepage | https://sakuramml.com |
repository | https://github.com/kujirahand/sakuramml-rust |
max_upload_size | |
id | 715481 |
size | 356,876 |
sakruamml
is a MML/ABC to MIDI compier.
This compiler that converts the MML/ABC into MIDI files.
MML is a notation system that represents sheet music using text such as cde
.
It is a tool that allows you to easily create music.
It is made with Rust and works on multiple platforms (macOS/Windows/Linux/WebAssembly).
sakuramml
is a historic music production tool developed around the year 2000.
It was recognized as an award-winning entry in the "Online Software Grand Prize 2001" in Japan, and was even featured in high school IT textbooks.
Many users have composed music using sakuramml
, and over 2,000 songs have been posted on this forum.
Additionally, more than 100 songs are compatible with sakuramml-rust
.
An online tutorial is available. You can learn the commands while listening to the music.
Please install Rust compier.
git clone https://github.com/kujirahand/sakuramml-rust.git
cd sakuramml-rust
cargo build --release
When compiled, the executable file will be saved in target/release/sakuramml
.
Please make text file test.mml
. And execute the following command to generate a MIDI file test.mid
.
# Compile MML file to MIDI file
./sakuramml test.mml test.mid
# Compile MML file to MIDI file, can omit output file
./sakuramml test.mml
You can test MML command easily with --eval
option.
./sakuramml --eval "o4l4 cege c1"
You can check MIDI file with --dump
option.
./sakuramml --dump test.mid
You can play the following text as a music.
o4 cdefgab>c<bagfedc
You can specify tracks(TR
) and channels(CH
), Voice(@
).
TR(1) CH(1) @1 l1 ceg^
TR(2) CH(2) @1 l1 egb^
You can play chords.
l4 `ceg` `dfa`8 `egb`8 `ceg`
You can specify the writing position using a time pointer(TIME
).
// top
TIME(1:1:0) cdef
TIME(1:1:0) efga
// 2mes
TIME(2:1:0) cdef
SUB{...}
command let time pointer back.
SUB{ cdef c }
SUB{ efga e }
rrrr g
In the rhythm macro, one character is treated as one instruction regardless of uppercase or lowercase letters. Rhythm macro definitions are described as "$(char){definition}".
// define macro
$b{n36,}
$h{n42,}
$o{n46,}
// new macro
$S{n37,}
CH(10)
// sample
Rhythm{
[4 l8
brSr bbsr r-1
hoho hoho
]
}
The tuplets are written as "DIV{...}", but "DIV" can be omitted and written as "{ceg}".
l4 DIV{cde} f DIV{gab} >c<
l4 {cde} f {gab} >c<
l4 {cde}c {gfe}d {c^d} e {d^e} f
The tuplets can nest.
l1 { c d {efe} d } c
Using the v
command, you can specify the velocity. It can be set within the range of 0 to 127.
l8 v127 cdef v64 cdef v127 c^^^
"(" decreases the velocity by 8, and ")" increases the velocity by 8.
v127 c ( c ( c (( c )) c ) c ) c
len
is the tick. When specifying the note length, it should be written as !4
, for example.v.onTime(0,127,!1) l8cccccccc
BR(2) PB.onTime(-8192,0,!4) l4c PB(0) efg^
It can define Macro.
// define Macro
STR P1 = {cdefg}
#P1 = {cdefg}
// expand Macro
P1
#P1
The macro can replace with arguments.
It replaces #?1
#?2
#?3
...
// define macro
#Unison = { Key=#?2 Sub{ #?1 } Key=0 #?1 }
// expand macro with arguments
#Unison{cde},7
It can use IF/FOR/WHILE/FUNCTION script.
// IF
INT A = 3
INT B = 5
IF (A == B) { PRINT({A == B}) } ELSE { PRINT({A != B}) }
// FOR
FOR (INT N=1; N < 5; N++) {
PRINT(N)
}
It can define variables of INT, STR, and ARRAY types.
// define variables
INT I1=30
STR S1={abcd}
ARRAY A1=(1,2,3)
// use variables
PRINT(I1) // 30
PRINT(S1) // abcd
PRINT(A1) // (1,2,3)
PRINT(A1(2)) // 3
Replace {i}
with {c}
in the value of the string variable S1
and S2
.
// define variables
STR S1={iiri iiri}
// replace {i} to {c}
S1.s({i}, {c})
PRINT(S1) // ccrc ccrc
// REPLACE function
STR S2 = REPLACE({iiri iiri}, {i}, {c})
PRINT(S2) // ccrc ccrc