XGravity/Public/ecma/Sounds/ShieldLowAlarmSound.ecma.js

94 lines
3.6 KiB
JavaScript

"use strict";
const ShieldLowAlarmSound = (function(){
return function(audio_ctx, output_node, volume_multiplier = 1.0){
const now = audio_ctx.currentTime;
const duration = 0.22; // Pulso de sirena industrial rápido
const preset_bus = audio_ctx.createGain();
preset_bus.gain.setValueAtTime(volume_multiplier * 0.45, now);
// 1. REVERBERACIÓN CORTA DE MAMPARA (Eco de pasillo de nave)
const room_delay = audio_ctx.createDelay();
room_delay.delayTime.setValueAtTime(0.045, now);
const room_feedback = audio_ctx.createGain();
room_feedback.gain.setValueAtTime(0.35, now);
const room_filter = audio_ctx.createBiquadFilter();
room_filter.type = "lowpass";
room_filter.frequency.setValueAtTime(1200, now);
room_delay.connect(room_filter);
room_filter.connect(room_feedback);
room_feedback.connect(room_delay);
room_filter.connect(preset_bus);
// 2. ENVOLVENTE DINÁMICA DE BOCINA (Ataque percusivo + cuerpo)
const env = audio_ctx.createGain();
env.gain.setValueAtTime(0.001, now);
// Ataque rápido simulando apertura de válvula
env.gain.linearRampToValueAtTime(0.85, now + 0.02);
env.gain.setValueAtTime(0.85, now + 0.14);
env.gain.exponentialRampToValueAtTime(0.001, now + duration);
// 3. GENERADOR DE SIRENA INDUSTRIAL (Síntesis FM limpia)
// Transportadora principal: Tono puro de bocina (senoidal limpia)
const carrier = audio_ctx.createOscillator();
carrier.type = "sine";
// Barrido característico de evacuación: empieza arriba y resbala hacia abajo
carrier.frequency.setValueAtTime(740, now);
carrier.frequency.exponentialRampToValueAtTime(460, now + duration);
// Modulador FM: Añade el zumbido de vibración de la membrana metálica
const modulator = audio_ctx.createOscillator();
const mod_gain = audio_ctx.createGain();
modulator.type = "sine";
// Modulación a 45Hz para simular el traqueteo del motor de la sirena
modulator.frequency.setValueAtTime(45, now);
mod_gain.gain.setValueAtTime(140, now);
mod_gain.gain.exponentialRampToValueAtTime(40, now + duration);
modulator.connect(mod_gain);
mod_gain.connect(carrier.frequency);
// 4. SEGUNDO TONO ARMÓNICO (Cuerpo de resonador hueco)
const sub_carrier = audio_ctx.createOscillator();
const sub_gain = audio_ctx.createGain();
sub_carrier.type = "triangle";
sub_carrier.frequency.setValueAtTime(370, now);
sub_carrier.frequency.exponentialRampToValueAtTime(230, now + duration);
sub_gain.gain.setValueAtTime(0.3, now);
sub_carrier.connect(sub_gain);
sub_gain.connect(env);
// 5. FILTRO PASO-BANDA (Emula el megáfono físico de cabina)
const megaphone_filter = audio_ctx.createBiquadFilter();
megaphone_filter.type = "bandpass";
megaphone_filter.frequency.setValueAtTime(650, now);
megaphone_filter.Q.setValueAtTime(1.8, now);
carrier.connect(env);
env.connect(megaphone_filter);
// Enviamos al bus directo y una copia a la reverberación de mampara
megaphone_filter.connect(preset_bus);
megaphone_filter.connect(room_delay);
preset_bus.connect(output_node);
// Disparo coordinado
modulator.start(now);
carrier.start(now);
sub_carrier.start(now);
modulator.stop(now + duration);
carrier.stop(now + duration);
sub_carrier.stop(now + duration);
};
})();