SoundFX Singleton
Basic Sound Controller Singleton
by Noncho Savov
HTML
<div>
<input type="button" id="start" value="SoundFX.start();" style="margin-top: 4px; margin-right: 4px;">
</div>
<div id="ui" style="opacity:.5;pointer-events:none">
<div id="volumeUI" style="display:none">
Master SoundFX.volume:<input id="masterVolume" type="text" style="width:50px" value="1">
</div>
<br/>
<div id="buttons">
<b>SoundFX sounds and effects:</b><br/>
</div>
<div id="custom">
<br/><b>Create your own sound:</b><br/>
Starting Frequency:<br/><input type="text" id="frequency"><br/>
Frequency Change value (+/-):<br/><input type="text" id="change"><br/>
Duration (animation frames):<br/><input type="text" id="duration"><br/>
Type (0-3 int):<br/><input type="text" id="type"><br/>
Volume (0-1 float):<br/><input type="text" id="volume"><br/>
Delay (frames):<br/><input type="text" id="delay"><br/>
Pitch (0-Duration/4 int):<br/><input type="text" id="pitch"><br/>
<input style="margin-top:8px;" type="button" id="play" value="Play Sound" disabled>
</div>
</div>
JavaScript
var SoundFX = (function() {
// Note: The Web Audio API will be included in the Chrome autoplay policy with M71 (December 2018).
// Audio Context needs to be initialized after some sort of user interaction has been occured first, otherwise
// it will be created in the "suspended" state and you will need to call resume() after a user gesture is received.
// To prevent that and to avoid seeing warnings in the console, use the method SoundFX.start()
var audioContext;
var oscTypes = ["square", "sawtooth", "triangle", "sine"];
var initialized;
var volume = 1;
function start(_volume){
try {
audioContext = new (
window.AudioContext ||
window.webkitAudioContext ||
window.mozAudioContext ||
window.msAudioContext ||
window.oAudioContext
)();
if(_volume) setVolume(_volume);
initialized = true;
console.log("[Event] AudioContext initialized");
} catch(e){
console.log("[Warning] AudioContext not found",e);
}
}
// start frequency HZ
// frequency change in time + / -
// length (number of frames taking to play the sound)
// volume of the current sound: 0.0 - 1.0 (multiplied by SoundFX.volume)
// oscillator type 0 - 3 ("square", "sawtooth", "triangle", "sine")
// starting delay (frames of silence before the sound starts)
// gradually ramp up the volume by a few frames: 0 - _duration/5
function playSound(_frequency, _change, _duration, _volume, _type, _delay, _pitch){
// validation
if(!audioContext || !_duration || !_volume) return;
if(_pitch > _duration/4|0) _pitch = _duration/4|0;
// instantiate oscillator
var oscillator = audioContext.createOscillator();
oscillator.type = oscTypes[_type%4|0];
// instantiate modulation for sound volume control
var modulationGain = audioContext.createGain();
// set the volume to 0 at the beginning to prevent sound glitches
modulationGain.gain.value = 0;
// frame counter, using requestAnimationFrame - all measures are in frames
var i =...