Symbolic library
Check package availability and use Symbolic's JavaScript and TypeScript functions for notes, chords and rhythm.
Symbolic provides headless music-theory functions for notes, intervals, chords, scales, sets, rhythm and notation conversion. The functions return musical data. Your application supplies playback, MIDI delivery or UI.
Installation and availability
Symbolic is included in the next maruaudio package through focused subpaths.
The published maruaudio@0.0.2 does not contain these entries. Use a
qualified Symbolic-enabled package tarball until that release is published;
the examples below describe that new package API.
After the Symbolic-enabled release is available, install the single package:
npm install maruaudio
To try a prepared package before publication, install its tarball instead:
npm install ./maruaudio-<version>.tgz
There is no separate Symbolic, MIDI or theory package to install for these
imports. The package bundles the required implementation and declarations.
Save an example as example.mjs and run node example.mjs in your project.
JavaScript and TypeScript use the same import paths.
| Import | Purpose |
|---|---|
maruaudio/symbolic | Common notes, sets, intervals, durations and notation conversions |
maruaudio/symbolic/rhythm | Rhythm patterns, named timelines, metrics and continuation |
maruaudio/symbolic/grid | Headless grid layout catalog and interval geometry |
maruaudio/symbolic/refs | Musical references and notation bridges with explicit context and losses |
maruaudio/symbolic/lead-sheet | Editable lead sheets and timed harmonic data |
maruaudio/symbolic/jazz-practice | Seeded practice phrases and instrument-aware exercises |
maruaudio/symbolic/percussion | Polyphonic percussion annotations |
maruaudio/symbolic/catalog | Musical concepts and relationships |
maruaudio/symbolic/library | The full library, including advanced analysis, song structures and generation |
The common entry keeps advanced reference registries and song structures
out of its runtime closure. Choose a focused entry for your task, or opt into
/library when you need the complete API. These are headless musical-data
functions; they do not open MIDI devices, start an audio engine or provide a
realtime Processor backend.
Explore the results in the Symbolic catalog. To compose and play patterns inside Code Sequencer, follow Symbolic Cycle, which has its own song language and execution environment.
Notes and MIDI pitches
Parse a note name and convert a MIDI pitch to a frequency. MIDI pitch 69 is A4; frequencies are in hertz.
import { noteFromMidi, parseNote } from "maruaudio/symbolic"
const middleC = parseNote("C4")
const a4 = noteFromMidi(69)
console.log(middleC.midi) // 60
console.log(a4.freq) // 440
Analyze a MIDI file
In Node.js, pass the bytes of a Standard MIDI File to midiHarmony from the
full library. It returns note counts, a pitch-class histogram and an estimated
key. Histogram entries run from C through B and weight notes by duration in
MIDI ticks; counts records note counts for those same pitch classes.
import { readFileSync } from "node:fs"
import { midiHarmony } from "maruaudio/symbolic/library"
const analysis = midiHarmony(readFileSync("example.mid"))
console.log(analysis.notes)
console.log(analysis.histogram)
console.log(analysis.counts)
In a browser, pass a Uint8Array made from the selected file's ArrayBuffer.
File selection and MIDI device access remain responsibilities of your app.
Transpose a chord
A note set retains octaves. Transposition takes a number of semitones; moving C major up seven semitones gives G major in the corresponding register.
import { parseNoteSet, transposeNoteSet } from "maruaudio/symbolic"
const cMajor = parseNoteSet("60-64-67")
const gMajor = transposeNoteSet(cMajor, 7)
console.log(gMajor.notes.map(note => note.midi)) // [67, 71, 74]
For octave-independent membership, use a pitch-class set instead. The pitch-class set catalog explores that distinction.
Convert rhythm notation
Convert explicit event positions to a grid, then to successive durations.
Positions and durations use quarter-note beats. The 4| prefix means four
cells per beat; x attacks, = continues a note and . rests.
import { convertRhythmNotation } from "maruaudio/symbolic"
const grid = convertRhythmNotation("0:0.25,r0.25:0.75,1:1", "positions", "grid")
console.log(grid) // "4|x...x==="
console.log(convertRhythmNotation(grid, "grid", "beats")) // "0.25,r0.75,1"
Parse an onset pattern
The rhythm entry parses an eight-step binary pattern without supplying a clock or playback host:
import { parseRhythmSpec } from "maruaudio/symbolic/rhythm"
const { pattern } = parseRhythmSpec("10010010", "binary")
console.log(pattern.steps) // 8
console.log(pattern.onsets) // [0, 3, 6]
Browse Symbolic for concepts and notation examples, or follow Symbolic Cycle to turn musical values into patterns inside Code Sequencer.