XGravity/Public/ecma/Managers/AudioManager.ecma.js

119 lines
4.0 KiB
JavaScript

"use strict";
const AudioManager = (function(){
const AudioManager = function(xgravity){
const self = this;
let context = null;
let sfx_bus = null;
let is_muted = false;
const sound_registry = {};
const init_audio = () => {
if(!context){
const AudioContextClass = window.AudioContext || window.webkitAudioContext;
if(AudioContextClass){
// Cadena Master: Bus -> Saturador -> Compresor/Limitador -> Altavoces
const limiter = (context = new AudioContextClass()).createDynamicsCompressor(),
saturator = context.createWaveShaper();
limiter.threshold.setValueAtTime(-4, context.currentTime);
limiter.knee.setValueAtTime(6, context.currentTime);
limiter.ratio.setValueAtTime(16, context.currentTime);
limiter.attack.setValueAtTime(0.003, context.currentTime);
limiter.release.setValueAtTime(0.18, context.currentTime);
saturator.curve = make_distortion_curve(15);
saturator.oversample = "2x";
sfx_bus = context.createGain();
sfx_bus.gain.setValueAtTime(1.0, context.currentTime);
sfx_bus.connect(saturator);
saturator.connect(limiter);
limiter.connect(context.destination);
};
};
context && context.state === "suspended" && context.resume();
};
const make_distortion_curve = (amount = null) => {
const curve = new Float32Array(xgravity.values.audio_samples);
const degrees = Math.PI / 180;
if(amount === null)
amount = xgravity.values.audio_default_amount;
for(let i = 0; i < xgravity.values.audio_samples; ++ i){
const x = (i * 2) / xgravity.values.audio_samples - 1;
curve[i] = ((3 + amount) * x * 20 * degrees) / (Math.PI + amount * Math.abs(x));
};
return curve;
};
this.register_sound = (id, generator_fn) => {
sound_registry[id] = generator_fn;
};
this.play = (sound_id, custom_volume = null) => {
if(is_muted) return;
init_audio();
if(!context || !sfx_bus) return;
const generator = sound_registry[sound_id];
if(typeof generator === "function"){
const master_vol = custom_volume !== null
? custom_volume
: xgravity.settings.get("explosion_volume", null, 1.0);
generator(context, sfx_bus, master_vol);
}
};
this.set_mute = (state) => {
is_muted = Boolean(state);
if(sfx_bus && context){
sfx_bus.gain.setValueAtTime(is_muted ? 0 : 1.0, context.currentTime);
}
};
const constructor = () => {
if(typeof ShieldExplosionSound !== "undefined"){
this.register_sound("shield_explosion", ShieldExplosionSound);
}
if(typeof HitExplosionSound !== "undefined"){
this.register_sound("hit_explosion", HitExplosionSound);
}
if(typeof ShieldLowAlarmSound !== "undefined"){
this.register_sound("shield_low_alarm", ShieldLowAlarmSound);
}
if(typeof PerimeterWarningSound !== "undefined"){
this.register_sound("perimeter_warning", PerimeterWarningSound);
}
if(typeof MothershipImpactSound !== "undefined"){
this.register_sound("mothership_impact", MothershipImpactSound);
}
if(typeof AsteroidThreatAlarmSound !== "undefined"){
this.register_sound("asteroid_threat", AsteroidThreatAlarmSound);
}
};
constructor();
};
return AudioManager;
})();