diff core.js @ 7:6a6272b06d34

Standalone version. Movable sliders with rating Comment boxes Submission to XML file TODO: Click track to listen
author Nicholas Jillings <nicholas.jillings@eecs.qmul.ac.uk>
date Wed, 25 Mar 2015 12:48:29 +0000
parents 955d229b8a02
children a6364db4c2ea
line wrap: on
line diff
--- a/core.js	Tue Mar 24 15:07:11 2015 +0000
+++ b/core.js	Wed Mar 25 12:48:29 2015 +0000
@@ -9,6 +9,7 @@
 var audioContext;
 var projectXML;
 var audioEngineContext;
+var projectReturn;
 
 window.onload = function() {
 	// Function called once the browser has loaded all files.
@@ -16,7 +17,7 @@
 	
 	// Create a web audio API context
 	// NORE: Currently this will only work with webkit browsers (Chrome/Safari)!
-	audioContext = new webkitAudioContext;
+	audioContext = new AudioContext;
 	
 	// Create the audio engine object
 	audioEngineContext = new AudioEngine();
@@ -52,6 +53,23 @@
 function createProjectSave(destURL) {
 	// Save the data from interface into XML and send to destURL
 	// If destURL is null then download XML in client
+	// Now time to render file locally
+	var xmlDoc = interfaceXMLSave();
+	if (destURL == "null" || destURL == undefined) {
+		var parent = document.createElement("div");
+		parent.appendChild(xmlDoc);
+		var file = [parent.innerHTML];
+		var bb = new Blob(file,{type : 'application/xml'});
+		var dnlk = window.URL.createObjectURL(bb);
+		var a = document.createElement("a");
+		a.hidden = '';
+		a.href = dnlk;
+		a.download = "save.xml";
+		a.textContent = "Save File";
+		
+		var submitDiv = document.getElementById('download-point');
+		submitDiv.appendChild(a);
+	}
 }
 
 function AudioEngine() {
@@ -64,6 +82,9 @@
 	this.fooGain = audioContext.createGain();
 	this.fooGain.gain = 0;
 	
+	// Use this to detect playback state: 0 - stopped, 1 - playing
+	this.status = 0;
+	
 	// Connect both gains to output
 	this.outputGain.connect(audioContext.destination);
 	this.fooGain.connect(audioContext.destination);
@@ -74,32 +95,42 @@
 	this.play = function() {
 		// Send play command to all playback buffers for synchronised start
 		// Also start timer callbacks to detect if playback has finished
+		if (this.status == 0) {
+			// First get current clock
+			var timer = audioContext.currentTime;
+			// Add 3 seconds
+			timer += 3.0;
+			
+			// Send play to all tracks
+			for (var i=0; i<this.audioObjects.length; i++)
+			{
+				this.audioObjects[i].play(timer);
+			}
+			this.status = 1;
+		}
 	}
 	
 	this.stop = function() {
 		// Send stop and reset command to all playback buffers
+		if (this.status == 1) {
+			for (var i=0; i<this.audioObjects.length; i++)
+			{
+				this.audioObjects[i].stop();
+			}
+			this.status = 0;
+		}
 	}
 	
 	this.newTrack = function(url) {
 		// Pull data from given URL into new audio buffer
 		// URLs must either be from the same source OR be setup to 'Access-Control-Allow-Origin'
-		var request = new XMLHttpRequest();
-		request.open('GET',url,true);
-		request.responseType = 'arraybuffer';
+		
 		// Create the audioObject with ID of the new track length;
 		audioObjectId = this.audioObjects.length
 		this.audioObjects[audioObjectId] = new audioObject(audioObjectId);
-		
-		// Create callback to decode the data asynchronously
-		request.onload = function() {
-			audioContext.decodeAudioData(request.response, function(decodedData) {
-				audioObj = audioEngineContext.audioObjects[audioObjectId];
-				audioObj.buffer = decodedData;
-				audioObj.bufferNode.buffer = audioObj.buffer;
-				audioObj.state = 1;
-			}, console.log("Err - Buffer not added to " + audioObjectId));
-		}
-		request.send();
+
+		// AudioObject will get track itself.
+		this.audioObjects[audioObjectId].constructTrack(url);
 	}
 	
 }
@@ -131,6 +162,33 @@
 		this.bufferNode = audioContext.createBufferSource();
 		this.bufferNode.connect(this.outputGain);
 		this.bufferNode.buffer = this.buffer;
+		this.bufferNode.loop = true;
 	}
 	
-}
+	this.constructTrack = function(url) {
+		var request = new XMLHttpRequest();
+		request.open('GET',url,true);
+		request.responseType = 'arraybuffer';
+		
+		var audioObj = this;
+		
+		// Create callback to decode the data asynchronously
+		request.onloadend = function() {
+			audioContext.decodeAudioData(request.response, function(decodedData) {
+				audioObj.buffer = decodedData;
+				audioObj.bufferNode.buffer = audioObj.buffer;
+				audioObj.bufferNode.loop = true;
+				audioObj.state = 1;
+			}, function(){
+				// Should only be called if there was an error, but sometimes gets called continuously
+				// Check here if the error is genuine
+				if (audioObj.state == 0 || audioObj.buffer == undefined) {
+					// Genuine error
+					console.log('FATAL - Error loading buffer on '+audioObj.id);
+				}
+			});
+		}
+		request.send();
+	}
+	
+}
\ No newline at end of file