fix: rebalance procedural audio mix

This commit is contained in:
2026-09-02 18:44:24 +03:00
parent 2ea3cab142
commit 7dae835ac5
2 changed files with 29 additions and 6 deletions

View File

@@ -54,7 +54,7 @@ export function createSynthEngine(createContext: AudioContextFactory): AudioGrap
musicFilter.frequency.setValueAtTime(900, context.currentTime); musicFilter.frequency.setValueAtTime(900, context.currentTime);
musicFilter.Q.setValueAtTime(0.72, context.currentTime); musicFilter.Q.setValueAtTime(0.72, context.currentTime);
const musicGain = context.createGain(); const musicGain = context.createGain();
musicGain.gain.setValueAtTime(0.38, context.currentTime); musicGain.gain.setValueAtTime(0.78, context.currentTime);
musicFilter.connect(musicGain); musicFilter.connect(musicGain);
musicGain.connect(dynamics); musicGain.connect(dynamics);
@@ -64,7 +64,7 @@ export function createSynthEngine(createContext: AudioContextFactory): AudioGrap
engineFilter.Q.setValueAtTime(1.25, context.currentTime); engineFilter.Q.setValueAtTime(1.25, context.currentTime);
const engineGain = context.createGain(); const engineGain = context.createGain();
engineGain.gain.setValueAtTime(0.24, context.currentTime); engineGain.gain.setValueAtTime(0.09, context.currentTime);
engineFilter.connect(engineGain); engineFilter.connect(engineGain);
engineGain.connect(dynamics); engineGain.connect(dynamics);
@@ -76,7 +76,7 @@ export function createSynthEngine(createContext: AudioContextFactory): AudioGrap
roadFilter.frequency.setValueAtTime(410, context.currentTime); roadFilter.frequency.setValueAtTime(410, context.currentTime);
roadFilter.Q.setValueAtTime(0.55, context.currentTime); roadFilter.Q.setValueAtTime(0.55, context.currentTime);
const roadGain = context.createGain(); const roadGain = context.createGain();
roadGain.gain.setValueAtTime(0.045, context.currentTime); roadGain.gain.setValueAtTime(0.018, context.currentTime);
roadFilter.connect(roadGain); roadFilter.connect(roadGain);
roadGain.connect(dynamics); roadGain.connect(dynamics);
@@ -90,7 +90,7 @@ export function createSynthEngine(createContext: AudioContextFactory): AudioGrap
ignition.frequency.setValueAtTime(68, context.currentTime); ignition.frequency.setValueAtTime(68, context.currentTime);
const ignitionGain = context.createGain(); const ignitionGain = context.createGain();
ignitionGain.gain.setValueAtTime(0.0001, context.currentTime); ignitionGain.gain.setValueAtTime(0.0001, context.currentTime);
ignitionGain.gain.exponentialRampToValueAtTime(0.07, context.currentTime + 0.12); ignitionGain.gain.exponentialRampToValueAtTime(0.025, context.currentTime + 0.12);
ignitionGain.gain.exponentialRampToValueAtTime(0.0001, context.currentTime + 1.15); ignitionGain.gain.exponentialRampToValueAtTime(0.0001, context.currentTime + 1.15);
ignition.connect(ignitionGain); ignition.connect(ignitionGain);
ignitionGain.connect(engineFilter); ignitionGain.connect(engineFilter);
@@ -154,8 +154,8 @@ export function createSynthEngine(createContext: AudioContextFactory): AudioGrap
engineFilter.frequency.setTargetAtTime(260 + next * 670, time, 0.38); engineFilter.frequency.setTargetAtTime(260 + next * 670, time, 0.38);
roadFilter.frequency.setTargetAtTime(410 + next * 520, time, 0.42); roadFilter.frequency.setTargetAtTime(410 + next * 520, time, 0.42);
musicFilter.frequency.setTargetAtTime(900 + next * 2_400, time, 0.42); musicFilter.frequency.setTargetAtTime(900 + next * 2_400, time, 0.42);
engineGain.gain.setTargetAtTime(0.24 + next * 0.12, time, 0.4); engineGain.gain.setTargetAtTime(0.09 + next * 0.04, time, 0.4);
roadGain.gain.setTargetAtTime(0.045 + next * 0.06, time, 0.45); roadGain.gain.setTargetAtTime(0.018 + next * 0.02, time, 0.45);
music.setIntensity(next, time); music.setIntensity(next, time);
}, },
onContextStateChange(listener) { onContextStateChange(listener) {

View File

@@ -212,6 +212,29 @@ describe('audio controller lifecycle', () => {
}); });
describe('procedural audio graph', () => { describe('procedural audio graph', () => {
it('keeps the soundtrack clearly ahead of the ambient drive effects across intensity changes', async () => {
vi.useFakeTimers();
const context = new FakeAudioContext();
try {
const graph = createSynthEngine(() => context as unknown as AudioContext);
const [, musicGain, engineGain, , , roadGain, ignitionGain] = context.gains;
expect(musicGain?.gain.value).toBe(0.78);
expect(engineGain?.gain.value).toBe(0.09);
expect(roadGain?.gain.value).toBe(0.018);
expect(ignitionGain?.gain.scheduledValues).toEqual([0.0001, 0.025, 0.0001]);
graph.setIntensity(1);
expect(engineGain?.gain.targetValues).toContain(0.13);
expect(roadGain?.gain.targetValues).toContain(0.038);
await graph.close();
} finally {
vi.useRealTimers();
}
});
it('routes independent music, engine, and road buses through compression before the master output', async () => { it('routes independent music, engine, and road buses through compression before the master output', async () => {
vi.useFakeTimers(); vi.useFakeTimers();
const context = new FakeAudioContext(); const context = new FakeAudioContext();