import { appConfig } from '../config'; import type { PianoNoteRole } from './garden-audio-types'; type GardenAudioChordQuality = 'major' | 'minor'; export interface GardenAudioChord { rootOffset: number; quality: GardenAudioChordQuality; } interface GardenAudioStyleVoice { scaleDegreeOffset: number; velocityMultiplier: number; panOffset: number; } export interface GardenAudioRegister { midiMin: number; midiMax: number; preferredMidi: number; pan: number; } export interface GardenAudioStylePool extends GardenAudioRegister { scaleDegrees: Array; } interface GardenAudioGenerativePianoConfig { stylePools: [GardenAudioStylePool, GardenAudioStylePool, GardenAudioStylePool]; padRegisters: [GardenAudioRegister, GardenAudioRegister, GardenAudioRegister]; chordVoicings: { majorOpen: Array; minorOpen: Array; majorClosed: Array; minorClosed: Array; }; vibeChangeStinger: { velocities: [number, number, number]; pans: [number, number, number]; delaySends: [number, number, number]; lowpassExpression: number; }; highActivityExtra: { barOffset: number; expressionMultiplier: number; }; padChord: { velocities: [number, number, number]; expressionVelocityWeight: number; delaySend: number; lowpassExpressionWeight: number; }; supportNote: { velocityBase: number; velocityExpressionWeight: number; durationBaseSeconds: number; durationExpressionSeconds: number; delaySendBase: number; delaySendExpressionWeight: number; lowpassExpressionWeight: number; expressionThreshold: number; offsetsByStyle: [Array, Array, Array]; }; textureNote: { velocityBase: number; velocityExpressionWeight: number; durationBaseSeconds: number; durationExpressionSeconds: number; delaySendBase: number; delaySendExpressionWeight: number; idleExpressionThreshold: number; mediumExpressionThreshold: number; intenseSpacing: number; idlePhase: number; }; gestureAccent: { rotationStrengthMultiplier: number; quantizeStepLookahead: number; velocityBase: number; velocityStrengthWeight: number; durationBaseSeconds: number; durationStrengthSeconds: number; delaySend: number; }; touchNote: { registerBiasManiaAmount: number; velocityBase: number; velocityStrengthWeight: number; durationBaseSeconds: number; durationStrengthSeconds: number; delaySend: number; lowpassBaseExpression: number; lowpassStrengthWeight: number; }; brushPhrase: { initialMotifOffset: number; energyRetain: number; maniaRetain: number; energyDecaySeconds: number; maniaDecaySeconds: number; fadeMinimumLifetimeSeconds: number; layerIntensityBase: number; layerIntensityManiaWeight: number; frameActivityWeight: number; frameManiaWeight: number; }; brushStream: { inferredManiaThreshold: number; inferredManiaRange: number; registerManiaShift: number; chordToneEverySteps: number; durationBaseSeconds: number; durationIntensitySeconds: number; durationManiaSeconds: number; durationMinSeconds: number; durationMaxSeconds: number; delaySendBase: number; delaySendIntensityWeight: number; delaySendManiaWeight: number; delaySendMin: number; delaySendMax: number; velocityBase: number; velocityIntensityWeight: number; lowpassBaseExpression: number; lowpassIntensityWeight: number; lowpassManiaWeight: number; manicThreshold: number; intenseThreshold: number; activeThreshold: number; }; brushStreamEcho: { maniaThreshold: number; stepModulo: number; stepRemainder: number; intensityThreshold: number; octaveSemitones: number; maxMidi: number; velocityBase: number; velocityIntensityWeight: number; durationMinSeconds: number; durationScale: number; panScale: number; delaySendMin: number; delaySendScale: number; lowpassBaseExpression: number; lowpassManiaWeight: number; }; brushMotif: { highThreshold: number; mediumThreshold: number; highOffset: number; mediumOffset: number; lowOffset: number; minOffset: number; maxOffset: number; }; registerBias: { maniaShiftSemitones: number; midiMin: number; midiMaxForMin: number; minimumSpan: number; midiMax: number; }; candidateOctaveSearch: { min: number; max: number; }; styleRotationMinSeconds: number; stylePanOffsetScale: number; lowpass: { midiBase: number; midiRange: number; midiLiftHz: number; expressionBase: number; expressionWeight: number; }; styleRotationSeconds: number; styleRotationBars: number; chordBars: number; supportBarSpacing: number; supportBarOffset: number; idleTextureBarSpacing: number; mediumTextureBarSpacing: number; textureBeat: number; highActivityExtraBeat: number; highActivityExtraThreshold: number; noteScorePreferenceWeight: number; noteScoreRegisterWeight: number; noteScoreChordToneWeight: number; noteScoreRepeatPenalty: number; gestureAccentMinIntervalSeconds: number; strokeAccentMinIntervalSeconds: number; strokeAccentMinSteps: number; strokeAccentThreshold: number; stingerDurationSeconds: number; stingerSpacingSeconds: number; maxBrushPhraseLayers: number; maxBrushStreamNotesPerBar: number; brushLayerBaseSeconds: number; brushLayerEnergySeconds: number; brushLayerMinIntensity: number; brushStreamIdleIntervalBeats: number; brushStreamActiveIntervalBeats: number; brushStreamIntenseIntervalBeats: number; brushStreamManicIntervalBeats: number; brushMotifMaxSteps: number; brushMotifCanonDelaySeconds: number; padDurationBarScale: number; } export interface GardenAudioVibeProfile { rootMidi: number; scale: Array; brightness: number; delayTimeMultiplier: number; progression: Array; } export interface GardenAudioConfig { masterVolume: number; fadeInSeconds: number; updateRampSeconds: number; highPassFrequencyHz: number; delay: { timeSeconds: number; feedback: number; wetGain: number; erasingActivity: number; activityFeedbackWeight: number; feedbackMax: number; feedbackMin: number; outputActivityWeight: number; outputBase: number; outputActivityDuck: number; timeRampSeconds: number; feedbackHighPassHz: number; feedbackLowPassHz: number; returnLowPassHz: number; }; piano: { maxVoices: number; filterType: BiquadFilterType; gain: number; sustainSeconds: number; sustainLevel: number; releaseSeconds: number; lowpassHz: number; filterQ: number; gainAttackSeconds: number; lowpassMaxHz: number; lowpassMinHz: number; minDurationSeconds: number; minFadeSeconds: number; minGain: number; pitchSemitonesPerOctave: number; scheduleAheadSeconds: number; sustainBase: number; sustainVelocityRange: number; tailStopExtraSeconds: number; voiceStealFadeSeconds: number; voiceStealStopSeconds: number; sampleBaseUrl: string; preloadDecode: { channels: number; frames: number; sampleRateHz: number; }; }; rhythm: { bpm: number; stepsPerBeat: number; stepsPerBar: number; lookaheadSeconds: number; sparseActivity: number; }; eraser: { minIntervalSeconds: number; noiseGain: number; filterMinHz: number; filterMaxHz: number; durationSeconds: number; pan: number; pianoActivity: number; }; energy: { attackSeconds: number; decaySeconds: number; immediateActivityScale: number; releaseSeconds: number; strokeDecaySeconds: number; }; graph: { closeGain: number; closeRampSeconds: number; delayMaxSeconds: number; eventBusGain: number; noiseMax: number; noiseMin: number; unlockTickFrequencyHz: number; unlockTickSeconds: number; unlockTickType: OscillatorType; latencyHint: AudioContextLatencyCategory; outputFilterType: BiquadFilterType; noiseBufferChannels: number; noiseBufferDurationSeconds: number; pianoBusGains: Record; pianoBusActivityDucking: Record; noiseBusGain: number; compressor: { thresholdDb: number; kneeDb: number; ratio: number; attackSeconds: number; releaseSeconds: number; }; }; input: { distanceWindowForFullActivityPixels: number; distanceWindowSeconds: number; fallbackFrameSeconds: number; fullActivitySpeed: number; activityNoiseFloorSpeed: number; activityCurve: number; activitySoftCeiling: number; activityAttackSeconds: number; activityReleaseSeconds: number; minAudibleDistance: number; manicActivityThreshold: number; manicReleaseThreshold: number; maniaSmoothingSeconds: number; minElapsedSeconds: number; }; muteGain: number; muteRampSeconds: number; noiseBurst: { attackSeconds: number; filterQ: number; offsetRandomSeconds: number; scheduleAheadSeconds: number; silentGain: number; filterType: BiquadFilterType; }; startDelaySeconds: number; vibeChangeStingerMinIntervalSeconds: number; generativePiano: GardenAudioGenerativePianoConfig; styleVoices: [GardenAudioStyleVoice, GardenAudioStyleVoice, GardenAudioStyleVoice]; } export const gardenAudioConfig: GardenAudioConfig = appConfig.audio;