scribbletune 5.2.0 → 5.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +276 -22
- package/dist/browser.cjs +1183 -0
- package/dist/browser.cjs.map +1 -0
- package/dist/browser.js +1135 -1
- package/dist/browser.js.map +1 -1
- package/dist/cli.cjs +813 -0
- package/dist/{index.mjs → index.cjs} +225 -169
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +323 -0
- package/dist/index.d.ts +303 -350
- package/dist/index.js +524 -1
- package/dist/index.js.map +1 -1
- package/dist/scribbletune.global.js +1944 -0
- package/dist/scribbletune.global.js.map +1 -0
- package/package.json +32 -40
- package/dist/lib/arp.d.ts +0 -10
- package/dist/lib/browser-clip.d.ts +0 -14
- package/dist/lib/browser-index.d.ts +0 -7
- package/dist/lib/channel.d.ts +0 -61
- package/dist/lib/clip.d.ts +0 -2
- package/dist/lib/index.d.ts +0 -7
- package/dist/lib/midi.d.ts +0 -11
- package/dist/lib/progression.d.ts +0 -25
- package/dist/lib/session.d.ts +0 -14
- package/dist/lib/types/arp-params.d.ts +0 -6
- package/dist/lib/types/channel-params.d.ts +0 -92
- package/dist/lib/types/channel-pattern.d.ts +0 -24
- package/dist/lib/types/clip-params.d.ts +0 -104
- package/dist/lib/types/event-fn.d.ts +0 -7
- package/dist/lib/types/index.d.ts +0 -14
- package/dist/lib/types/note-object.d.ts +0 -6
- package/dist/lib/types/nvp.d.ts +0 -4
- package/dist/lib/types/play-params.d.ts +0 -15
- package/dist/lib/types/player-observer-fn.d.ts +0 -6
- package/dist/lib/types/progression-scale.d.ts +0 -2
- package/dist/lib/types/seq-fn.d.ts +0 -2
- package/dist/lib/types/sizzle-style.d.ts +0 -2
- package/dist/lib/types/synth-params.d.ts +0 -20
- package/dist/lib/types/tpd.d.ts +0 -15
- package/dist/lib/utils.d.ts +0 -56
- package/dist/scribbletune.js +0 -2
- package/dist/scribbletune.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,41 +1,295 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img width="64" src="https://scribbletune.com/images/scribbletune-logo.png" alt="Scribbletune">
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
[](https://npm.runkit.com/scribbletune)
|
|
5
|
+
<h1 align="center">Scribbletune</h1>
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
Create music with JavaScript. Use simple strings and arrays to craft rhythms, melodies, and chord progressions — then export MIDI files or play them live in the browser with <a href="https://tonejs.github.io/">Tone.js</a>.
|
|
9
|
+
</p>
|
|
7
10
|
|
|
8
|
-
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://www.npmjs.com/package/scribbletune"><img src="https://img.shields.io/npm/v/scribbletune.svg" alt="npm version"></a>
|
|
13
|
+
<a href="https://www.npmjs.com/package/scribbletune"><img src="https://img.shields.io/npm/l/scribbletune.svg" alt="license"></a>
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Install
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install scribbletune
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Quick start
|
|
25
|
+
|
|
26
|
+
### CLI
|
|
27
|
+
|
|
28
|
+
The package now ships a CLI binary: `scribbletune`.
|
|
29
|
+
|
|
30
|
+
Run modes:
|
|
9
31
|
|
|
10
32
|
```bash
|
|
33
|
+
# Global install
|
|
34
|
+
npm install -g scribbletune
|
|
35
|
+
scribbletune --help
|
|
36
|
+
|
|
37
|
+
# Local/project install
|
|
11
38
|
npm install scribbletune
|
|
39
|
+
npx scribbletune --help
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
#### Command format
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
scribbletune --riff <root> <mode> <pattern> [octaveShift] [motif] [options]
|
|
46
|
+
scribbletune --chord <root> <mode> <progression|random> <pattern> [subdiv] [options]
|
|
47
|
+
scribbletune --arp <root> <mode> <progression|random> <pattern> [subdiv] [options]
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Common options:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
--outfile <file.mid> # default: music.mid
|
|
54
|
+
--bpm <number>
|
|
55
|
+
--subdiv <4n|8n|1m...>
|
|
56
|
+
--sizzle [sin|cos|rampUp|rampDown] [reps]
|
|
57
|
+
--sizzle-reps <number>
|
|
58
|
+
--amp <0-127>
|
|
59
|
+
--accent <x--x...>
|
|
60
|
+
--accent-low <0-127>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
#### `--riff` examples
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Basic riff from scale
|
|
67
|
+
scribbletune --riff C3 phrygian x-xRx_RR --outfile riff.mid
|
|
68
|
+
|
|
69
|
+
# With octave shift and motif
|
|
70
|
+
scribbletune --riff C3 phrygian x-xRx_RR 0 AABC --sizzle sin 2 --outfile riff-aabc.mid
|
|
12
71
|
```
|
|
13
72
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
73
|
+
#### `--chord` examples
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Degree digits (resolved against root/mode)
|
|
77
|
+
scribbletune --chord C3 major 1645 xxxx 1m --sizzle cos 1 --outfile chords-1645.mid
|
|
78
|
+
|
|
79
|
+
# Roman numerals (space/comma separated)
|
|
80
|
+
scribbletune --chord C3 major "I IV vi V" xxxx 1m --outfile chords-roman.mid
|
|
81
|
+
|
|
82
|
+
# Random progression
|
|
83
|
+
scribbletune --chord C3 major random xxxx 1m --outfile chords-random.mid
|
|
84
|
+
|
|
85
|
+
# Explicit chord names (root/mode currently ignored for this style)
|
|
86
|
+
scribbletune --chord C3 major CM-FM-Am-GM xxxx 1m --outfile chords-explicit.mid
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### `--arp` examples
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# Arp from degree progression
|
|
93
|
+
scribbletune --arp C3 major 1736 xxxx 1m --sizzle cos 4 --outfile arp-1736.mid
|
|
94
|
+
|
|
95
|
+
# Arp from explicit chords
|
|
96
|
+
scribbletune --arp C3 major CM-FM-Am-GM xxxx 1m --count 4 --order 0123 --outfile arp-explicit.mid
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Run `scribbletune --help` to see the latest CLI usage text.
|
|
100
|
+
|
|
101
|
+
### Generate a MIDI file (Node.js)
|
|
102
|
+
|
|
103
|
+
```js
|
|
104
|
+
import { scale, clip, midi } from 'scribbletune';
|
|
105
|
+
|
|
106
|
+
const notes = scale('C4 major');
|
|
107
|
+
const c = clip({ notes, pattern: 'x'.repeat(8) });
|
|
108
|
+
|
|
109
|
+
midi(c, 'c-major.mid');
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Run it with `node` and open the `.mid` file in Ableton Live, GarageBand, Logic, or any DAW.
|
|
113
|
+
|
|
114
|
+
### Play in the browser (with Tone.js)
|
|
115
|
+
|
|
116
|
+
Scribbletune's browser entry point adds `Session`, `Channel`, and live `clip()` support on top of [Tone.js](https://tonejs.github.io/).
|
|
117
|
+
|
|
118
|
+
```js
|
|
119
|
+
import { Session } from 'scribbletune/browser';
|
|
120
|
+
|
|
121
|
+
const session = new Session();
|
|
122
|
+
const channel = session.createChannel({
|
|
123
|
+
instrument: 'PolySynth',
|
|
124
|
+
clips: [
|
|
125
|
+
{ pattern: 'x-x-', notes: 'C4 E4 G4' },
|
|
126
|
+
{ pattern: '[-xx]', notes: 'C4 D#4' },
|
|
127
|
+
],
|
|
20
128
|
});
|
|
21
129
|
|
|
22
|
-
|
|
130
|
+
await Tone.start();
|
|
131
|
+
Tone.Transport.start();
|
|
132
|
+
channel.startClip(0);
|
|
23
133
|
```
|
|
24
134
|
|
|
135
|
+
### Standalone sample clip (no Session/Channel needed)
|
|
136
|
+
|
|
137
|
+
```js
|
|
138
|
+
import { clip } from 'scribbletune/browser';
|
|
25
139
|
|
|
26
|
-
|
|
140
|
+
await Tone.start();
|
|
141
|
+
Tone.Transport.start();
|
|
27
142
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
143
|
+
const kick = clip({
|
|
144
|
+
sample: 'https://scribbletune.com/sounds/kick.wav',
|
|
145
|
+
pattern: 'x-x-',
|
|
146
|
+
});
|
|
147
|
+
kick.start();
|
|
31
148
|
```
|
|
32
149
|
|
|
33
|
-
|
|
150
|
+
## Core concepts
|
|
34
151
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
152
|
+
### Pattern language
|
|
153
|
+
|
|
154
|
+
Scribbletune uses a simple string notation to describe rhythms:
|
|
155
|
+
|
|
156
|
+
| Char | Meaning |
|
|
157
|
+
|------|---------|
|
|
158
|
+
| `x` | Note on |
|
|
159
|
+
| `-` | Note off (rest) |
|
|
160
|
+
| `_` | Sustain previous note |
|
|
161
|
+
| `R` | Random note (from `randomNotes` pool) |
|
|
162
|
+
| `[]` | Subdivide (e.g. `[xx]` = two notes in one beat) |
|
|
163
|
+
|
|
164
|
+
```js
|
|
165
|
+
'x---x---x-x-x---' // basic kick pattern
|
|
166
|
+
'[xx][xx]x-x-' // hihat with subdivisions
|
|
167
|
+
'x___' // one long sustained note
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Scales and chords
|
|
171
|
+
|
|
172
|
+
Powered by [harmonics](https://github.com/scribbletune/harmonics):
|
|
173
|
+
|
|
174
|
+
```js
|
|
175
|
+
import { scale, chord, scales, chords } from 'scribbletune';
|
|
176
|
+
|
|
177
|
+
scale('C4 major'); // ['C4', 'D4', 'E4', 'F4', 'G4', 'A4', 'B4']
|
|
178
|
+
chord('CM'); // ['C4', 'E4', 'G4']
|
|
179
|
+
scales(); // list all available scale names
|
|
180
|
+
chords(); // list all available chord names
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Arpeggios
|
|
184
|
+
|
|
185
|
+
```js
|
|
186
|
+
import { arp } from 'scribbletune';
|
|
187
|
+
|
|
188
|
+
arp({ chords: 'CM FM', count: 4, order: '0123' });
|
|
189
|
+
// ['C4', 'E4', 'G4', 'C5', 'F4', 'A4', 'C5', 'F5']
|
|
38
190
|
```
|
|
39
|
-
This will provide the same API but augment it a bit to support browser based functionality.
|
|
40
191
|
|
|
41
|
-
|
|
192
|
+
### Chord progressions
|
|
193
|
+
|
|
194
|
+
```js
|
|
195
|
+
import { progression, getChordsByProgression } from 'scribbletune';
|
|
196
|
+
|
|
197
|
+
progression('M', 4); // e.g. ['I', 'ii', 'V', 'IV']
|
|
198
|
+
|
|
199
|
+
getChordsByProgression('C4 major', 'I IV V IV');
|
|
200
|
+
// 'CM_4 FM_4 GM_4 FM_4'
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Browser API
|
|
204
|
+
|
|
205
|
+
The browser entry point (`scribbletune/browser`) provides everything above plus:
|
|
206
|
+
|
|
207
|
+
### Session and Channel
|
|
208
|
+
|
|
209
|
+
```js
|
|
210
|
+
import { Session } from 'scribbletune/browser';
|
|
211
|
+
|
|
212
|
+
const session = new Session();
|
|
213
|
+
const drums = session.createChannel({
|
|
214
|
+
sample: 'https://scribbletune.com/sounds/kick.wav',
|
|
215
|
+
clips: [
|
|
216
|
+
{ pattern: 'x---x---' },
|
|
217
|
+
{ pattern: 'x-x-x-x-' },
|
|
218
|
+
],
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
const synth = session.createChannel({
|
|
222
|
+
instrument: 'PolySynth',
|
|
223
|
+
clips: [
|
|
224
|
+
{ pattern: 'x-x-', notes: 'C4 E4 G4' },
|
|
225
|
+
],
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
await Tone.start();
|
|
229
|
+
Tone.Transport.start();
|
|
230
|
+
|
|
231
|
+
// Start clips independently
|
|
232
|
+
drums.startClip(0);
|
|
233
|
+
synth.startClip(0);
|
|
234
|
+
|
|
235
|
+
// Switch patterns on the fly
|
|
236
|
+
drums.startClip(1);
|
|
237
|
+
|
|
238
|
+
// Or start a row across all channels
|
|
239
|
+
session.startRow(0);
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Channel options
|
|
243
|
+
|
|
244
|
+
Channels accept various sound sources:
|
|
245
|
+
|
|
246
|
+
```js
|
|
247
|
+
// Built-in Tone.js synth (by name)
|
|
248
|
+
{ instrument: 'PolySynth' }
|
|
249
|
+
|
|
250
|
+
// Pre-built Tone.js instrument
|
|
251
|
+
{ instrument: new Tone.FMSynth() }
|
|
252
|
+
|
|
253
|
+
// Audio sample URL
|
|
254
|
+
{ sample: 'https://example.com/kick.wav' }
|
|
255
|
+
|
|
256
|
+
// Multi-sample instrument
|
|
257
|
+
{ samples: { C3: 'piano-c3.wav', D3: 'piano-d3.wav' } }
|
|
258
|
+
|
|
259
|
+
// With effects
|
|
260
|
+
{ instrument: 'PolySynth', effects: ['Chorus', 'Reverb'] }
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## API reference
|
|
264
|
+
|
|
265
|
+
| Export | Description |
|
|
266
|
+
|--------|-------------|
|
|
267
|
+
| `clip(params)` | Create a clip — returns note objects (Node.js) or a Tone.Sequence (browser) |
|
|
268
|
+
| `midi(clip, filename?)` | Export a clip to a MIDI file |
|
|
269
|
+
| `scale(name)` | Get notes of a scale, e.g. `'C4 minor'` |
|
|
270
|
+
| `chord(name)` | Get notes of a chord, e.g. `'CM'` |
|
|
271
|
+
| `scales()` | List all available scale names |
|
|
272
|
+
| `chords()` | List all available chord names |
|
|
273
|
+
| `arp(params)` | Generate arpeggiated note sequences |
|
|
274
|
+
| `progression(type, count)` | Generate a chord progression (`'M'` or `'m'`) |
|
|
275
|
+
| `getChordsByProgression(scale, degrees)` | Convert Roman numeral degrees to chord names |
|
|
276
|
+
| `getChordDegrees(mode)` | Get Roman numeral degrees for a mode |
|
|
277
|
+
| `Session` | _(browser only)_ Manage multiple channels and coordinate playback |
|
|
278
|
+
|
|
279
|
+
## Development
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
npm install # install dependencies
|
|
283
|
+
npm test # run tests
|
|
284
|
+
npm run build # build with tsup
|
|
285
|
+
npm run lint # check with biome
|
|
286
|
+
npm run dev # build in watch mode
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## License
|
|
290
|
+
|
|
291
|
+
MIT
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
[scribbletune.com](https://scribbletune.com) | [Soundcloud](https://soundcloud.com/scribbletune)
|