feat: daybreak finale turns the contact arrival into a sunrise with a dawn chord

This commit is contained in:
2026-10-11 05:32:08 +03:00
parent c9e6ac0f29
commit b6e22a1299
37 changed files with 756 additions and 44 deletions

View File

@@ -17,6 +17,38 @@ function recordFor(
}
describe('adaptive mixer', () => {
it('sums the dawn input after the mood controls, untouched by chapter moods', () => {
const harness = createFakeAudioHarness();
const connections = new Map<unknown, unknown[]>();
const createGain = harness.context.createGain.bind(harness.context);
harness.context.createGain = () => {
const node = createGain();
const connect = node.connect.bind(node) as (target: AudioNode) => AudioNode;
node.connect = ((target: AudioNode) => {
connections.set(node, [...(connections.get(node) ?? []), target]);
return connect(target);
}) as GainNode['connect'];
return node;
};
const mixer = createAdaptiveMixer(harness.context, harness.destination);
const sum = connections.get(mixer.dawnInput)?.[0];
expect(sum).toBeDefined();
// The same summing node feeds the destination (mute, volume, pulse tap).
expect(connections.get(sum)).toEqual([harness.destination]);
const dawnRecord = recordFor(harness, mixer.dawnInput.gain);
harness.setCurrentTime(2);
mixer.setChapterIntent({
sectionId: 'contact',
mood: 'resolve',
atStart: false,
entryPhrase: 6,
generation: 1,
});
expect(dawnRecord.events).toEqual([]);
mixer.dispose();
expect((mixer.dawnInput as GainNode & { disconnectCount: number }).disconnectCount).toBe(1);
});
it('ramps only the four approved mood controls over 1.4 seconds', () => {
const harness = createFakeAudioHarness();
const mixer = createAdaptiveMixer(harness.context, harness.destination);
@@ -129,7 +161,8 @@ describe('adaptive mixer', () => {
mixer.dispose();
mixer.dispose();
expect(harness.gainNodes).toHaveLength(8);
// Nine with the END OF SHIFT dawn input.
expect(harness.gainNodes).toHaveLength(9);
for (const node of harness.gainNodes) {
expect((node as GainNode & { disconnectCount: number }).disconnectCount).toBe(1);
}