X-Git-Url: http://105106.c2e0p.group/sound.git/blobdiff_plain/b742b684ca931de2f906a0c24ee773d7c7dfad0a..9c85ed989d2c423bdc31f43c90cbe229f321442e:/sound.js?ds=inline

diff --git a/sound.js b/sound.js
index 843be80..08cd4d0 100644
--- a/sound.js
+++ b/sound.js
@@ -1,11 +1,33 @@
-function Sound() {
+/* Copyright (c) 2014 Jer Noble
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+function Sound(src) {
+
+	if (Sound.audioContext === undefined) {
+		var AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext;
+		Sound.audioContext = new AudioContext();
+	}
 
-	if (Sound.audioContext === undefined)
-		Sound.audioContext = new webkitAudioContext();
-
-	this._src = null;
 	this._networkState = this.NETWORK.EMPTY;
-	this._preload = true;
+	this._preload = this.PRELOAD.AUTO;
 	this._buffered = {};
 	this._readyState = this.READY.NOTHING;
 	this._seeking = false;
@@ -15,7 +37,7 @@ function Sound() {
 	this._played = {};
 	this._seekable = {};
 	this._ended = false;
-	this._autoplay = false;
+	this._autoplay = true;
 	this._loop = false;
 	this._volume = 1;
 	this._muted = false;
@@ -26,11 +48,12 @@ function Sound() {
 	this.gainNode = null;
 
 	this.ajax = null;
-	this.eventListeners = { }; 
+	this.eventListeners = { };
 	this.shouldBePlaying = 0;
 	this.startTime = 0;
 	this.nextStartTime = 0;
-	this.load();
+
+	this.setSrc(src);
 }
 
 Sound.prototype = {
@@ -58,6 +81,12 @@ Sound.prototype = {
 		ENOUGH_DATA: 4,
 	},
 
+	PRELOAD: {
+		NONE: 0,
+		METADATA: 1,
+		AUTO: 2,
+	},
+
 	load: function() {
 		if (this.ajax)
 			this.ajax.abort();
@@ -75,7 +104,7 @@ Sound.prototype = {
 
 		this.setPlaybackRate(this.defaultPlaybackRate);
 		this._error = null;
-		this._autoplay = true;
+		this.shouldBePlaying = this._autoplay;
 		this.stopInternal();
 
 		if (!this._src) {
@@ -147,7 +176,7 @@ Sound.prototype = {
 
 	playInternal: function() {
 		this.gainNode = Sound.audioContext.createGainNode();
-		this.gainNode.gain.value = this._volume;
+		this.gainNode.gain.value = this._muted ? 0 : this._volume;
 		this.gainNode.connect(Sound.audioContext.destination);
 
 		this.node = Sound.audioContext.createBufferSource();
@@ -187,6 +216,13 @@ Sound.prototype = {
 	},
 
 	onended: function() {
+		if (this._loop) {
+			this.stopInternal();
+			this.setCurrentTime(0);
+			this.playInternal();
+			return;
+		}
+
 		this._ended = true;
 		this.nextStartTime = 0;
 		this.stopInternal();
@@ -237,7 +273,8 @@ Sound.prototype = {
 
 	setSrc: function(src) {
 		this._src = src;
-		this.load();
+		if (this._autoplay || this._preload != this.PRELOAD.NONE)
+			this.load();
 	},
 
 	getCurrentSrc: function() {
@@ -257,21 +294,30 @@ Sound.prototype = {
 	},
 
 	getPreload: function() {
-		if (!this._preload)
-			return 'none';
-		return 'auto';
+		switch (this._preload) {
+			case this.PRELOAD.NONE: return 'none';
+			case this.PRELOAD.METADATA: return 'metadata';
+			case this.PRELOAD.AUTO: return 'auto';
+			default: return '';
+		}
 	},
 
 	setPreload: function(preload) {
 		switch (preload) {
-		case 'none':
-			this._preload = false;
-			break;
-		default:
-			this._preload = true;
-			if (!this.buffer)
-				load();
-			break;
+			default:
+			case 'none':
+				this._preload = this.PRELOAD.NONE;
+				break;
+			case 'metadata':
+				this._preload = this.PRELOAD.METADATA;
+				if (this._networkState === this.NETWORK.EMPTY)
+					this.load();
+				break;
+			case 'auto':
+				this._preload = this.PRELOAD.auto;
+				if (this._networkState === this.NETWORK.EMPTY)
+					this.load();
+				break;
 		}
 	},
 
@@ -281,7 +327,7 @@ Sound.prototype = {
 		return this.nextStartTime + Sound.audioContext.currentTIme - this.startTime;
 	},
 
-	setCurrentTime: function(time) { 
+	setCurrentTime: function(time) {
 		this.nextStartTime = time;
 		this.dispatchEventAsync(new CustomEvent('timeupdate'));
 		if (!this.node)
@@ -320,7 +366,7 @@ Sound.prototype = {
 	},
 
 	setVolume: function(volume) {
-		if (this._volume == volume)
+		if (this._volume === volume)
 			return;
 
 		this._volume = volume;
@@ -335,7 +381,7 @@ Sound.prototype = {
 	},
 
 	setMuted: function(muted) {
-		if (this._muted == muted)
+		if (this._muted === muted)
 			return;
 
 		this._muted = muted;
@@ -344,6 +390,27 @@ Sound.prototype = {
 		if (this.gainNode)
 			this.gainNode.gain.value = this._muted ? 0 : this._volume;
 	},
+
+	getAutoplay: function() {
+		return this._autoplay;
+	},
+
+	setAutoplay: function(autoplay) {
+		if (this._autoplay === autoplay)
+			return;
+
+		this._autoplay = autoplay;
+		if (this._autoplay && this._networkState === this.NETWORK.EMPTY)
+			this.load();
+	},
+
+	getLoop: function() {
+		return this._loop;
+	},
+
+	setLoop: function(loop) {
+		this._loop = loop;
+	},
 };
 
 Object.defineProperty(Sound.prototype, 'src', {
@@ -441,8 +508,17 @@ Object.defineProperty(Sound.prototype, 'defaultMuted', {
 	set: Sound.prototype.setDefaultMuted,
 });
 
+Object.defineProperty(Sound.prototype, 'preload', {
+	get: Sound.prototype.getPreload,
+	set: Sound.prototype.setPreload,
+});
+
 document.createElement = function(elementName) {
 	if (elementName === "Audio" || elementName === "audio")
 		return new Sound();
 	return Document.prototype.createElement.call(this, elementName);
+};
+
+window.Audio = function(src) {
+	return new Sound(src);
 };
\ No newline at end of file