119 lines
4.0 KiB
JavaScript
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;
|
|
})(); |