npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

sakuramml

v0.2.3

Published

MML(Music Macro Language) compiler, MML to MIDI

Readme

Sakura Text Music (Rust Edition) / PicoSakura

Sakura is a compiler that converts MML (Music Macro Language) into MIDI files. It converts musical text such as Japanese solfège (ドレミ) or cde into MIDI files. Written in Rust, it runs on multiple platforms: macOS, Windows, Linux, and WebAssembly.

Sakura is a long-standing music-production tool originally developed before 2000. MML is a notation for representing music as text, such as cde. It makes it easy to create music. Written in Rust, it runs on macOS, Windows, Linux, and WebAssembly. It received an award in Japan's Online Software Grand Prize 2001 and was featured in Japanese high-school information-technology textbooks.

Samples

  • mmlbbs6 --- Many songs have been posted to the Sakura MML Bulletin Board 6.

Tutorial

An online tutorial is available. You can learn the commands while listening to the music in your browser.

PicoSakura: Installation

The web version, PicoSakura, lets you easily play MIDI files in your browser.

For local use, the command-line edition is also available. Download binaries for each operating system below.

Building the Latest Version (Rust)

First, install Rust.

$ git clone https://github.com/kujirahand/sakuramml-rust.git
$ cd sakuramml-rust
$ cargo build --release

This creates target/release/sakuramml.

Usage

Command-line Edition

Write the musical score as text, for example in a file named test.mml. To convert test.mml to test.mid, run the following command from the command line:

$ sakuramml test.mml

For safety, generated MIDI event data is limited to 3 MiB by default. The command-line edition can change this limit when compiling trusted MML:

$ sakuramml --max-event-bytes 10485760 test.mml

The WebAssembly limit is fixed at 3 MiB. See the MIDI event data limit for details. When the limit is exceeded, the compiler records an error and returns the partial MIDI generated up to that point.

Basic Usage

音階4 ドレミファソラシ↑ド↓シラソファミレド
o4 cdefgab>c<bagfedc
トラック1 チャンネル1 音符1 ドミソー
TR=1 CH=1 l1 ceg^

Chords

音符1「ドミソ」
l4 'ceg' 'dfa'8 'egb'8 'ceg'

Enclose chords in single quotes. After the closing quote, you can specify the note length, gate time, and velocity, as in 'ceg'4,90,120.

Moving the Time Pointer

Use TIME(measure:beat:step) to move to any position in the score.

// Move to the beginning
TIME(1:1:0) cdef
TIME(1:1:0) efga

// Move to the second measure
TIME(2:1:0) cdef

Use SUB{...} to return the time pointer to just before the SUB. This lets you play chords easily.

SUB{ cdef  c }
SUB{ efga  e }
     rrrr  g

Rhythm Macros

In a rhythm macro, each character is treated as one instruction, regardless of case. Define a rhythm macro in the form $character{definition}.

// Define rhythm macros (the following are defined by default, but can be redefined)
$b{n36,}
$h{n42,}
$o{n46,}
// Define a new rhythm macro
$S{n37,}
CH(10)
// Rhythm sample
Rhythm{
 [4 l8
   brSr bbsr r-1
   hoho hoho
 ]
}

Differences from Sakura v1/v2

This edition intentionally differs from Sakura v1/v2 in several respects.

Specifying Step Mode

This version uses a different method for specifying step mode. In v1/v2, specifying a note length such as l%96 caused all subsequent notes to use step mode. However, since notes are rarely specified in step mode, this version allows a step specification only temporarily; it does not continue to affect subsequent notes.

// The following two lines have the same meaning
l%96 cde
c4d4e4

Tuplet Notation

Previously, tuplets were written as Div{...}. You can now omit Div and write them as {ceg}.

l4 Div{cde} f Div{gab} >c<
l4 {cde} f {gab} >c<

The sustain mark ^ also counts as one note, which is convenient.

l4 {cde}c {gfe}d {c^d} e {d^e} f

Tuplets can be nested.

l1 { c d {efe} d } c

Relative Volume Notation

( decreases velocity by 8, and ) increases velocity by 8.

v127 c ( c ( c (( c )) c ) c ) c

Chord Notation

Chords using zero-valued notes, such as c0e0g, are not supported. Use ordinary chord notation instead.

'ceg' 'dfa' 'egb' 'ceg'
「ドミソ」「レファラ」「ミソシ」「ドミソ」

Reservation Notation and Continuous CC/PB Writing

Advance specifications are available for note parameters (v q t o l) and for control changes / pitch bend.

  • .onNote(v1, v2, ...) / abbreviated form: .N(...) — switch the value on every note
  • .onTime(low, high, len, ...) / abbreviated form: .T(...) — move the value over time
  • .onCycle(step, v1, v2, ...) / abbreviated form: .C(...) — switch the value every step steps
  • .Random(n) / .Range(low, high) / .Delay(n) / .Repeat(on/off)
  • v.Max(n) / q.Max(n) — change the upper limit of the value (a range setting, not an advance specification)
  • CC / PB only: .onNoteWave / .onNoteWaveEx / .onNoteWaveR / .Sine / .onNoteSine / .Frequency (.Frequency sets the write interval; CC and pitch bend are configured separately)
  • v__n.onTime/onNote/onCycle/Random(...) / per-layer advance specification added to the base velocity
v.onTime(0,127,!1)l8cccccccc
Array m=(10,10,!16); Array A=(100,100,!16); q.onTime(m,A) // Array arguments in advance specifications
v70 v__1.onCycle(!4,10,-10) cdef // velocities: 80,60,80,60
BR(2) PB.onTime(-8192,0,!4) l4c PB(0) efg^

v__n(value) (n is 0 or greater) defines an independent adjustment layer added to the base velocity. Multiple layers are summed, and the final value is clamped to 0–127. See the MML syntax reference for completion and reset behavior.

Macros

Define macros as follows:

// Define macros
STR P1 = {cdefg}
#P1 = {cdefg}
// Expand macros
P1
#P1

You can provide arguments to a macro and substitute them into its contents. Define #?1, #?2, #?3, and so on inside the macro; each placeholder is replaced with the corresponding argument written immediately after the macro.

// Define a macro
#Unison = { Key=#?2 Sub{ #?1 } Key=0 #?1 }
// Expand the macro
#Unison{cde},7

References

  • MML syntax reference --- docs/syntax.md
  • Sakura (Rust Edition) command list --- command.md
    • Sakura (v2 Edition) command list --- https://sakuramml.com/doc/command/index.htm
  • Instrument list --- voice.md

Repository