diff --git a/dist/SciFiAmbientDisplay_v4.html b/dist/SciFiAmbientDisplay_v4.html index 8a92537..9bc3f70 100644 --- a/dist/SciFiAmbientDisplay_v4.html +++ b/dist/SciFiAmbientDisplay_v4.html @@ -3560,6 +3560,23 @@ class TelemetrySynth { ]; } + /** + * Lazily creates the telemetry gain node so soundboard one-shots (LCARS + * chirps, era-specific one-shots) work standalone even before the ambient + * bed has been engaged via start(). Mirrors the init() self-heal pattern + * used by ExpandedSciFiAudioSynth and WhoniverseAudioSynth. start() below + * still unconditionally rebuilds the node on every engage so a fresh + * preset's volume takes effect immediately; this only fills the gap + * before that has ever happened. + */ + init() { + if (this.gainNode || !this.am.ctx) return; + const ctx = this.am.ctx; + this.gainNode = ctx.createGain(); + this.gainNode.gain.setValueAtTime(this.isMuted ? 0 : this.params.volume, ctx.currentTime); + this.gainNode.connect(this.am.compressor); + } + start() { this.stop(); const ctx = this.am.ctx; @@ -3663,6 +3680,7 @@ class TelemetrySynth { * Star Trek Comm Badge Confirmation Chirp */ synthesizeCommBadge() { + this.init(); if (window.expandedAudio) { window.expandedAudio.synthesizeCommBadge(); return; @@ -3690,6 +3708,7 @@ class TelemetrySynth { * TNG/Voyager Single LCARS Touch Tone (Soft sine with gentle attack and rapid exponential decay) */ synthesizeLCARSSingleChirp(pitch = null) { + this.init(); const ctx = this.am.ctx; if (!ctx || !this.gainNode) return; @@ -3725,6 +3744,7 @@ class TelemetrySynth { * TNG LCARS Double Chirp (Iconic standard confirmation tone) */ synthesizeLCARSDoubleChirp() { + this.init(); const ctx = this.am.ctx; if (!ctx) return; const idx = Math.floor(Math.random() * (this.lcarsPitches.length - 2)); @@ -3741,6 +3761,7 @@ class TelemetrySynth { * TNG LCARS Multi-Tone Data Acknowledgment Sequence */ synthesizeLCARSSequence() { + this.init(); const ctx = this.am.ctx; if (!ctx) return; const notes = [ @@ -3760,6 +3781,7 @@ class TelemetrySynth { * High-tech Sensor Sweep Tone (Voyager/TNG Long-Range Sensor telemetry) */ synthesizeSensorSweep() { + this.init(); const ctx = this.am.ctx; if (!ctx || !this.gainNode) return; @@ -3790,6 +3812,7 @@ class TelemetrySynth { * Two detuned square/triangle oscillators modulated by high-speed vibrato LFO */ synthesizeTOSWarble() { + this.init(); const ctx = this.am.ctx; if (!ctx || !this.gainNode) return; @@ -3846,6 +3869,7 @@ class TelemetrySynth { * TOS Mechanical Relay Solenoid Click */ synthesizeTOSRelayClick() { + this.init(); const ctx = this.am.ctx; if (!ctx || !this.gainNode) return; @@ -3872,6 +3896,7 @@ class TelemetrySynth { * DS9 / Cardassian Cavernous Sensor Tone (Resonant metallic ring) */ synthesizeCardassianSensor() { + this.init(); const ctx = this.am.ctx; if (!ctx || !this.gainNode) return; @@ -3906,6 +3931,7 @@ class TelemetrySynth { * NX-01 Industrial Hydraulic Relay Click */ synthesizeNXRelay() { + this.init(); const ctx = this.am.ctx; if (!ctx || !this.gainNode) return; @@ -3932,6 +3958,7 @@ class TelemetrySynth { * NX-01 Indicator Beep (Early 22nd century industrial tone) */ synthesizeNXIndicatorBeep() { + this.init(); const ctx = this.am.ctx; if (!ctx || !this.gainNode) return; @@ -3959,6 +3986,7 @@ class TelemetrySynth { * Iconic TNG 2-Tone Door Chime ("Come in") */ synthesizeDoorChime() { + this.init(); const ctx = this.am.ctx; if (!ctx || !this.gainNode) return; @@ -4005,6 +4033,7 @@ class TelemetrySynth { * the single scheduler timeout can never orphan nodes. */ synthesizeWhoMechanicalTelemetry_() { + this.init(); const ctx = this.am.ctx; if (!ctx || !this.gainNode) return; @@ -4088,6 +4117,7 @@ class TelemetrySynth { * One 0.5-1.1 s phrase of 2-4 events on absolute ctx time. */ synthesizeBioshipOrganicTelemetry_() { + this.init(); const ctx = this.am.ctx; if (!ctx || !this.gainNode) return; @@ -4198,6 +4228,7 @@ class TelemetrySynth { * occasional late sub-cluster to mimic an unsteady clock. */ synthesizeBelterJuryRiggedTelemetry_() { + this.init(); const ctx = this.am.ctx; if (!ctx || !this.gainNode) return; diff --git a/js/audio.js b/js/audio.js index d39ee79..e8668ec 100644 --- a/js/audio.js +++ b/js/audio.js @@ -826,6 +826,23 @@ class TelemetrySynth { ]; } + /** + * Lazily creates the telemetry gain node so soundboard one-shots (LCARS + * chirps, era-specific one-shots) work standalone even before the ambient + * bed has been engaged via start(). Mirrors the init() self-heal pattern + * used by ExpandedSciFiAudioSynth and WhoniverseAudioSynth. start() below + * still unconditionally rebuilds the node on every engage so a fresh + * preset's volume takes effect immediately; this only fills the gap + * before that has ever happened. + */ + init() { + if (this.gainNode || !this.am.ctx) return; + const ctx = this.am.ctx; + this.gainNode = ctx.createGain(); + this.gainNode.gain.setValueAtTime(this.isMuted ? 0 : this.params.volume, ctx.currentTime); + this.gainNode.connect(this.am.compressor); + } + start() { this.stop(); const ctx = this.am.ctx; @@ -929,6 +946,7 @@ class TelemetrySynth { * Star Trek Comm Badge Confirmation Chirp */ synthesizeCommBadge() { + this.init(); if (window.expandedAudio) { window.expandedAudio.synthesizeCommBadge(); return; @@ -956,6 +974,7 @@ class TelemetrySynth { * TNG/Voyager Single LCARS Touch Tone (Soft sine with gentle attack and rapid exponential decay) */ synthesizeLCARSSingleChirp(pitch = null) { + this.init(); const ctx = this.am.ctx; if (!ctx || !this.gainNode) return; @@ -991,6 +1010,7 @@ class TelemetrySynth { * TNG LCARS Double Chirp (Iconic standard confirmation tone) */ synthesizeLCARSDoubleChirp() { + this.init(); const ctx = this.am.ctx; if (!ctx) return; const idx = Math.floor(Math.random() * (this.lcarsPitches.length - 2)); @@ -1007,6 +1027,7 @@ class TelemetrySynth { * TNG LCARS Multi-Tone Data Acknowledgment Sequence */ synthesizeLCARSSequence() { + this.init(); const ctx = this.am.ctx; if (!ctx) return; const notes = [ @@ -1026,6 +1047,7 @@ class TelemetrySynth { * High-tech Sensor Sweep Tone (Voyager/TNG Long-Range Sensor telemetry) */ synthesizeSensorSweep() { + this.init(); const ctx = this.am.ctx; if (!ctx || !this.gainNode) return; @@ -1056,6 +1078,7 @@ class TelemetrySynth { * Two detuned square/triangle oscillators modulated by high-speed vibrato LFO */ synthesizeTOSWarble() { + this.init(); const ctx = this.am.ctx; if (!ctx || !this.gainNode) return; @@ -1112,6 +1135,7 @@ class TelemetrySynth { * TOS Mechanical Relay Solenoid Click */ synthesizeTOSRelayClick() { + this.init(); const ctx = this.am.ctx; if (!ctx || !this.gainNode) return; @@ -1138,6 +1162,7 @@ class TelemetrySynth { * DS9 / Cardassian Cavernous Sensor Tone (Resonant metallic ring) */ synthesizeCardassianSensor() { + this.init(); const ctx = this.am.ctx; if (!ctx || !this.gainNode) return; @@ -1172,6 +1197,7 @@ class TelemetrySynth { * NX-01 Industrial Hydraulic Relay Click */ synthesizeNXRelay() { + this.init(); const ctx = this.am.ctx; if (!ctx || !this.gainNode) return; @@ -1198,6 +1224,7 @@ class TelemetrySynth { * NX-01 Indicator Beep (Early 22nd century industrial tone) */ synthesizeNXIndicatorBeep() { + this.init(); const ctx = this.am.ctx; if (!ctx || !this.gainNode) return; @@ -1225,6 +1252,7 @@ class TelemetrySynth { * Iconic TNG 2-Tone Door Chime ("Come in") */ synthesizeDoorChime() { + this.init(); const ctx = this.am.ctx; if (!ctx || !this.gainNode) return; @@ -1271,6 +1299,7 @@ class TelemetrySynth { * the single scheduler timeout can never orphan nodes. */ synthesizeWhoMechanicalTelemetry_() { + this.init(); const ctx = this.am.ctx; if (!ctx || !this.gainNode) return; @@ -1354,6 +1383,7 @@ class TelemetrySynth { * One 0.5-1.1 s phrase of 2-4 events on absolute ctx time. */ synthesizeBioshipOrganicTelemetry_() { + this.init(); const ctx = this.am.ctx; if (!ctx || !this.gainNode) return; @@ -1464,6 +1494,7 @@ class TelemetrySynth { * occasional late sub-cluster to mimic an unsteady clock. */ synthesizeBelterJuryRiggedTelemetry_() { + this.init(); const ctx = this.am.ctx; if (!ctx || !this.gainNode) return;