changeset 799:43801b3d6131

Merge
author Nicholas Jillings <nicholas.jillings@eecs.qmul.ac.uk>
date Fri, 18 Dec 2015 10:11:10 +0000
parents 01c026742e1e (diff) 397f19747594 (current diff)
children 62cd4657fc38
files ape.css ape.js core.js docs/Instructions/Instructions.tex example_eval/project.xml index.html loudness.js mushra.js scripts/generate_report.py scripts/score_plot.py test_create/test_create.html
diffstat 6 files changed, 208 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/ape.js	Fri Dec 18 01:45:54 2015 +0000
+++ b/ape.js	Fri Dec 18 10:11:10 2015 +0000
@@ -60,10 +60,15 @@
 			}
 			if (interfaceTID.length != 0)
 			{
-				str += 'On axis "'+this.interfaceSliders[i].interfaceObject.title+'" you must move ';
+				var interfaceName = this.interfaceSliders[i].interfaceObject.title;
+				if (interfaceName == undefined) {
+					str += 'On axis '+String(i+1)+' you must move ';
+				} else {
+					str += 'On axis "'+interfaceName+'" you must move ';
+				}
 				if (interfaceTID.length == 1)
 				{
-					str += 'slider +'+interfaceTID[0]+'. ';
+					str += 'slider '+interfaceTID[0]+'. ';
 				}
 				else {
 					str += 'sliders ';
@@ -449,6 +454,8 @@
 	if (interfaceObject.title != undefined && typeof interfaceObject.title == "string")
 	{
 		titleSpan.textContent = interfaceObject.title;
+	} else {
+		titleSpan.textContent = "Axis "+String(this.id+1);
 	}
 	pagetitle.appendChild(titleSpan);
 	this.sliderDOM.appendChild(pagetitle);
@@ -580,7 +587,17 @@
 			});
 		}
 	};
-	
+	this.updateLoading = function(progress)
+	{
+		if (progress != 100)
+		{
+			progress = String(progress);
+			progress = progress.split('.')[0];
+			this.trackSliderObjects[0].children[0].textContent = progress+'%';
+		} else {
+			this.trackSliderObjects[0].children[0].textContent = this.parent.id;
+		}
+	};
 	this.exportXMLDOM = function(audioObject) {
 		// Called by the audioObject holding this element. Must be present
 		var obj = [];
@@ -636,6 +653,9 @@
 				var checkState = interfaceContext.checkScaleRange();
 				if (checkState == false) {canContinue = false;}
 				break;
+			default:
+				console.log("WARNING - Check option "+checks[i].check+" is not supported on this interface");
+				break;
 			}
 
 		}
--- a/core.js	Fri Dec 18 01:45:54 2015 +0000
+++ b/core.js	Fri Dec 18 10:11:10 2015 +0000
@@ -767,6 +767,7 @@
 		this.url = null;
 		this.buffer = null;
 		this.xmlRequest = new XMLHttpRequest();
