changeset 950:05e7edb032b9

Fix Bug #1241 and #1213: Added checks each time new test page is loaded that all audioObjects have decoded. Writes to browser console WAIT and does not issue any play command if any audioObjects not ready.
author Nicholas Jillings <n.g.r.jillings@se14.qmul.ac.uk>
date Mon, 25 May 2015 11:14:12 +0100
parents 48e05b7a16e0
children 55bf2500f278
files ape.js core.js example_eval/project.xml index.html
diffstat 4 files changed, 53 insertions(+), 66 deletions(-) [+]
line wrap: on
line diff
--- a/ape.js	Mon May 25 10:06:28 2015 +0100
+++ b/ape.js	Mon May 25 11:14:12 2015 +0100
@@ -265,8 +265,7 @@
 {
 	
 	// Reset audioEngineContext.Metric globals for new test
-	audioEngineContext.metric.lastClicked = -1;
-	audioEngineContext.metric.data = -1;
+	audioEngineContext.newTestPage();
 	
 	// Used to load a specific test page
 	var textXML = testXMLSetups[id];
@@ -341,37 +340,6 @@
 	loopPlayback = false;
 	// Create AudioEngine bindings for playback
 	if (loopPlayback) {
-		audioEngineContext.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) {
-				this.timer.startTest();
-				// 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;
-			}
-		};
-		
-		audioEngineContext.stop = function() {
-			// Send stop and reset command to all playback buffers
-			if (this.status == 1) {
-				if (this.loopPlayback) {
-					for (var i=0; i<this.audioObjects.length; i++)
-					{
-						this.audioObjects[i].stop();
-					}
-				}
-				this.status = 0;
-			}
-		};
-		
 		audioEngineContext.selectedTrack = function(id) {
 			for (var i=0; i<this.audioObjects.length; i++)
 			{
@@ -383,26 +351,6 @@
 			}
 		};
 	} else {
-		audioEngineContext.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) {
-				this.timer.startTest();
-				this.status = 1;
-			}
-		};
-		
-		audioEngineContext.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;
-			}
-		};
-		
 		audioEngineContext.selectedTrack = function(id) {
 			for (var i=0; i<this.audioObjects.length; i++)
 			{
@@ -753,7 +701,7 @@
 		var testId = currentState.substr(8,currentState.length-7);
 		// Check if we have any post tests to perform
 		var postXML = $(testXMLSetups[testId]).find('PostTest')[0];
-		if (postXML == undefined) {
+		if (postXML == undefined || postXML.childElementCount == 0) {
 			testEnded(testId);
 		}
 		else if (postXML.childElementCount > 0)
--- a/core.js	Mon May 25 10:06:28 2015 +0100
+++ b/core.js	Mon May 25 11:14:12 2015 +0100
@@ -105,6 +105,7 @@
 	
 	// Use this to detect playback state: 0 - stopped, 1 - playing
 	this.status = 0;
+	this.audioObjectsReady = false;
 	
 	// Connect both gains to output
 	this.outputGain.connect(audioContext.destination);
@@ -120,9 +121,30 @@
 	// Create store for new audioObjects
 	this.audioObjects = [];
 	
-	this.play = function(){};
+	this.play = function() {
+		// Start the timer and set the audioEngine state to playing (1)
+		if (this.status == 0) {
+			// Check if all audioObjects are ready
+			if (this.audioObjectsReady == false) {
+				this.audioObjectsReady = this.checkAllReady();
+			}
+			if (this.audioObjectsReady == true) {
+				this.timer.startTest();
+				this.status = 1;
+			}
+		}
+	};
 	
-	this.stop = function(){};
+	this.stop = function() {
+		// Send stop and reset command to all playback buffers and set audioEngine state to stopped (1)
+		if (this.status == 1) {
+			for (var i=0; i<this.audioObjects.length; i++)
+			{
+				this.audioObjects[i].stop();
+			}
+			this.status = 0;
+		}
+	};
 	
 	
 	this.newTrack = function(url) {
@@ -137,6 +159,13 @@
 		this.audioObjects[audioObjectId].constructTrack(url);
 	};
 	
+	this.newTestPage = function() {
+		this.state = 0;
+		this.audioObjectsReady = false;
+		this.metric.reset();
+		this.audioObjects = [];
+	};
+	
 	this.checkAllPlayed = function() {
 		arr = [];
 		for (var id=0; id<this.audioObjects.length; id++) {
@@ -147,6 +176,18 @@
 		return arr;
 	};
 	
+	this.checkAllReady = function() {
+		var ready = true;
+		for (var i=0; i<this.audioObjects.length; i++) {
+			if (this.audioObjects[i].state == 0) {
+				// Track not ready
+				console.log('WAIT -- audioObject '+i+' not ready yet!');
+				ready = false;
+			};
+		}
+		return ready;
+	};
+	
 }
 
 function audioObject(id) {
@@ -182,7 +223,7 @@
 		if (this.bufferNode.loop == false) {
 			this.bufferNode.onended = function() {
 				this.owner.metric.listening(audioEngineContext.timer.getTestTime());
-			}
+			};
 		}
 		this.metric.listening(audioEngineContext.timer.getTestTime());
 		this.bufferNode.start(startTime);
@@ -275,6 +316,10 @@
 	this.engine = engine;
 	this.lastClicked = -1;
 	this.data = -1;
+	this.reset = function() {
+		this.lastClicked = -1;
+		this.data = -1;
+	};
 	this.initialiseTest = function(){};
 }
 
--- a/example_eval/project.xml	Mon May 25 10:06:28 2015 +0100
+++ b/example_eval/project.xml	Mon May 25 11:14:12 2015 +0100
@@ -3,10 +3,6 @@
 	<setup interface="APE" projectReturn="null" randomiseOrder='true' collectMetrics='true'>
 		<PreTest>
 			<statement>Please listen to all mixes</statement>
-			<question id="SessionID">Please enter your name.</question>
-			<question id="location" mandatory="true">Please enter your listening location (Yellow Room/SSL Duality or Red Room/Neve VR). </question>
-			<question id="SessionID">Please enter your name.</question>
-			<question id="location" mandatory="true">Please enter your listening location (Yellow Room/SSL Duality or Red Room/Neve VR). </question>
 		</PreTest>
 		<PostTest>
 			<statement>Thank you for taking this listening test.</statement>
@@ -21,7 +17,7 @@
 			<metricEnable>elementFlagMoved</metricEnable>
 		</Metric>
 	</setup>
-	<audioHolder id='0' hostURL="example_eval/" sampleRate="44100" randomiseOrder='true' repeatCount='0' loop='false' elementComments='true'>
+	<audioHolder id='0' hostURL="example_eval/" sampleRate="44100" randomiseOrder='true' repeatCount='1' loop='true' elementComments='true'>
 		<interface>
 			<title>Example Test Question</title>
 			<scale position="0">Min</scale>
@@ -45,8 +41,6 @@
 			<statement>Start the Test 3</statement>
 		</PreTest>
 		<PostTest>
-			<question id="testComment" mandatory="true">How did you find the test</question>
-			<question id="songGenre" mandatory="true">How would you describe the genre of this song? Multiple answers possible. </question>
-	</PostTest>
+		</PostTest>
 	</audioHolder>
 </BrowserEvalProjectDocument>
\ No newline at end of file
--- a/index.html	Mon May 25 10:06:28 2015 +0100
+++ b/index.html	Mon May 25 11:14:12 2015 +0100
@@ -26,7 +26,7 @@
 		</script>
 		<!-- Uncomment the following script for automatic loading of projects -->
 		<script>
-			url = 'example_eval/project.xml'; //Project XML document location
+			url = 'PXL_test/brecht.xml'; //Project XML document location
 			loadProjectSpec(url);
 		</script>