Stop previews when arrowing or selecting

This commit is contained in:
2026-03-12 17:16:17 +01:00
parent 26274c3f31
commit 31abff05f3
3 changed files with 59 additions and 1 deletions

View File

@@ -48,6 +48,9 @@ export class AudioEngine {
private readonly sampleLoaders = new Map<string, Promise<AudioBuffer>>();
private readonly activeSpatialSamples = new Set<ActiveSpatialSampleRuntime>();
private previewSourceNode: AudioBufferSourceNode | null = null;
private previewGainNode: GainNode | null = null;
private outboundSource: MediaStreamAudioSourceNode | null = null;
private outboundInputGain: GainNode | null = null;
private outboundInputGainValue = 1;
@@ -491,6 +494,47 @@ export class AudioEngine {
}
}
stopPreviewSample(): void {
if (this.previewSourceNode) {
try { this.previewSourceNode.stop(); } catch { /* already ended */ }
try { this.previewSourceNode.disconnect(); } catch { /* ignore */ }
this.previewSourceNode = null;
}
if (this.previewGainNode) {
try { this.previewGainNode.disconnect(); } catch { /* ignore */ }
this.previewGainNode = null;
}
}
async playPreviewSample(url: string, gain = 1): Promise<void> {
this.stopPreviewSample();
await this.ensureContext();
const { audioCtx, sfxGainNode } = this;
if (!audioCtx || !sfxGainNode) return;
if (gain <= 0) return;
try {
const buffer = await this.getSampleBuffer(url);
this.stopPreviewSample();
const source = audioCtx.createBufferSource();
source.buffer = buffer;
const gainNode = audioCtx.createGain();
gainNode.gain.setValueAtTime(0, audioCtx.currentTime);
gainNode.gain.setTargetAtTime(gain, audioCtx.currentTime, ONE_SHOT_ATTACK_SECONDS);
source.connect(gainNode).connect(sfxGainNode);
this.previewSourceNode = source;
this.previewGainNode = gainNode;
source.onended = () => {
if (this.previewSourceNode === source) {
this.previewSourceNode = null;
this.previewGainNode = null;
}
};
source.start();
} catch {
// Ignore decode/load errors.
}
}
/** Starts a looping sample and returns a stop callback for explicit teardown. */
async startLoopingSample(url: string, gain = 1): Promise<(() => void) | null> {
await this.ensureContext();