+		this.xmlRequest.parent = this;
 		this.users = [];
 		this.getMedia = function(url) {
 			this.url = url;
@@ -807,7 +808,17 @@
 			this.progressCallback = function(event){
 				if (event.lengthComputable)
 				{
-					this.progress = event.loaded / event.total;
+					this.parent.progress = event.loaded / event.total;
+					for (var i=0; i<this.parent.users.length; i++)
+					{
+						if(this.parent.users[i].interfaceDOM != null)
+						{
+							if (typeof this.parent.users[i].interfaceDOM.updateLoading === "function")
+							{
+								this.parent.users[i].interfaceDOM.updateLoading(this.parent.progress*100);
+							}
+						}
+					}
 				}
 			};
 			this.xmlRequest.addEventListener("progress", this.progressCallback);
@@ -1114,7 +1125,7 @@
 		if (this.specification.type != 'outsidereference') {
 			var interfaceXML = this.interfaceDOM.exportXMLDOM(this);
 			if (interfaceXML.length == undefined) {
-				root.appendChild();
+				root.appendChild(interfaceXML);
 			} else {
 				for (var i=0; i<interfaceXML.length; i++)
 				{
@@ -1847,6 +1858,7 @@
 		this.elementComments = undefined;
 		this.outsideReference = null;
 		this.loudness = null;
+		this.initialPosition = null;
 		this.preTest = new parent.prepostNode("pretest");
 		this.postTest = new parent.prepostNode("pretest");
 		this.interfaces = [];
@@ -1871,6 +1883,18 @@
 			{
 				this.loudness = parent.loudness;
 			}
+			if (typeof xml.getAttribute('initial-position') === "string")
+			{
+				var xmlInitialPosition = Number(xml.getAttribute('initial-position'));
+				if (isNaN(xmlInitialPosition) == false)
+				{
+					if (xmlInitialPosition > 1)
+					{
+						xmlInitialPosition /= 100;
+					}
+					this.initialPosition = xmlInitialPosition;
+				}
+			}
 			if (xml.getAttribute('loudness') != null)
 			{
 				var XMLloudness = xml.getAttribute('loudness');
@@ -1946,7 +1970,9 @@
 			AHNode.setAttribute("loop",this.loop);
 			AHNode.setAttribute("elementComments",this.elementComments);
 			if(this.loudness != null) {AHNode.setAttribute("loudness",this.loudness);}
-			
+			if(this.initialPosition != null) {
+				AHNode.setAttribute("loudness",this.initialPosition*100);
+				}
 			for (var i=0; i<this.interfaces.length; i++)
 			{
 				AHNode.appendChild(this.interfaces[i].encode(root));
@@ -2755,7 +2781,7 @@
 		for (var i = 0; i<audioEngineContext.audioObjects.length; i++)
 		{
 			var object = audioEngineContext.audioObjects[i];
-			var time = object.buffer.duration;
+			var time = object.buffer.buffer.duration;
 			var metric = object.metric;
 			var passed = false;
 			for (var j=0; j<metric.listenTracker.length; j++)
@@ -2779,7 +2805,7 @@
 		}
 		if (check_pass == false)
 		{
-			var str_start = "You have not listened to fragments ";
+			var str_start = "You have not completely listened to fragments ";
 			for (var i=0; i<error_obj.length; i++)
 			{
 				str_start += error_obj[i];
@@ -2793,4 +2819,64 @@
 			alert(str_start);
 		}
 	};
+	this.checkAllMoved = function()
+	{
+		var str = "You have not moved ";
+		var failed = [];
+		for (var i in audioEngineContext.audioObjects)
+		{
+			if(audioEngineContext.audioObjects[i].metric.wasMoved == false)
+			{
+				failed.push(audioEngineContext.audioObjects[i].id);
+			}
+		}
+		if (failed.length == 0)
+		{
+			return true;
+		} else if (failed.length == 1)
+		{
+			str += 'track '+failed[0];
+		} else {
+			str += 'tracks ';
+			for (var i=0; i<failed.length-1; i++)
+			{
+				str += failed[i]+', ';
+			}
+			str += 'and '+failed[i];
+		}
+		str +='.';
+		alert(str);
+		console.log(str);
+		return false;
+	};
+	this.checkAllPlayed = function()
+	{
+		var str = "You have not played ";
+		var failed = [];
+		for (var i in audioEngineContext.audioObjects)
+		{
+			if(audioEngineContext.audioObjects[i].metric.wasListenedTo == false)
+			{
+				failed.push(audioEngineContext.audioObjects[i].id);
+			}
+		}
+		if (failed.length == 0)
+		{
+			return true;
+		} else if (failed.length == 1)
+		{
+			str += 'track '+failed[0];
+		} else {
+			str += 'tracks ';
+			for (var i=0; i<failed.length-1; i++)
+			{
+				str += failed[i]+', ';
+			}
+			str += 'and '+failed[i];
+		}
+		str +='.';
+		alert(str);
+		console.log(str);
+		return false;
+	};
 }
\ No newline at end of file
--- a/example_eval/project.xml	Fri Dec 18 01:45:54 2015 +0000
+++ b/example_eval/project.xml	Fri Dec 18 10:11:10 2015 +0000
@@ -35,7 +35,6 @@
 	</setup>
 	<audioHolder id='test-0' hostURL="example_eval/" randomiseOrder='true' repeatCount='0' loop='true' elementComments='true' loudness="-12">
 		<interface name="preference">
-			<title>Preference</title>
 			<scale position="0">Min</scale>
 			<scale position="100">Max</scale>
 			<scale position="50">Middle</scale>
--- a/index.html	Fri Dec 18 01:45:54 2015 +0000
+++ b/index.html	Fri Dec 18 10:11:10 2015 +0000
@@ -23,14 +23,26 @@
 			window.onbeforeunload = function() {
 				return "Please only leave this page once you have completed the tests. Are you sure you have completed all testing?";
 			};
-		</script>
-		<!-- Uncomment the following script for automatic loading of projects -->
-		<script>
-			//url = '/pseudo.xml'; //Project XML document location
-			url = 'example_eval/project.xml';
+			
+			var url = 'example_eval/project.xml';
+			// SEARCH QUERY: By using the GET Request option ?url=loca/path/to/project.xml in the URL bar, you can load a project quickly
+			if (window.location.search.length != 0)
+			{
+				var search = window.location.search.split('?')[1];
+				// Now split the requests into pairs
+				var searchQueries = search.split('&');
+				for (var i in searchQueries)
+				{
+					// Split each request into
+					searchQueries[i] = searchQueries[i].split('=');
+					if (searchQueries[i][0] == "url")
+					{
+						url = searchQueries[i][1];
+					}
+				}
+			}
 			loadProjectSpec(url);
 		</script>
-		
 	</head>
 
 	<body>
--- a/mushra.css	Fri Dec 18 01:45:54 2015 +0000
+++ b/mushra.css	Fri Dec 18 10:11:10 2015 +0000
@@ -45,11 +45,20 @@
 	padding:2px;
 }
 
+div.track-slider-playing {
+	background-color: #FFDDDD;
+}
+
+input.track-slider-range {
+	margin-left: 0px;
+	margin-right: 0px;
+}
+
 input[type=range][orient=vertical]
 {
     writing-mode: bt-lr; /* IE */
     -webkit-appearance: slider-vertical; /* WebKit */
     width: 8px;
-    height: 175px;
     padding: 0 5px;
+    color: rgb(255, 144, 144);
 }
\ No newline at end of file
--- a/mushra.js	Fri Dec 18 01:45:54 2015 +0000
+++ b/mushra.js	Fri Dec 18 10:11:10 2015 +0000
@@ -99,6 +99,10 @@
 	
 	var feedbackHolder = document.getElementById('feedbackHolder');
 	var interfaceObj = audioHolderObject.interfaces;
+	if (interfaceObj.length > 1)
+	{
+		console.log("WARNING - This interface only supports one <interface> node per page. Using first interface node");
+	}
 	
 	var sliderBox = document.getElementById('slider');
 	feedbackHolder.innerHTML = null;
@@ -133,8 +137,14 @@
 		// Create a slider per track
 		audioObject.interfaceDOM = new sliderObject(audioObject);
 		
-		// Distribute it randomnly
-		audioObject.interfaceDOM.slider.value = Math.random();
+		if (typeof audioHolderObject.initialPosition === "number")
+		{
+			// Set the values
+			audioObject.interfaceDOM.slider.value = audioHolderObject.initalPosition;
+		} else {
+			// Distribute it randomnly
+			audioObject.interfaceDOM.slider.value = Math.random();
+		}
 		
 		sliderBox.appendChild(audioObject.interfaceDOM.holder);
 		audioObject.metric.initialised(audioObject.interfaceDOM.slider.value);
@@ -171,12 +181,11 @@
 	this.title.style.float = "left";
 	
 	this.slider.type = "range";
+	this.slider.className = "track-slider-range";
 	this.slider.min = "0";
 	this.slider.max = "1";
 	this.slider.step = "0.01";
 	this.slider.setAttribute('orient','vertical');
-	this.slider.style.float = "left";
-	this.slider.style.width = "100%";
 	this.slider.style.height = window.innerHeight-250 + 'px';
 	this.slider.onchange = function()
 	{
@@ -186,25 +195,24 @@
 		console.log('slider '+id+' moved to '+this.value+' ('+time+')');
 	};
 	
-	this.play.textContent = "Play";
+	this.play.textContent = "Loading...";
 	this.play.value = audioObject.id;
 	this.play.style.float = "left";
 	this.play.style.width = "100%";
-	this.play.onclick = function()
+	this.play.disabled = true;
+	this.play.onclick = function(event)
 	{
-		audioEngineContext.play();
-		if (audioEngineContext.audioObjectsReady) {
-			var id = Number(event.srcElement.value);
-			//audioEngineContext.metric.sliderPlayed(id);
-			audioEngineContext.play(id);
-		}
+		var id = Number(event.srcElement.value);
+		//audioEngineContext.metric.sliderPlayed(id);
+		audioEngineContext.play(id);
+		$(".track-slider").removeClass('track-slider-playing');
+		$(event.currentTarget.parentElement).addClass('track-slider-playing');
 	};
 	
 	this.enable = function() {
-		if (this.parent.state == 1)
-		{
-			$(this.slider).removeClass('track-slider-disabled');
-		}
+		this.play.disabled = false;
+		this.play.textContent = "Play";
+		$(this.slider).removeClass('track-slider-disabled');
 	};
 	
 	this.exportXMLDOM = function(audioObject) {
@@ -216,6 +224,40 @@
 	this.getValue = function() {
 		return this.slider.value;
 	};
+	
+	this.resize = function(event)
+	{
+		this.holder.style.height = window.innerHeight-200 + 'px';
+		this.slider.style.height = window.innerHeight-250 + 'px';
+	}
+	this.updateLoading = function(progress)
+	{
+		progress = String(progress);
+		progress = progress.substr(0,5);
+		this.play.textContent = "Loading: "+progress+"%";
+	}
+	
+	if (this.parent.state == 1)
+	{
+		this.enable();
+	}
+}
+
+function resizeWindow(event)
+{
+	// Function called when the window has been resized.
+	// MANDATORY FUNCTION
+	
+	// Auto-align
+	var numObj = audioEngineContext.audioObjects.length;
+	var totalWidth = (numObj-1)*150+100;
+	var diff = (window.innerWidth - totalWidth)/2;
+	document.getElementById('slider').style.height = window.innerHeight - 180 + 'px';
+	audioEngineContext.audioObjects[0].interfaceDOM.holder.style.marginLeft = diff + 'px';
+	for (var i in audioEngineContext.audioObjects)
+	{
+		audioEngineContext.audioObjects[i].interfaceDOM.resize(event);
+	}
 }
 
 
@@ -227,7 +269,7 @@
 	// Check that the anchor and reference objects are correctly placed
 	if (interfaceContext.checkHiddenAnchor() == false) {return;}
 	if (interfaceContext.checkHiddenReference() == false) {return;}
-	/*
+	
 	for (var i=0; i<checks.length; i++) {
 		if (checks[i].type == 'check')
 		{
@@ -253,17 +295,20 @@
 				var checkState = interfaceContext.checkAllCommented();
 				if (checkState == false) {canContinue = false;}
 				break;
-			case 'scalerange':
+			//case 'scalerange':
 				// Check the scale is used to its full width outlined by the node
-				var checkState = interfaceContext.checkScaleRange();
-				if (checkState == false) {canContinue = false;}
+				//var checkState = interfaceContext.checkScaleRange();
+				//if (checkState == false) {canContinue = false;}
+			//	break;
+			default:
+				console.log("WARNING - Check option "+checks[i].check+" is not supported on this interface");
 				break;
 			}
 
 		}
 		if (!canContinue) {break;}
 	}
-   */
+	
     if (canContinue) {
 	    if (audioEngineContext.status == 1) {
 	        var playback = document.getElementById('playback-button');