28 lines
1.4 KiB
JavaScript
28 lines
1.4 KiB
JavaScript
// Audio the host app supplied survives every pass that rebuilds audio_meta.json from the storyboard: an entry
|
|||
|
|
// marked "source": "host" whose file exists. A frame the host scored takes no looked-up cue sound.
|
||
|
|
/** The host's own entries in an earlier audio_meta.json, and why any other host-marked entry was dropped; `exists`
|
||
|
|
* resolves a path from the project root. A frame written as "1" is frame 1. */
|
||
|
|
export function hostAudio(previous, exists) {
|
||
|
|
const marked = [[previous?.bgm, "path"], ...(previous?.sfx ?? []).map((s) => [s, "file"])].filter(
|
||
|
|
([entry]) => entry?.source === "host",
|
||
|
|
);
|
||
|
|
const kept = new Set();
|
||
|
|
const dropped = [];
|
||
|
|
for (const [entry, key] of marked) {
|
||
|
|
const path = entry[key];
|
||
|
|
if (typeof path !== "string") dropped.push(`a host entry has no "${key}"`);
|
||
|
|
else if (!exists(path)) dropped.push(`${path} is not on disk`);
|
||
|
|
else kept.add(entry);
|
||
|
|
}
|
||
|
|
const bgm = kept.has(previous?.bgm) ? previous.bgm : null;
|
||
|
|
const sfx = (previous?.sfx ?? [])
|
||
|
|
.filter((s) => kept.has(s))
|
||
|
|
.map((s) => ({ ...s, frame: Number(s.frame) }));
|
||
|
|
return { bgm, sfx, frames: new Set(sfx.map((s) => s.frame)), dropped };
|
||
|
|
}
|
||
|
|
|
||
|
|
/** `rebuilt` with the host's bed and sounds put back; the host's bed wins over a looked-up one. */
|
||
|
|
export function keepHostAudio(rebuilt, host) {
|
||
|
|
const looked = (rebuilt.sfx ?? []).filter((s) => !host.frames.has(s.frame));
|
||
|
|
return { ...rebuilt, bgm: host.bgm ?? rebuilt.bgm, sfx: [...host.sfx, ...looked] };
|
||
|
|
}
|