import { constantTempoMidi, cropMidi, deleteNote, editNote, dropChannel, encodeMidi, exportMidiCsv, exportMidiJson, parseMidi, quantizeMidi, remapChannel, transposeMidi, type MidiDocument, } from "./midi"; export type MidiOperation = | { kind: "transpose"; semitones: number } | { kind: "quantize"; grid: number } | { kind: "tempo"; bpm: number } | { kind: "crop"; start: number; end: number } | { kind: "remap-channel"; from: number; to: number } | { kind: "drop-channel"; channel: number } | { kind: "edit-note"; onOrder: number; note: number; velocity: number; startTick: number; endTick: number; } | { kind: "delete-note"; onOrder: number }; export type MidiTask = | { kind: "parse"; name: string; bytes: ArrayBuffer } | { kind: "operation"; document: MidiDocument; operation: MidiOperation } | { kind: "export"; document: MidiDocument; format: "midi" | "csv" | "json"; }; export type MidiTaskResult = | { kind: "document"; document: MidiDocument } | { kind: "bytes"; bytes: ArrayBuffer; mimeType: string } | { kind: "text"; text: string; mimeType: string }; /** Pure task entry point shared by the module worker and test fallback. */ export function executeMidiTask(task: MidiTask): MidiTaskResult { if (task.kind === "parse") return { kind: "document", document: parseMidi(task.name, new Uint8Array(task.bytes)), }; if (task.kind === "operation") { const { document, operation } = task; const next = operation.kind === "transpose" ? transposeMidi(document, operation.semitones) : operation.kind === "quantize" ? quantizeMidi(document, operation.grid) : operation.kind === "tempo" ? constantTempoMidi(document, operation.bpm) : operation.kind === "crop" ? cropMidi(document, operation.start, operation.end) : operation.kind === "remap-channel" ? remapChannel(document, operation.from, operation.to) : operation.kind === "drop-channel" ? dropChannel(document, operation.channel) : operation.kind === "edit-note" ? editNote(document, operation.onOrder, operation) : deleteNote(document, operation.onOrder); return { kind: "document", document: next }; } if (task.format === "midi") { const bytes = encodeMidi(task.document); return { kind: "bytes", bytes: Uint8Array.from(bytes).buffer, mimeType: "audio/midi", }; } return { kind: "text", text: task.format === "csv" ? exportMidiCsv(task.document) : exportMidiJson(task.document), mimeType: task.format === "csv" ? "text/csv" : "application/json", }; }