Skip to content

Instantly share code, notes, and snippets.

@jackfuchs
Last active January 12, 2017 13:46
Show Gist options
  • Save jackfuchs/4b822958e8e4d1a70338b8e3cc091dd6 to your computer and use it in GitHub Desktop.
Save jackfuchs/4b822958e8e4d1a70338b8e3cc091dd6 to your computer and use it in GitHub Desktop.
/**
* jackfuchs.Sound.js
* Can play and stop single and multi frequency tones
* Can play, pause, resume and stop sound files
*
* @author: Axel Jack Fuchs (Cologne, Germany)
* @date: 01-12-2017 12:55
* @url https://gist.github.com/jackfuchs/
*
* Usage:
*
* // Playing sound assets
* Sound.assets.add('background_music', {pathname: 'background.mp3'});
* Sound.assets.add('success', {pathname: 'success.mp3'});
* Sound.assets.add('fail', {pathname: 'fail.mp3', volume: 0.5});
*
* Sound.assets.play('background_music', {loop: true});
* Sound.assets.play('success');
*
* // Plays a tone with a frequency of 400Hz for 250ms
* Sound.tones.play(400, .25);
*
* // Plays a tone with a frequency of 40Hz for an indefinite amount of time
* var tone = Sound.tones.playTone(40);
* // Can be stopped manually
* tone.stop();
*
* // Plays a multi frequency tone for 250ms
* Sound.tones.play([697, 1209], .25);
*/
var Sound = {
tones: {
audioContext: null,
/**
* Plays a tone in the given frequency and duration
*
* @param int frequency
* @param int duration (seconds)
*/
playTone: function(frequency, duration) {
this.audioContext = this.audioContext || new (window.AudioContext || window.webkitAudioContext)();
// Generates a new oscillator
var osc = this.audioContext.createOscillator();
// Sets the given frequency and plays it
osc.frequency.value = parseInt(frequency);
osc.connect(this.audioContext.destination);
osc.start();
// Stops this tone after a given duration
if (duration) {
osc.stop(this.audioContext.currentTime + duration);
}
return osc;
},
/**
* Plays tones in the given frequenc(y|ies) and duration
*
* @param mixed frequencies
* @param int duration (seconds)
*/
play: function(frequencies, duration) {
// Casts the frequency input to an array
frequencies = frequencies.constructor !== Array ? [frequencies] : frequencies;
// Contains the playing tones
var tones = {
items: [],
// Stops the contained tones
stop: function() {
for (var i=0, len=tones.items.length; i<len; i++) {
tones.items[i].stop(0);
}
}
};
// Delegates the requested frequencies to playTone
for (var i=0, len=frequencies.length; i<len; i++) {
tones.items[i] = this.playTone(frequencies[i], duration);
}
return tones;
}
},
assets: {
assets: {
example: {
filename: 'example.mp3',
loop: false,
volume: 1
}
},
add: function(id, settings) {
var Asset = new Audio(settings.pathname);
Asset.volume = settings.volume || 1;
Asset.loop = settings.loop || false;
this.assets[id] = Asset;
},
/**
* Plays the added assets
*/
play: function(id, settings) {
// Stops if no sound with such id was found
if (!this.assets.hasOwnProperty(id)) {
return false;
}
settings = settings || {};
var self = this,
Asset = this.assets[id];
// Configures the player to loop the sound if requested
if (settings.hasOwnProperty('loop') && settings.loop === true) {
if (typeof Asset.loop == 'boolean') {
Asset.loop = true;
} else {
Asset.addEventListener('ended', function() {
this.currentTime = 0;
this.play();
}, false);
}
}
// Sets the assets volume if given
if (settings.hasOwnProperty('volume')) {
Asset.volume = settings.volume;
}
Asset.play();
},
pause: function(id) {
if (this.assets.hasOwnProperty(id)) {
this.assets[id].pause();
}
},
resume: function(id) {
if (this.assets.hasOwnProperty(id)) {
this.assets[id].play();
}
},
stop: function(id) {
if (this.assets.hasOwnProperty(id)) {
this.assets[id].pause();
this.assets[id].currentTime = 0;
}
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment