From 9b1b1505f0288fa4b9653e315a6b6311630230ff Mon Sep 17 00:00:00 2001 From: Jage9 Date: Sun, 22 Feb 2026 21:33:11 -0500 Subject: [PATCH] Unify one-shot sample attack smoothing --- client/public/version.js | 2 +- client/src/audio/audioEngine.ts | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/client/public/version.js b/client/public/version.js index 52de58e..a9fe6d1 100644 --- a/client/public/version.js +++ b/client/public/version.js @@ -1,5 +1,5 @@ // Maintainer-controlled web client version. // Format: YYYY.MM.DD Rn (example: 2026.02.20 R2) -window.CHGRID_WEB_VERSION = "2026.02.22 R192"; +window.CHGRID_WEB_VERSION = "2026.02.22 R193"; // Optional display timezone for timestamps. Falls back to America/Detroit if unset/invalid. window.CHGRID_TIME_ZONE = "America/Detroit"; diff --git a/client/src/audio/audioEngine.ts b/client/src/audio/audioEngine.ts index e0db6cf..cfb4710 100644 --- a/client/src/audio/audioEngine.ts +++ b/client/src/audio/audioEngine.ts @@ -31,6 +31,7 @@ type SoundSpec = { type OutputMode = 'stereo' | 'mono'; const SPATIAL_RAMP_SECONDS = 0.2; const SPATIAL_TIME_CONSTANT_SECONDS = SPATIAL_RAMP_SECONDS / 3; +const ONE_SHOT_ATTACK_SECONDS = 0.02; export class AudioEngine { private audioCtx: AudioContext | null = null; @@ -356,7 +357,8 @@ export class AudioEngine { const source = audioCtx.createBufferSource(); source.buffer = buffer; const gainNode = audioCtx.createGain(); - gainNode.gain.value = resolved.gain; + gainNode.gain.setValueAtTime(0, audioCtx.currentTime); + gainNode.gain.setTargetAtTime(resolved.gain, audioCtx.currentTime, ONE_SHOT_ATTACK_SECONDS); source.connect(gainNode); if (resolved.pan !== undefined && this.supportsStereoPanner() && this.outputMode === 'stereo') { const panner = audioCtx.createStereoPanner(); @@ -387,7 +389,8 @@ export class AudioEngine { gainNode.gain.setValueAtTime(0, audioCtx.currentTime); gainNode.gain.linearRampToValueAtTime(gain, audioCtx.currentTime + safeFadeMs / 1000); } else { - gainNode.gain.value = gain; + gainNode.gain.setValueAtTime(0, audioCtx.currentTime); + gainNode.gain.setTargetAtTime(gain, audioCtx.currentTime, ONE_SHOT_ATTACK_SECONDS); } source.connect(gainNode).connect(sfxGainNode); source.start();