scribbletune
v5.5.4
Published
Create music with JavaScript and Node.js!
Maintainers
Readme
Install
npm install scribbletuneQuick start
Option 1: CLI
If you installed Scribbletune globally via npm i -g scribbletune then you can directly use scribbletune as the command. If you installed it locally via npm i scribbletune then please use npx scribbletune as the command.
Run modes:
# Global install
npm install -g scribbletune
scribbletune --help
# Local/project install
npm install scribbletune
npx scribbletune --helpQuick command examples:
Command format
scribbletune --riff <root> <mode> <pattern> <subdiv> [options]
scribbletune --chord <root> <mode> <pattern> <subdiv> <progression|random> [options]
scribbletune --arp <root> <mode> <pattern> <subdiv> <progression|random> [options]Progression input rules for --chord and --arp:
1645 # degree digits
"I IV vi V" # roman numerals (space separated)
I,IV,vi,V # roman numerals (comma separated)
random # generated progression
CM-FM-Am-GM # explicit chord names (`root` and `mode` are ignored)Common options:
--outfile <file.mid> # default: music.mid
--subdiv <4n|8n|1m...>
--sizzle [sin|cos|rampUp|rampDown] [reps]
--sizzle-reps <number>
--amp <0-127>
--accent <x--x...>
--accent-low <0-127>
--style <letters> # riff motif/style, e.g. AABC
--fit-pattern # explicit enable (already enabled by default)
--no-fit-pattern # disable automatic pattern fitting
--bpm <number> # your DAW may or may not support itNote: if your pattern uses [ and ] (for subdivisions), quote it in shell:
scribbletune --arp C3 major 1 'x-x[xx]-x-[xx]' 16nPattern helpers:
x.repeat(4) # -> xxxx
'x-x[xx]'.repeat(2)
2(x-x[xx]) # prefix repeat shorthand
(x-x[xx])2 # suffix repeat shorthand--riff examples
# Basic riff from scale
scribbletune --riff C3 phrygian x-xRx_RR --outfile riff.mid
# With motif/style and positional subdiv
scribbletune --riff C3 phrygian x-xRx_RR 8n --style AABC --sizzle sin 2 --outfile riff-aabc.mid
# Set riff subdivision via positional arg
scribbletune --riff C3 phrygian x-xRx_RR 8n --style AABC --outfile riff-8n.mid
# Pattern with subdivisions (quote [] in shell)
scribbletune --riff C3 phrygian 'x-x[xx]-x-[xx]' 8n --style AABC --outfile riff-subdiv.midRiff + motif note:
--stylecreates riff sections by repeating the full pattern per letter.- Example:
--style AABCwith patternx-x[xx]creates 4 sections:A,A,B,C. - Repeated letters reuse the exact same generated section (same rhythm and same notes, including random
Rchoices).
--chord examples
# Degree digits (resolved against root/mode)
scribbletune --chord C3 major xxxx 1m 1645 --sizzle cos 1 --outfile chords-1645.mid
# Roman numerals (space/comma separated)
scribbletune --chord C3 major xxxx 1m "I IV vi V" --outfile chords-roman.mid
# Random progression
scribbletune --chord C3 major xxxx 1m random --outfile chords-random.mid
# Explicit chord names (root/mode currently ignored for this style)
scribbletune --chord C3 major xxxx 1m CM-FM-Am-GM --outfile chords-explicit.mid
# Subdivisions in pattern
scribbletune --chord C3 major 'x-x[xx]-x-[xx]' 8n I,IV,vi,V --outfile chords-subdiv.mid--arp examples
# Arp from degree progression
scribbletune --arp C3 major xxxx 1m 1736 --sizzle cos 4 --outfile arp-1736.mid
# Single degree "1" means tonic chord in the chosen key/mode
scribbletune --arp C3 major xxxx 4n 1 --outfile arp-degree-1.mid
# Arp from explicit chords
scribbletune --arp C3 major xxxx 1m CM-FM-Am-GM --count 4 --order 1234 --outfile arp-explicit.mid
# Custom note order inside each arpeggiated chord (one-based)
scribbletune --arp C3 major xxxx 4n 1 --order 2143 --outfile arp-order-2143.mid
# Same custom order using local dist build
node dist/cli.cjs --arp C3 major xxxx 4n 1 --order 2143 --outfile arp-order-local.mid
# Auto-fit is default (single x expands to full generated arp length)
scribbletune --arp C3 major x 4n 1736 --outfile arp-fit-default.mid
# Disable auto-fit if you want a short clip
scribbletune --arp C3 major x 4n 1736 --no-fit-pattern --outfile arp-no-fit.mid--order behavior:
- One-based order is supported (
1234,2143) and is recommended. - Zero-based order is also accepted for backward compatibility (
0123,1032).
Run scribbletune --help to see the latest CLI usage text.
Option 2: Node.js
import { scale, clip, midi } from 'scribbletune';
const notes = scale('C4 major');
const c = clip({ notes, pattern: 'x'.repeat(8) });
midi(c, 'c-major.mid');Run it with node and open the .mid file in Ableton Live, GarageBand, Logic, or any DAW.
Option 3: Browser (with Tone.js)
Scribbletune's browser entry point adds Session, Channel, and live clip() support on top of Tone.js.
import { Session } from 'scribbletune/browser';
const session = new Session();
const channel = session.createChannel({
instrument: 'PolySynth',
clips: [
{ pattern: 'x-x-', notes: 'C4 E4 G4' },
{ pattern: '[-xx]', notes: 'C4 D#4' },
],
});
await Tone.start();
Tone.Transport.start();
channel.startClip(0);Standalone sample clip (no Session/Channel needed)
import { clip } from 'scribbletune/browser';
await Tone.start();
Tone.Transport.start();
const kick = clip({
sample: 'https://scribbletune.com/sounds/kick.wav',
pattern: 'x-x-',
});
kick.start();Core concepts
Pattern language
Scribbletune uses a simple string notation to describe rhythms:
| Char | Meaning |
|------|---------|
| x | Note on |
| - | Note off (rest) |
| _ | Sustain previous note |
| R | Random note (from randomNotes pool) |
| [] | Subdivide (e.g. [xx] = two notes in one beat) |
'x---x---x-x-x---' // basic kick pattern
'[xx][xx]x-x-' // hihat with subdivisions
'x___' // one long sustained noteScales and chords
Powered by harmonics:
import { scale, chord, scales, chords } from 'scribbletune';
scale('C4 major'); // ['C4', 'D4', 'E4', 'F4', 'G4', 'A4', 'B4']
chord('CM'); // ['C4', 'E4', 'G4']
scales(); // list all available scale names
chords(); // list all available chord namesArpeggios
import { arp } from 'scribbletune';
arp({ chords: 'CM FM', count: 4, order: '0123' });
// ['C4', 'E4', 'G4', 'C5', 'F4', 'A4', 'C5', 'F5']Chord progressions
import { progression, getChordsByProgression } from 'scribbletune';
progression('M', 4); // e.g. ['I', 'ii', 'V', 'IV']
getChordsByProgression('C4 major', 'I IV V IV');
// 'CM_4 FM_4 GM_4 FM_4'Browser API
The browser entry point (scribbletune/browser) provides everything above plus:
Session and Channel
import { Session } from 'scribbletune/browser';
const session = new Session();
const drums = session.createChannel({
sample: 'https://scribbletune.com/sounds/kick.wav',
clips: [
{ pattern: 'x---x---' },
{ pattern: 'x-x-x-x-' },
],
});
const synth = session.createChannel({
instrument: 'PolySynth',
clips: [
{ pattern: 'x-x-', notes: 'C4 E4 G4' },
],
});
await Tone.start();
Tone.Transport.start();
// Start clips independently
drums.startClip(0);
synth.startClip(0);
// Switch patterns on the fly
drums.startClip(1);
// Or start a row across all channels
session.startRow(0);Channel options
Channels accept various sound sources:
// Built-in Tone.js synth (by name)
{ instrument: 'PolySynth' }
// Pre-built Tone.js instrument
{ instrument: new Tone.FMSynth() }
// Audio sample URL
{ sample: 'https://example.com/kick.wav' }
// Multi-sample instrument
{ samples: { C3: 'piano-c3.wav', D3: 'piano-d3.wav' } }
// With effects
{ instrument: 'PolySynth', effects: ['Chorus', 'Reverb'] }API reference
| Export | Description |
|--------|-------------|
| clip(params) | Create a clip — returns note objects (Node.js) or a Tone.Sequence (browser) |
| midi(clip, filename?) | Export a clip to a MIDI file |
| scale(name) | Get notes of a scale, e.g. 'C4 minor' |
| chord(name) | Get notes of a chord, e.g. 'CM' |
| scales() | List all available scale names |
| chords() | List all available chord names |
| arp(params) | Generate arpeggiated note sequences |
| progression(type, count) | Generate a chord progression ('M' or 'm') |
| getChordsByProgression(scale, degrees) | Convert Roman numeral degrees to chord names |
| getChordDegrees(mode) | Get Roman numeral degrees for a mode |
| Session | (browser only) Manage multiple channels and coordinate playback |
Development
npm install # install dependencies
npm test # run tests
npm run build # build with tsup
npm run lint # check with biome
npm run dev # build in watch modeIf developing new features for the CLI, use the following command after running npm run build to test before publishing,
node dist/cli.cjs --helpLicense
MIT
