picopilot 0.2.0 → 0.3.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/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +129 -36
- package/dist/cli.js.map +1 -1
- package/dist/commands/audio.d.ts +23 -2
- package/dist/commands/audio.d.ts.map +1 -1
- package/dist/commands/audio.js +239 -26
- package/dist/commands/audio.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +8 -3
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/gfx.d.ts.map +1 -1
- package/dist/commands/gfx.js +11 -5
- package/dist/commands/gfx.js.map +1 -1
- package/dist/commands/music.d.ts +2 -1
- package/dist/commands/music.d.ts.map +1 -1
- package/dist/commands/music.js +209 -2
- package/dist/commands/music.js.map +1 -1
- package/dist/commands/pico8-env.d.ts +39 -3
- package/dist/commands/pico8-env.d.ts.map +1 -1
- package/dist/commands/pico8-env.js +51 -4
- package/dist/commands/pico8-env.js.map +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +8 -2
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/sfx.d.ts.map +1 -1
- package/dist/commands/sfx.js +99 -11
- package/dist/commands/sfx.js.map +1 -1
- package/dist/engine/audio/analyze.d.ts +164 -0
- package/dist/engine/audio/analyze.d.ts.map +1 -0
- package/dist/engine/audio/analyze.js +512 -0
- package/dist/engine/audio/analyze.js.map +1 -0
- package/dist/engine/audio/index.d.ts +4 -2
- package/dist/engine/audio/index.d.ts.map +1 -1
- package/dist/engine/audio/index.js +4 -2
- package/dist/engine/audio/index.js.map +1 -1
- package/dist/engine/audio/score.d.ts +137 -0
- package/dist/engine/audio/score.d.ts.map +1 -0
- package/dist/engine/audio/score.js +420 -0
- package/dist/engine/audio/score.js.map +1 -0
- package/dist/engine/audio/section.d.ts +7 -0
- package/dist/engine/audio/section.d.ts.map +1 -1
- package/dist/engine/audio/section.js +17 -0
- package/dist/engine/audio/section.js.map +1 -1
- package/dist/engine/audio/sfx.d.ts +114 -12
- package/dist/engine/audio/sfx.d.ts.map +1 -1
- package/dist/engine/audio/sfx.js +236 -33
- package/dist/engine/audio/sfx.js.map +1 -1
- package/dist/engine/pico8/harness.d.ts +11 -5
- package/dist/engine/pico8/harness.d.ts.map +1 -1
- package/dist/engine/pico8/harness.js +24 -10
- package/dist/engine/pico8/harness.js.map +1 -1
- package/dist/engine/scaffold/scaffold.d.ts.map +1 -1
- package/dist/engine/scaffold/scaffold.js +5 -1
- package/dist/engine/scaffold/scaffold.js.map +1 -1
- package/package.json +2 -2
- package/src/cli.test.ts +42 -1
- package/src/cli.ts +143 -37
- package/src/commands/audio.test.ts +170 -1
- package/src/commands/audio.ts +294 -30
- package/src/commands/doctor.test.ts +1 -0
- package/src/commands/doctor.ts +8 -3
- package/src/commands/gfx.ts +12 -9
- package/src/commands/music.test.ts +119 -0
- package/src/commands/music.ts +251 -1
- package/src/commands/pico8-env.ts +71 -3
- package/src/commands/run.ts +8 -2
- package/src/commands/sfx.test.ts +55 -0
- package/src/commands/sfx.ts +118 -11
- package/src/engine/audio/analyze.test.ts +239 -0
- package/src/engine/audio/analyze.ts +664 -0
- package/src/engine/audio/index.ts +46 -1
- package/src/engine/audio/score.test.ts +402 -0
- package/src/engine/audio/score.ts +630 -0
- package/src/engine/audio/section.ts +19 -0
- package/src/engine/audio/sfx.test.ts +219 -4
- package/src/engine/audio/sfx.ts +326 -40
- package/src/engine/pico8/harness.test.ts +19 -0
- package/src/engine/pico8/harness.ts +29 -11
- package/src/engine/scaffold/scaffold.ts +5 -1
- package/src/mcp.process.test.ts +219 -0
- package/src/skills/picopilot-audio/SKILL.md +74 -184
- package/src/skills/picopilot-overview/SKILL.md +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'incur';
|
|
2
|
-
import { DEFAULT_DISPLAY_MODE, isDisplayMode, pico8ChildEnv, ShellPico8Adapter, } from '../engine/pico8/index.js';
|
|
2
|
+
import { DEFAULT_DISPLAY_MODE, DISPLAY_MODES, isDisplayMode, pico8ChildEnv, ShellPico8Adapter, } from '../engine/pico8/index.js';
|
|
3
3
|
/**
|
|
4
4
|
* The env schema every PICO-8-gated command declares. These are the values
|
|
5
5
|
* picopilot itself RESOLVES (incur reads them from its env source, which tests
|
|
@@ -28,9 +28,20 @@ export function createShellAdapterFactory(deps = {}) {
|
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
|
-
* The display
|
|
32
|
-
*
|
|
33
|
-
*
|
|
31
|
+
* The `display` option of the commands that use the display mode (`run`,
|
|
32
|
+
* `audio record`, `audio render`, `doctor`). A per-command option, not an incur
|
|
33
|
+
* global, because incur's MCP transport passes no globals: as an option it is
|
|
34
|
+
* also an argument of the MCP tool. Unset = the invocation-level value.
|
|
35
|
+
*/
|
|
36
|
+
export const DISPLAY_OPTION = z
|
|
37
|
+
.enum(DISPLAY_MODES)
|
|
38
|
+
.optional()
|
|
39
|
+
.describe('How a PICO-8 -run session (audio recording) gets a display: auto (default: a private virtual display only when there is none), xvfb (always virtual), native (as-is). Else PICOPILOT_DISPLAY, else picopilot.json "display".');
|
|
40
|
+
/**
|
|
41
|
+
* The display mode the root middleware in `createCli` resolved for this
|
|
42
|
+
* invocation (top-level `--display` > PICOPILOT_DISPLAY > picopilot.json >
|
|
43
|
+
* auto). A command mounted on a bare CLI (some tests) has no var and gets the
|
|
44
|
+
* default.
|
|
34
45
|
*/
|
|
35
46
|
export function displayModeOf(vars) {
|
|
36
47
|
const value = vars !== null && typeof vars === 'object'
|
|
@@ -38,6 +49,42 @@ export function displayModeOf(vars) {
|
|
|
38
49
|
: undefined;
|
|
39
50
|
return isDisplayMode(value) ? value : DEFAULT_DISPLAY_MODE;
|
|
40
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* The display mode a command uses: its own `display` option (a per-call MCP
|
|
54
|
+
* argument) wins, else the invocation-level value. An invalid invocation-level
|
|
55
|
+
* value (a typo in PICOPILOT_DISPLAY, say) is an `invalid-display-mode` error
|
|
56
|
+
* here, so only the commands that use the mode fail on it.
|
|
57
|
+
*/
|
|
58
|
+
export function resolveCommandDisplay(option, vars) {
|
|
59
|
+
if (option !== undefined)
|
|
60
|
+
return { ok: true, mode: option };
|
|
61
|
+
const problem = vars !== null && typeof vars === 'object'
|
|
62
|
+
? vars.displayError
|
|
63
|
+
: undefined;
|
|
64
|
+
if (typeof problem === 'string') {
|
|
65
|
+
return {
|
|
66
|
+
ok: false,
|
|
67
|
+
error: { code: 'invalid-display-mode', message: problem, exitCode: 1 },
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return { ok: true, mode: displayModeOf(vars) };
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Under `--mcp`, incur loads no config file, so picopilot loads picopilot.json
|
|
74
|
+
* itself and hands the tree to commands as the `mcpConfig` var. A command whose
|
|
75
|
+
* option can come from the config reads its fallback here (CLI runs get it from
|
|
76
|
+
* incur as the option's default, so this is undefined there).
|
|
77
|
+
*/
|
|
78
|
+
export function mcpConfigOption(vars, commandPath, key) {
|
|
79
|
+
let node = vars !== null && typeof vars === 'object'
|
|
80
|
+
? vars.mcpConfig
|
|
81
|
+
: undefined;
|
|
82
|
+
for (const part of commandPath) {
|
|
83
|
+
node = node
|
|
84
|
+
?.commands?.[part];
|
|
85
|
+
}
|
|
86
|
+
return node?.options?.[key];
|
|
87
|
+
}
|
|
41
88
|
/**
|
|
42
89
|
* The `error(...)` payload for a `display-unavailable` result (ADR-0017): the
|
|
43
90
|
* session needs a display, there is none, and no Xvfb is installed to provide a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pico8-env.js","sourceRoot":"","sources":["../../src/commands/pico8-env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,CAAC,EAAC,MAAM,OAAO,CAAC;AACxB,OAAO,EACN,oBAAoB,
|
|
1
|
+
{"version":3,"file":"pico8-env.js","sourceRoot":"","sources":["../../src/commands/pico8-env.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AASA,OAAO,EAAC,KAAK,GAAG,EAAI,MAAM,OAAO,CAAC;AAOlC,OAAO,
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AASA,OAAO,EAAC,KAAK,GAAG,EAAI,MAAM,OAAO,CAAC;AAOlC,OAAO,EAON,KAAK,mBAAmB,EACxB,MAAM,gBAAgB,CAAC;AAExB;;;;GAIG;AACH,YAAY,EAAC,mBAAmB,EAAC,MAAM,gBAAgB,CAAC;AAOxD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAC1B,GAAG,EAAE,GAAG,CAAC,GAAG,EACZ,cAAc,GAAE,mBAA2C,GACzD,IAAI,CA4QN"}
|
package/dist/commands/run.js
CHANGED
|
@@ -4,7 +4,7 @@ import { isAbsolute, join, resolve } from 'node:path';
|
|
|
4
4
|
import { z } from 'incur';
|
|
5
5
|
import { buildRecordHarness, DONE_SENTINEL, HarnessError, } from '../engine/pico8/index.js';
|
|
6
6
|
import { makeReadInclude } from './cart-includes.js';
|
|
7
|
-
import { createShellAdapterFactory,
|
|
7
|
+
import { createShellAdapterFactory, DISPLAY_OPTION, displayUnavailableError, PICO8_ENV, pico8NotFoundError, resolveCommandDisplay, } from './pico8-env.js';
|
|
8
8
|
const defaultAdapterFactory = createShellAdapterFactory();
|
|
9
9
|
/** The default backstop: kill a cart that never signals/exits after this many ms. */
|
|
10
10
|
const DEFAULT_BACKSTOP_MS = 15_000;
|
|
@@ -55,6 +55,7 @@ export function registerRun(cli, adapterFactory = defaultAdapterFactory) {
|
|
|
55
55
|
.string()
|
|
56
56
|
.optional()
|
|
57
57
|
.describe('One-shot scripted input passed as `-p` (the cart reads it via stat(6)) for automated playtests.'),
|
|
58
|
+
display: DISPLAY_OPTION,
|
|
58
59
|
recordAudio: z
|
|
59
60
|
.boolean()
|
|
60
61
|
.default(false)
|
|
@@ -125,8 +126,13 @@ export function registerRun(cli, adapterFactory = defaultAdapterFactory) {
|
|
|
125
126
|
: mkdtempSync(join(tmpdir(), 'picopilot-run-'));
|
|
126
127
|
if (!existsSync(shotDir))
|
|
127
128
|
mkdirSync(shotDir, { recursive: true });
|
|
129
|
+
// The display mode only matters to the --record-audio (-run) pass, so a
|
|
130
|
+
// bad PICOPILOT_DISPLAY only fails a run that records.
|
|
131
|
+
const display = resolveCommandDisplay(options.display, vars);
|
|
132
|
+
if (options.recordAudio && !display.ok)
|
|
133
|
+
return error(display.error);
|
|
128
134
|
const adapter = adapterFactory(env, {
|
|
129
|
-
display:
|
|
135
|
+
display: display.ok ? display.mode : 'auto',
|
|
130
136
|
});
|
|
131
137
|
const result = await adapter.run({
|
|
132
138
|
cartPath,
|
package/dist/commands/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,UAAU,EACV,SAAS,EACT,WAAW,EACX,YAAY,EACZ,aAAa,GACb,MAAM,SAAS,CAAC;AACjB,OAAO,EAAC,MAAM,EAAC,MAAM,SAAS,CAAC;AAC/B,OAAO,EAAC,UAAU,EAAE,IAAI,EAAE,OAAO,EAAC,MAAM,WAAW,CAAC;AACpD,OAAO,EAAW,CAAC,EAAC,MAAM,OAAO,CAAC;AAClC,OAAO,EACN,kBAAkB,EAClB,aAAa,EACb,YAAY,GACZ,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAC,eAAe,EAAC,MAAM,oBAAoB,CAAC;AACnD,OAAO,EACN,yBAAyB,EACzB,
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sfx.d.ts","sourceRoot":"","sources":["../../src/commands/sfx.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,GAAG,EAAI,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"sfx.d.ts","sourceRoot":"","sources":["../../src/commands/sfx.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,GAAG,EAAI,MAAM,OAAO,CAAC;AAwY7B;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,GAAG,IAAI,CAE9C"}
|
package/dist/commands/sfx.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { isAbsolute, resolve } from 'node:path';
|
|
3
3
|
import { Cli, z } from 'incur';
|
|
4
|
-
import { AudioMmlError, mergeSfxRow, mmlToSfxRow, PITCH_MAX, SFX_MAX_ROWS, SFX_SLOT_COUNT, } from '../engine/audio/index.js';
|
|
4
|
+
import { AudioMmlError, clearSfxSlot, formatSlots, isFreeSfxRow, mergeSfxRow, mmlToSfxRow, parseSlotList, PITCH_MAX, readSfxRows, SFX_MAX_ROWS, SFX_SLOT_COUNT, } from '../engine/audio/index.js';
|
|
5
5
|
import { Cart, CartParseError } from '../engine/cart/index.js';
|
|
6
6
|
/** Resolves a path argument to an absolute path (relative to cwd). */
|
|
7
7
|
function resolvePath(p) {
|
|
@@ -43,7 +43,7 @@ function buildSfxGroup() {
|
|
|
43
43
|
description: 'Compose SFX as text: transpile picopilot-MML into a cart __sfx__ slot. Durations are TRACKER ROWS at one SFX speed, NOT tempo/BPM (PICO-8 has no per-note duration).',
|
|
44
44
|
});
|
|
45
45
|
sfx.command('from-mml', {
|
|
46
|
-
description: 'Transpile picopilot-MML text into one __sfx__ slot (0-63) and merge it into the cart (only that slot changes). picopilot-MML is TRACKER-ROW based: a length is a ROW COUNT (l4 = 4 rows), NOT a musical note value, and there is NO tempo/BPM (PICO-8 measures in ticks/row via `s<N>` speed). Notes carry per-note waveform (@0-7, @8-f = custom SFX-instrument), volume (v0-7), and effect (e0-7) that a score notation cannot express. SFX-level FILTER directives reach DESIGNED sounds (explosion/engine/pad): !dampen[2] (low-pass body), !reverb (echo tail), !noiz (@6 white noise), !buzz, !detune1/!detune2. Out-of-range pitch (below C0 / above D#5), >32 rows, and a bad filter level are refused loudly, never silently clamped.',
|
|
46
|
+
description: 'Transpile picopilot-MML text into one __sfx__ slot (0-63) and merge it into the cart (only that slot changes). picopilot-MML is TRACKER-ROW based: a length is a ROW COUNT (l4 = 4 rows), NOT a musical note value, and there is NO tempo/BPM (PICO-8 measures in ticks/row via `s<N>` speed). Notes carry per-note waveform (@0-7, @8-f = custom SFX-instrument), volume (v0-7), and effect (e0-7) that a score notation cannot express. A held note (c8) is ONE note: fade in/out and drop land once per held note, not on every row (ADR-0019); shape its volume with an envelope v[3 2 2 1/0] (one digit per row, last value held, after / = release) and delay vibrato with ~N (vibrato from row N). For melodies over 32 rows use `music from-score`. SFX-level FILTER directives reach DESIGNED sounds (explosion/engine/pad): !dampen[2] (low-pass body), !reverb (echo tail), !noiz (@6 white noise), !buzz, !detune1/!detune2. Out-of-range pitch (below C0 / above D#5), >32 rows, and a bad filter level are refused loudly, never silently clamped.',
|
|
47
47
|
args: z.object({
|
|
48
48
|
slot: z.coerce
|
|
49
49
|
.number()
|
|
@@ -54,7 +54,7 @@ function buildSfxGroup() {
|
|
|
54
54
|
mml: z
|
|
55
55
|
.string()
|
|
56
56
|
.optional()
|
|
57
|
-
.describe('The picopilot-MML source (e.g. "s16 @1 v6 c d e f"). Omit and pass --file to read from a file instead. Modal state: @ waveform, v volume, e effect, o octave, l default length (all sticky). Durations are ROWS: c4 =
|
|
57
|
+
.describe('The picopilot-MML source (e.g. "s16 @1 v6 c d e f"). Omit and pass --file to read from a file instead. Modal state: @ waveform, v volume or v[...] envelope, e effect, ~N delayed vibrato, o octave, l default length (all sticky). Durations are ROWS: c4 = one note held 4 rows. Loop with {..}; a lone { marks the pattern LEN. SFX filters (per-SFX, place anywhere): !dampen/!dampen2, !reverb, !noiz, !buzz, !detune1/!detune2 (e.g. "!dampen !reverb @6 v7 o3 e c o1 g" = an explosion).'),
|
|
58
58
|
}),
|
|
59
59
|
options: z.object({
|
|
60
60
|
cart: z
|
|
@@ -107,6 +107,10 @@ function buildSfxGroup() {
|
|
|
107
107
|
description: 'A DESIGNED explosion: DAMPEN body + REVERB tail on @6 noise',
|
|
108
108
|
args: { slot: 3, mml: 's7 !dampen2 !reverb @6 v7 o3 e c o1 g c' },
|
|
109
109
|
},
|
|
110
|
+
{
|
|
111
|
+
description: 'A soft lead note: held 8 rows with a decaying envelope and vibrato from row 4',
|
|
112
|
+
args: { slot: 6, mml: 's16 !dampen @0 ~4 v[3 3 2 2 2 1/1 0] o2 a8' },
|
|
113
|
+
},
|
|
110
114
|
{
|
|
111
115
|
description: 'Read a longer source from a file',
|
|
112
116
|
args: { slot: 1 },
|
|
@@ -169,25 +173,35 @@ function buildSfxGroup() {
|
|
|
169
173
|
}
|
|
170
174
|
: e.code === 'audio-mml-sfx-overflow'
|
|
171
175
|
? {
|
|
172
|
-
description: `One SFX holds at most ${SFX_MAX_ROWS} rows;
|
|
176
|
+
description: `One SFX holds at most ${SFX_MAX_ROWS} rows; for longer melodies:`,
|
|
173
177
|
commands: [
|
|
174
178
|
{
|
|
175
|
-
command: '
|
|
176
|
-
description: '
|
|
179
|
+
command: 'music from-score --file score.json',
|
|
180
|
+
description: 'Write each voice at any length; picopilot splits it into SFX + patterns.',
|
|
177
181
|
},
|
|
178
182
|
],
|
|
179
183
|
}
|
|
180
|
-
: e.code === 'audio-mml-
|
|
184
|
+
: e.code === 'audio-mml-tie-state-change'
|
|
181
185
|
? {
|
|
182
|
-
description: '
|
|
186
|
+
description: 'A tie continues one held note; shape it instead:',
|
|
183
187
|
commands: [
|
|
184
188
|
{
|
|
185
|
-
command: 'sfx from-mml <slot> "
|
|
186
|
-
description: '
|
|
189
|
+
command: 'sfx from-mml <slot> "v[3 2 2 1] c8"',
|
|
190
|
+
description: 'A volume envelope: one digit per row, last value held.',
|
|
187
191
|
},
|
|
188
192
|
],
|
|
189
193
|
}
|
|
190
|
-
:
|
|
194
|
+
: e.code === 'audio-mml-filter-level-out-of-range'
|
|
195
|
+
? {
|
|
196
|
+
description: 'The SFX filters + their valid levels:',
|
|
197
|
+
commands: [
|
|
198
|
+
{
|
|
199
|
+
command: 'sfx from-mml <slot> "!dampen[2] !reverb !noiz !buzz !detune1/!detune2 ..."',
|
|
200
|
+
description: '!dampen has 2 levels (!dampen/!dampen2); !reverb/!noiz/!buzz are on/off; !detune needs 1 or 2.',
|
|
201
|
+
},
|
|
202
|
+
],
|
|
203
|
+
}
|
|
204
|
+
: undefined;
|
|
191
205
|
return error({
|
|
192
206
|
code: e.code,
|
|
193
207
|
message: e.message,
|
|
@@ -236,6 +250,80 @@ function buildSfxGroup() {
|
|
|
236
250
|
});
|
|
237
251
|
},
|
|
238
252
|
});
|
|
253
|
+
sfx.command('clear', {
|
|
254
|
+
description: 'Clear SFX slots back to EMPTY (no notes). Only the named slots change; every other slot and section stays byte-identical. Use it to free slots for `music from-score` or to remove a leftover song.',
|
|
255
|
+
args: z.object({
|
|
256
|
+
slots: z
|
|
257
|
+
.string()
|
|
258
|
+
.describe('The slots to clear: one slot ("5"), a range ("16-63"), or a list ("3,5,16-20").'),
|
|
259
|
+
}),
|
|
260
|
+
options: z.object({
|
|
261
|
+
cart: z
|
|
262
|
+
.string()
|
|
263
|
+
.default('main.p8')
|
|
264
|
+
.describe('The .p8 cart to edit. Defaults to main.p8 in the current folder.'),
|
|
265
|
+
}),
|
|
266
|
+
output: z.object({
|
|
267
|
+
cart: z
|
|
268
|
+
.string()
|
|
269
|
+
.describe('The absolute path of the cart that was written.'),
|
|
270
|
+
cleared: z
|
|
271
|
+
.array(z.number())
|
|
272
|
+
.describe('The slots that held notes and are now empty.'),
|
|
273
|
+
alreadyEmpty: z
|
|
274
|
+
.array(z.number())
|
|
275
|
+
.describe('The named slots that had no notes already (left byte-identical).'),
|
|
276
|
+
}),
|
|
277
|
+
examples: [
|
|
278
|
+
{ description: 'Clear slot 11', args: { slots: '11' } },
|
|
279
|
+
{
|
|
280
|
+
description: 'Clear a whole music range of a cart',
|
|
281
|
+
args: { slots: '16-63' },
|
|
282
|
+
options: { cart: 'game.p8' },
|
|
283
|
+
},
|
|
284
|
+
],
|
|
285
|
+
run({ args, options, error, ok }) {
|
|
286
|
+
const slots = parseSlotList(args.slots);
|
|
287
|
+
if (slots === undefined) {
|
|
288
|
+
return error({
|
|
289
|
+
code: 'bad-slot-list',
|
|
290
|
+
message: `"${args.slots}" is not a slot list within 0-${SFX_SLOT_COUNT - 1}: use "5", "16-63" or "3,5,16-20".`,
|
|
291
|
+
exitCode: 1,
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
const cartPath = resolvePath(options.cart);
|
|
295
|
+
const loaded = loadCart(cartPath);
|
|
296
|
+
if (!loaded.ok) {
|
|
297
|
+
return error({ code: loaded.code, message: loaded.message, exitCode: 1 });
|
|
298
|
+
}
|
|
299
|
+
const before = readSfxRows(loaded.cart);
|
|
300
|
+
const cleared = [];
|
|
301
|
+
const alreadyEmpty = [];
|
|
302
|
+
for (const slot of slots) {
|
|
303
|
+
// A note-less slot is already empty: leave its bytes (header) alone.
|
|
304
|
+
if (isFreeSfxRow(before[slot])) {
|
|
305
|
+
alreadyEmpty.push(slot);
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
308
|
+
cleared.push(slot);
|
|
309
|
+
clearSfxSlot(loaded.cart, slot);
|
|
310
|
+
}
|
|
311
|
+
writeFileSync(cartPath, loaded.cart.serialize());
|
|
312
|
+
return ok({ cart: cartPath, cleared, alreadyEmpty }, cleared.length > 0
|
|
313
|
+
? {
|
|
314
|
+
cta: {
|
|
315
|
+
description: `Cleared SFX ${formatSlots(cleared)}. If __music__ still references them, those channels are now silent:`,
|
|
316
|
+
commands: [
|
|
317
|
+
{
|
|
318
|
+
command: 'verify',
|
|
319
|
+
description: 'Static gate: the cart still parses.',
|
|
320
|
+
},
|
|
321
|
+
],
|
|
322
|
+
},
|
|
323
|
+
}
|
|
324
|
+
: undefined);
|
|
325
|
+
},
|
|
326
|
+
});
|
|
239
327
|
return sfx;
|
|
240
328
|
}
|
|
241
329
|
/**
|
package/dist/commands/sfx.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sfx.js","sourceRoot":"","sources":["../../src/commands/sfx.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,YAAY,EAAE,aAAa,EAAC,MAAM,SAAS,CAAC;AAChE,OAAO,EAAC,UAAU,EAAE,OAAO,EAAC,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAC,GAAG,EAAE,CAAC,EAAC,MAAM,OAAO,CAAC;AAE7B,OAAO,EACN,aAAa,EACb,WAAW,EACX,WAAW,EACX,SAAS,EACT,YAAY,EACZ,cAAc,GACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAC,IAAI,EAAE,cAAc,EAAC,MAAM,yBAAyB,CAAC;AAE7D,sEAAsE;AACtE,SAAS,WAAW,CAAC,CAAS;IAC7B,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;AACtD,CAAC;AAED;;;GAGG;AACH,SAAS,QAAQ,CAChB,QAAgB;IAEhB,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3B,OAAO;YACN,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,gBAAgB;YACtB,OAAO,EAAE,cAAc,QAAQ,EAAE;SACjC,CAAC;IACH,CAAC;IACD,MAAM,IAAI,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC5C,IAAI,CAAC;QACJ,OAAO,EAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACZ,IAAI,CAAC,YAAY,cAAc,EAAE,CAAC;YACjC,OAAO;gBACN,EAAE,EAAE,KAAK;gBACT,IAAI,EAAE,mBAAmB;gBACzB,OAAO,EAAE,WAAW,QAAQ,oBAAoB,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,OAAO,EAAE;aACvE,CAAC;QACH,CAAC;QACD,MAAM,CAAC,CAAC;IACT,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa;IACrB,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE;QAC7B,WAAW,EACV,sKAAsK;KACvK,CAAC,CAAC;IAEH,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE;QACvB,WAAW,EACV,
|
|
1
|
+
{"version":3,"file":"sfx.js","sourceRoot":"","sources":["../../src/commands/sfx.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `engine/audio`: "ears" for a model that cannot hear. Measures a WAV (a
|
|
3
|
+
* `picopilot audio render` / `audio record` capture) and turns the numbers into
|
|
4
|
+
* plain-language warnings: too loud, shrill, monotonous, spiky, repetitive.
|
|
5
|
+
*
|
|
6
|
+
* Pure TypeScript (no Python, no PICO-8): a RIFF/WAVE PCM reader, a radix-2
|
|
7
|
+
* FFT, and frame statistics. The thresholds are CALIBRATED on the conquest
|
|
8
|
+
* dogfood (finding `pico8-audio-music-taste-and-analysis`): a soundtrack the
|
|
9
|
+
* user called shrill and grating, one called "far too violent", and the two
|
|
10
|
+
* accepted ones, all measured this way.
|
|
11
|
+
*
|
|
12
|
+
* Measures are over the recording minus its first `skipSeconds` (default 1 s,
|
|
13
|
+
* as in the calibration: the cart's own startup for `audio record`, a song's
|
|
14
|
+
* first notes for `audio render`; an SFX render skips nothing), in
|
|
15
|
+
* non-overlapping frames of {@link FRAME_SIZE} samples.
|
|
16
|
+
*/
|
|
17
|
+
/** Samples per analysis frame (93 ms at PICO-8's 22050 Hz). */
|
|
18
|
+
export declare const FRAME_SIZE = 2048;
|
|
19
|
+
/** A frame quieter than this RMS (about -50 dBFS) counts as silence. */
|
|
20
|
+
export declare const SILENCE_RMS = 0.003;
|
|
21
|
+
/** The loudness-profile step, in seconds. */
|
|
22
|
+
export declare const PROFILE_STEP_SECONDS = 0.5;
|
|
23
|
+
/**
|
|
24
|
+
* The warning thresholds (documented in the picopilot-audio skill and the
|
|
25
|
+
* finding). Calibration, mean RMS / centroid / energy above 2 kHz / dynamic
|
|
26
|
+
* range / loop:
|
|
27
|
+
* - shrill, grating first track: 0.156 / 1286 Hz / 13.2 % / 1.9 dB / ~15 s;
|
|
28
|
+
* - "far too violent": 0.195 / 612 Hz / 3.1 %;
|
|
29
|
+
* - accepted title: 0.097 / 459 Hz / 0.2 % / 7 dB;
|
|
30
|
+
* - accepted in-game: 0.069 / 378 Hz / - / 8 dB / ~64 s.
|
|
31
|
+
*/
|
|
32
|
+
export declare const THRESHOLDS: {
|
|
33
|
+
/** Mean frame RMS above this: too loud for music under SFX. */
|
|
34
|
+
readonly loudMeanRms: 0.12;
|
|
35
|
+
/** Mean frame RMS below this: (nearly) nothing was captured. */
|
|
36
|
+
readonly quietMeanRms: 0.01;
|
|
37
|
+
/** Median spectral centroid above this (Hz): shrill. */
|
|
38
|
+
readonly shrillCentroidHz: 900;
|
|
39
|
+
/** Median spectral centroid above this (Hz): on the bright side. */
|
|
40
|
+
readonly brightCentroidHz: 550;
|
|
41
|
+
/** Share of energy above 2 kHz above this (%): shrill. */
|
|
42
|
+
readonly shrillAbove2kHzPercent: 8;
|
|
43
|
+
/** Share of energy above 2 kHz above this (%): on the bright side. */
|
|
44
|
+
readonly brightAbove2kHzPercent: 2;
|
|
45
|
+
/** Dynamic range (p90 - p10 frame level) below this (dB): monotonous. */
|
|
46
|
+
readonly flatRangeDb: 4;
|
|
47
|
+
/** Loudest frame over the median frame above this ratio: spikes. */
|
|
48
|
+
readonly spikeRatio: 3;
|
|
49
|
+
/** 99.9th-percentile absolute sample above this: close to clipping. */
|
|
50
|
+
readonly clipSample: 0.9;
|
|
51
|
+
/** A detected loop shorter than this (s): repetitive. */
|
|
52
|
+
readonly shortLoopSeconds: 20;
|
|
53
|
+
/** Music louder than this relative to the reference SFX (dB): SFX get buried. */
|
|
54
|
+
readonly musicOverSfxDb: -3;
|
|
55
|
+
};
|
|
56
|
+
/** A decoded WAV: mono samples in [-1, 1]. */
|
|
57
|
+
export interface DecodedWav {
|
|
58
|
+
sampleRate: number;
|
|
59
|
+
channels: number;
|
|
60
|
+
samples: Float32Array;
|
|
61
|
+
}
|
|
62
|
+
/** A structured analysis failure. */
|
|
63
|
+
export declare class AudioAnalyzeError extends Error {
|
|
64
|
+
readonly code: 'audio-analyze-bad-wav' | 'audio-analyze-too-short';
|
|
65
|
+
constructor(code: AudioAnalyzeError['code'], message: string);
|
|
66
|
+
}
|
|
67
|
+
/** One plain-language finding about the recording. */
|
|
68
|
+
export interface AnalysisWarning {
|
|
69
|
+
code: 'loud' | 'near-silent' | 'shrill' | 'bright' | 'monotonous' | 'spikes' | 'near-clipping' | 'repetitive' | 'music-over-sfx';
|
|
70
|
+
message: string;
|
|
71
|
+
}
|
|
72
|
+
/** The analysis of one recording. */
|
|
73
|
+
export interface AudioAnalysis {
|
|
74
|
+
sampleRate: number;
|
|
75
|
+
/** Length of the whole file, in seconds. */
|
|
76
|
+
durationSeconds: number;
|
|
77
|
+
/** Seconds skipped at the start (PICO-8 startup). */
|
|
78
|
+
skippedSeconds: number;
|
|
79
|
+
/** Seconds actually analysed. */
|
|
80
|
+
analyzedSeconds: number;
|
|
81
|
+
loudness: {
|
|
82
|
+
/** Mean RMS of the 2048-sample frames (0..1). */
|
|
83
|
+
meanRms: number;
|
|
84
|
+
/** Median frame RMS. */
|
|
85
|
+
medianRms: number;
|
|
86
|
+
/** The loudest frame's RMS. */
|
|
87
|
+
peakFrameRms: number;
|
|
88
|
+
/** When the loudest frame starts, in seconds from the start of the file. */
|
|
89
|
+
peakFrameAtSeconds: number;
|
|
90
|
+
/** The 99.9th-percentile absolute sample (0..1). */
|
|
91
|
+
peakSample: number;
|
|
92
|
+
/** Share of frames that are silence (%). */
|
|
93
|
+
silentPercent: number;
|
|
94
|
+
};
|
|
95
|
+
brightness: {
|
|
96
|
+
/** Median energy-weighted spectral centroid of the non-silent frames (Hz). */
|
|
97
|
+
centroidHz: number;
|
|
98
|
+
/** Share of spectral energy above 2 kHz (%). */
|
|
99
|
+
above2kHzPercent: number;
|
|
100
|
+
};
|
|
101
|
+
/** p90 minus p10 of the non-silent frames' level (dB). */
|
|
102
|
+
dynamicRangeDb: number;
|
|
103
|
+
profile: {
|
|
104
|
+
stepSeconds: number;
|
|
105
|
+
/** RMS per step. */
|
|
106
|
+
rms: number[];
|
|
107
|
+
/** The same, as a one-line bar chart (relative to the loudest step). */
|
|
108
|
+
sparkline: string;
|
|
109
|
+
};
|
|
110
|
+
/** The repetition (loop) length, when one is detectable. */
|
|
111
|
+
loop: {
|
|
112
|
+
seconds: number;
|
|
113
|
+
confidence: number;
|
|
114
|
+
} | {
|
|
115
|
+
seconds: null;
|
|
116
|
+
reason: string;
|
|
117
|
+
};
|
|
118
|
+
/** Loudness against a reference SFX recording (`--against`). */
|
|
119
|
+
against?: {
|
|
120
|
+
/** The reference's mean RMS over its non-silent frames. */
|
|
121
|
+
referenceRms: number;
|
|
122
|
+
/** 20*log10(music meanRms / referenceRms): below 0 = the music is quieter. */
|
|
123
|
+
musicOverReferenceDb: number;
|
|
124
|
+
};
|
|
125
|
+
warnings: AnalysisWarning[];
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Decodes a RIFF/WAVE file (PCM 8/16/24/32-bit integer or 32-bit float, any
|
|
129
|
+
* channel count; channels are averaged to mono).
|
|
130
|
+
*
|
|
131
|
+
* @throws {AudioAnalyzeError} `audio-analyze-bad-wav`.
|
|
132
|
+
*/
|
|
133
|
+
export declare function decodeWav(bytes: Uint8Array): DecodedWav;
|
|
134
|
+
/** Encodes mono samples in [-1, 1] as a 16-bit PCM WAV (fixtures, tests). */
|
|
135
|
+
export declare function encodeWav16(samples: Float32Array, sampleRate: number): Uint8Array;
|
|
136
|
+
/** The p-th percentile (0..100) of a numeric array (linear interpolation). */
|
|
137
|
+
export declare function percentile(values: ArrayLike<number>, p: number): number;
|
|
138
|
+
/** A one-line bar chart of non-negative values (blank = silence). */
|
|
139
|
+
export declare function sparkline(values: readonly number[]): string;
|
|
140
|
+
/** The analysis options. */
|
|
141
|
+
export interface AnalyzeOptions {
|
|
142
|
+
/** Seconds to skip at the start (as the calibration did). Default 1. */
|
|
143
|
+
skipSeconds?: number;
|
|
144
|
+
/** A reference SFX recording to compare the music's loudness against. */
|
|
145
|
+
against?: DecodedWav;
|
|
146
|
+
/**
|
|
147
|
+
* What the recording is. `music` (default) applies every warning; `sfx` (a
|
|
148
|
+
* short one-shot with a silent tail) keeps only near-silent and
|
|
149
|
+
* near-clipping, since the music thresholds (loudness, dynamics, spikes,
|
|
150
|
+
* repetition) do not apply to a one-shot sound.
|
|
151
|
+
*/
|
|
152
|
+
kind?: 'music' | 'sfx';
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Analyses a decoded recording. Skips `skipSeconds` (default 1) unless the
|
|
156
|
+
* recording is too short for it (then nothing is skipped and the report says
|
|
157
|
+
* so via `skippedSeconds: 0`).
|
|
158
|
+
*
|
|
159
|
+
* @throws {AudioAnalyzeError} `audio-analyze-too-short` (under one frame).
|
|
160
|
+
*/
|
|
161
|
+
export declare function analyzeAudio(wav: DecodedWav, options?: AnalyzeOptions): AudioAnalysis;
|
|
162
|
+
/** The plain-language warnings for an analysis (see {@link THRESHOLDS}). */
|
|
163
|
+
export declare function warningsFor(a: AudioAnalysis): AnalysisWarning[];
|
|
164
|
+
//# sourceMappingURL=analyze.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../../src/engine/audio/analyze.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,+DAA+D;AAC/D,eAAO,MAAM,UAAU,OAAO,CAAC;AAE/B,wEAAwE;AACxE,eAAO,MAAM,WAAW,QAAQ,CAAC;AAEjC,6CAA6C;AAC7C,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC;;;;;;;;GAQG;AACH,eAAO,MAAM,UAAU;IACtB,+DAA+D;;IAE/D,gEAAgE;;IAEhE,wDAAwD;;IAExD,oEAAoE;;IAEpE,0DAA0D;;IAE1D,sEAAsE;;IAEtE,yEAAyE;;IAEzE,oEAAoE;;IAEpE,uEAAuE;;IAEvE,yDAAyD;;IAEzD,iFAAiF;;CAExE,CAAC;AAEX,8CAA8C;AAC9C,MAAM,WAAW,UAAU;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,YAAY,CAAC;CACtB;AAED,qCAAqC;AACrC,qBAAa,iBAAkB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,IAAI,EAAE,uBAAuB,GAAG,yBAAyB,CAAC;gBACvD,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM;CAK5D;AAED,sDAAsD;AACtD,MAAM,WAAW,eAAe;IAC/B,IAAI,EACD,MAAM,GACN,aAAa,GACb,QAAQ,GACR,QAAQ,GACR,YAAY,GACZ,QAAQ,GACR,eAAe,GACf,YAAY,GACZ,gBAAgB,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,qCAAqC;AACrC,MAAM,WAAW,aAAa;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,eAAe,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,cAAc,EAAE,MAAM,CAAC;IACvB,iCAAiC;IACjC,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE;QACT,iDAAiD;QACjD,OAAO,EAAE,MAAM,CAAC;QAChB,wBAAwB;QACxB,SAAS,EAAE,MAAM,CAAC;QAClB,+BAA+B;QAC/B,YAAY,EAAE,MAAM,CAAC;QACrB,4EAA4E;QAC5E,kBAAkB,EAAE,MAAM,CAAC;QAC3B,oDAAoD;QACpD,UAAU,EAAE,MAAM,CAAC;QACnB,4CAA4C;QAC5C,aAAa,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,UAAU,EAAE;QACX,8EAA8E;QAC9E,UAAU,EAAE,MAAM,CAAC;QACnB,gDAAgD;QAChD,gBAAgB,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,0DAA0D;IAC1D,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE;QACR,WAAW,EAAE,MAAM,CAAC;QACpB,oBAAoB;QACpB,GAAG,EAAE,MAAM,EAAE,CAAC;QACd,wEAAwE;QACxE,SAAS,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,4DAA4D;IAC5D,IAAI,EAAE;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAC,GAAG;QAAC,OAAO,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAC,CAAC;IAC9E,gEAAgE;IAChE,OAAO,CAAC,EAAE;QACT,2DAA2D;QAC3D,YAAY,EAAE,MAAM,CAAC;QACrB,8EAA8E;QAC9E,oBAAoB,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAoEvD;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,CAC1B,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,MAAM,GAChB,UAAU,CAuBZ;AAsCD,8EAA8E;AAC9E,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAOvE;AA2JD,qEAAqE;AACrE,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAW3D;AAED,4BAA4B;AAC5B,MAAM,WAAW,cAAc;IAC9B,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC3B,GAAG,EAAE,UAAU,EACf,OAAO,GAAE,cAAmB,GAC1B,aAAa,CAyGf;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,CAAC,EAAE,aAAa,GAAG,eAAe,EAAE,CAsE/D"}
|