Implement Phase 2 audio gaps: 25 medium-difficulty synthesizers and ambient loops

- 23 new ExpandedSciFiAudioSynth methods + 2 WhoniverseAudioSynth methods
  covering audio_gaps.md rows #21-#45: Cardassian door, turbolift, replicator,
  scanner activation, console type clatter, Vorlon song, neural-bond swell,
  hull regen, Belter jury-rig telemetry, hull strain moan, Icarus beacon,
  void whisper, Beryllium thrum, Omega-13, repulsorlift drone, Bebop chug,
  carousel groan, slipstream surge, O2 regulator, pipe drips, steam vent,
  crash-couch gimbal, HAL respiration, Death Blossom, Cygnus piston chug
- Keyed ambient-loop registry (_scheduleLoop/_stopLoop) replacing ad-hoc
  timer fields; stopAllLoops clears registry plus legacy timers
- Single startPresetAmbience funnel in app.js engages ambience per preset on
  engage/switch and tears down on full stop; whoniverse ambience stopped on
  every preset change
- All 10 universe soundboards rebuilt (6-8 buttons each, span-2 Belter
  telemetry); NEURAL PULSE event now fires the real neural-bond swell
- TelemetrySynth era routing intentionally untouched (Phase 3 scope); docs
  updated in audio_gaps.md and sound_reference.md
