# Symbolic library

> Check package availability and use Symbolic's JavaScript and TypeScript functions for notes, chords and rhythm.

Canonical: https://maruaudio.com/docs/symbolic-library
Documentation index: https://maruaudio.com/llms.txt

[Symbolic](https://maruaudio.com/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:

```bash
npm install maruaudio
```

To try a prepared package before publication, install its tarball instead:

```bash
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](https://maruaudio.com/symbolic). To compose and play
patterns inside [Code Sequencer](https://maruaudio.com/modules/code-sequencer), follow
[Symbolic Cycle](https://maruaudio.com/docs/symbolic-cycle.md), 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.

```ts
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.

```ts
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.

```ts
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](https://maruaudio.com/symbolic/pc-set) 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.

```ts
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:

```ts
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](https://maruaudio.com/symbolic) for concepts and notation examples, or follow
[Symbolic Cycle](https://maruaudio.com/docs/symbolic-cycle.md) to turn musical values into patterns
inside Code Sequencer.
