This commit is contained in:
Andras Schmelczer 2026-05-16 16:15:54 +01:00
commit d2da0d1617
25 changed files with 521 additions and 1026 deletions

View file

@ -1,10 +1,6 @@
import type { GardenAudioEngineConfig } from '../config';
import { clamp } from '../utils/clamp';
import { GardenAudioConfig, GardenAudioVibeProfile } from './garden-audio-config';
const UNLOCK_TICK_SECONDS = 0.035;
const UNLOCK_TICK_FREQUENCY_HZ = 440;
export class GardenAudioGraph {
public context: AudioContext | null = null;
public eventBus: GainNode | null = null;
@ -16,10 +12,7 @@ export class GardenAudioGraph {
private delayFeedback: GainNode | null = null;
private delayOutput: GainNode | null = null;
public constructor(
private readonly config: GardenAudioConfig,
private readonly engineConfig: GardenAudioEngineConfig
) {}
public constructor(private readonly config: GardenAudioConfig) {}
public ensureContext(canCreate: boolean): AudioContext | null {
if (this.context) {
@ -73,16 +66,16 @@ export class GardenAudioGraph {
const gain = this.context.createGain();
source.type = 'sine';
source.frequency.setValueAtTime(UNLOCK_TICK_FREQUENCY_HZ, now);
gain.gain.setValueAtTime(this.engineConfig.piano.minGain, now);
source.frequency.setValueAtTime(this.config.graph.unlockTickFrequencyHz, now);
gain.gain.setValueAtTime(this.config.piano.minGain, now);
gain.gain.exponentialRampToValueAtTime(
this.engineConfig.piano.minGain,
now + UNLOCK_TICK_SECONDS
this.config.piano.minGain,
now + this.config.graph.unlockTickSeconds
);
source.connect(gain);
gain.connect(this.context.destination);
source.start(now);
source.stop(now + UNLOCK_TICK_SECONDS);
source.stop(now + this.config.graph.unlockTickSeconds);
source.addEventListener(
'ended',
() => {
@ -113,7 +106,7 @@ export class GardenAudioGraph {
this.delayNode.delayTime.setTargetAtTime(
this.config.delay.timeSeconds * profile.delayTimeMultiplier,
this.context.currentTime,
this.engineConfig.graph.delayTimeRampSeconds
this.config.delay.timeRampSeconds
);
}
@ -126,22 +119,21 @@ export class GardenAudioGraph {
this.delayNode.delayTime.setTargetAtTime(
this.config.delay.timeSeconds * profile.delayTimeMultiplier,
now,
this.engineConfig.graph.delayTimeRampSeconds
this.config.delay.timeRampSeconds
);
this.delayFeedback.gain.setTargetAtTime(
clamp(
this.config.delay.feedback +
activity * this.engineConfig.graph.delayActivityFeedbackWeight,
this.engineConfig.graph.delayFeedbackMin,
this.engineConfig.graph.delayFeedbackMax
this.config.delay.feedback + activity * this.config.delay.activityFeedbackWeight,
this.config.delay.feedbackMin,
this.config.delay.feedbackMax
),
now,
this.config.updateRampSeconds
);
this.delayOutput.gain.setTargetAtTime(
this.config.delay.wetGain *
(this.engineConfig.graph.delayOutputBase +
activity * this.engineConfig.graph.delayOutputActivityWeight),
(this.config.delay.outputBase +
activity * this.config.delay.outputActivityWeight),
now,
this.config.updateRampSeconds
);
@ -155,9 +147,9 @@ export class GardenAudioGraph {
if (this.masterGain && context.state !== 'closed') {
this.masterGain.gain.setTargetAtTime(
this.engineConfig.graph.closeGain,
this.config.graph.closeGain,
context.currentTime,
this.engineConfig.graph.closeRampSeconds
this.config.graph.closeRampSeconds
);
}
@ -170,7 +162,7 @@ export class GardenAudioGraph {
private createDelay(context: AudioContext, masterGain: GainNode): void {
const delayInput = context.createGain();
const delayNode = context.createDelay(2);
const delayNode = context.createDelay(this.config.graph.delayMaxSeconds);
const delayFeedback = context.createGain();
const delayOutput = context.createGain();
@ -192,7 +184,7 @@ export class GardenAudioGraph {
private createBuses(context: AudioContext, masterGain: GainNode): void {
this.eventBus = context.createGain();
this.eventBus.gain.value = this.engineConfig.graph.eventBusGain;
this.eventBus.gain.value = this.config.graph.eventBusGain;
this.eventBus.connect(masterGain);
}
@ -202,9 +194,8 @@ export class GardenAudioGraph {
for (let index = 0; index < data.length; index++) {
data[index] =
this.engineConfig.graph.noiseMin +
Math.random() *
(this.engineConfig.graph.noiseMax - this.engineConfig.graph.noiseMin);
this.config.graph.noiseMin +
Math.random() * (this.config.graph.noiseMax - this.config.graph.noiseMin);
}
return buffer;