feat: restore restrained drive texture

This commit is contained in:
2026-09-04 15:50:37 +03:00
parent b427d101fa
commit 6fce20a228
3 changed files with 473 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
import { describe, expect, it } from 'vitest';
import { createDriveTexture } from '@/audio/drive-texture';
import { createFakeAudioHarness } from '../helpers/fake-audio-context';
describe('drive texture', () => {
it('preallocates one texture and uses exact attack and release ramps', () => {
const harness = createFakeAudioHarness();
const texture = createDriveTexture(harness.context, harness.destination);
const sourceCount = harness.sources.length;
const eventCount = () => harness.params.flatMap((record) => record.events).length;
harness.setCurrentTime(2);
const beforeAttack = eventCount();
texture.setEnergy({ energy: 1, source: 'physical' });
expect(harness.sources).toHaveLength(sourceCount);
expect(harness.params.flatMap((record) => record.events).slice(beforeAttack))
.toContainEqual(expect.objectContaining({ kind: 'linear', at: 2.22 }));
harness.setCurrentTime(3);
const beforeRelease = eventCount();
texture.setEnergy({ energy: 0, source: 'idle' });
expect(harness.sources).toHaveLength(sourceCount);
expect(harness.params.flatMap((record) => record.events).slice(beforeRelease))
.toContainEqual(expect.objectContaining({ kind: 'linear', at: 3.9 }));
});
it('stops and disconnects every scheduled source exactly once', () => {
const harness = createFakeAudioHarness();
const texture = createDriveTexture(harness.context, harness.destination);
texture.dispose();
texture.dispose();
for (const source of harness.sources) {
expect(source.stops).toHaveLength(1);
expect(source.disconnectCount).toBe(1);
}
});
it('creates deterministic decorrelated stereo road noise', () => {
const first = createFakeAudioHarness();
const second = createFakeAudioHarness();
createDriveTexture(first.context, first.destination);
createDriveTexture(second.context, second.destination);
const firstNoise = first.buffers[0];
const secondNoise = second.buffers[0];
expect(firstNoise).toBeDefined();
expect(secondNoise).toBeDefined();
if (firstNoise === undefined || secondNoise === undefined) return;
expect([...firstNoise.getChannelData(0)]).toEqual([...secondNoise.getChannelData(0)]);
expect([...firstNoise.getChannelData(1)]).toEqual([...secondNoise.getChannelData(1)]);
expect([...firstNoise.getChannelData(0)]).not.toEqual([...firstNoise.getChannelData(1)]);
});
});