feat(align): SMF parser, role guess, reference manifest
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
67168e6103
commit
e910036e67
8 files changed
+414
-1
No files matched your search
@@ -0,0 +1,33 @@
|
||||
import { parseArgs } from "node:util";
|
||||
import { addSong, trackKeys } from "../ref/manifest.ts";
|
||||
import { parseSmf } from "./smf.ts";
|
||||
|
||||
const USAGE = `usage: bun run align add <audio> <midi> --id <id> [--title <t>] [--capo "<track name>=9"]...`;
|
||||
|
||||
async function add(argv: string[]) {
|
||||
const { values, positionals } = parseArgs({ args: argv, allowPositionals: true, options: { id: { type: "string" }, title: { type: "string" }, capo: { type: "string", multiple: true } } });
|
||||
const [audio, midi] = positionals;
|
||||
if (!audio || !midi || !values.id) throw new Error(USAGE);
|
||||
const smf = parseSmf(new Uint8Array(await Bun.file(midi).arrayBuffer()));
|
||||
const keys = new Set(trackKeys(smf.tracks));
|
||||
const capo: Record<string, number> = {};
|
||||
for (const c of values.capo ?? []) {
|
||||
const i = c.lastIndexOf("=");
|
||||
const k = c.slice(0, i), n = Number(c.slice(i + 1));
|
||||
if (i < 0 || !Number.isInteger(n) || n < 0) throw new Error(`bad --capo ${JSON.stringify(c)}; expected "<track name>=<fret>"`);
|
||||
if (!keys.has(k)) throw new Error(`--capo: no track named ${JSON.stringify(k)}; tracks: ${[...keys].map((x) => JSON.stringify(x)).join(", ")}`);
|
||||
capo[k] = n;
|
||||
}
|
||||
const e = await addSong({ id: values.id, title: values.title ?? values.id, audio, midi, capo });
|
||||
console.log(`added ${e.id} (${e.title})`);
|
||||
for (const [k, r] of Object.entries(e.roles)) console.log(` ${JSON.stringify(k)} -> ${r ?? "unmapped"}`);
|
||||
}
|
||||
|
||||
const [cmd, ...rest] = process.argv.slice(2);
|
||||
try {
|
||||
if (cmd === "add") await add(rest);
|
||||
else throw new Error(USAGE);
|
||||
} catch (err) {
|
||||
console.error((err as Error).message);
|
||||
process.exit(1);
|
||||
}
|
||||
Reference in new issue
Block a user