feat(pipeline): transcribe guitar from guitar+piano+other stems

Demucs-6s scatters guitar energy across its guitar, piano and other stems.
Synthetic t1 median guitar F1 rises from 0.39-0.60 to 0.72-0.87; the real
'Last Night on Earth' reference goes 0.390 -> 0.403.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Lucas WintherandClaude Opus 5.5 committed 2026-10-30 20:46:31 +01:00
1 parent c24c7c979f
commit 0f14fbc574
2 files changed
+28 -5

No files matched your search

+16 -2
View File
@@ -40,6 +40,19 @@ export function copyFingering(timed: TimedNote[], assigned: ScoreNote[], grid: G
});
}
/** Sample-wise sum of equally shaped audio buffers. */
export function sumAudio(...as: Audio[]): Audio {
const first = as[0]!;
return {
sampleRate: first.sampleRate,
channels: first.channels.map((c, k) => {
const o = new Float32Array(c.length);
for (const a of as) { const x = a.channels[k]!; for (let i = 0; i < o.length; i++) o[i]! += x[i]!; }
return o;
}),
};
}
export async function createPipeline(
models: { demucs: Uint8Array; basicPitch: Uint8Array },
): Promise<(input: PipelineInput, flags: OracleFlags) => Promise<PipelineResult>> {
@@ -63,9 +76,10 @@ export async function createPipeline(
}
} else {
const s = await separate(input.mix);
warnings.push('demucs "other" stem unused');
const mk = (name: string, role: Role, audio: Audio): Job => ({ name, role, audio, truthNotes: null });
jobs.push(mk("Guitar", "guitar", s.guitar), mk("Bass", "bass", s.bass), mk("Keys", "keys", s.piano),
// Guitar is transcribed from guitar + piano + other: Demucs-6s scatters guitar energy across all three
// (synthetic t1 median guitar F1 0.39–0.60 → 0.72–0.87; real "Last Night on Earth" 0.390 → 0.403).
jobs.push(mk("Guitar", "guitar", sumAudio(s.guitar, s.piano, s.other)), mk("Bass", "bass", s.bass), mk("Keys", "keys", s.piano),
mk("Vocals", "vocals", s.vocals), mk("Drums", "drums", s.drums));
}