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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@hoge1e3/mml

v1.0.1

Published

mml player using @hoge1e3/oscillator

Readme

@hoge1e3/mml

A Music Macro Language (MML) parser and playback library that uses @hoge1e3/oscillator to generate sound.

Features

  • Parsing of standard MML syntax
  • Support for notes, rests, note lengths, and octave specifications
  • Support for different character sets (standard and Japanese)
  • Sound generation using WebAudioAPI

Installation

npm install @hoge1e3/mml

Basic Usage

import { MelodyParser, standardLiteralSet, toSource } from "@hoge1e3/mml";
import { Playback } from "@hoge1e3/oscillator";

// Create an AudioContext instance
const audioCtx = new AudioContext();

// Parse and play MML
function playMML(mml: string) {
  // Parse MML
  const parser = new MelodyParser(standardLiteralSet, mml);
  const melody = parser.parse();
  
  // Generate sound source (tempo 120)
  const source = toSource(melody, 120);
  
  // Play
  const playback = source.play(audioCtx);
  
  // To stop
  // playback.stop();
}

// Example
playMML("cdefgab>c");

MML Syntax

Basic Notes

c d e f g a b  // C, D, E, F, G, A, B

Note Lengths

By default, each note is treated as a quarter note (1/4).

l4 cdef     // Quarter notes (same as default)
l8 cdef     // Eighth notes
l16 cdef    // Sixteenth notes
l2 cdef     // Half notes
l1 cdef     // Whole notes

Dots and Extended Notes

c. d. e. f.   // Dotted notes (multiply length by 1.5)
c^ d^ e^ f^   // Extended notes (multiply length by 2)

Compound Length Specifications

c4&8 d8&16    // Quarter note + eighth note, eighth note + sixteenth note

Octaves

c d e f       // Standard octave
> c d e f     // One octave up
< c d e f     // One octave down

Rests

r           // Rest

Sharps and Flats

c# d# f#     // Sharp (raise a half tone)
c+ d+ f+     // Alternative sharp notation
c- d- e-     // Flat (lower a half tone)

Type Definitions

Core Types

// Type representing note length
export interface NoteLength {
    n: number;   // Numerator
    d: number;   // Denominator
}

// Type representing a note
export interface Note {
    scale: number|null; // 0-95 scale, null for rests
    length: NoteLength; // Note length
}

// Type representing a melody (array of notes)
export type Melody = Note[];

// Type representing parser state
export type MelodyState = {
    length: NoteLength,
    octave: number,
}

// Type representing a character set
export type LieteralSet = {
    scales: Pattern[],           // Scales
    longSyllable: Pattern,       // Extended note symbol
    halfSyllable: Pattern,       // Dotted note symbol
    concatLength: Pattern,       // Length concatenation symbol
    rest: Pattern,               // Rest symbol
    sharp: Pattern,              // Sharp symbol
    flat: Pattern,               // Flat symbol
    octave: {up: Pattern, down: Pattern}, // Octave change symbols
    length: Pattern,             // Length specification symbol
    rhysms?: Map<string, Source>; // Rhythm patterns (optional)
}

Character Sets

This library includes two predefined character sets:

Standard Character Set

export const standardLiteralSet: LieteralSet = {
    scales: ["c","d","e","f","g","a","b"],
    rest: "r",
    octave: {up:">", down:"<"},
    length: "l",
    concatLength: "&",
    longSyllable: "^", 
    sharp: /^[#+]/, 
    flat: "-",
    halfSyllable: ".",    
};

Japanese Character Set

The library also supports a Japanese character set for use with Japanese notation.

Examples

Simple Example

import { MelodyParser, standardLiteralSet, toSource } from "@hoge1e3/mml";

const audioCtx = new AudioContext();
const mml = "cdefgab>c";

const parser = new MelodyParser(standardLiteralSet, mml);
const melody = parser.parse();
const source = toSource(melody, 120);
const playback = source.play(audioCtx);

// To stop
playback.stop();

Complex Example (Twinkle Twinkle Little Star)

import { MelodyParser, standardLiteralSet, toSource } from "@hoge1e3/mml";

const audioCtx = new AudioContext();
const mml = "ccgg aag^ ffee ddc^";

const parser = new MelodyParser(standardLiteralSet, mml);
const melody = parser.parse();
const source = toSource(melody, 120);
const playback = source.play(audioCtx);

HTML UI Example

<div>
    <input id="mml" value="cdefedc^efgagfe^c^c^c^c^l8ccddeeffe^d^c^"/>
</div>
<button id="play">Play</button>
<button id="stop">Stop</button>
<script type="module">
    import { MelodyParser, standardLiteralSet, toSource } from "@hoge1e3/mml";
    
    const audioCtx = new AudioContext();
    let playback;
    
    document.getElementById('play').addEventListener('click', () => {
        const mml = document.getElementById('mml').value;
        const parser = new MelodyParser(standardLiteralSet, mml);
        const melody = parser.parse();
        const source = toSource(melody, 120);
        playback = source.play(audioCtx);
    });
    
    document.getElementById('stop').addEventListener('click', () => {
        playback?.stop();
    });
</script>

Testing

The project includes a simple test page that can be run with:

npm run test

On the test page, you can enter MML in the text box and click the play button to hear the sound.

Building

# Development build
npm run build-dev

# Production build
npm run build

License

This project is provided under a specific license. Please refer to the license file in the package for details.

Dependencies