This commit is contained in:
Claude
2026-09-04 08:49:58 -07:00
parent f2776885c9
commit 71252ff84f
6 changed files with 3602 additions and 121 deletions
+119 -11
View File
@@ -283,6 +283,41 @@ document.addEventListener('DOMContentLoaded', () => {
});
}
// 4a. Phase 2 Preset Ambience
// Single funnel that stops every automated loop (legacy + registry) and then
// re-engages the ambience matching the currently selected preset.
function startPresetAmbience(presetId) {
expandedAudio.stopAllLoops();
whoniverseAudio.stopAmbientLoops();
// Legacy Phase 1 loops, kept on their original presets
if (presetId === 'sta-sevastopol') {
expandedAudio.startStationSparks(4000, 11000);
} else if (presetId === 'sta-gateway' || presetId.includes('sickbay') || presetId.includes('med')) {
expandedAudio.startMedicalMonitor(1.15);
}
// Phase 2 audio_gaps.md rows #25-#45
if (activeUniverseId === 'whoniverse' && presetId.indexOf('tardis-') === 0) {
whoniverseAudio.startConsoleTypeTelemetry(2800, 6500); // #25
}
if (presetId === 'bio-vorlon') expandedAudio.startVorlonSong(); // #26
if (presetId === 'bio-wraith') expandedAudio.startHullRegen(); // #28
if (presetId === 'sta-ceres' || presetId === 'sta-tycho') expandedAudio.startBelterTelemetry(); // #29
if (presetId === 'deep-event-horizon' || presetId === 'deep-icarus-ii') expandedAudio.startHullStrainMoans(); // #30
if (presetId === 'deep-icarus-ii') expandedAudio.startIcarusBeacon(); // #31
if (presetId === 'deep-event-horizon' || presetId === 'deep-nightflyer') expandedAudio.startVoidWhispers(); // #32
if (presetId === 'com-protector') expandedAudio.startBerylliumThrum(); // #33
if (presetId === 'out-marauder') expandedAudio.startRepulsorliftDrone(); // #35
if (presetId === 'out-bebop') expandedAudio.startBebopChug(); // #36
if (presetId === 'mil-agamemnon') expandedAudio.startCarouselGroan(); // #37
if (presetId === 'mil-viper') expandedAudio.startOxygenRegulator(); // #39
if (presetId === 'ind-nostromo') expandedAudio.startPipeDrips(); // #40
if (presetId === 'ind-serenity' || presetId === 'ind-starbug') expandedAudio.startSteamVent(); // #41
if (presetId === 'ret-discovery-one') expandedAudio.startHalBreathing(); // #43
if (presetId === 'ret-cygnus') expandedAudio.startCygnusChug(); // #45
}
// 4. Select & Apply Preset
function selectPreset(presetId) {
const universe = UniverseRegistry[activeUniverseId];
@@ -311,13 +346,9 @@ document.addEventListener('DOMContentLoaded', () => {
syncSlidersToSynthParams();
expandedAudio.stopAllLoops();
whoniverseAudio.stopAmbientLoops();
if (isPlaying) {
if (presetId === 'sta-sevastopol') {
expandedAudio.startStationSparks(4000, 11000);
} else if (presetId === 'sta-gateway' || presetId.includes('sickbay') || presetId.includes('med')) {
expandedAudio.startMedicalMonitor(1.15);
}
startPresetAmbience(presetId);
if (activeUniverseId === 'whoniverse') whoniverseAudio.synthesizeDematSwitch();
else if (activeUniverseId === 'industrial') expandedAudio.synthesizeDockingClamp();
else telemetry.synthesizeLCARSSingleChirp();
@@ -400,10 +431,8 @@ document.addEventListener('DOMContentLoaded', () => {
statAudioStatus.textContent = 'ONLINE';
statAudioStatus.style.color = '#00ff88';
if (activePresetId === 'sta-sevastopol') {
expandedAudio.startStationSparks(4000, 11000);
} else if (activePresetId === 'sta-gateway' || activePresetId.includes('sickbay') || activePresetId.includes('med')) {
expandedAudio.startMedicalMonitor(1.15);
if (activePresetId) {
startPresetAmbience(activePresetId);
}
}, ENGINE_TRANSITION_SECS * 1000);
@@ -428,6 +457,7 @@ document.addEventListener('DOMContentLoaded', () => {
lifeSupport.stop(ENGINE_TRANSITION_SECS);
telemetry.stop();
expandedAudio.stopAllLoops();
whoniverseAudio.stopAmbientLoops();
alerts.stopAlert();
whoniverseAudio.stopCloisterBell();
resetAlertButtons();
@@ -632,7 +662,8 @@ document.addEventListener('DOMContentLoaded', () => {
visualizer.spawnWarpPulses();
break;
case 'neural':
whoniverseAudio.synthesizeTelepathicChime();
expandedAudio.synthesizeNeuralBondSwell();
visualizer.spawnWarpPulses();
break;
case 'centrifuge':
case 'astrogator':
@@ -813,6 +844,83 @@ document.addEventListener('DOMContentLoaded', () => {
expandedAudio.synthesizeHalChime();
break;
// Phase 2 (audio_gaps.md #21-#45)
case 'btn-cardassian-door':
expandedAudio.synthesizeCardassianDoor();
break;
case 'btn-turbolift':
expandedAudio.synthesizeTurboliftWhoosh();
break;
case 'btn-replicator':
expandedAudio.synthesizeReplicatorShimmer();
break;
case 'btn-scanner-activate':
whoniverseAudio.synthesizeScannerActivate();
break;
case 'btn-type-clatter':
whoniverseAudio.synthesizeTypeClatter();
break;
case 'btn-vorlon-song':
expandedAudio.synthesizeVorlonSingingSwell();
break;
case 'btn-neural-bond':
expandedAudio.synthesizeNeuralBondSwell();
break;
case 'btn-hull-regen':
expandedAudio.synthesizeHullRegenBurst();
break;
case 'btn-belter-telemetry':
expandedAudio.synthesizeBelterTelemetryJitter();
break;
case 'btn-hull-strain':
expandedAudio.synthesizeHullStrainMoan();
break;
case 'btn-icarus-beacon':
expandedAudio.synthesizeIcarusBeacon();
break;
case 'btn-void-whisper':
expandedAudio.synthesizeVoidWhisper();
break;
case 'btn-beryllium-thrum':
expandedAudio.synthesizeBerylliumThrumSwell();
break;
case 'btn-omega-13':
expandedAudio.synthesizeOmega13Whine();
break;
case 'btn-repulsor-drone':
expandedAudio.synthesizeRepulsorliftDrone();
break;
case 'btn-bebop-chug':
expandedAudio.synthesizeBebopChugStroke();
break;
case 'btn-carousel-groan':
expandedAudio.synthesizeCarouselGroanCycle();
break;
case 'btn-slipstream':
expandedAudio.synthesizeSlipstreamSurge();
break;
case 'btn-oxygen-reg':
expandedAudio.synthesizeOxygenRegulatorCycle();
break;
case 'btn-pipe-drips':
expandedAudio.synthesizePipeDrip();
break;
case 'btn-steam-vent':
expandedAudio.synthesizeSteamVentSwell();
break;
case 'btn-crash-couch':
expandedAudio.synthesizeCrashCouchGimbal();
break;
case 'btn-hal-breath':
expandedAudio.synthesizeHalBreathCycle();
break;
case 'btn-death-blossom':
expandedAudio.synthesizeDeathBlossomSurge();
break;
case 'btn-cygnus-chug':
expandedAudio.synthesizeCygnusPistonChug();
break;
default:
telemetry.synthesizeLCARSSingleChirp();
break;