This commit is contained in:
Andras Schmelczer 2026-05-18 08:11:52 +01:00
commit 15e99380b5
84 changed files with 1659 additions and 4726 deletions

View file

@ -1,12 +1,18 @@
import type { GardenAudioConfig } from './garden-audio-config';
import { GardenAudioGraph } from './garden-audio-graph';
import { NoiseBurst } from './garden-audio-types';
import { createAudioPanNode } from './audio-pan-node';
import type { GardenAudioGraph } from './garden-audio-graph';
import type { NoiseBurst } from './garden-audio-types';
const noiseBurstTuning = {
attackSeconds: 0.004,
filterQ: 1.4,
offsetRandomSeconds: 0.4,
scheduleAheadSeconds: 0.002,
silentGain: 0.0001,
filterType: 'bandpass' as BiquadFilterType,
};
export class NoiseBurstPlayer {
public constructor(
private readonly config: GardenAudioConfig,
private readonly graph: GardenAudioGraph
) {}
public constructor(private readonly graph: GardenAudioGraph) {}
public play({ startTime, durationSeconds, gain, filterHz, pan }: NoiseBurst): void {
const { context, eventBus, noiseBus, noiseBuffer } = this.graph;
@ -16,35 +22,30 @@ export class NoiseBurstPlayer {
}
const scheduledStart = Math.max(
context.currentTime + this.config.noiseBurst.scheduleAheadSeconds,
context.currentTime + noiseBurstTuning.scheduleAheadSeconds,
startTime
);
const source = context.createBufferSource();
const filter = context.createBiquadFilter();
const envelope = context.createGain();
const panner = context.createStereoPanner();
const panNode = createAudioPanNode(context, pan, scheduledStart);
const stopAt = scheduledStart + durationSeconds;
source.buffer = noiseBuffer;
filter.type = this.config.noiseBurst.filterType;
filter.type = noiseBurstTuning.filterType;
filter.frequency.setValueAtTime(filterHz, scheduledStart);
filter.Q.value = this.config.noiseBurst.filterQ;
envelope.gain.setValueAtTime(this.config.noiseBurst.silentGain, scheduledStart);
filter.Q.value = noiseBurstTuning.filterQ;
envelope.gain.setValueAtTime(noiseBurstTuning.silentGain, scheduledStart);
envelope.gain.exponentialRampToValueAtTime(
Math.max(this.config.noiseBurst.silentGain, gain),
scheduledStart + this.config.noiseBurst.attackSeconds
Math.max(noiseBurstTuning.silentGain, gain),
scheduledStart + noiseBurstTuning.attackSeconds
);
envelope.gain.exponentialRampToValueAtTime(this.config.noiseBurst.silentGain, stopAt);
panner.pan.setValueAtTime(pan, scheduledStart);
envelope.gain.exponentialRampToValueAtTime(noiseBurstTuning.silentGain, stopAt);
source.connect(filter);
filter.connect(envelope);
envelope.connect(panner);
panner.connect(outputBus);
source.start(
scheduledStart,
Math.random() * this.config.noiseBurst.offsetRandomSeconds
);
envelope.connect(panNode.input);
panNode.output.connect(outputBus);
source.start(scheduledStart, Math.random() * noiseBurstTuning.offsetRandomSeconds);
source.stop(stopAt);
source.addEventListener(
'ended',
@ -52,7 +53,7 @@ export class NoiseBurstPlayer {
source.disconnect();
filter.disconnect();
envelope.disconnect();
panner.disconnect();
panNode.disconnect();
},
{ once: true }
);