changeset 1102:b5bf2f57187c

Merge
author Nicholas Jillings <n.g.r.jillings@se14.qmul.ac.uk>
date Tue, 08 Mar 2016 14:44:14 +0000
parents a497058ae2ae
children 2051868b21f0
files CITING.txt README.txt analyse.html analysis/analysis.css analysis/analysis.js analysis/index.html core.css core.js docs/WAC2016/WAC2016.bib docs/WAC2016/WAC2016.pdf docs/WAC2016/WAC2016.tex docs/WAC2016/sig-alternate-sample.tex docs/WAC2016/sig-alternate.cls docs/WAC2016/sigproc.bib docs/WAC2016/waccopyright.sty interfaces/AB.css interfaces/AB.js interfaces/ape.js interfaces/blank.js interfaces/discrete.js interfaces/horizontal-sliders.js interfaces/mushra.js loudness.js pythonServer.py save.php scripts/comment_parser.html scripts/comment_parser.php scripts/comment_parser.py scripts/evaluation_stats.py scripts/generate_report.py scripts/score_parser.php scripts/score_parser.py scripts/timeline_view_movement.py test-schema.xsd test_create/attributes.json test_create/custom.css test_create/style.css test_create/test_core.js test_create/test_create.html
diffstat 38 files changed, 2445 insertions(+), 510 deletions(-) [+]
line wrap: on
line diff
--- a/CITING.txt	Wed Feb 24 14:00:10 2016 +0000
+++ b/CITING.txt	Tue Mar 08 14:44:14 2016 +0000
@@ -2,6 +2,14 @@
 
 Nicholas Jillings, Brecht De Man, David Moffat and Joshua D. Reiss, "Web Audio Evaluation Tool: A Browser-Based Listening Test Environment," 12th Sound and Music Computing Conference, July 2015.
 
+BibTeX: 
+@conference{deman2015c,
+	Author = {Jillings, Nicholas and Moffat, David and De Man, Brecht and Reiss, Joshua D.},
+	Booktitle = {12th Sound and Music Computing Conference},
+	Month = {July},
+	Title = {Web {A}udio {E}valuation {T}ool: {A} browser-based listening test environment},
+	Year = {2015}}
+
 
 Feel free to let us know how you have used it! We highly welcome any kind of feedback, bug reports and feature requests. 
 
--- a/README.txt	Wed Feb 24 14:00:10 2016 +0000
+++ b/README.txt	Tue Mar 08 14:44:14 2016 +0000
@@ -1,11 +1,24 @@
 WEB AUDIO EVALUATION TOOL
 
 AUTHORS
-Nicholas Jillings 		<n.g.r.jillings@se14.qmul.ac.uk>
-Brecht De Man			<b.deman@qmul.ac.uk>
-David Moffat			<d.j.moffat@qmul.ac.uk>
+
+Nicholas Jillings 				<nicholas.jillings@mail.bcu.ac.uk>
+Brecht De Man					<b.deman@qmul.ac.uk>
+David Moffat					<d.j.moffat@qmul.ac.uk>
 Joshua D. Reiss (supervisor)	<j.d.reiss@qmul.ac.uk>
+Ryan Stables (supervisor)		<ryan.stables@bcu.ac.uk>
+
 
 INSTRUCTIONS FOR USE
 
-Please refer to ‘docs/Instructions/Instructions.pdf’
\ No newline at end of file
+Please refer to 'docs/Instructions/Instructions.pdf'.
+
+
+ACADEMIC USE
+
+Please refer to CITING.txt.
+
+
+OTHER USE
+
+Please refer to LICENSE.txt (GNU GENERAL PUBLIC LICENSE).
\ No newline at end of file
--- a/analyse.html	Wed Feb 24 14:00:10 2016 +0000
+++ b/analyse.html	Tue Mar 08 14:44:14 2016 +0000
@@ -24,7 +24,7 @@
 			xmlFileFolder = "saves";
 			// array of XML files
 			// THIS IS WHERE YOU SPECIFY RESULT XML FILES TO ANALYSE
-			var xmlFiles = ['test-0.xml','test-1.xml','test-2.xml','test-3.xml']; 
+			var xmlFiles = ['test-2.xml']; 
 							
 
 			//TODO: make retrieval of file names automatic / drag files on here
@@ -284,6 +284,7 @@
 				  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
 				  }
 				xmlhttp.open("GET",xmlFileName,false);
+				xmlhttp.overrideMimeType('text/xml');
 				xmlhttp.send();
 				return xmlhttp.responseXML; 
 			}
@@ -300,11 +301,11 @@
 						fileNameArray.push(xmlFiles[fileIndex]);
 						
 						// get root of XML file
-						root = xml.getElementsByTagName('browserevaluationresult')[0];
+						root = xml.getElementsByTagName('waetresult')[0];
 						
 						// get subject ID, add to array if not already there
-						pretest = root.getElementsByTagName('pretest')[0];
-						subjectID = pretest.getElementsByTagName('comment')[0];
+						pretestSurveyResult = root.getElementsByTagName('surveyresult')[0];
+						subjectID = pretestSurveyResult.getElementsByTagName('comment')[0];
 						if (subjectID){
 							if (subjectID.getAttribute('id')!='sessionId') { // warning in console when not available
 								console.log(xmlFiles[fileIndex]+': no SessionID available');
@@ -378,7 +379,7 @@
 					// which songs did they do
 					if (xml != null) { // if file exists
 						// get root of XML file
-						root = xml.getElementsByTagName('browserevaluationresult')[0];
+						root = xml.getElementsByTagName('waetresult')[0];
 						// go over all audioholders
 						// document.getElementById('div_survey_'+xmlFileName).innerHTML += '<strong>Audioholders: </strong>';
 						// audioholderNodes = root.getElementsByTagName('audioholder');
@@ -415,7 +416,7 @@
 
 			function makePlots() { //TODO: split into different functions
 				// TEMPORARY
-				makeTimeline(xmlFileFolder+"/"+xmlFiles[7]);
+				makeTimeline(xmlFileFolder+"/"+xmlFiles[0]);
 
 				// create value array
 				var ratings = [];  // 3D matrix of ratings (audioholder, audioelement, subject)
@@ -432,7 +433,7 @@
 					xml = readXML(xmlFileName); 
 					if (xml != null) { // if file exists
 						// get root of XML file
-						root = xml.getElementsByTagName('browserevaluationresult')[0];
+						root = xml.getElementsByTagName('waetresult')[0];
 						// go over all audioholders
 						audioholderNodes = root.getElementsByTagName('audioholder');
 						for (audioholderIndex = 0; audioholderIndex < audioholderNodes.length; audioholderIndex++) { 
@@ -594,7 +595,7 @@
 					return; // do nothing; exit function
 				}
 				// get root of XML file
-				root = xml.getElementsByTagName('browserevaluationresult')[0];
+				root = xml.getElementsByTagName('waetresult')[0];
 
 				audioholder_time = 0; 
 				previous_audioholder_time = 0; // time spent before current audioholder
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analysis/analysis.css	Tue Mar 08 14:44:14 2016 +0000
@@ -0,0 +1,10 @@
+div.chart-holder {
+    border: 1px black solid;
+    margin: 10px 0px;
+}
+div.code {
+    margin: 5px;
+    padding-left: 15px;
+    background-color: rgb(200,200,200);
+    border: 2px dashed black;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analysis/analysis.js	Tue Mar 08 14:44:14 2016 +0000
@@ -0,0 +1,395 @@
+/*
+* Analysis script for WAET
+*/
+
+var chartContext;
+window.onload = function() {
+    // Load the Visualization API and the corechart package.
+      google.charts.load('current', {'packages':['corechart']});
+    chartContext = new Chart();
+}
+
+function arrayMean(values) {
+    var mean = 0;
+    for (var value of values) {
+        mean += value;
+    }
+    mean /= values.length;
+    return mean;
+}
+
+function percentile(values, n) {
+    values.sort( function(a,b) {return a - b;} );
+    // get ordinal rank
+    var rank = Math.min(Math.floor(values.length*n/100), values.length-1);
+    return values[rank];
+}
+
+function arrayMin(array) {
+    // Return the minimum value of an array
+    var min = array[0];
+    for (var value of array) {
+        if (value < min) {
+            min = value;
+        }
+    }
+    return min;
+}
+
+function arrayMax(array) {
+    // Return the minimum value of an array
+    var max = array[0];
+    for (var value of array) {
+        if (value > max) {
+            max = value;
+        }
+    }
+    return max;
+}
+
+function arrayHistogram(values,steps,min,max) {
+    if (steps == undefined) {
+        steps = 0.25;
+        console.log("Warning: arrayHistogram called without steps size set, default to 0.25");
+    }
+    if (min == undefined) {min = arrayMin(values);}
+    if (max == undefined) {max = arrayMax(values);}
+    var histogram = [];
+    var index = min;
+    while(index < max) {
+        histogram.push({
+            marker: index,
+            lt: index,
+            rt: index+steps,
+            count: 0
+        });
+        index += steps;
+    }
+    for (var value of values) {
+        for (var entry of histogram) {
+            if (value >= entry.lt && value <= entry.rt) {
+                entry.count++;
+                break;
+            }
+        }
+    }
+    return histogram;
+}
+
+function Chart() {
+    this.valueData = null;
+    this.commentData = null;
+    this.loadStatus = 0;
+    this.charts = [];
+    
+    var XMLHttp = new XMLHttpRequest();
+    XMLHttp.parent = this;
+    XMLHttp.open("GET","../scripts/score_parser.php?format=JSON",true);
+    XMLHttp.onload = function() {
+        // Now we have the JSON data, extract
+        this.parent.valueData = JSON.parse(this.responseText);
+        this.parent.loadStatus++;
+    }
+    XMLHttp.send();
+    var XMLHttp2 = new XMLHttpRequest();
+    XMLHttp2.parent = this;
+    XMLHttp2.open("GET","../scripts/comment_parser.php?format=JSON",true);
+    XMLHttp2.onload = function() {
+        // Now we have the JSON data, extract
+        this.parent.commentData = JSON.parse(this.responseText);
+        this.parent.loadStatus++;
+    }
+    XMLHttp2.send();
+    
+    this.chartObject = function(name) {
+        // Create the charting object
+        this.name = name;
+        this.root = document.createElement("div");
+        this.root.className = "chart-holder";
+        this.root.setAttribute("name",name);
+        this.chartDOM = document.createElement("div");
+        this.tableDOM = document.createElement("div");
+        this.latexDOM = document.createElement("div");
+        this.downloadDOM = document.createElement("div");
+        this.chart = undefined;
+        this.data = new google.visualization.DataTable();
+        this.options = {};
+        this.print = document.createElement("button");
+        this.sortDataButton = document.createElement("button");
+        this.sortDataButton.textContent = "Sort by Data";
+        this.sortDataButton.addEventListener("click",this);
+        this.sortDataButton.setAttribute("name","sort-data");
+        this.sortNameButton = document.createElement("button");
+        this.sortNameButton.textContent = "Sort by Name";
+        this.sortNameButton.addEventListener("click",this);
+        this.sortNameButton.setAttribute("name","sort-name");
+        this.draw = function() {
+            if (this.chart == undefined) {return;}
+            this.tableDOM.innerHTML = null;
+            this.latexDOM.innerHTML = null;
+            this.buildTable();
+            this.writeLatex();
+            this.chart.draw(this.data,this.options);
+        }
+        this.sortData = function() {
+            
+            var map = this.data.Jf.map(function(el,i){
+                return {index: i, value: el.c[1].v};
+            });
+            
+            map.sort(function(a,b){
+                if (a.value > b.value) {return -1;}
+                if (a.value < b.value) {return 1;}
+                return 0;
+            })
+            
+            var Jf = [];
+            var cc = [];
+            for (var i=0; i<map.length; i++) {
+                Jf.push(this.data.Jf[map[i].index]);
+                cc.push(this.data.cc[map[i].index]);
+            }
+            this.data.Jf = Jf;
+            this.data.cc = cc;
+        }
+        this.sortName = function() {
+            var map = this.data.Jf.map(function(el,i){
+                return {index: i, value: el.c[0].v};
+            });
+            
+            map.sort(function(a,b){
+                if (a.value < b.value) {return -1;}
+                if (a.value > b.value) {return 1;}
+                return 0;
+            })
+            
+            var Jf = [];
+            var cc = [];
+            for (var i=0; i<map.length; i++) {
+                Jf.push(this.data.Jf[map[i].index]);
+                cc.push(this.data.cc[map[i].index]);
+            }
+            this.data.Jf = Jf;
+            this.data.cc = cc;
+        }
+        this.handleEvent = function() {
+            // Only used to handle the chart.event.addListener(this,'ready') callback
+            switch(event.currentTarget.getAttribute("name"))
+            {
+                case "download":
+                    window.open(this.chart.getImageURI());
+                    break;
+                case "sort-data":
+                    this.sortData();
+                    this.draw();
+                    break;
+                case "sort-name":
+                    this.sortName();
+                    this.draw();
+                    break;
+            }
+        }
+        
+        this.root.appendChild(this.chartDOM);
+        this.root.appendChild(this.tableDOM);
+        this.root.appendChild(this.latexDOM);
+        this.root.appendChild(this.sortDataButton);
+        this.root.appendChild(this.sortNameButton);
+        this.root.appendChild(this.print);
+        this.print.textContent = "Download";
+        this.print.setAttribute("name","download");
+        this.print.addEventListener("click",this);
+        this.root.appendChild(this.downloadDOM);
+        this.buildTable = function() {
+            var table = document.createElement("table");
+            table.border = "1";
+            for (var rowIndex=0; rowIndex<this.data.If.length; rowIndex++) {
+                var row = document.createElement("tr");
+                table.appendChild(row);
+                var rowTitle = document.createElement("td");
+                rowTitle.textContent = this.data.If[rowIndex].label;
+                row.appendChild(rowTitle);
+                for (var cIndex=0; cIndex<this.data.cc.length; cIndex++) {
+                    var column = document.createElement("td");
+                    column.textContent = this.data.cc[cIndex][rowIndex].tf;
+                    row.appendChild(column);
+                }
+            }
+            this.tableDOM.appendChild(table);
+        };
+        this.writeLatex = function() {
+            var root = document.createElement("div");
+            root.className = "code";
+            var holder = document.createElement("pre");
+            // Table start
+            var start = document.createElement("p");
+            start.textContent = "\\" + "begin{tabular}{|l|";
+            holder.appendChild(start);
+            for (var i=0; i<this.data.cc.length; i++) {
+                start.textContent = start.textContent+"c|";
+            }
+            start.textContent = start.textContent.concat("}");
+            // Now write the rows:
+            for (var rIndex=0; rIndex<this.data.If.length; rIndex++) {
+                var row = document.createElement("p");
+                row.textContent = this.data.If[rIndex].label.concat(" & ");
+                for (var cIndex=0; cIndex<this.data.cc.length; cIndex++) {
+                    row.textContent = row.textContent.concat(this.data.cc[cIndex][rIndex].tf);
+                    if (cIndex < this.data.cc.length-1) {
+                        row.textContent = row.textContent.concat(" & ");
+                    }
+                }
+                holder.appendChild(row);
+            }
+            // Table end
+            var end = document.createElement("p");
+            end.textContent = "\\" + "end{tabular}";
+            holder.appendChild(end);
+            root.appendChild(holder);
+            this.latexDOM.appendChild(root);
+        }
+    }
+    
+    this.clear = function() {
+        var inject = document.getElementById("test-pages");
+        for (var chart of this.charts) {
+            inject.removeChild(chart.root);
+        }
+        this.charts = [];
+    }
+    
+    this.drawTestMean = function() {
+        // This draws one bargraph per axis with every test element on
+        if (this.valueData == null) {
+            console.log("Error - Data not loaded");
+            return;
+        }
+        var chartList = [];
+        
+        // Create the data table
+        for (var page of this.valueData.pages) {
+            for (var element of page.elements) {
+                for (var axis of element.axis) {
+                    // Find the axis
+                    var axisChart = chartList.find(function(element,index,array){
+                        if (element.name == this) {return true;} else {return false;}
+                    },"mean-test-"+axis.id);
+                    if (axisChart == null) {
+                        axisChart = new this.chartObject("mean-test-"+axis.id);
+                        axisChart.options = {
+                            'title':'Mean of axis: '+axis.name,
+                            'width':window.innerWidth*0.9,
+                            'height':(window.innerWidth*0.9)/1.77
+                        }
+                        axisChart.data.addColumn('string','id');
+                        axisChart.data.addColumn('number',axis.name);
+                        chartList.push(axisChart);
+                        document.getElementById("test-pages").appendChild(axisChart.root);
+                    }
+                    var mean = arrayMean(axis.values);
+                    axisChart.data.addRow([element.id,mean]);
+                }
+            }
+        }
+        
+        // Build and push charts
+        for (var chart of chartList) {
+            chart.chart = new google.visualization.ColumnChart(chart.chartDOM);
+            chart.chart.draw(chart.data,chart.options);
+            chart.buildTable();
+            chart.writeLatex();
+            this.charts.push(chart);
+        }
+    }
+    
+    this.drawPageMean = function() {
+        // First we must get the value data
+        if (this.valueData == null) {
+            console.log("Error - Data not loaded");
+            return;
+        }
+        // We create one plot per page
+        for (var page of this.valueData.pages) {
+            
+            // Create the chart resulting point
+            var chart = new this.chartObject("mean-page-"+page.id);
+            document.getElementById("test-pages").appendChild(chart.root);
+            
+            // Create the data table
+            chart.data.addColumn('string','id');
+            // Get axis labels
+            for (var axis of page.elements[0].axis) {
+                chart.data.addColumn('number',axis.name);
+            }
+            var rows = []; // Rows is an array of tuples [col1, col2, col3 ... colN];
+            for (var element of page.elements) {
+                var entry = [element.id];
+                for (var i=0; i<page.elements[0].axis.length; i++) {
+                    var mean =0;
+                    if (i < element.axis.length) {
+                        var axis = element.axis[i];
+                        mean = arrayMean(axis.values);
+                    }
+                    entry.push(mean);
+                }
+                rows.push(entry);
+            }
+            chart.data.addRows(rows);
+            chart.options = {
+                'title':'Mean of page: '+page.id,
+                'width':800,
+                'height':700
+            }
+            // Draw the chart
+            chart.chart = new google.visualization.ColumnChart(chart.chartDOM);
+            chart.chart.draw(chart.data,chart.options);
+            chart.buildTable();
+            chart.writeLatex();
+            this.charts.push(chart);
+        }
+    }
+    
+    this.drawElementHistogram = function() {
+        // First we must get the value data
+        if (this.valueData == null) {
+            console.log("Error - Data not loaded");
+            return;
+        }
+        // We create one plot per element, enjoy...
+        for (var page of this.valueData.pages) {
+            for (var element of page.elements) {
+                // Build the chart object
+                var chart = new this.chartObject("histogram-element-"+element.id);
+                document.getElementById("test-pages").appendChild(chart.root);
+                chart.data.addColumn('string','index');
+                var histograms = [];
+                for (var axis of element.axis) {
+                    chart.data.addColumn('number',axis.name);
+                    histograms.push(arrayHistogram(axis.values,0.125,0.0,1.0));
+                }
+                for (var axis of element.axis) {
+                    for (var i=0; i<histograms[0].length; i++)
+                    {
+                        var entry = [""+histograms[0][i].lt.toPrecision(2)+"-"+histograms[0][i].rt.toPrecision(3)]
+                        for (var histogram of histograms) {
+                            entry.push(histogram[i].count);
+                        }
+                        chart.data.addRow(entry);
+                    }
+                }
+                chart.options = {
+                    'title':'Histogram of element: '+element.id,
+                    'width':800,
+                    'height':700,
+                    'bar':{'groupWidth': '100%'}
+                }
+                // Draw the chart
+                chart.chart = new google.visualization.ColumnChart(chart.chartDOM);
+                chart.chart.draw(chart.data,chart.options);
+                chart.buildTable();
+                chart.writeLatex();
+                this.charts.push(chart);
+            }
+        }
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/analysis/index.html	Tue Mar 08 14:44:14 2016 +0000
@@ -0,0 +1,26 @@
+<html lang="en">
+    <head>
+        <meta charset="utf-8" />
+        <link rel='stylesheet' href="analysis.css" type="text/css"/>
+        <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
+        <script type="text/javascript" src="analysis.js"></script>
+    </head>
+    <body>
+        <h1>Web Audio Evaluation Toolbox: Analysis</h1>
+        <button onclick="chartContext.clear();">Clear Charts</button>
+        <div id="test-charts">
+            <p>Charts per test</p>
+            <button onclick="chartContext.drawTestMean();">Means</button>
+        </div>
+        <div id="page-charts">
+            <p>Charts per test page</p>
+            <button onclick="chartContext.drawPageMean();">Means</button>
+        </div>
+        <div id="element-charts">
+            <p>Charts per element</p>
+            <button onclick="chartContext.drawElementHistogram();">Histogram</button>
+        </div>
+        
+        <div id="test-pages"></div>
+    </body>
+</html>
\ No newline at end of file
--- a/core.css	Wed Feb 24 14:00:10 2016 +0000
+++ b/core.css	Tue Mar 08 14:44:14 2016 +0000
@@ -151,4 +151,12 @@
     height: 25px;
     margin-left: 5px;
     float: left;
+}
+
+div.error-colour {
+    background-color: #FF8F8F;
+}
+button.error-colour {
+    background-color: #FF8F8F;
+    color: black;
 }
\ No newline at end of file
--- a/core.js	Wed Feb 24 14:00:10 2016 +0000
+++ b/core.js	Tue Mar 08 14:44:14 2016 +0000
@@ -147,6 +147,15 @@
 		r.onload = function() {
 			loadProjectSpecCallback(r.response);
 		};
+        r.onerror = function() {
+            document.getElementsByTagName('body')[0].innerHTML = null;
+            var msg = document.createElement("h3");
+            msg.textContent = "FATAL ERROR";
+            var span = document.createElement("p");
+            span.textContent = "There was an error when loading your XML file. Please check your path in the URL. After the path to this page, there should be '?url=path/to/your/file.xml'. Check the spelling of your filename as well. If you are still having issues, check the log of the python server or your webserver distribution for 404 codes for your file.";
+            document.getElementsByTagName('body')[0].appendChild(msg);
+            document.getElementsByTagName('body')[0].appendChild(span);
+        }
 		r.send();
 	};
 	xmlhttp.send();
@@ -344,11 +353,13 @@
 			if (xmlhttp.status != 200 && xmlhttp.readyState == 4) {
 				createProjectSave(null);
 			} else {
-				if (xmlhttp.responseXML == null)
+				var parser = new DOMParser();
+				var xmlDoc = parser.parseFromString(xmlhttp.responseText, "application/xml");
+				if (xmlDoc == null)
 				{
 					createProjectSave('null');
 				}
-				var response = xmlhttp.responseXML.childNodes[0];
+				var response = xmlDoc.childNodes[0];
 				if (response.getAttribute('state') == "OK")
 				{
 					var file = response.getElementsByTagName('file')[0];
@@ -356,6 +367,7 @@
 					popup.showPopup();
 					popup.popupContent.innerHTML = null;
 					popup.popupContent.textContent = "Thank you!";
+					window.onbeforeunload=null;
 				} else {
 					var message = response.getElementsByTagName('message')[0];
 					errorSessionDump(message.textContent);
@@ -366,6 +378,8 @@
 		popup.showPopup();
 		popup.popupContent.innerHTML = null;
 		popup.popupContent.textContent = "Submitting. Please Wait";
+        popup.hideNextButton();
+        popup.hidePreviousButton();
 	}
 }
 
@@ -736,6 +750,18 @@
 			blank.style.height = window.innerHeight;
 		}
 	};
+    this.hideNextButton = function() {
+        this.buttonProceed.style.visibility = "hidden";
+    }
+    this.hidePreviousButton = function() {
+        this.buttonPrevious.style.visibility = "hidden";
+    }
+    this.showNextButton = function() {
+        this.buttonProceed.style.visibility = "visible";
+    }
+    this.showPreviousButton = function() {
+        this.buttonPrevious.style.visibility = "visible";
+    }
 }
 
 function advanceState()
@@ -777,10 +803,10 @@
 		}
 		for (var i=0; i<specification.pages.length; i++)
 		{
-			if (specification.testPages < i && specification.testPages != 0) {break;}
+			if (specification.testPages <= i && specification.testPages != 0) {break;}
 			this.stateMap.push(pageHolder[i]);
-			
 		}
+        
 		if (specification.preTest != null) {this.preTestSurvey = specification.preTest;}
 		if (specification.postTest != null) {this.postTestSurvey = specification.postTest;}
 		
@@ -957,6 +983,7 @@
 			// Create callback to decode the data asynchronously
 			this.xmlRequest.onloadend = function() {
                 // Use inbuilt WAVE decoder first
+                if (this.status == -1) {return;}
                 var waveObj = new WAVE();
                 if (waveObj.open(bufferObj.xmlRequest.response) == 0)
                 {
@@ -986,7 +1013,7 @@
                                 console.log('URL: '+audioObj.url);
                                 errorSessionDump('Fragment '+audioObj.id+' 404 error');
                             }
-                            this.status = -1;
+                            this.parent.status = -1;
                         }
                     });
                 }
@@ -996,6 +1023,20 @@
                     calculateLoudness(bufferObj,"I");
                 }
 			};
+            
+            // Create callback for any error in loading
+            this.xmlRequest.onerror = function() {
+                this.parent.status = -1;
+                for (var i=0; i<this.parent.users.length; i++)
+                {
+                    this.parent.users[i].state = -1;
+                    if (this.parent.users[i].interfaceDOM != null)
+                    {
+                        this.parent.users[i].bufferLoaded(this);
+                    }
+                }
+            }
+            
 			this.progress = 0;
 			this.progressCallback = function(event){
 				if (event.lengthComputable)
@@ -1027,7 +1068,7 @@
                 if (audioObject.id == objects.id){return 0;}
             }
             this.users.push(audioObject);
-            if (this.status == 3)
+            if (this.status == 3 || this.status == -1)
             {
                 // The buffer is already ready, trigger bufferLoaded
                 audioObject.bufferLoaded(this);
@@ -1140,7 +1181,7 @@
 	
 	this.newTestPage = function(audioHolderObject,store) {
 		this.pageStore = store;
-		this.state = 0;
+		this.status = 0;
 		this.audioObjectsReady = false;
 		this.metric.reset();
 		for (var i=0; i < this.buffers.length; i++)
@@ -1242,6 +1283,13 @@
 	{
 		// Called by the associated buffer when it has finished loading, will then 'bind' the buffer to the
 		// audioObject and trigger the interfaceDOM.enable() function for user feedback
+        if (callee.status == -1) {
+            // ERROR
+            this.state = -1;
+            if (this.interfaceDOM != null) {this.interfaceDOM.error();}
+            this.buffer = callee;
+            return;
+        }
 		if (audioEngineContext.loopPlayback){
 			// First copy the buffer into this.buffer
 			this.buffer = new audioEngineContext.bufferObj();
@@ -1283,7 +1331,11 @@
 		if (this.state == 1)
 		{
 			this.interfaceDOM.enable();
-		}
+		} else if (this.state == -1) {
+            // ERROR
+            this.interfaceDOM.error();
+            return;
+        }
 		this.storeDOM.setAttribute('presentedId',interfaceObject.getPresentedId());
 	};
     
@@ -1311,7 +1363,9 @@
 			this.bufferNode.onended = function(event) {
 				// Safari does not like using 'this' to reference the calling object!
 				//event.currentTarget.owner.metric.stopListening(audioEngineContext.timer.getTestTime(),event.currentTarget.owner.getCurrentPosition());
-				event.currentTarget.owner.stop(audioContext.currentTime+1);
+                if (event.currentTarget != null) {
+				    event.currentTarget.owner.stop(audioContext.currentTime+1);
+                }
 			};
 			if (this.bufferNode.loop == false) {
 				this.metric.startListening(audioEngineContext.timer.getTestTime());
@@ -1321,7 +1375,7 @@
                  this.outputGain.gain.setValueAtTime(0.0,startTime);
             }
 			this.bufferNode.start(startTime);
-            this.bufferNode.playbackStartTime = startTime;
+            this.bufferNode.playbackStartTime = audioEngineContext.timer.getTestTime();
 		}
 	};
 	
@@ -1340,7 +1394,9 @@
 	this.getCurrentPosition = function() {
 		var time = audioEngineContext.timer.getTestTime();
 		if (this.bufferNode != undefined) {
-            return (time - this.bufferNode.playbackStartTime)%this.buffer.buffer.duration;
+            var position = (time - this.bufferNode.playbackStartTime)%this.buffer.buffer.duration;
+            if (isNaN(position)){return 0;}
+            return position;
 		} else {
 			return 0;
 		}
@@ -1563,14 +1619,9 @@
 			elementTrackerFull.setAttribute('name','elementTrackerFull');
 			for (var k=0; k<this.movementTracker.length; k++)
 			{
-				var timePos = storage.document.createElement('timePos');
-				timePos.id = k;
-				var time = storage.document.createElement('time');
-				time.textContent = this.movementTracker[k][0];
-				var position = document.createElement('position');
-				position.textContent = this.movementTracker[k][1];
-				timePos.appendChild(time);
-				timePos.appendChild(position);
+				var timePos = storage.document.createElement('movement');
+                timePos.setAttribute("time",this.movementTracker[k][0]);
+                timePos.setAttribute("value",this.movementTracker[k][1]);
 				elementTrackerFull.appendChild(timePos);
 			}
 			storeDOM.push(elementTrackerFull);
@@ -1910,7 +1961,7 @@
 			
 			this.exportXML = function(doc)
 			{
-				var node = doc.createElement('surveyelement');
+				var node = doc.createElement('surveyentry');
 				node.setAttribute('type',this.type);
 				var statement = doc.createElement('statement');
 				statement.textContent = this.statement;
@@ -1920,17 +1971,16 @@
 				case "statement":
 					break;
 				case "question":
-					node.id = this.id;
-					node.setAttribute("mandatory",this.mandatory);
-					node.setAttribute("boxsize",this.boxsize);
-					break;
-				case "number":
-					node.id = this.id;
-					node.setAttribute("mandatory",this.mandatory);
-					node.setAttribute("min", this.min);
-					node.setAttribute("max", this.max);
-					node.setAttribute("step", this.step);
-					break;
+                    node.id = this.id;
+                    if (this.mandatory != undefined) { node.setAttribute("mandatory",this.mandatory);}
+                    if (this.boxsize != undefined) {node.setAttribute("boxsize",this.boxsize);}
+                    break;
+                case "number":
+                    node.id = this.id;
+                    if (this.mandatory != undefined) { node.setAttribute("mandatory",this.mandatory);}
+                    if (this.min != undefined) {node.setAttribute("min", this.min);}
+                    if (this.max != undefined) {node.setAttribute("max", this.max);}
+                    break;
 				case "checkbox":
 				case "radio":
 					node.id = this.id;
@@ -2254,9 +2304,9 @@
 			this.id = null;
 			this.parent = null;
 			this.type = null;
-			this.marker = false;
+			this.marker = null;
 			this.enforce = false;
-			this.gain = 1.0;
+			this.gain = 0.0;
 			this.schema = specification.schema.getAllElementsByName('audioelement')[0];;
 			this.parent = null;
 			this.decode = function(parent,xml)
@@ -2310,7 +2360,7 @@
 	this.newPage = function(audioHolderObject,store)
 	{
 		audioEngineContext.newTestPage(audioHolderObject,store);
-		interfaceContext.deleteCommentBoxes();
+		interfaceContext.commentBoxes.deleteCommentBoxes();
 		interfaceContext.deleteCommentQuestions();
 		loadTest(audioHolderObject,store);
 	};
@@ -2358,58 +2408,88 @@
 		return node;
 	};
 	
-	this.commentBoxes = [];
-	this.elementCommentBox = function(audioObject) {
-		var element = audioObject.specification;
-		this.audioObject = audioObject;
-		this.id = audioObject.id;
-		var audioHolderObject = audioObject.specification.parent;
-		// Create document objects to hold the comment boxes
-		this.trackComment = document.createElement('div');
-		this.trackComment.className = 'comment-div';
-		this.trackComment.id = 'comment-div-'+audioObject.id;
-		// Create a string next to each comment asking for a comment
-		this.trackString = document.createElement('span');
-		this.trackString.innerHTML = audioHolderObject.commentBoxPrefix+' '+audioObject.interfaceDOM.getPresentedId();
-		// Create the HTML5 comment box 'textarea'
-		this.trackCommentBox = document.createElement('textarea');
-		this.trackCommentBox.rows = '4';
-		this.trackCommentBox.cols = '100';
-		this.trackCommentBox.name = 'trackComment'+audioObject.id;
-		this.trackCommentBox.className = 'trackComment';
-		var br = document.createElement('br');
-		// Add to the holder.
-		this.trackComment.appendChild(this.trackString);
-		this.trackComment.appendChild(br);
-		this.trackComment.appendChild(this.trackCommentBox);
-		
-		this.exportXMLDOM = function() {
-			var root = document.createElement('comment');
-            var question = document.createElement('question');
-            question.textContent = this.trackString.textContent;
-            var response = document.createElement('response');
-            response.textContent = this.trackCommentBox.value;
-            console.log("Comment frag-"+this.id+": "+response.textContent);
-            root.appendChild(question);
-            root.appendChild(response);
-			return root;
-		};
-		this.resize = function()
-		{
-			var boxwidth = (window.innerWidth-100)/2;
-			if (boxwidth >= 600)
-			{
-				boxwidth = 600;
-			}
-			else if (boxwidth < 400)
-			{
-				boxwidth = 400;
-			}
-			this.trackComment.style.width = boxwidth+"px";
-			this.trackCommentBox.style.width = boxwidth-6+"px";
-		};
-		this.resize();
-	};
+	this.commentBoxes = new function() {
+        this.boxes = [];
+        this.injectPoint = null;
+        this.elementCommentBox = function(audioObject) {
+            var element = audioObject.specification;
+            this.audioObject = audioObject;
+            this.id = audioObject.id;
+            var audioHolderObject = audioObject.specification.parent;
+            // Create document objects to hold the comment boxes
+            this.trackComment = document.createElement('div');
+            this.trackComment.className = 'comment-div';
+            this.trackComment.id = 'comment-div-'+audioObject.id;
+            // Create a string next to each comment asking for a comment
+            this.trackString = document.createElement('span');
+            this.trackString.innerHTML = audioHolderObject.commentBoxPrefix+' '+audioObject.interfaceDOM.getPresentedId();
+            // Create the HTML5 comment box 'textarea'
+            this.trackCommentBox = document.createElement('textarea');
+            this.trackCommentBox.rows = '4';
+            this.trackCommentBox.cols = '100';
+            this.trackCommentBox.name = 'trackComment'+audioObject.id;
+            this.trackCommentBox.className = 'trackComment';
+            var br = document.createElement('br');
+            // Add to the holder.
+            this.trackComment.appendChild(this.trackString);
+            this.trackComment.appendChild(br);
+            this.trackComment.appendChild(this.trackCommentBox);
+
+            this.exportXMLDOM = function() {
+                var root = document.createElement('comment');
+                var question = document.createElement('question');
+                question.textContent = this.trackString.textContent;
+                var response = document.createElement('response');
+                response.textContent = this.trackCommentBox.value;
+                console.log("Comment frag-"+this.id+": "+response.textContent);
+                root.appendChild(question);
+                root.appendChild(response);
+                return root;
+            };
+            this.resize = function()
+            {
+                var boxwidth = (window.innerWidth-100)/2;
+                if (boxwidth >= 600)
+                {
+                    boxwidth = 600;
+                }
+                else if (boxwidth < 400)
+                {
+                    boxwidth = 400;
+                }
+                this.trackComment.style.width = boxwidth+"px";
+                this.trackCommentBox.style.width = boxwidth-6+"px";
+            };
+            this.resize();
+        };
+        this.createCommentBox = function(audioObject) {
+            var node = new this.elementCommentBox(audioObject);
+            this.boxes.push(node);
+            audioObject.commentDOM = node;
+            return node;
+        };
+        this.sortCommentBoxes = function() {
+            this.boxes.sort(function(a,b){return a.id - b.id;});
+        };
+
+        this.showCommentBoxes = function(inject, sort) {
+            this.injectPoint = inject;
+            if (sort) {this.sortCommentBoxes();}
+            for (var box of this.boxes) {
+                inject.appendChild(box.trackComment);
+            }
+        };
+
+        this.deleteCommentBoxes = function() {
+            if (this.injectPoint != null) {
+                for (var box of this.boxes) {
+                    this.injectPoint.removeChild(box.trackComment);
+                }
+                this.injectPoint = null;
+            }
+            this.boxes = [];
+        };
+    }
 	
 	this.commentQuestions = [];
 	
@@ -2678,28 +2758,6 @@
 		};
 		this.resize();
 	};
-
-	this.createCommentBox = function(audioObject) {
-		var node = new this.elementCommentBox(audioObject);
-		this.commentBoxes.push(node);
-		audioObject.commentDOM = node;
-		return node;
-	};
-	
-	this.sortCommentBoxes = function() {
-		this.commentBoxes.sort(function(a,b){return a.id - b.id;});
-	};
-	
-	this.showCommentBoxes = function(inject, sort) {
-		if (sort) {interfaceContext.sortCommentBoxes();}
-		for (var box of interfaceContext.commentBoxes) {
-			inject.appendChild(box.trackComment);
-		}
-	};
-	
-	this.deleteCommentBoxes = function() {
-		this.commentBoxes = [];
-	};
 	
 	this.createCommentQuestion = function(element) {
 		var node;
@@ -3036,7 +3094,7 @@
 	this.globalPostTest = null;
 	this.testPages = [];
 	this.document = document.implementation.createDocument(null,"waetresult");
-	this.root = this.document.children[0];
+	this.root = this.document.childNodes[0];
 	this.state = 0;
 	
 	this.initialise = function()
--- a/docs/WAC2016/WAC2016.bib	Wed Feb 24 14:00:10 2016 +0000
+++ b/docs/WAC2016/WAC2016.bib	Tue Mar 08 14:44:14 2016 +0000
@@ -1,7 +1,7 @@
 %% This BibTeX bibliography file was created using BibDesk.
 %% http://bibdesk.sourceforge.net/
 
-%% Created for Brecht De Man at 2015-10-12 17:58:50 +0100 
+%% Created for Brecht De Man at 2016-02-29 11:43:56 +0100 
 
 
 %% Saved with string encoding Unicode (UTF-8) 
@@ -16,28 +16,27 @@
 	Keywords = {perceptual evaluation},
 	Title = {Preliminary guidelines for subjective evalutation of audio source separation algorithms},
 	Year = {2006},
-	Bdsk-File-1 = {YnBsaXN0MDDUAQIDBAUGJCVYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKgHCBMUFRYaIVUkbnVsbNMJCgsMDxJXTlMua2V5c1pOUy5vYmplY3RzViRjbGFzc6INDoACgAOiEBGABIAFgAdccmVsYXRpdmVQYXRoWWFsaWFzRGF0YV8QNS4uLy4uLy4uLy4uL0dvb2dsZSBEcml2ZS9Eb2N1bWVudHMvUGFwZXJzL211c2hyYW0ucGRm0hcLGBlXTlMuZGF0YU8RAaAAAAAAAaAAAgAADE1hY2ludG9zaCBIRAAAAAAAAAAAAAAAAAAAANBcT3dIKwAAAApfEQttdXNocmFtLnBkZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACqdQz0+BaAAAAAAAAAAAAAQABAAACSAAAAAAAAAAAAAAAAAAAAAGUGFwZXJzABAACAAA0FxBZwAAABEACAAAz0+BaAAAAAEAFAAKXxEACl67AApdAgAJRF4AApPVAAIASE1hY2ludG9zaCBIRDpVc2VyczoAQnJlY2h0OgBHb29nbGUgRHJpdmU6AERvY3VtZW50czoAUGFwZXJzOgBtdXNocmFtLnBkZgAOABgACwBtAHUAcwBoAHIAYQBtAC4AcABkAGYADwAaAAwATQBhAGMAaQBuAHQAbwBzAGgAIABIAEQAEgA2VXNlcnMvQnJlY2h0L0dvb2dsZSBEcml2ZS9Eb2N1bWVudHMvUGFwZXJzL211c2hyYW0ucGRmABMAAS8AABUAAgAN//8AAIAG0hscHR5aJGNsYXNzbmFtZVgkY2xhc3Nlc11OU011dGFibGVEYXRhox0fIFZOU0RhdGFYTlNPYmplY3TSGxwiI1xOU0RpY3Rpb25hcnmiIiBfEA9OU0tleWVkQXJjaGl2ZXLRJidUcm9vdIABAAgAEQAaACMALQAyADcAQABGAE0AVQBgAGcAagBsAG4AcQBzAHUAdwCEAI4AxgDLANMCdwJ5An4CiQKSAqACpAKrArQCuQLGAskC2wLeAuMAAAAAAAACAQAAAAAAAAAoAAAAAAAAAAAAAAAAAAAC5Q==}}
+	Bdsk-File-1 = {YnBsaXN0MDDUAQIDBAUGJCVYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKgHCBMUFRYaIVUkbnVsbNMJCgsMDxJXTlMua2V5c1pOUy5vYmplY3RzViRjbGFzc6INDoACgAOiEBGABIAFgAdccmVsYXRpdmVQYXRoWWFsaWFzRGF0YV8QNS4uLy4uLy4uLy4uL0dvb2dsZSBEcml2ZS9Eb2N1bWVudHMvUGFwZXJzL211c2hyYW0ucGRm0hcLGBlXTlMuZGF0YU8RAaAAAAAAAaAAAgAADE1hY2ludG9zaCBIRAAAAAAAAAAAAAAAAAAAANBcXYdIKwAAAApfEQttdXNocmFtLnBkZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACqdQz0+PeAAAAAAAAAAAAAQABAAACSAAAAAAAAAAAAAAAAAAAAAGUGFwZXJzABAACAAA0FxBZwAAABEACAAAz0+BaAAAAAEAFAAKXxEACl67AApdAgAJRF4AApPVAAIASE1hY2ludG9zaCBIRDpVc2VyczoAQnJlY2h0OgBHb29nbGUgRHJpdmU6AERvY3VtZW50czoAUGFwZXJzOgBtdXNocmFtLnBkZgAOABgACwBtAHUAcwBoAHIAYQBtAC4AcABkAGYADwAaAAwATQBhAGMAaQBuAHQAbwBzAGgAIABIAEQAEgA2VXNlcnMvQnJlY2h0L0dvb2dsZSBEcml2ZS9Eb2N1bWVudHMvUGFwZXJzL211c2hyYW0ucGRmABMAAS8AABUAAgAN//8AAIAG0hscHR5aJGNsYXNzbmFtZVgkY2xhc3Nlc11OU011dGFibGVEYXRhox0fIFZOU0RhdGFYTlNPYmplY3TSGxwiI1xOU0RpY3Rpb25hcnmiIiBfEA9OU0tleWVkQXJjaGl2ZXLRJidUcm9vdIABAAgAEQAaACMALQAyADcAQABGAE0AVQBgAGcAagBsAG4AcQBzAHUAdwCEAI4AxgDLANMCdwJ5An4CiQKSAqACpAKrArQCuQLGAskC2wLeAuMAAAAAAAACAQAAAAAAAAAoAAAAAAAAAAAAAAAAAAAC5Q==}}
 
 @conference{scale,
 	Author = {Arnau Vazquez Giner},
 	Booktitle = {AIA/DAGA Conference on Acoustics, Merano (Italy)},
 	Date-Added = {2015-10-12 16:55:54 +0000},
-	Date-Modified = {2015-10-12 16:55:54 +0000},
+	Date-Modified = {2016-02-29 10:29:38 +0000},
 	Keywords = {perceptual evaluation},
-	Title = {Scale - A Software Tool for Listening Experiments},
+	Title = {Scale - {A} Software Tool for Listening Experiments},
 	Year = {2013},
-	Bdsk-File-1 = {YnBsaXN0MDDUAQIDBAUGJCVYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKgHCBMUFRYaIVUkbnVsbNMJCgsMDxJXTlMua2V5c1pOUy5vYmplY3RzViRjbGFzc6INDoACgAOiEBGABIAFgAdccmVsYXRpdmVQYXRoWWFsaWFzRGF0YV8QMy4uLy4uLy4uLy4uL0dvb2dsZSBEcml2ZS9Eb2N1bWVudHMvUGFwZXJzL1NjYWxlLnBkZtIXCxgZV05TLmRhdGFPEQGYAAAAAAGYAAIAAAxNYWNpbnRvc2ggSEQAAAAAAAAAAAAAAAAAAADQXE93SCsAAAAKXxEJU2NhbGUucGRmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqmAM9QyZAAAAAAAAAAAAAEAAQAAAkgAAAAAAAAAAAAAAAAAAAABlBhcGVycwAQAAgAANBcQWcAAAARAAgAAM9QyZAAAAABABQACl8RAApeuwAKXQIACUReAAKT1QACAEZNYWNpbnRvc2ggSEQ6VXNlcnM6AEJyZWNodDoAR29vZ2xlIERyaXZlOgBEb2N1bWVudHM6AFBhcGVyczoAU2NhbGUucGRmAA4AFAAJAFMAYwBhAGwAZQAuAHAAZABmAA8AGgAMAE0AYQBjAGkAbgB0AG8AcwBoACAASABEABIANFVzZXJzL0JyZWNodC9Hb29nbGUgRHJpdmUvRG9jdW1lbnRzL1BhcGVycy9TY2FsZS5wZGYAEwABLwAAFQACAA3//wAAgAbSGxwdHlokY2xhc3NuYW1lWCRjbGFzc2VzXU5TTXV0YWJsZURhdGGjHR8gVk5TRGF0YVhOU09iamVjdNIbHCIjXE5TRGljdGlvbmFyeaIiIF8QD05TS2V5ZWRBcmNoaXZlctEmJ1Ryb290gAEACAARABoAIwAtADIANwBAAEYATQBVAGAAZwBqAGwAbgBxAHMAdQB3AIQAjgDEAMkA0QJtAm8CdAJ/AogClgKaAqECqgKvArwCvwLRAtQC2QAAAAAAAAIBAAAAAAAAACgAAAAAAAAAAAAAAAAAAALb}}
+	Bdsk-File-1 = {YnBsaXN0MDDUAQIDBAUGJCVYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKgHCBMUFRYaIVUkbnVsbNMJCgsMDxJXTlMua2V5c1pOUy5vYmplY3RzViRjbGFzc6INDoACgAOiEBGABIAFgAdccmVsYXRpdmVQYXRoWWFsaWFzRGF0YV8QMy4uLy4uLy4uLy4uL0dvb2dsZSBEcml2ZS9Eb2N1bWVudHMvUGFwZXJzL1NjYWxlLnBkZtIXCxgZV05TLmRhdGFPEQGYAAAAAAGYAAIAAAxNYWNpbnRvc2ggSEQAAAAAAAAAAAAAAAAAAADQXF2HSCsAAAAKXxEJU2NhbGUucGRmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqmAM9Q16AAAAAAAAAAAAAEAAQAAAkgAAAAAAAAAAAAAAAAAAAABlBhcGVycwAQAAgAANBcQWcAAAARAAgAAM9QyZAAAAABABQACl8RAApeuwAKXQIACUReAAKT1QACAEZNYWNpbnRvc2ggSEQ6VXNlcnM6AEJyZWNodDoAR29vZ2xlIERyaXZlOgBEb2N1bWVudHM6AFBhcGVyczoAU2NhbGUucGRmAA4AFAAJAFMAYwBhAGwAZQAuAHAAZABmAA8AGgAMAE0AYQBjAGkAbgB0AG8AcwBoACAASABEABIANFVzZXJzL0JyZWNodC9Hb29nbGUgRHJpdmUvRG9jdW1lbnRzL1BhcGVycy9TY2FsZS5wZGYAEwABLwAAFQACAA3//wAAgAbSGxwdHlokY2xhc3NuYW1lWCRjbGFzc2VzXU5TTXV0YWJsZURhdGGjHR8gVk5TRGF0YVhOU09iamVjdNIbHCIjXE5TRGljdGlvbmFyeaIiIF8QD05TS2V5ZWRBcmNoaXZlctEmJ1Ryb290gAEACAARABoAIwAtADIANwBAAEYATQBVAGAAZwBqAGwAbgBxAHMAdQB3AIQAjgDEAMkA0QJtAm8CdAJ/AogClgKaAqECqgKvArwCvwLRAtQC2QAAAAAAAAIBAAAAAAAAACgAAAAAAAAAAAAAAAAAAALb}}
 
 @conference{whisper,
 	Author = {Simon Ciba and Andr{\'e} Wlodarski and Hans-Joachim Maempel},
 	Booktitle = {126th Convention of the AES},
 	Date-Added = {2015-10-12 16:55:54 +0000},
-	Date-Modified = {2015-10-12 16:55:54 +0000},
+	Date-Modified = {2016-02-29 10:43:56 +0000},
 	Keywords = {perceptual evaluation},
-	Month = {May 7-10},
-	Title = {WhisPER -- {A} new tool for performing listening tests},
+	Title = {Whis{PER} - {A} new tool for performing listening tests},
 	Year = {2009},
-	Bdsk-File-1 = {YnBsaXN0MDDUAQIDBAUGJCVYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKgHCBMUFRYaIVUkbnVsbNMJCgsMDxJXTlMua2V5c1pOUy5vYmplY3RzViRjbGFzc6INDoACgAOiEBGABIAFgAdccmVsYXRpdmVQYXRoWWFsaWFzRGF0YV8QNS4uLy4uLy4uLy4uL0dvb2dsZSBEcml2ZS9Eb2N1bWVudHMvUGFwZXJzL3doaXNwZXIucGRm0hcLGBlXTlMuZGF0YU8RAaAAAAAAAaAAAgAADE1hY2ludG9zaCBIRAAAAAAAAAAAAAAAAAAAANBcT3dIKwAAAApfEQt3aGlzcGVyLnBkZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACngFz1DL0QAAAAAAAAAAAAQABAAACSAAAAAAAAAAAAAAAAAAAAAGUGFwZXJzABAACAAA0FxBZwAAABEACAAAz1DL0QAAAAEAFAAKXxEACl67AApdAgAJRF4AApPVAAIASE1hY2ludG9zaCBIRDpVc2VyczoAQnJlY2h0OgBHb29nbGUgRHJpdmU6AERvY3VtZW50czoAUGFwZXJzOgB3aGlzcGVyLnBkZgAOABgACwB3AGgAaQBzAHAAZQByAC4AcABkAGYADwAaAAwATQBhAGMAaQBuAHQAbwBzAGgAIABIAEQAEgA2VXNlcnMvQnJlY2h0L0dvb2dsZSBEcml2ZS9Eb2N1bWVudHMvUGFwZXJzL3doaXNwZXIucGRmABMAAS8AABUAAgAN//8AAIAG0hscHR5aJGNsYXNzbmFtZVgkY2xhc3Nlc11OU011dGFibGVEYXRhox0fIFZOU0RhdGFYTlNPYmplY3TSGxwiI1xOU0RpY3Rpb25hcnmiIiBfEA9OU0tleWVkQXJjaGl2ZXLRJidUcm9vdIABAAgAEQAaACMALQAyADcAQABGAE0AVQBgAGcAagBsAG4AcQBzAHUAdwCEAI4AxgDLANMCdwJ5An4CiQKSAqACpAKrArQCuQLGAskC2wLeAuMAAAAAAAACAQAAAAAAAAAoAAAAAAAAAAAAAAAAAAAC5Q==}}
+	Bdsk-File-1 = {YnBsaXN0MDDUAQIDBAUGJCVYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKgHCBMUFRYaIVUkbnVsbNMJCgsMDxJXTlMua2V5c1pOUy5vYmplY3RzViRjbGFzc6INDoACgAOiEBGABIAFgAdccmVsYXRpdmVQYXRoWWFsaWFzRGF0YV8QNS4uLy4uLy4uLy4uL0dvb2dsZSBEcml2ZS9Eb2N1bWVudHMvUGFwZXJzL3doaXNwZXIucGRm0hcLGBlXTlMuZGF0YU8RAaAAAAAAAaAAAgAADE1hY2ludG9zaCBIRAAAAAAAAAAAAAAAAAAAANBcXYdIKwAAAApfEQt3aGlzcGVyLnBkZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABG5Iuz1DZ4QAAAAAAAAAAAAQABAAACSAAAAAAAAAAAAAAAAAAAAAGUGFwZXJzABAACAAA0FxBZwAAABEACAAAz1DL0QAAAAEAFAAKXxEACl67AApdAgAJRF4AApPVAAIASE1hY2ludG9zaCBIRDpVc2VyczoAQnJlY2h0OgBHb29nbGUgRHJpdmU6AERvY3VtZW50czoAUGFwZXJzOgB3aGlzcGVyLnBkZgAOABgACwB3AGgAaQBzAHAAZQByAC4AcABkAGYADwAaAAwATQBhAGMAaQBuAHQAbwBzAGgAIABIAEQAEgA2VXNlcnMvQnJlY2h0L0dvb2dsZSBEcml2ZS9Eb2N1bWVudHMvUGFwZXJzL3doaXNwZXIucGRmABMAAS8AABUAAgAN//8AAIAG0hscHR5aJGNsYXNzbmFtZVgkY2xhc3Nlc11OU011dGFibGVEYXRhox0fIFZOU0RhdGFYTlNPYmplY3TSGxwiI1xOU0RpY3Rpb25hcnmiIiBfEA9OU0tleWVkQXJjaGl2ZXLRJidUcm9vdIABAAgAEQAaACMALQAyADcAQABGAE0AVQBgAGcAagBsAG4AcQBzAHUAdwCEAI4AxgDLANMCdwJ5An4CiQKSAqACpAKrArQCuQLGAskC2wLeAuMAAAAAAAACAQAAAAAAAAAoAAAAAAAAAAAAAAAAAAAC5Q==}}
 
 @book{bech,
 	Annote = {p 115: GLS
@@ -77,22 +76,21 @@
 	Author = {Schoeffler, Michael and St{\"o}ter, Fabian-Robert and Edler, Bernd and Herre, J{\"u}rgen},
 	Booktitle = {1st Web Audio Conference},
 	Date-Added = {2015-09-29 18:35:27 +0000},
-	Date-Modified = {2015-09-29 18:37:59 +0000},
-	Title = {Towards the Next Generation of Web-based Experiments: {A} Case Study Assessing Basic Audio Quality Following the {ITU-R} Recommendation {BS}. 1534 ({MUSHRA})},
+	Date-Modified = {2016-02-29 10:35:38 +0000},
+	Title = {Towards the Next Generation of Web-based Experiments: {A} Case Study Assessing Basic Audio Quality Following the {ITU-R} {R}ecommendation {BS}. 1534 ({MUSHRA})},
 	Year = {2015},
-	Bdsk-File-1 = {YnBsaXN0MDDUAQIDBAUGJCVYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKgHCBMUFRYaIVUkbnVsbNMJCgsMDxJXTlMua2V5c1pOUy5vYmplY3RzViRjbGFzc6INDoACgAOiEBGABIAFgAdccmVsYXRpdmVQYXRoWWFsaWFzRGF0YV8QOi4uLy4uLy4uLy4uL0dvb2dsZSBEcml2ZS9Eb2N1bWVudHMvUGFwZXJzL3dhYzE1X211c2hyYS5wZGbSFwsYGVdOUy5kYXRhTxEBtgAAAAABtgACAAAMTWFjaW50b3NoIEhEAAAAAAAAAAAAAAAAAAAA0FxPd0grAAAACl8REHdhYzE1X211c2hyYS5wZGYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAESrbDSMIYSAAAAAAAAAAAABAAEAAAJIAAAAAAAAAAAAAAAAAAAAAZQYXBlcnMAEAAIAADQXEFnAAAAEQAIAADSMHgCAAAAAQAUAApfEQAKXrsACl0CAAlEXgACk9UAAgBNTWFjaW50b3NoIEhEOlVzZXJzOgBCcmVjaHQ6AEdvb2dsZSBEcml2ZToARG9jdW1lbnRzOgBQYXBlcnM6AHdhYzE1X211c2hyYS5wZGYAAA4AIgAQAHcAYQBjADEANQBfAG0AdQBzAGgAcgBhAC4AcABkAGYADwAaAAwATQBhAGMAaQBuAHQAbwBzAGgAIABIAEQAEgA7VXNlcnMvQnJlY2h0L0dvb2dsZSBEcml2ZS9Eb2N1bWVudHMvUGFwZXJzL3dhYzE1X211c2hyYS5wZGYAABMAAS8AABUAAgAN//8AAIAG0hscHR5aJGNsYXNzbmFtZVgkY2xhc3Nlc11OU011dGFibGVEYXRhox0fIFZOU0RhdGFYTlNPYmplY3TSGxwiI1xOU0RpY3Rpb25hcnmiIiBfEA9OU0tleWVkQXJjaGl2ZXLRJidUcm9vdIABAAgAEQAaACMALQAyADcAQABGAE0AVQBgAGcAagBsAG4AcQBzAHUAdwCEAI4AywDQANgCkgKUApkCpAKtArsCvwLGAs8C1ALhAuQC9gL5Av4AAAAAAAACAQAAAAAAAAAoAAAAAAAAAAAAAAAAAAADAA==}}
+	Bdsk-File-1 = {YnBsaXN0MDDUAQIDBAUGJCVYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKgHCBMUFRYaIVUkbnVsbNMJCgsMDxJXTlMua2V5c1pOUy5vYmplY3RzViRjbGFzc6INDoACgAOiEBGABIAFgAdccmVsYXRpdmVQYXRoWWFsaWFzRGF0YV8QOi4uLy4uLy4uLy4uL0dvb2dsZSBEcml2ZS9Eb2N1bWVudHMvUGFwZXJzL3dhYzE1X211c2hyYS5wZGbSFwsYGVdOUy5kYXRhTxEBtgAAAAABtgACAAAMTWFjaW50b3NoIEhEAAAAAAAAAAAAAAAAAAAA0Fxdh0grAAAACl8REHdhYzE1X211c2hyYS5wZGYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAESrbDSMJQiAAAAAAAAAAAABAAEAAAJIAAAAAAAAAAAAAAAAAAAAAZQYXBlcnMAEAAIAADQXEFnAAAAEQAIAADSMHgCAAAAAQAUAApfEQAKXrsACl0CAAlEXgACk9UAAgBNTWFjaW50b3NoIEhEOlVzZXJzOgBCcmVjaHQ6AEdvb2dsZSBEcml2ZToARG9jdW1lbnRzOgBQYXBlcnM6AHdhYzE1X211c2hyYS5wZGYAAA4AIgAQAHcAYQBjADEANQBfAG0AdQBzAGgAcgBhAC4AcABkAGYADwAaAAwATQBhAGMAaQBuAHQAbwBzAGgAIABIAEQAEgA7VXNlcnMvQnJlY2h0L0dvb2dsZSBEcml2ZS9Eb2N1bWVudHMvUGFwZXJzL3dhYzE1X211c2hyYS5wZGYAABMAAS8AABUAAgAN//8AAIAG0hscHR5aJGNsYXNzbmFtZVgkY2xhc3Nlc11OU011dGFibGVEYXRhox0fIFZOU0RhdGFYTlNPYmplY3TSGxwiI1xOU0RpY3Rpb25hcnmiIiBfEA9OU0tleWVkQXJjaGl2ZXLRJidUcm9vdIABAAgAEQAaACMALQAyADcAQABGAE0AVQBgAGcAagBsAG4AcQBzAHUAdwCEAI4AywDQANgCkgKUApkCpAKtArsCvwLGAs8C1ALhAuQC9gL5Av4AAAAAAAACAQAAAAAAAAAoAAAAAAAAAAAAAAAAAAADAA==}}
 
 @conference{ape,
 	Author = {De Man, Brecht and Joshua D. Reiss},
 	Booktitle = {136th Convention of the AES},
 	Date-Added = {2015-09-29 17:07:16 +0000},
-	Date-Modified = {2015-09-29 17:07:20 +0000},
+	Date-Modified = {2016-02-29 10:30:11 +0000},
 	Keywords = {perceptual evaluation},
-	Month = {April},
 	Read = {1},
 	Title = {{APE}: {A}udio {P}erceptual {E}valuation toolbox for {MATLAB}},
 	Year = {2014},
-	Bdsk-File-1 = {YnBsaXN0MDDUAQIDBAUGJCVYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKgHCBMUFRYaIVUkbnVsbNMJCgsMDxJXTlMua2V5c1pOUy5vYmplY3RzViRjbGFzc6INDoACgAOiEBGABIAFgAdccmVsYXRpdmVQYXRoWWFsaWFzRGF0YV8QOi4uLy4uLy4uLy4uL0dvb2dsZSBEcml2ZS9Xcml0aW5ncy9fcHVibGljYXRpb25zL2FlczEzNi5wZGbSFwsYGVdOUy5kYXRhTxEBsgAAAAABsgACAAAMTWFjaW50b3NoIEhEAAAAAAAAAAAAAAAAAAAA0FxPd0grAAAACl8UCmFlczEzNi5wZGYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKaS7PXG0EAAAAAAAAAAAABAAEAAAJIAAAAAAAAAAAAAAAAAAAAA1fcHVibGljYXRpb25zAAAQAAgAANBcQWcAAAARAAgAAM9cbQQAAAABABQACl8UAApeugAKXQIACUReAAKT1QACAE1NYWNpbnRvc2ggSEQ6VXNlcnM6AEJyZWNodDoAR29vZ2xlIERyaXZlOgBXcml0aW5nczoAX3B1YmxpY2F0aW9uczoAYWVzMTM2LnBkZgAADgAWAAoAYQBlAHMAMQAzADYALgBwAGQAZgAPABoADABNAGEAYwBpAG4AdABvAHMAaAAgAEgARAASADtVc2Vycy9CcmVjaHQvR29vZ2xlIERyaXZlL1dyaXRpbmdzL19wdWJsaWNhdGlvbnMvYWVzMTM2LnBkZgAAEwABLwAAFQACAA3//wAAgAbSGxwdHlokY2xhc3NuYW1lWCRjbGFzc2VzXU5TTXV0YWJsZURhdGGjHR8gVk5TRGF0YVhOU09iamVjdNIbHCIjXE5TRGljdGlvbmFyeaIiIF8QD05TS2V5ZWRBcmNoaXZlctEmJ1Ryb290gAEACAARABoAIwAtADIANwBAAEYATQBVAGAAZwBqAGwAbgBxAHMAdQB3AIQAjgDLANAA2AKOApAClQKgAqkCtwK7AsICywLQAt0C4ALyAvUC+gAAAAAAAAIBAAAAAAAAACgAAAAAAAAAAAAAAAAAAAL8}}
+	Bdsk-File-1 = {YnBsaXN0MDDUAQIDBAUGJCVYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKgHCBMUFRYaIVUkbnVsbNMJCgsMDxJXTlMua2V5c1pOUy5vYmplY3RzViRjbGFzc6INDoACgAOiEBGABIAFgAdccmVsYXRpdmVQYXRoWWFsaWFzRGF0YV8QOi4uLy4uLy4uLy4uL0dvb2dsZSBEcml2ZS9Xcml0aW5ncy9fcHVibGljYXRpb25zL2FlczEzNi5wZGbSFwsYGVdOUy5kYXRhTxEBsgAAAAABsgACAAAMTWFjaW50b3NoIEhEAAAAAAAAAAAAAAAAAAAA0Fxdh0grAAAACl8UCmFlczEzNi5wZGYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKaS7PXHsUAAAAAAAAAAAABAAEAAAJIAAAAAAAAAAAAAAAAAAAAA1fcHVibGljYXRpb25zAAAQAAgAANBcQWcAAAARAAgAAM9cbQQAAAABABQACl8UAApeugAKXQIACUReAAKT1QACAE1NYWNpbnRvc2ggSEQ6VXNlcnM6AEJyZWNodDoAR29vZ2xlIERyaXZlOgBXcml0aW5nczoAX3B1YmxpY2F0aW9uczoAYWVzMTM2LnBkZgAADgAWAAoAYQBlAHMAMQAzADYALgBwAGQAZgAPABoADABNAGEAYwBpAG4AdABvAHMAaAAgAEgARAASADtVc2Vycy9CcmVjaHQvR29vZ2xlIERyaXZlL1dyaXRpbmdzL19wdWJsaWNhdGlvbnMvYWVzMTM2LnBkZgAAEwABLwAAFQACAA3//wAAgAbSGxwdHlokY2xhc3NuYW1lWCRjbGFzc2VzXU5TTXV0YWJsZURhdGGjHR8gVk5TRGF0YVhOU09iamVjdNIbHCIjXE5TRGljdGlvbmFyeaIiIF8QD05TS2V5ZWRBcmNoaXZlctEmJ1Ryb290gAEACAARABoAIwAtADIANwBAAEYATQBVAGAAZwBqAGwAbgBxAHMAdQB3AIQAjgDLANAA2AKOApAClQKgAqkCtwK7AsICywLQAt0C4ALyAvUC+gAAAAAAAAIBAAAAAAAAACgAAAAAAAAAAAAAAAAAAAL8}}
 
 @inproceedings{beaqlejs,
 	Author = {Kraft, Sebastian and Z{\"o}lzer, Udo},
@@ -102,17 +100,17 @@
 	Keywords = {perceptual evaluation},
 	Title = {{BeaqleJS}: {HTML5} and {JavaScript} based framework for the subjective evaluation of audio quality},
 	Year = {2014},
-	Bdsk-File-1 = {YnBsaXN0MDDUAQIDBAUGJCVYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKgHCBMUFRYaIVUkbnVsbNMJCgsMDxJXTlMua2V5c1pOUy5vYmplY3RzViRjbGFzc6INDoACgAOiEBGABIAFgAdccmVsYXRpdmVQYXRoWWFsaWFzRGF0YV8QQC4uLy4uLy4uLy4uL0dvb2dsZSBEcml2ZS9Eb2N1bWVudHMvUGFwZXJzL3pvbHplcjIwMTRiZWFxbGVqcy5wZGbSFwsYGVdOUy5kYXRhTxEBzgAAAAABzgACAAAMTWFjaW50b3NoIEhEAAAAAAAAAAAAAAAAAAAA0FxPd0grAAAACl8RFnpvbHplcjIwMTRiZWFxbGVqcy5wZGYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACnAK7RX7izAAAAAAAAAAAABAAEAAAJIAAAAAAAAAAAAAAAAAAAAAZQYXBlcnMAEAAIAADQXEFnAAAAEQAIAADRX6qjAAAAAQAUAApfEQAKXrsACl0CAAlEXgACk9UAAgBTTWFjaW50b3NoIEhEOlVzZXJzOgBCcmVjaHQ6AEdvb2dsZSBEcml2ZToARG9jdW1lbnRzOgBQYXBlcnM6AHpvbHplcjIwMTRiZWFxbGVqcy5wZGYAAA4ALgAWAHoAbwBsAHoAZQByADIAMAAxADQAYgBlAGEAcQBsAGUAagBzAC4AcABkAGYADwAaAAwATQBhAGMAaQBuAHQAbwBzAGgAIABIAEQAEgBBVXNlcnMvQnJlY2h0L0dvb2dsZSBEcml2ZS9Eb2N1bWVudHMvUGFwZXJzL3pvbHplcjIwMTRiZWFxbGVqcy5wZGYAABMAAS8AABUAAgAN//8AAIAG0hscHR5aJGNsYXNzbmFtZVgkY2xhc3Nlc11OU011dGFibGVEYXRhox0fIFZOU0RhdGFYTlNPYmplY3TSGxwiI1xOU0RpY3Rpb25hcnmiIiBfEA9OU0tleWVkQXJjaGl2ZXLRJidUcm9vdIABAAgAEQAaACMALQAyADcAQABGAE0AVQBgAGcAagBsAG4AcQBzAHUAdwCEAI4A0QDWAN4CsAKyArcCwgLLAtkC3QLkAu0C8gL/AwIDFAMXAxwAAAAAAAACAQAAAAAAAAAoAAAAAAAAAAAAAAAAAAADHg==}}
+	Bdsk-File-1 = {YnBsaXN0MDDUAQIDBAUGJCVYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKgHCBMUFRYaIVUkbnVsbNMJCgsMDxJXTlMua2V5c1pOUy5vYmplY3RzViRjbGFzc6INDoACgAOiEBGABIAFgAdccmVsYXRpdmVQYXRoWWFsaWFzRGF0YV8QQC4uLy4uLy4uLy4uL0dvb2dsZSBEcml2ZS9Eb2N1bWVudHMvUGFwZXJzL3pvbHplcjIwMTRiZWFxbGVqcy5wZGbSFwsYGVdOUy5kYXRhTxEBzgAAAAABzgACAAAMTWFjaW50b3NoIEhEAAAAAAAAAAAAAAAAAAAA0Fxdh0grAAAACl8RFnpvbHplcjIwMTRiZWFxbGVqcy5wZGYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACnAK7RX8bDAAAAAAAAAAAABAAEAAAJIAAAAAAAAAAAAAAAAAAAAAZQYXBlcnMAEAAIAADQXEFnAAAAEQAIAADRX6qjAAAAAQAUAApfEQAKXrsACl0CAAlEXgACk9UAAgBTTWFjaW50b3NoIEhEOlVzZXJzOgBCcmVjaHQ6AEdvb2dsZSBEcml2ZToARG9jdW1lbnRzOgBQYXBlcnM6AHpvbHplcjIwMTRiZWFxbGVqcy5wZGYAAA4ALgAWAHoAbwBsAHoAZQByADIAMAAxADQAYgBlAGEAcQBsAGUAagBzAC4AcABkAGYADwAaAAwATQBhAGMAaQBuAHQAbwBzAGgAIABIAEQAEgBBVXNlcnMvQnJlY2h0L0dvb2dsZSBEcml2ZS9Eb2N1bWVudHMvUGFwZXJzL3pvbHplcjIwMTRiZWFxbGVqcy5wZGYAABMAAS8AABUAAgAN//8AAIAG0hscHR5aJGNsYXNzbmFtZVgkY2xhc3Nlc11OU011dGFibGVEYXRhox0fIFZOU0RhdGFYTlNPYmplY3TSGxwiI1xOU0RpY3Rpb25hcnmiIiBfEA9OU0tleWVkQXJjaGl2ZXLRJidUcm9vdIABAAgAEQAaACMALQAyADcAQABGAE0AVQBgAGcAagBsAG4AcQBzAHUAdwCEAI4A0QDWAN4CsAKyArcCwgLLAtkC3QLkAu0C8gL/AwIDFAMXAxwAAAAAAAACAQAAAAAAAAAoAAAAAAAAAAAAAAAAAAADHg==}}
 
 @article{lipshitz1981great,
 	Author = {Lipshitz, Stanley P and Vanderkooy, John},
 	Date-Added = {2015-09-23 09:09:51 +0000},
-	Date-Modified = {2015-09-23 09:09:51 +0000},
+	Date-Modified = {2016-02-29 10:27:05 +0000},
 	Journal = {Journal of the AES},
 	Number = {7/8},
 	Pages = {482--491},
 	Publisher = {Audio Engineering Society},
-	Title = {The great debate: Subjective evaluation},
+	Title = {{The Great Debate}: Subjective evaluation},
 	Volume = {29},
 	Year = {1981}}
 
@@ -139,12 +137,12 @@
 @article{pascoe1983evaluation,
 	Author = {Pascoe, Gregory C and Attkisson, C Clifford},
 	Date-Added = {2015-09-23 08:59:38 +0000},
-	Date-Modified = {2015-09-23 08:59:38 +0000},
+	Date-Modified = {2016-02-29 10:41:55 +0000},
 	Journal = {Evaluation and program planning},
 	Number = {3},
 	Pages = {335--347},
 	Publisher = {Elsevier},
-	Title = {The evaluation ranking scale: a new methodology for assessing satisfaction},
+	Title = {The evaluation ranking scale: {A} new methodology for assessing satisfaction},
 	Volume = {6},
 	Year = {1983}}
 
@@ -169,9 +167,9 @@
 @article{likert1932technique,
 	Author = {Likert, Rensis},
 	Date-Added = {2015-09-23 08:49:36 +0000},
-	Date-Modified = {2015-09-23 08:49:36 +0000},
-	Journal = {Archives of psychology},
-	Title = {A technique for the measurement of attitudes.},
+	Date-Modified = {2016-02-29 10:42:48 +0000},
+	Journal = {Archives of Psychology},
+	Title = {A technique for the measurement of attitudes},
 	Year = {1932}}
 
 @book{nunnally1967psychometric,
@@ -184,35 +182,42 @@
 	Year = {1967}}
 
 @article{recommendation19971116,
-	Author = {{ITURBS Recommendation}},
 	Date-Added = {2015-09-23 08:36:37 +0000},
-	Date-Modified = {2015-09-23 08:36:37 +0000},
-	Journal = {International Telecommunication Union, Geneva},
-	Title = {1116-1: Methods for the subjective assessment of small impairments in audio systems including multichannel sound systems},
+	Date-Modified = {2016-02-29 10:37:34 +0000},
+	Journal = {International Telecommunication Union},
+	Keywords = {standard},
+	Title = {{Recommendation ITU-R BS. 1116-1}: {M}ethods for the subjective assessment of small impairments in audio systems including multichannel sound systems},
 	Year = {1997}}
 
 @article{recommendation20031534,
-	Author = {{ITURBS Recommendation}},
 	Date-Added = {2015-09-23 08:34:26 +0000},
-	Date-Modified = {2015-09-23 08:34:41 +0000},
+	Date-Modified = {2016-02-29 10:38:07 +0000},
 	Journal = {International Telecommunication Union},
-	Title = {BS. 1534-1: Method for the subjective assessment of intermediate quality levels of coding systems},
+	Keywords = {standard},
+	Title = {Recommendation {ITU}-{R} {BS}.1534-1: {M}ethod for the subjective assessment of intermediate quality levels of coding systems},
 	Year = {2003}}
 
+@article{loudness201510,
+	Date-Modified = {2016-02-29 10:38:52 +0000},
+	Journal = {International Telecommunication Union},
+	Keywords = {standard},
+	Title = {Recommendation {ITU}-{R} {BS}.1770-4: {A}lgorithms to measure audio programme loudness and true-peak audio level},
+	Year = {2015}}
+
 @article{recommendation2001bs,
-	Author = {{ITUR Recommendation}},
 	Date-Added = {2015-09-23 08:33:38 +0000},
-	Date-Modified = {2015-09-23 08:33:38 +0000},
-	Journal = {International Telecommunications Union, Geneva},
-	Title = {BS. 1534-1. Method for the Subjective Assessment of Intermediate Sound Quality (MUSHRA)},
+	Date-Modified = {2016-02-29 10:40:39 +0000},
+	Journal = {International Telecommunication Union},
+	Keywords = {standard},
+	Title = {{Recommendation ITU-R BS. 1534-1}: {M}ethod for the Subjective Assessment of Intermediate Sound Quality ({MUSHRA})},
 	Year = {2001}}
 
 @article{rec1997bs,
-	Author = {{ITUR Recommendation}},
 	Date-Added = {2015-09-23 08:32:42 +0000},
-	Date-Modified = {2015-09-23 08:32:42 +0000},
-	Journal = {International Telecommunications Union},
-	Title = {BS. 562-3,`Subjective Assessment of Sound Quality'},
+	Date-Modified = {2016-02-29 10:40:47 +0000},
+	Journal = {International Telecommunication Union},
+	Keywords = {standard},
+	Title = {{Recommendation ITU-R BS. 562-3}: {S}ubjective Assessment of Sound Quality},
 	Year = {1997}}
 
 @article{peryam1952advanced,
@@ -227,28 +232,26 @@
 	Year = {1952}}
 
 @article{rec1996p,
-	Author = {{ITUT Recommendation}},
 	Date-Added = {2015-09-23 08:30:24 +0000},
-	Date-Modified = {2015-09-23 08:30:24 +0000},
-	Journal = {International Telecommunication Union, Geneva},
-	Title = {P. 800: Methods for subjective determination of transmission quality},
+	Date-Modified = {2016-02-29 10:40:26 +0000},
+	Journal = {International Telecommunication Union},
+	Keywords = {standard},
+	Title = {{Recommendation ITU-T P. 800}: {M}ethods for subjective determination of transmission quality},
 	Year = {1996}}
 
 @inproceedings{hultigen,
 	Author = {Gribben, Christopher and Lee, Hyunkook},
 	Booktitle = {AES Convention 138},
 	Date-Added = {2015-09-23 08:11:17 +0000},
-	Date-Modified = {2015-09-29 16:23:17 +0000},
-	Organization = {Audio Engineering Society},
-	Title = {Toward the Development of a Universal Listening Test Interface Generator in Max},
+	Date-Modified = {2016-02-29 10:29:19 +0000},
+	Title = {Toward the Development of a Universal Listening Test Interface Generator in {Max}},
 	Year = {2015}}
 
 @conference{waet,
 	Author = {Nicholas Jillings and David Moffat and De Man, Brecht and Joshua D. Reiss},
 	Booktitle = {12th Sound and Music Computing Conference},
 	Date-Added = {2015-09-22 16:48:27 +0000},
-	Date-Modified = {2015-09-22 16:48:33 +0000},
-	Month = {July},
+	Date-Modified = {2016-02-29 10:30:22 +0000},
 	Read = {1},
 	Title = {Web {A}udio {E}valuation {T}ool: {A} browser-based listening test environment},
 	Year = {2015}}
Binary file docs/WAC2016/WAC2016.pdf has changed
--- a/docs/WAC2016/WAC2016.tex	Wed Feb 24 14:00:10 2016 +0000
+++ b/docs/WAC2016/WAC2016.tex	Tue Mar 08 14:44:14 2016 +0000
@@ -10,9 +10,27 @@
 % Copyright
 \setcopyright{waclicense}
 
+\conferenceinfo{Web Audio Conference WAC-2016,}{April 4--6, 2016, Atlanta, USA.}
+\CopyrightYear{2016} % Allows default copyright year (20XX) to be over-ridden - IF NEED BE.
+
 \newcommand*\rot{\rotatebox{90}}
 
 
+% Make clickable footnote (Brecht)
+\newcommand{\hyperfootnote}[1][]{\def\ArgI{{#1}}\hyperfootnoteRelay}
+  % relay to new command to make extra optional command possible
+\newcommand\hyperfootnoteRelay[2][]{\href{#1#2}{\ArgI}\footnote{\href{#1#2}{#2}}}
+  % the first optional argument is now in \ArgI, the second is in #1
+  
+% Takes at most 3 parameters (see http://www.tex.ac.uk/FAQ-twooptarg.html for info on multiple optional parameters)
+% If first parameter isn't given, it's value is '' (empty string in text before footnote reference)
+% If second parameter isn't given, it's value is '' (string before visible URL, e.g. 'http://')
+% Makes a clickable footnote (alternatively: \url{}) with optional reference in the text as well
+% Use 1: \hyperfootnote{www.mywebsite.com}: creates a footnote consisting of a clickable URL
+% Use 2: \hyperfootnote[My website]{www.mywebsite.com}: creates a clickable piece of text in the text ('My website') plus a footnote consisting of a clickable URL
+% Note: requires the hyperref package.
+% Note: using xspace package to add/absorb spaces when necessary (e.g. to avoid a space between the footnote number and a punctuation mark)
+
 %% DOI
 %\doi{10.475/123_4}
 %
@@ -133,9 +151,8 @@
 
 \maketitle
 \begin{abstract}
-
-Perceptual listening tests are commonplace in audio research and a vital form of evaluation. Many tools exist to run such tests, however many operate one test type and are therefore limited whilst most require proprietary software. Using Web Audio the Web Audio Evaluation Tool (WAET) addresses these concerns by having one toolbox which can be configured to run many different tests, perform it through a web browser and without needing proprietary software or computer programming knowledge. In this paper the role of the Web Audio API in giving WAET key functionalities are shown. The paper also highlights less common features, available to web based tools, such as easy remote testing environment and in-browser analytics.
-
+Perceptual listening tests are commonplace in audio research and a vital form of evaluation. % ?
+While a large number of tools exist to run such tests, many feature just one test type, are platform dependent, run on proprietary software, or require considerable configuration and programming. Using Web Audio, the Web Audio Evaluation Tool (WAET) addresses these concerns by having one toolbox which can be configured to run many different tests, perform it through a web browser and without needing proprietary software or computer programming knowledge. In this paper the role of the Web Audio API in giving WAET key functionalities are shown. The paper also highlights less common features, available to web based tools, such as easy remote testing environment and in-browser analytics.
 \end{abstract}
 
 
@@ -143,7 +160,7 @@
 
 	% Listening tests/perceptual audio evaluation: what are they, why are they important
 	% As opposed to limited scope of WAC15 paper: also musical features, realism of sound effects / sound synthesis, performance of source separation and other algorithms... 
-	Perceptual evaluation of audio, in the form of listening tests, is a powerful way to assess anything from audio codec quality to realism of sound synthesis to the performance of source separation, automated music production and other auditory evaluations.
+	Perceptual evaluation of audio, using listening tests, is a powerful way to assess anything from audio codec quality over realism of sound synthesis to the performance of source separation, automated music production and other auditory evaluations.
 	In less technical areas, the framework of a listening test can be used to measure emotional response to music or test cognitive abilities. 
 	% maybe some references? If there's space.
 
@@ -151,14 +168,14 @@
 
 	% Why difficult? Challenges? What constitutes a good interface?
 	% Technical, interfaces, user friendliness, reliability 
-	Several applications for performing perceptual listening tests currently exist. A review of existing listening test frameworks was undertaken and presented in~\Cref{tab:toolboxes}. Note that many rely on proprietary, 3rd party software such as MATLAB and MAX, making them less attractive for many. With the exception of the existing JavaScript-based toolboxes, remote deployment (web-based test hosting and result collection) is not possible. 
+	Several applications for performing perceptual listening tests currently exist, see~\Cref{tab:toolboxes}. Many rely on proprietary, third party software such as MATLAB and Max, making them less attractive for many. With the exception of the existing JavaScript-based toolboxes, remote deployment (web-based test hosting and result collection) is not possible. 
 	
-	HULTI-GEN~\cite{hultigen} is a single example of a toolbox that presents the user with a large number of different test interfaces and allows for customisation of each test interface, without requiring knowledge of any programming language. The Web Audio Evaluation Toolbox (WAET), presented here, stands out as it does not require proprietary software or a specific platform. It also provides a wide range of interface and test types in one user friendly environment. Furthermore any test based on the default test types can be configured in the browser as well. Note that the design of an effective listening test further poses many challenges unrelated to interface design, which are beyond the scope of this paper \cite{bech}. 
+	HULTI-GEN~\cite{hultigen} is an example of a toolbox that presents the user with a large number of different test interfaces and customisation, without requiring knowledge of any programming language. The Web Audio Evaluation Toolbox (WAET), presented here, stands out for the same reasons but in addition does not require proprietary software or a specific platform. It also provides a wide range of interface and test types in one user friendly environment. Furthermore, any test based on the default test types can be configured in the browser as well. Note that the design of an effective listening test further poses many challenges unrelated to interface design, which are beyond the scope of this paper \cite{bech}. 
 
 	% Why in the browser? 
-	The Web Audio API provides important features including sample level manipulation of audio streams \cite{schoeffler2015mushra} and synchronous and flexible playback. Being in the browser allows leveraging the flexible object oriented JavaScript language and native support for web documents, such as the extensible markup language (XML) which is used for configuration and test result files. Using the web also reduces deployment requirements to a basic web server with extra functionality, such as test collection and automatic processing, using PHP. As recruiting participants can be very time-consuming, and as for some tests a large number of participants is needed, browser-based tests can enable participants in multiple locations to perform the test \cite{schoeffler2015mushra}.
+	The Web Audio API provides important features including sample level manipulation of audio streams \cite{schoeffler2015mushra} and synchronous and flexible playback. Operating in the browser allows leveraging the flexible JavaScript language and native support for web documents, such as the extensible markup language (XML) which is used for configuration and test result files. Using the web also reduces deployment requirements to a basic web server with extra functionality, such as test collection and automatic processing, using PHP. As recruiting participants can be very time-consuming, and as for some tests a large number of participants is needed, browser-based tests can enable participants in multiple locations to perform the test simultaneously \cite{schoeffler2015mushra}.
 
-	Both BeaqleJS \cite{beaqlejs} and mushraJS\footnote{https://github.com/akaroice/mushraJS} also operate in the browser. However, BeaqleJS does not make use of the Web Audio API and therefore lacks arbitrary manipulation of audio stream samples, and neither offer an adequately wide choice of test designs for them to be useful to many researchers. %requires programming knowledge?... 
+	Both BeaqleJS \cite{beaqlejs} and \hyperfootnote[mushraJS][https://]{github.com/akaroice/mushraJS} also operate in the browser. However, BeaqleJS does not make use of the Web Audio API and therefore lacks arbitrary manipulation of audio stream samples, and neither offer an adequately wide choice of test designs for them to be useful to many researchers. %requires programming knowledge?... 
 	
 	% only browser-based? 
 	\begin{table*}[ht]
@@ -191,13 +208,15 @@
 	    		 n-Alternative Forced Choice & & & & & & \checkmark & & \\ \hline
 	    	\end{tabular}
 	 \end{center}
+	 \vspace{-.5cm}
 	 \label{tab:toolboxes}
 	 \end{table*}
+
         % 
         %Selling points: remote tests, visualisaton, create your own test in the browser, many interfaces, few/no dependencies, flexibility
 
         %[Talking about what we do in the various sections of this paper. Referring to \cite{waet}. ]
-    To meet the need for a cross-platform, versatile and easy-to-use listening test tool, we previously developed the Web Audio Evaluation Tool \cite{waet} which at the time of its inception was capable of running a listening test in the browser from an XML configuration file, and storing an XML file as well, with one particular interface. This has now expanded into a tool with which a wide range of listening test types can easily be constructed and set up remotely, without any need for manually altering code or configuration files, and allows visualisation of the collected results in the browser. In this paper, we discuss these different aspects and explore which future improvements would be possible.
+    To meet the need for a cross-platform, versatile and easy-to-use listening test tool, we previously developed the Web Audio Evaluation Tool \cite{waet} which was capable of running a listening test in the browser from an XML configuration file, and storing an XML file as well, with one particular interface. This has now expanded into a tool with which a wide range of listening test types can easily be constructed and set up remotely, without any need for manually altering code or configuration files, and allows visualisation of the collected results in the browser. In this paper, we discuss these different aspects and explore which future improvements would be possible.
 
     \begin{figure}[tb]
     	\centering
@@ -240,41 +259,31 @@
 
     Although WAET uses a sparse subset of the Web Audio API functionality, its performance comes directly from it. Listening tests can convey large amounts of information other than obtaining the perceptual relationship between the audio fragments. With WAET it is possible to track which parts of the audio fragments were listened to and when, at what point in the audio stream the participant switched to a different fragment, and how a fragment's rating was adjusted over time within a session, to name a few. Not only does this allow evaluation of a wealth of perceptual aspects, but it also helps detect poor participants whose results are potentially not representative.
     
-    One of the key initial design parameters for WAET was to make the tool as open as possible to non-programmers and to this end all of the user modifiable options are included in a single XML document. This document is the specification document and can be designed either by manually writing the XML (or modifying an existing document or template) or using the included test creator. These standalone HTML pages do not require any server or internet connection and help a build the specification document. The first (test\_create.html) is for simple tests and operates step-by-step to guide the user through a drag and drop, clutter free interface. The advanced version is for more complex tests. Both models support automatic verification to ensure the XML file is valid and will highlight areas which are either incorrect and would cause an error, or options which should be removed as they are blank.
-    
-    The basic test creator, Figure \ref{fig:test_create}, utilises the Web Audio API to perform quick playback checks and also allows for loudness normalisation techniques inspired from \cite{ape}. These are calculated offline by accessing the raw audio samples exposed from the buffer before being applied to the audio element as a gain attribute. Therefore the tool performs loudness normalisation without editing any audio files. Equally the gain attribute can be modified in either editor using an HTML5 slider or number box respectively.
-    \begin{comment}
-    \begin{figure}[h!]
-	\centering
-	\includegraphics[width=.45\textwidth]{test_create_2.png}
-	\caption{Screen-shot of test creator tool using drag and drop to create specification document}
-	\label{fig:test_create}
-	\end{figure}
-	\end{comment}
+    One of the key initial design parameters for WAET was to make the tool as open as possible to non-programmers. To this end, all of the user modifiable options are included in a single XML document, referred to as the specification document, that can be written  manually (or modifying an existing document or template) or using the included test creator. The test creator can modify existing specification documents or generate new ones in an intuitive yet powerful HTML GUI. This simplifies the creation of elements by visualising the data structure with explanatory text.
     
     %Describe and/or visualise audioholder-audioelement-... structure. 
-    The specification document contains the URL of the audio fragments for each test page. These fragments are downloaded asynchronously in the test and decoded offline by the Web Audio offline decoder. The resulting buffers are assigned to a custom Audio Objects node which tracks the fragment buffer, the playback \textit{bufferSourceNode}, other specification attributes including its unique test ID, the interface object(s) associated with the fragment and any metric or data collection objects. The Audio Object is controlled by an over-arching custom Audio Context node (not to be confused with the Web Audio Context). This parent JS Node allows for session wide control of the Audio Objects including starting and stopping playback of specific nodes.
+    The specification document contains the URL of the audio fragments for each test page. These fragments are downloaded asynchronously in the test and decoded offline by the Web Audio offline decoder. The LUFS integrated loudness of the buffers are calculated \cite{loudness201510} and stored to enable on-the-fly loudness normalisation. If the playback uses synchronous looping, the buffers are zero-padded accordingly. Performing these in the browser removes any need for pre-processing. The resulting buffers are assigned to a custom Audio Objects node which tracks the fragment buffer, the Web Audio \textit{bufferSourceNode}, and other specification attributes including its ID, the interface object(s) associated with the fragment and any metric or data collection objects. The Audio Object is controlled by an over-arching custom Audio Engine node allowing for session wide control of the Audio Objects.
     
-    The only issue with this model is the \textit{bufferNode} in the Web Audio API, implemented in the standard as a `use once' object. Once this has been played, the node must be discarded as it cannot be instructed to play the same \textit{bufferSourceNode} again. Therefore on each play request the buffer object must be created and then linked with the stored \textit{bufferSourceNode}. This is an odd behaviour for such a simple object which has no alternative except to use the HTML5 audio element. However, they do not have the ability to synchronously start on a given time and therefore not suited.
+    The only significant issue with this model is the \textit{bufferNode} in the Web Audio API, implemented in the standard as a `use once' object. Once the node has been played, it must be discarded as it cannot be instructed to play again. Therefore on each play request the \textit{bufferSourceNode} must be created and then linked with the stored \textit{bufferNode}. This is an odd behaviour with no alternative except to use the HTML5 audio element, but they do not have the ability to synchronously start on a given time and therefore not suited.
     
-    In the test, each buffer node is connected to a gain node which will operate at the level determined by the specification document. Therefore it is possible to perform a `Method of Adjustment' test where an interface could directly manipulate these gain nodes. These gain nodes are used for cross-fading between samples when operating in synchronous playback. Cross-fading can either be fade-out fade-in or a true cross-fade. There is also an optional `Master Volume' slider which can be shown on the test GUI. This slider modifies a gain node before the destination node. This slider can also be monitored and therefore its data tracked providing extra validation. This is not indicative of the final volume exiting the speakers and therefore its use should only be considered in a lab environment to ensure proper usage.
+    In the test, each buffer node is connected to a gain node configured by the loudness normalisation and any user specified gain. Therefore it is possible to perform a `Method of Adjustment' test where an interface could directly manipulate these gain nodes. These gain nodes are used for cross-fading between samples when operating in synchronous playback. Cross-fading can either be fade-out followed by a fade-in, or a true cross-fade. This is achieved by using the AudioParam controls to provide linear ramping from 0 to the calculated playback level. There is also an optional `Master Volume' slider which can be shown on the test GUI to modify a gain node before the destination. The control's position is tracked providing extra test use validation. This is not indicative of the final volume exiting the speakers, though, not least because the browser cannot read the system volume. Therefore its use should only be considered in a lab environment to ensure results are representative.
     
     %Which type of files?  WAV, anything else? Perhaps not exhaustive list, but say something along the lines of 'whatever browser supports'. Compatability?
-    The media files supported depend on the browser level support for the initial decoding of information and is the same as the browser support for the HTML5 audio element. The most widely supported media file is the wave (.WAV) format which is accepted by every browser supporting the Web Audio API. The toolbox will work in any browser which supports the Web Audio API.
+    The media files supported depend on the browser level support for the initial decoding of information and is the same as the browser support for the HTML5 audio element. The most widely supported media file is the wave (.WAV) format which is accepted by every browser supporting the Web Audio API. Most browsers support floating point WAV except Firefox. To resolve this, the tool includes its own wave file decoder to extract the samples. The toolbox works in any browser which supports the Web Audio API and HTML 5.
     
-    All the collected session data is returned in an XML document structured similarly to the configuration document, where test pages contain the audio elements with their trace collection, results, comments and any other interface-specific data points.
+    All collected session data is returned in an XML document structured similarly to the configuration document, where test pages contain the audio elements with their trace collection, results, comments and any interface-specific data points.
     
 \section{Remote tests} % with previous? 
 	\label{sec:remote}
 
-	If the experimenter is willing to trade some degree of control for a higher number of participants, the test can be hosted on a public web server so that participants can take part remotely. This way, a link can be shared widely in the hope of attracting a large amount of subjects, while listening conditions and subject reliability may be less ideal. However, a sound system calibration page and a wide range of metrics logged during the test mitigate these problems. In some experiments, it may be preferred that the subject has a `real life', familiar listening set-up, for instance when perceived quality differences on everyday sound systems are investigated. 
+	If the experimenter is willing to trade some degree of control for a higher number of participants, the test can be hosted on a public web server. This way, a link can be shared widely in the hope of attracting a large amount of subjects, while listening conditions and subject reliability may be less ideal. However, a sound system calibration page and the range of metrics logged mitigate these problems. In some experiments, it may be preferred that the subject has a `real life', familiar listening set-up, for instance when perceived quality differences on everyday sound systems are investigated. 
 	Furthermore, a fully browser-based test, where the collection of the results is automatic, is more efficient and technically reliable even when the test still takes place under lab conditions.
 
 	The following features allow easy and effective remote testing: 
-	\begin{description}[noitemsep,nolistsep]
-		\item[PHP script to collect result XML files] and store on central server. 
-		\item[Randomly pick a specified number of pages] to ensure an equal and randomised spread of the different pages (`audioHolders') across participants. 
-		\item[Calibration of the sound system (and participant)] by a perceptual pre-test to gather information about the frequency response and speaker configuration - this can be supplemented with a survey.
+	\begin{itemize}[noitemsep,nolistsep] % replaced description list with itemize as it went outside the margins
+		\item \textbf{PHP script to collect result XML files} and store on central server.
+		\item \textbf{Randomly pick a specified number of pages} to ensure an equal and randomised spread of the different pages across participants. 
+		\item \textbf{Calibration of the sound system (and participant)} by a perceptual pre-test to gather information about the frequency response and speaker configuration - this can be supplemented with a survey.
 		% In theory calibration could be applied anywhere??
 		% \item Functionality to participate multiple times
 		% 	\begin{itemize}[noitemsep,nolistsep]
@@ -285,43 +294,42 @@
 		% 		\item Pick `new' audioholders if available
 		% 		\item Copy survey information first time to new XMLs
 		% 	\end{itemize}
-		\item[Intermediate saves] for tests which were interrupted or unfinished.
-		\item[Collect IP address information] for geographic location, through PHP function which grabs address and appends to XML file. 
-		\item[Collect Browser and Display information] to the extent it is available and reliable. 
-	\end{description}
+		\item \textbf{Intermediate saves} for tests which were interrupted or unfinished.
+		\item \textbf{Collect IP address information} for geographic location, through PHP function which grabs address and appends to XML file. 
+		\item \textbf{Collect browser and display information} to the extent it is available and reliable. 
+	\end{itemize}
 
 	
 \section{Interfaces} % title? 'Front end'? % Dave
 \label{sec:interfaces}
 
-The purpose of this listening test framework is to allow any user the maximum flexibility to design a listening test for their exact application with minimum effort. To this end, a large range of standard listening test interfaces have been implemented.
-
-To provide users with a flexible system, a large range of `standard' listening test interfaces have been implemented, including: % pretty much the same wording as two sentences earlier
+The purpose of this listening test framework is to allow any user the maximum flexibility to design a listening test for their exact application with minimum effort. To this end, a large range of standard listening test interfaces have been implemented, including 
 	\begin{itemize}[noitemsep,nolistsep]
-		\item MUSHRA (ITU-R BS. 1534)~\cite{recommendation20031534}
+		\item AB Test~\cite{lipshitz1981great}: Two stimuli presented simultaneously, participant selects a preferred stimulus.
+		\item ABC/HR (ITU-R BS. 1116)~\cite{recommendation19971116} (Mean Opinion Score: MOS): each stimulus has a continuous scale (5-1), labeled as Imperceptible, Perceptible but not annoying, Slightly annoying, Annoying, Very annoying.
+		\item -50 to 50 Bipolar with Ref: each stimulus has a continuous scale -50 to 50 with default values as 0 in middle and a reference.
+		\item Absolute Category Rating (ACR) Scale~\cite{rec1996p}: Likert but labels are Bad, Poor, Fair, Good, Excellent
+		\item ABX Test~\cite{clark1982high}: Two stimuli are presented along with a reference and the participant has to select a preferred stimulus, often the closest to the reference.
+		\item APE \cite{ape}: Multiple stimuli on one or more axes for inter-sample rating.
+		%\item APE style 2D \cite{ape}: Multiple stimuli on a 2D plane for inter-sample rating (e.g. Valence Arousal).
+		\item Comparison Category Rating (CCR) Scale~\cite{rec1996p}: ACR \& DCR but 7 point scale, with reference: Much better, Better, Slightly better, About the same, Slightly worse, Worse, Much worse. 
+		\item Degredation Category Rating (DCR) Scale~\cite{rec1996p}: ABC \& Likert but labels are (5) Inaudible, (4) Audible but not annoying, (3) Slightly annoying, (2) Annoying, (1) Very annoying.
+		\item ITU-R 5 Point Continuous Impairment Scale~\cite{rec1997bs}: Same as ABC/HR but with a reference.
+		\item Likert scale~\cite{likert1932technique}: each stimulus has a five point scale with values: Strongly agree, Agree, Neutral, Disagree and Strongly disagree.
+		\item MUSHRA (ITU-R BS. 1534)~\cite{recommendation20031534} 
 		\begin{comment}
 		\begin{itemize}[noitemsep,nolistsep]
 			\item Multiple stimuli are presented and rated on a continuous scale, which includes a reference, hidden reference and hidden anchors.
 		\end{itemize}
 		\end{comment}
+		\item Pairwise Comparison (Better/Worse)~\cite{david1963method}: every stimulus is rated as being either better or worse than the reference.
 		\item Rank Scale~\cite{pascoe1983evaluation}: stimuli ranked on single horizontal scale, where they are ordered in preference order.
-		\item Likert scale~\cite{likert1932technique}: each stimuli has a five point scale with values: Strongly Agree, Agree, Neutral, Disagree and Strongly Disagree.
-		\item ABC/HR (ITU-R BS. 1116)~\cite{recommendation19971116} (Mean Opinion Score: MOS): each stimulus has a continuous scale (5-1), labeled as Imperceptible, Perceptible but not annoying, slightly annoying, annoying, very annoying.
-		\item -50 to 50 Bipolar with Ref: each stimulus has a continuous scale -50 to 50 with default values as 0 in middle and a reference.
-		\item Absolute Category Rating (ACR) Scale~\cite{rec1996p}: Likert but labels are Bad, Poor, Fair, Good, Excellent
-		\item Degredation Category Rating (DCR) Scale~\cite{rec1996p}: ABC \& Likert but labels are (5) Inaudible, (4) Audible but not annoying, (3) slightly annoying, (2) annoying, (1) very annoying.
-		\item Comparison Category Rating (CCR) Scale~\cite{rec1996p}: ACR \& DCR but 7 point scale: Much Better, Better, Slightly Better, About the same, slightly worse, worse, much worse. There is also a provided reference.
-		\item 9 Point Hedonic Category Rating Scale~\cite{peryam1952advanced}: each stimuli has a seven point scale with values: Like Extremely, Like Very Much, Like Moderate, Like Slightly, Neither Like nor Dislike, dislike Extremely, dislike Very Much, dislike Moderate, dislike Slightly. There is also a provided reference.
-		\item ITU-R 5 Point Continuous Impairment Scale~\cite{rec1997bs}: Same as ABC/HR but with a reference.
-		\item Pairwise Comparison (Better/Worse)~\cite{david1963method}: every stimulus is rated as being either better or worse than the reference.
-		\item APE style \cite{ape}: Multiple stimuli as points on a 2D plane for inter-sample rating (eg. Valence Arousal)
-		\item AB Test~\cite{lipshitz1981great}: Two stimuli presented at a time, participant selects a preferred stimulus.
-		\item ABX Test~\cite{clark1982high}: Two stimuli are presented along with a reference and the participant has to select a preferred stimulus, often the closest to the reference.
+		\item 9 Point Hedonic Category Rating Scale~\cite{peryam1952advanced}: each stimulus has a seven point scale with values: Like extremely, Like very much, Like moderate, Like slightly, Neither like nor dislike, Dislike extremely, Dislike very much, Dislike moderate, Dislike slightly. There is also a provided reference.
 	\end{itemize}
 	
-	It is possible to include any number of references, anchors, hidden references and hidden anchors into all of these listening test formats.
+	It is possible to include any number of references, hidden references, hidden anchors and comment fields into all of these listening test formats.
 	
-	Because of the design to separate the core code and interface modules, it is possible for a 3rd party interface to be built with minimal effort. The repository includes documentation on which functions must be called and the specific functions they expect your interface to perform. The core includes an `Interface' object which includes object prototypes for the on-page comment boxes (including those with radio or checkbox responses), start and stop buttons and the playhead / transport bars.
+	Because of the design to have separate core code and interface modules, it is possible for a third party interface to be built with minimal effort. The repository includes a boilerplate (blank.js) and documentation on which functions must be called and the specific functions they expect your interface to perform. The core includes an `Interface' object which includes object prototypes for the on-page comment boxes (including those with radio or checkbox responses), start and stop buttons and the playhead / transport bars.
 	
 %%%%	\begin{itemize}[noitemsep,nolistsep]
 %%%%		\item (APE style) \cite{ape}
@@ -380,19 +388,13 @@
 \label{sec:analysis}
 	% don't mention Python scripts
 	There are several benefits to providing basic analysis tools in the browser: they allow diagnosing problems, with the interface or with the test subject; they may be sufficient for many researchers' purposes; and test subjects may enjoy seeing an overview of their own results and/or results thus far at the end of their tests. 
-	\begin{figure}[bh]
-		\centering
-		\includegraphics[width=.5\textwidth]{boxplot.png}
-		%\caption{This timeline of a single subject's listening test shows playback of fragments (red segments) and marker movements on the rating axis in function of time. }
-		\caption{Box and whisker plot showing the aggregated numerical ratings of six stimuli by a group of subjects.}
-		\label{fig:timeline}
-	\end{figure}
+	
 	For this reason, we include a proof-of-concept web page with:
 	\begin{itemize}[noitemsep,nolistsep]
-		\item All audioholder IDs, file names, subject IDs, audio element IDs, ... in the collected XMLs so far (\texttt{saves/*.xml})
+		\item All page IDs, file names, subject IDs, audio element IDs, ... in the collected XMLs so far
 		\item Selection of subjects and/or test samples to zoom in on a subset of the data %Check/uncheck each of the above for analysis (e.g. zoom in on a certain song, or exclude a subset of subjects)
 		\item Embedded audio to hear corresponding test samples % (follow path in XML setup file, which is also embedded in the XML result file)
-		\item Scatter plot, confidence plot and box plot of rating values (see Figure )
+		\item Scatter plot, confidence plot and box plot of rating values (see Figure \ref{fig:boxplot})
 		\item Timeline for a specific subject %(see Figure \ref{fig:timeline})%, perhaps re-playing the experiment in X times realtime. (If actual realtime, you could replay the audio...)
 		\item Distribution plots of any radio button and number questions in pre- and post-test survey %(drop-down menu with `pretest', `posttest', ...; then drop-down menu with question `IDs' like `gender', `age', ...; make pie chart/histogram of these values over selected range of XMLs)
 		\item All `comments' on a specific audioelement
@@ -400,16 +402,23 @@
 		%\item Validation of setup XMLs (easily spot `errors', like duplicate IDs or URLs, missing/dangling tags, ...)
 	\end{itemize}
 
+	\begin{figure}[tbh]
+		\centering
+		\includegraphics[width=.5\textwidth]{boxplot.png}
+		%\caption{This timeline of a single subject's listening test shows playback of fragments (red segments) and marker movements on the rating axis in function of time. }
+		\caption{Box and whisker plot showing the aggregated numerical ratings of six stimuli by a group of subjects.}
+		\label{fig:boxplot}
+	\end{figure}
 
 	%A subset of the above would already be nice for this paper. 
-\section{Concluding remarks and future work}
+\section{Concluding remarks}
 \label{sec:conclusion}
 
-	We have developed a browser-based tool for the design and deployment of listening tests, essentially requiring no programming experience and third party software. Following the predictions or guidelines in \cite{schoeffler2015mushra}, it supports remote testing, cross-fading between audio streams, collecting information about the system, among others. 
+	We have developed a browser-based tool for the design and deployment of listening tests, requiring no programming experience or proprietary software. Following the predictions or guidelines in \cite{schoeffler2015mushra}, it supports remote testing, cross-fading between audio streams, collecting information about the system, among others. 
 
-	Whereas many other types of interfaces do exist, we felt that supporting e.g. a range of `method of adjustment' tests would be beyond the scope of a tool that aims to be versatile enough while not claiming to support any custom experiment one might want to set up. Rather, it supports any non-adaptive listening test up to multi-stimulus, multi-attribute evaluation including references, anchors, text boxes, radio buttons and/or checkboxes, with arbitrary placement of the various UI elements. 
+	Whereas many other types of interfaces do exist, we felt that supporting e.g.~a range of `method of adjustment' tests would be beyond the scope of a tool that aims to be versatile enough while not claiming to support any custom experiment one might want to set up. Rather, it supports intuitive creation of non-adaptive listening tests up to multi-stimulus, multi-attribute evaluation including references, anchors, text boxes, radio buttons and/or checkboxes, with arbitrary placement of the various UI elements, and many standard test `presets' already available.
 	
-	The code and documentation can be pulled or downloaded from our online repository available at \url{code.soundsoftware.ac.uk/projects/webaudioevaluationtool}.
+	The code and documentation can be downloaded from the \hyperfootnote[SoundSoftware repository][https://]{code.soundsoftware.ac.uk/projects/webaudioevaluationtool}.
 		% remote
 		% language support (not explicitly stated)
 		% crossfades
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/WAC2016/sig-alternate-sample.tex	Tue Mar 08 14:44:14 2016 +0000
@@ -0,0 +1,661 @@
+% This is "sig-alternate.tex" V2.1 April 2013
+% This file should be compiled with V2.8 of "sig-alternate.cls" May 2012
+%
+% This example file demonstrates the use of the 'sig-alternate.cls'
+% V2.8 LaTeX2e document class file. It is for those submitting
+% articles to ACM Conference Proceedings WHO DO NOT WISH TO
+% STRICTLY ADHERE TO THE SIGS (PUBS-BOARD-ENDORSED) STYLE.
+% The 'sig-alternate.cls' file will produce a similar-looking,
+% albeit, 'tighter' paper resulting in, invariably, fewer pages.
+%
+% ----------------------------------------------------------------------------------------------------------------
+% This .tex file (and associated .cls V2.8) produces:
+%       1) The Permission Statement
+%       2) The Conference (location) Info information
+%       3) The Copyright Line with ACM data
+%       4) NO page numbers
+%
+% as against the acm_proc_article-sp.cls file which
+% DOES NOT produce 1) thru' 3) above.
+%
+% Using 'sig-alternate.cls' you have control, however, from within
+% the source .tex file, over both the CopyrightYear
+% (defaulted to 200X) and the ACM Copyright Data
+% (defaulted to X-XXXXX-XX-X/XX/XX).
+% e.g.
+% \CopyrightYear{2007} will cause 2007 to appear in the copyright line.
+% \crdata{0-12345-67-8/90/12} will cause 0-12345-67-8/90/12 to appear in the copyright line.
+%
+% ---------------------------------------------------------------------------------------------------------------
+% This .tex source is an example which *does* use
+% the .bib file (from which the .bbl file % is produced).
+% REMEMBER HOWEVER: After having produced the .bbl file,
+% and prior to final submission, you *NEED* to 'insert'
+% your .bbl file into your source .tex file so as to provide
+% ONE 'self-contained' source file.
+%
+% ================= IF YOU HAVE QUESTIONS =======================
+% Questions regarding the SIGS styles, SIGS policies and
+% procedures, Conferences etc. should be sent to
+% Adrienne Griscti (griscti@acm.org)
+%
+% Technical questions _only_ to
+% Gerald Murray (murray@hq.acm.org)
+% ===============================================================
+%
+% For tracking purposes - this is V2.0 - May 2012
+
+\documentclass{sig-alternate}
+
+\setlength{\paperheight}{11in}
+\setlength{\paperwidth}{8.5in}
+\usepackage[
+  pass,% keep layout unchanged 
+  % showframe,% show the layout
+]{geometry}
+
+\begin{document}
+
+% Copyright
+\setcopyright{waclicense}
+
+
+%% DOI
+%\doi{10.475/123_4}
+%
+%% ISBN
+%\isbn{123-4567-24-567/08/06}
+%
+%%Conference
+%\conferenceinfo{PLDI '13}{June 16--19, 2013, Seattle, WA, USA}
+%
+%\acmPrice{\$15.00}
+
+%
+% --- Author Metadata here ---
+\conferenceinfo{Web Audio Conference WAC-2016,}{April 4--6, 2016, Atlanta, USA.}
+\CopyrightYear{2016} % Allows default copyright year (20XX) to be over-ridden - IF NEED BE.
+%\crdata{0-12345-67-8/90/01}  % Allows default copyright data (0-89791-88-6/97/05) to be over-ridden - IF NEED BE.
+% --- End of Author Metadata ---
+
+\title{Latex Template for WAC 2016}
+%\subtitle{[Extended Abstract]
+%\titlenote{A full version of this paper is available as
+%\textit{Author's Guide to Preparing ACM SIG Proceedings Using
+%\LaTeX$2_\epsilon$\ and BibTeX} at
+%\texttt{www.acm.org/eaddress.htm}}}
+%
+% You need the command \numberofauthors to handle the 'placement
+% and alignment' of the authors beneath the title.
+%
+% For aesthetic reasons, we recommend 'three authors at a time'
+% i.e. three 'name/affiliation blocks' be placed beneath the title.
+%
+% NOTE: You are NOT restricted in how many 'rows' of
+% "name/affiliations" may appear. We just ask that you restrict
+% the number of 'columns' to three.
+%
+% Because of the available 'opening page real-estate'
+% we ask you to refrain from putting more than six authors
+% (two rows with three columns) beneath the article title.
+% More than six makes the first-page appear very cluttered indeed.
+%
+% Use the \alignauthor commands to handle the names
+% and affiliations for an 'aesthetic maximum' of six authors.
+% Add names, affiliations, addresses for
+% the seventh etc. author(s) as the argument for the
+% \additionalauthors command.
+% These 'additional authors' will be output/set for you
+% without further effort on your part as the last section in
+% the body of your article BEFORE References or any Appendices.
+
+\numberofauthors{8} %  in this sample file, there are a *total*
+% of EIGHT authors. SIX appear on the 'first-page' (for formatting
+% reasons) and the remaining two appear in the \additionalauthors section.
+%
+\author{
+% You can go ahead and credit any number of authors here,
+% e.g. one 'row of three' or two rows (consisting of one row of three
+% and a second row of one, two or three).
+%
+% The command \alignauthor (no curly braces needed) should
+% precede each author name, affiliation/snail-mail address and
+% e-mail address. Additionally, tag each line of
+% affiliation/address with \affaddr, and tag the
+% e-mail address with \email.
+%
+% 1st. author
+\alignauthor
+Ben Trovato\titlenote{Dr.~Trovato insisted his name be first.}\\
+       \affaddr{Institute for Clarity in Documentation}\\
+       \affaddr{1932 Wallamaloo Lane}\\
+       \email{trovato@corporation.com}
+% 2nd. author
+\alignauthor
+G.K.M. Tobin\titlenote{The secretary disavows
+any knowledge of this author's actions.}\\
+       \affaddr{Institute for Clarity in Documentation}\\
+       \affaddr{P.O. Box 1212}\\
+       \email{webmaster@marysville-ohio.com}
+% 3rd. author
+\alignauthor Lars Th{\o}rv{\"a}ld\titlenote{This author is the
+one who did all the really hard work.}\\
+       \affaddr{The Th{\o}rv{\"a}ld Group}\\
+       \affaddr{1 Th{\o}rv{\"a}ld Circle}\\
+       \email{larst@affiliation.org}
+\and  % use '\and' if you need 'another row' of author names
+% 4th. author
+\alignauthor Lawrence P. Leipuner\\
+       \affaddr{Brookhaven Laboratories}\\
+       \affaddr{Brookhaven National Lab}\\
+       \email{lleipuner@researchlabs.org}
+% 5th. author
+\alignauthor Sean Fogarty\\
+       \affaddr{NASA Ames Research Center}\\
+       \affaddr{Moffett Field}\\
+       \email{fogartys@amesres.org}
+% 6th. author
+\alignauthor Charles Palmer\\
+       \affaddr{Palmer Research Laboratories}\\
+       \affaddr{8600 Datapoint Drive}\\
+       \email{cpalmer@prl.com}
+}
+% There's nothing stopping you putting the seventh, eighth, etc.
+% author on the opening page (as the 'third row') but we ask,
+% for aesthetic reasons that you place these 'additional authors'
+% in the \additional authors block, viz.
+\additionalauthors{Additional authors: John Smith (The Th{\o}rv{\"a}ld Group,
+email: {\texttt{jsmith@affiliation.org}}) and Julius P.~Kumquat
+(The Kumquat Consortium, email: {\texttt{jpkumquat@consortium.net}}).}
+\date{30 July 1999}
+% Just remember to make sure that the TOTAL number of authors
+% is the number that will appear on the first page PLUS the
+% number that will appear in the \additionalauthors section.
+
+\maketitle
+\begin{sloppypar}
+\begin{abstract}
+In this paper, we describe the formatting guidelines for the  Proceedings of the Web Audio Conference 2016. This template has been adapted from the ACM SIG Proceedings Template available at www.acm.org.\footnote{\url{http://www.acm.org/publications/article-templates/proceedings-template.html}} This paper provides a sample of a \LaTeX\ document which conforms,
+somewhat loosely, to the formatting guidelines for
+ACM SIG Proceedings. It is an {\em alternate} style which produces
+a {\em tighter-looking} paper and was designed in response to
+concerns expressed, by authors, over page-budgets.
+It complements the document \textit{Author's (Alternate) Guide to
+Preparing ACM SIG Proceedings Using \LaTeX$2_\epsilon$\ and Bib\TeX}.
+This source file has been written with the intention of being
+compiled under \LaTeX$2_\epsilon$\ and BibTeX.
+
+The developers have tried to include every imaginable sort
+of ``bells and whistles", such as a subtitle, footnotes on
+title, subtitle and authors, as well as in the text, and
+every optional component (e.g. Acknowledgments, Additional
+Authors, Appendices), not to mention examples of
+equations, theorems, tables and figures.
+
+To make best use of this sample document, run it through \LaTeX\
+and BibTeX, and compare this source code with the printed
+output produced by the dvi file. A compiled PDF version
+is available on the web page to help you with the
+`look and feel'.
+\end{abstract}
+
+
+%
+% The code below should be generated by the tool at
+% http://dl.acm.org/ccs.cfm
+% Please copy and paste the code instead of the example below. 
+%
+%\begin{CCSXML}
+%<ccs2012>
+ %<concept>
+  %<concept_id>10010520.10010553.10010562</concept_id>
+  %<concept_desc>Computer systems organization~Embedded systems</concept_desc>
+  %<concept_significance>500</concept_significance>
+ %</concept>
+ %<concept>
+  %<concept_id>10010520.10010575.10010755</concept_id>
+  %<concept_desc>Computer systems organization~Redundancy</concept_desc>
+  %<concept_significance>300</concept_significance>
+ %</concept>
+ %<concept>
+  %<concept_id>10010520.10010553.10010554</concept_id>
+  %<concept_desc>Computer systems organization~Robotics</concept_desc>
+  %<concept_significance>100</concept_significance>
+ %</concept>
+ %<concept>
+  %<concept_id>10003033.10003083.10003095</concept_id>
+  %<concept_desc>Networks~Network reliability</concept_desc>
+  %<concept_significance>100</concept_significance>
+ %</concept>
+%</ccs2012>  
+%\end{CCSXML}
+%
+%\ccsdesc[500]{Computer systems organization~Embedded systems}
+%\ccsdesc[300]{Computer systems organization~Redundancy}
+%\ccsdesc{Computer systems organization~Robotics}
+%\ccsdesc[100]{Networks~Network reliability}
+%
+%
+%%
+%% End generated code
+%%
+%
+%%
+%%  Use this command to print the description
+%%
+%\printccsdesc
+%
+%% We no longer use \terms command
+%%\terms{Theory}
+%
+%\keywords{ACM proceedings, \LaTeX, text tagging}
+
+\section{Introduction}
+The \textit{proceedings} are the records of a conference.
+ACM seeks to give these conference by-products a uniform,
+high-quality appearance.  To do this, ACM has some rigid
+requirements for the format of the proceedings documents: there
+is a specified format (balanced  double columns), a specified
+set of fonts (Arial or Helvetica and Times Roman) in
+certain specified sizes (for instance, 9 point for body copy),
+a specified live area (18 $\times$ 23.5 cm [7" $\times$ 9.25"]) centered on
+the page, specified size of margins (1.9 cm [0.75"]) top, (2.54 cm [1"]) bottom
+and (1.9 cm [.75"]) left and right; specified column width
+(8.45 cm [3.33"]) and gutter size (.83 cm [.33"]).
+
+The good news is, with only a handful of manual
+settings\footnote{Two of these, the {\texttt{\char'134 numberofauthors}}
+and {\texttt{\char'134 alignauthor}} commands, you have
+already used; another, {\texttt{\char'134 balancecolumns}}, will
+be used in your very last run of \LaTeX\ to ensure
+balanced column heights on the last page.}, the \LaTeX\ document
+class file handles all of this for you.
+
+The remainder of this document is concerned with showing, in
+the context of an ``actual'' document, the \LaTeX\ commands
+specifically available for denoting the structure of a
+proceedings paper, rather than with giving rigorous descriptions
+or explanations of such commands.
+
+\section{The {\secit Body} of The Paper}
+Typically, the body of a paper is organized
+into a hierarchical structure, with numbered or unnumbered
+headings for sections, subsections, sub-subsections, and even
+smaller sections.  The command \texttt{{\char'134}section} that
+precedes this paragraph is part of such a
+hierarchy.\footnote{This is the second footnote.  It
+starts a series of three footnotes that add nothing
+informational, but just give an idea of how footnotes work
+and look. It is a wordy one, just so you see
+how a longish one plays out.} \LaTeX\ handles the numbering
+and placement of these headings for you, when you use
+the appropriate heading commands around the titles
+of the headings.  If you want a sub-subsection or
+smaller part to be unnumbered in your output, simply append an
+asterisk to the command name.  Examples of both
+numbered and unnumbered headings will appear throughout the
+balance of this sample document.
+
+Because the entire article is contained in
+the \textbf{document} environment, you can indicate the
+start of a new paragraph with a blank line in your
+input file; that is why this sentence forms a separate paragraph.
+
+\subsection{Type Changes and {\subsecit Special} Characters}
+We have already seen several typeface changes in this sample.  You
+can indicate italicized words or phrases in your text with
+the command \texttt{{\char'134}textit}; emboldening with the
+command \texttt{{\char'134}textbf}
+and typewriter-style (for instance, for computer code) with
+\texttt{{\char'134}texttt}.  But remember, you do not
+have to indicate typestyle changes when such changes are
+part of the \textit{structural} elements of your
+article; for instance, the heading of this subsection will
+be in a sans serif\footnote{A third footnote, here.
+Let's make this a rather short one to
+see how it looks.} typeface, but that is handled by the
+document class file. Take care with the use
+of\footnote{A fourth, and last, footnote.}
+the curly braces in typeface changes; they mark
+the beginning and end of
+the text that is to be in the different typeface.
+
+You can use whatever symbols, accented characters, or
+non-English characters you need anywhere in your document;
+you can find a complete list of what is
+available in the \textit{\LaTeX\
+User's Guide}\cite{Lamport:LaTeX}.
+
+\subsection{Math Equations}
+You may want to display math equations in three distinct styles:
+inline, numbered or non-numbered display.  Each of
+the three are discussed in the next sections.
+
+\subsubsection{Inline (In-text) Equations}
+A formula that appears in the running text is called an
+inline or in-text formula.  It is produced by the
+\textbf{math} environment, which can be
+invoked with the usual \texttt{{\char'134}begin. . .{\char'134}end}
+construction or with the short form \texttt{\$. . .\$}. You
+can use any of the symbols and structures,
+from $\alpha$ to $\omega$, available in
+\LaTeX\cite{Lamport:LaTeX}; this section will simply show a
+few examples of in-text equations in context. Notice how
+this equation: \begin{math}\lim_{n\rightarrow \infty}x=0\end{math},
+set here in in-line math style, looks slightly different when
+set in display style.  (See next section).
+
+\subsubsection{Display Equations}
+A numbered display equation -- one set off by vertical space
+from the text and centered horizontally -- is produced
+by the \textbf{equation} environment. An unnumbered display
+equation is produced by the \textbf{displaymath} environment.
+
+Again, in either environment, you can use any of the symbols
+and structures available in \LaTeX; this section will just
+give a couple of examples of display equations in context.
+First, consider the equation, shown as an inline equation above:
+\begin{equation}\lim_{n\rightarrow \infty}x=0\end{equation}
+Notice how it is formatted somewhat differently in
+the \textbf{displaymath}
+environment.  Now, we'll enter an unnumbered equation:
+\begin{displaymath}\sum_{i=0}^{\infty} x + 1\end{displaymath}
+and follow it with another numbered equation:
+\begin{equation}\sum_{i=0}^{\infty}x_i=\int_{0}^{\pi+2} f\end{equation}
+just to demonstrate \LaTeX's able handling of numbering.
+
+\subsection{Citations}
+Citations to articles \cite{bowman:reasoning,
+clark:pct, braams:babel, herlihy:methodology},
+conference proceedings \cite{clark:pct} or
+books \cite{salas:calculus, Lamport:LaTeX} listed
+in the Bibliography section of your
+article will occur throughout the text of your article.
+You should use BibTeX to automatically produce this bibliography;
+you simply need to insert one of several citation commands with
+a key of the item cited in the proper location in
+the \texttt{.tex} file \cite{Lamport:LaTeX}.
+The key is a short reference you invent to uniquely
+identify each work; in this sample document, the key is
+the first author's surname and a
+word from the title.  This identifying key is included
+with each item in the \texttt{.bib} file for your article.
+
+The details of the construction of the \texttt{.bib} file
+are beyond the scope of this sample document, but more
+information can be found in the \textit{Author's Guide},
+and exhaustive details in the \textit{\LaTeX\ User's
+Guide}\cite{Lamport:LaTeX}.
+
+This article shows only the plainest form
+of the citation command, using \texttt{{\char'134}cite}.
+This is what is stipulated in the SIGS style specifications.
+No other citation format is endorsed or supported.
+
+\subsection{Tables}
+Because tables cannot be split across pages, the best
+placement for them is typically the top of the page
+nearest their initial cite.  To
+ensure this proper ``floating'' placement of tables, use the
+environment \textbf{table} to enclose the table's contents and
+the table caption.  The contents of the table itself must go
+in the \textbf{tabular} environment, to
+be aligned properly in rows and columns, with the desired
+horizontal and vertical rules.  Again, detailed instructions
+on \textbf{tabular} material
+is found in the \textit{\LaTeX\ User's Guide}.
+
+Immediately following this sentence is the point at which
+Table 1 is included in the input file; compare the
+placement of the table here with the table in the printed
+dvi output of this document.
+
+\begin{table}
+\centering
+\caption{Frequency of Special Characters}
+\begin{tabular}{|c|c|l|} \hline
+Non-English or Math&Frequency&Comments\\ \hline
+\O & 1 in 1,000& For Swedish names\\ \hline
+$\pi$ & 1 in 5& Common in math\\ \hline
+\$ & 4 in 5 & Used in business\\ \hline
+$\Psi^2_1$ & 1 in 40,000& Unexplained usage\\
+\hline\end{tabular}
+\end{table}
+
+To set a wider table, which takes up the whole width of
+the page's live area, use the environment
+\textbf{table*} to enclose the table's contents and
+the table caption.  As with a single-column table, this wide
+table will ``float" to a location deemed more desirable.
+Immediately following this sentence is the point at which
+Table 2 is included in the input file; again, it is
+instructive to compare the placement of the
+table here with the table in the printed dvi
+output of this document.
+
+
+\begin{table*}
+\centering
+\caption{Some Typical Commands}
+\begin{tabular}{|c|c|l|} \hline
+Command&A Number&Comments\\ \hline
+\texttt{{\char'134}alignauthor} & 100& Author alignment\\ \hline
+\texttt{{\char'134}numberofauthors}& 200& Author enumeration\\ \hline
+\texttt{{\char'134}table}& 300 & For tables\\ \hline
+\texttt{{\char'134}table*}& 400& For wider tables\\ \hline\end{tabular}
+\end{table*}
+% end the environment with {table*}, NOTE not {table}!
+
+\subsection{Figures}
+Like tables, figures cannot be split across pages; the
+best placement for them
+is typically the top or the bottom of the page nearest
+their initial cite.  To ensure this proper ``floating'' placement
+of figures, use the environment
+\textbf{figure} to enclose the figure and its caption.
+
+This sample document contains examples of \textbf{.eps} files to be
+displayable with \LaTeX.  If you work with pdf\LaTeX, use files in the
+\textbf{.pdf} format.  Note that most modern \TeX\ system will convert
+\textbf{.eps} to \textbf{.pdf} for you on the fly.  More details on
+each of these is found in the \textit{Author's Guide}.
+
+\begin{figure}
+\centering
+\includegraphics{fly}
+\caption{A sample black and white graphic.}
+\end{figure}
+
+\begin{figure}
+\centering
+\includegraphics[height=1in, width=1in]{fly}
+\caption{A sample black and white graphic
+that has been resized with the \texttt{includegraphics} command.}
+\end{figure}
+
+
+As was the case with tables, you may want a figure
+that spans two columns.  To do this, and still to
+ensure proper ``floating'' placement of tables, use the environment
+\textbf{figure*} to enclose the figure and its caption.
+and don't forget to end the environment with
+{figure*}, not {figure}!
+
+\begin{figure*}
+\centering
+\includegraphics{flies}
+\caption{A sample black and white graphic
+that needs to span two columns of text.}
+\end{figure*}
+
+
+%\begin{figure}
+%\centering
+%\includegraphics[height=1in, width=1in]{rosette}
+%\caption{A sample black and white graphic that has
+%been resized with the \texttt{includegraphics} command.}
+%\vskip -6pt
+%\end{figure}
+
+\subsection{Theorem-like Constructs}
+Other common constructs that may occur in your article are
+the forms for logical constructs like theorems, axioms,
+corollaries and proofs.  There are
+two forms, one produced by the
+command \texttt{{\char'134}newtheorem} and the
+other by the command \texttt{{\char'134}newdef}; perhaps
+the clearest and easiest way to distinguish them is
+to compare the two in the output of this sample document:
+
+This uses the \textbf{theorem} environment, created by
+the\linebreak\texttt{{\char'134}newtheorem} command:
+\newtheorem{theorem}{Theorem}
+\begin{theorem}
+Let $f$ be continuous on $[a,b]$.  If $G$ is
+an antiderivative for $f$ on $[a,b]$, then
+\begin{displaymath}\int^b_af(t)dt = G(b) - G(a).\end{displaymath}
+\end{theorem}
+
+The other uses the \textbf{definition} environment, created
+by the \texttt{{\char'134}newdef} command:
+\newdef{definition}{Definition}
+\begin{definition}
+If $z$ is irrational, then by $e^z$ we mean the
+unique number which has
+logarithm $z$: \begin{displaymath}{\log e^z = z}\end{displaymath}
+\end{definition}
+
+Two lists of constructs that use one of these
+forms is given in the
+\textit{Author's  Guidelines}.
+ 
+There is one other similar construct environment, which is
+already set up
+for you; i.e. you must \textit{not} use
+a \texttt{{\char'134}newdef} command to
+create it: the \textbf{proof} environment.  Here
+is a example of its use:
+\begin{proof}
+Suppose on the contrary there exists a real number $L$ such that
+\begin{displaymath}
+\lim_{x\rightarrow\infty} \frac{f(x)}{g(x)} = L.
+\end{displaymath}
+Then
+\begin{displaymath}
+l=\lim_{x\rightarrow c} f(x)
+= \lim_{x\rightarrow c}
+\left[ g{x} \cdot \frac{f(x)}{g(x)} \right ]
+= \lim_{x\rightarrow c} g(x) \cdot \lim_{x\rightarrow c}
+\frac{f(x)}{g(x)} = 0\cdot L = 0,
+\end{displaymath}
+which contradicts our assumption that $l\neq 0$.
+\end{proof}
+
+Complete rules about using these environments and using the
+two different creation commands are in the
+\textit{Author's Guide}; please consult it for more
+detailed instructions.  If you need to use another construct,
+not listed therein, which you want to have the same
+formatting as the Theorem
+or the Definition\cite{salas:calculus} shown above,
+use the \texttt{{\char'134}newtheorem} or the
+\texttt{{\char'134}newdef} command,
+respectively, to create it.
+
+\subsection*{A {\secit Caveat} for the \TeX\ Expert}
+Because you have just been given permission to
+use the \texttt{{\char'134}newdef} command to create a
+new form, you might think you can
+use \TeX's \texttt{{\char'134}def} to create a
+new command: \textit{Please refrain from doing this!}
+Remember that your \LaTeX\ source code is primarily intended
+to create camera-ready copy, but may be converted
+to other forms -- e.g. HTML. If you inadvertently omit
+some or all of the \texttt{{\char'134}def}s recompilation will
+be, to say the least, problematic.
+
+\section{Conclusions}
+This paragraph will end the body of this sample document.
+Remember that you might still have Acknowledgments or
+Appendices; brief samples of these
+follow.  There is still the Bibliography to deal with; and
+we will make a disclaimer about that here: with the exception
+of the reference to the \LaTeX\ book, the citations in
+this paper are to articles which have nothing to
+do with the present subject and are used as
+examples only.
+%\end{document}  % This is where a 'short' article might terminate
+
+%ACKNOWLEDGMENTS are optional
+\section{Acknowledgments}
+This section is optional; it is a location for you
+to acknowledge grants, funding, editing assistance and
+what have you.  In the present case, for example, the
+authors would like to thank Gerald Murray of ACM for
+his help in codifying this \textit{Author's Guide}
+and the \textbf{.cls} and \textbf{.tex} files that it describes.
+
+%
+% The following two commands are all you need in the
+% initial runs of your .tex file to
+% produce the bibliography for the citations in your paper.
+\bibliographystyle{abbrv}
+\bibliography{sigproc}  % sigproc.bib is the name of the Bibliography in this case
+% You must have a proper ".bib" file
+%  and remember to run:
+% latex bibtex latex latex
+% to resolve all references
+%
+% ACM needs 'a single self-contained file'!
+%
+%APPENDICES are optional
+%\balancecolumns
+\appendix
+%Appendix A
+\section{Headings in Appendices}
+The rules about hierarchical headings discussed above for
+the body of the article are different in the appendices.
+In the \textbf{appendix} environment, the command
+\textbf{section} is used to
+indicate the start of each Appendix, with alphabetic order
+designation (i.e. the first is A, the second B, etc.) and
+a title (if you include one).  So, if you need
+hierarchical structure
+\textit{within} an Appendix, start with \textbf{subsection} as the
+highest level. Here is an outline of the body of this
+document in Appendix-appropriate form:
+\subsection{Introduction}
+\subsection{The Body of the Paper}
+\subsubsection{Type Changes and  Special Characters}
+\subsubsection{Math Equations}
+\paragraph{Inline (In-text) Equations}
+\paragraph{Display Equations}
+\subsubsection{Citations}
+\subsubsection{Tables}
+\subsubsection{Figures}
+\subsubsection{Theorem-like Constructs}
+\subsubsection*{A Caveat for the \TeX\ Expert}
+\subsection{Conclusions}
+\subsection{Acknowledgments}
+\subsection{Additional Authors}
+This section is inserted by \LaTeX; you do not insert it.
+You just add the names and information in the
+\texttt{{\char'134}additionalauthors} command at the start
+of the document.
+\subsection{References}
+Generated by bibtex from your ~.bib file.  Run latex,
+then bibtex, then latex twice (to resolve references)
+to create the ~.bbl file.  Insert that ~.bbl file into
+the .tex source file and comment out
+the command \texttt{{\char'134}thebibliography}.
+% This next section command marks the start of
+% Appendix B, and does not continue the present hierarchy
+\section{More Help for the Hardy}
+The sig-alternate.cls file itself is chock-full of succinct
+and helpful comments.  If you consider yourself a moderately
+experienced to expert user of \LaTeX, you may find reading
+it useful but please remember not to change it.
+%\balancecolumns % GM June 2007
+% That's all folks!
+\end{sloppypar}
+\end{document}
--- a/docs/WAC2016/sig-alternate.cls	Wed Feb 24 14:00:10 2016 +0000
+++ b/docs/WAC2016/sig-alternate.cls	Tue Mar 08 14:44:14 2016 +0000
@@ -374,7 +374,7 @@
 \newfont{\affaddrit}{phvro8t at 10pt} % GM 2/4/2000
 \newfont{\eaddfnt}{phvr8t at 12pt}
 \newfont{\ixpt}{ptmr8t at 9pt}
-\newfont{\confname}{ptmri8t at 8pt}
+\newfont{\confname}{ptmri8t at 7pt}%\newfont{\confname}{ptmri8t at 8pt}
 \newfont{\crnotice}{ptmr8t at 8pt}
 \newfont{\ninept}{ptmr8t at 9pt}
 % +++++++++++++++++++++++++++++++++++++++++++++
@@ -898,8 +898,8 @@
 \@float{copyrightbox}[b]
 \begin{center}
 \setlength{\unitlength}{1pc}
-\begin{picture}(20,6) %Space for copyright notice
-\put(0,-0.95){\crnotice{\@toappear}}
+\begin{picture}(20,4) %\begin{picture}(20,6) %Space for copyright notice
+\put(0,-0.25){\crnotice{\@toappear}}
 \end{picture}
 \end{center}
 \end@float}
@@ -1512,14 +1512,14 @@
 
 \newtoks\copyrightetc
 \global\copyrightetc{%
-{\noindent\confname\ \the\conf\ \the\confinfo}\par\smallskip
+{\noindent\confname\the\conf\ \the\confinfo}\par\smallskip%{\noindent\confname\ \the\conf\ \the\confinfo}\par\smallskip
   \if@printcopyright
-    \copyright\ \the\copyrtyr\ \@copyrightowner
+    \copyright\ \the\copyrtyr\ \@copyrightowner%\ \copyright\ \the\copyrtyr\ \@copyrightowner
   \fi
   \if@acmowned ISBN \else\ifnum\acm@copyrightmode=2 ISBN \else %\par\smallskip ~ 
 \fi\fi
 % \the\acmcopyr
-\ifx\@acmPrice\@empty.\else\dots\@acmPrice\fi\par%\smallskip
+\ifx\@acmPrice\@empty\else\dots\@acmPrice\fi\par%\smallskip%\ifx\@acmPrice\@empty.\else\dots\@acmPrice\fi\par%\smallskip
 %{DOI: \small\expandafter\printdoi\expandafter{\@doi}%
 } 
 \toappear{\fontsize{7pt}{8pt}\fontfamily{ptm}\selectfont
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/WAC2016/sigproc.bib	Tue Mar 08 14:44:14 2016 +0000
@@ -0,0 +1,59 @@
+@ARTICLE{bowman:reasoning,
+	AUTHOR = "Mic Bowman and Saumya K. Debray and Larry L. Peterson",
+	TITLE = "Reasoning About Naming Systems",
+	JOURNAL = "ACM Trans. Program. Lang. Syst.",
+	VOLUME = {15},
+	NUMBER = {5},
+	PAGES = {795-825},
+	MONTH = "November",
+	YEAR = {1993}	}
+
+@ARTICLE{braams:babel,
+	AUTHOR = "Johannes Braams",
+	TITLE = "Babel, a Multilingual Style-Option System for Use with LaTeX's Standard Document Styles",
+	JOURNAL = {TUGboat},
+	VOLUME = {12},
+	NUMBER = {2},
+	PAGES = {291-301},
+	MONTH = "June",
+	YEAR = {1991}	}
+
+@INPROCEEDINGS{clark:pct,
+	AUTHOR = "Malcolm Clark",
+	TITLE = "Post Congress Tristesse",
+	BOOKTITLE = "TeX90 Conference Proceedings",
+	PAGES = "84-89",
+	ORGANIZATION = "TeX Users Group",
+	MONTH = "March", 
+	YEAR = {1991}	}
+
+@ARTICLE{herlihy:methodology,
+	AUTHOR = "Maurice Herlihy",
+	TITLE = "A Methodology for Implementing Highly Concurrent
+	Data Objects",
+	JOURNAL = {ACM Trans. Program. Lang. Syst.},
+	VOLUME = {15},
+	NUMBER = {5},
+	PAGES = {745-770},
+	MONTH = "November",
+	YEAR = {1993}	}
+
+@BOOK{Lamport:LaTeX,
+	AUTHOR = "Leslie Lamport",
+	TITLE = "LaTeX User's Guide and Document Reference Manual",
+	PUBLISHER = "Addison-Wesley Publishing Company",
+	ADDRESS = "Reading, Massachusetts",
+	YEAR = "1986"	}
+
+@BOOK{salas:calculus,
+	AUTHOR = "S.L. Salas and Einar Hille",
+	TITLE = "Calculus: One and Several Variable",
+	PUBLISHER = "John Wiley and Sons",
+	ADDRESS = "New York",
+	YEAR = "1978"	}
+
+
+
+
+
+
--- a/docs/WAC2016/waccopyright.sty	Wed Feb 24 14:00:10 2016 +0000
+++ b/docs/WAC2016/waccopyright.sty	Tue Mar 08 14:44:14 2016 +0000
@@ -37,7 +37,7 @@
 %%   Right brace   \}     Tilde         \~}
 \NeedsTeXFormat{LaTeX2e}
 \ProvidesPackage{waccopyright}
-[2014/06/29 v1.2 Copyright statemens for ACM classes]
+[2014/06/29 v1.2 Copyright statements for ACM classes]
 \newif\if@printcopyright
 \@printcopyrighttrue
 \newif\if@printpermission
@@ -221,7 +221,8 @@
    this article, or to allow others to do so, for Government purposes
    only.
   \or % waclicense
-   \includegraphics[scale=.39]{cc}\\ Licensed under a Creative Commons Attribution 4.0 International License (CC BY 4.0). Attribution: owner/author(s).
+   \frame{\includegraphics[scale=.54]{cc}}\vspace{1mm}\vfill 
+   Licensed under a Creative Commons Attribution 4.0 International License (CC BY 4.0). \textbf{Attribution}: owner/author(s).
   \fi}
 \endinput
 %%
--- a/interfaces/AB.css	Wed Feb 24 14:00:10 2016 +0000
+++ b/interfaces/AB.css	Tue Mar 08 14:44:14 2016 +0000
@@ -37,7 +37,7 @@
 	font-size: 1.2em;
 }
 
-div.comparitor-holder {
+div.comparator-holder {
 	width: 260px;
 	height: 300px;
 	border:  black 1px solid;
@@ -46,7 +46,7 @@
     margin: 25px;
 }
 
-div.comparitor-selector {
+div.comparator-selector {
 	width: 248px;
 	height: 250px;
 	border: black 1px solid;
@@ -63,11 +63,11 @@
 	background-color: #008000;
 }
 
-div.comparitor-selector span {
+div.comparator-selector span {
 	font-size: 4em;
 }
 
-button.comparitor-button {
+button.comparator-button {
 	width: 250px;
 	height: 38px;
 	position: relative;
--- a/interfaces/AB.js	Wed Feb 24 14:00:10 2016 +0000
+++ b/interfaces/AB.js	Tue Mar 08 14:44:14 2016 +0000
@@ -7,8 +7,8 @@
 	var height = window.innerHeight;
 	interfaceContext.insertPoint.innerHTML = null; // Clear the current schema
 	
-	// Custom Comparitor Object
-	Interface.prototype.comparitor = null;
+	// Custom comparator Object
+	Interface.prototype.comparator = null;
 	
 	// The injection point into the HTML page
 	interfaceContext.insertPoint = document.getElementById("topLevelBody");
@@ -134,7 +134,7 @@
                         pagecountHolder = document.createElement('div');
                         pagecountHolder.id = 'page-count';
                     }
-                    pagecountHolder.innerHTML = '<span>Page '+(audioHolderObject.presentedId+1)+' of '+specification.pages.length+'</span>';
+                    pagecountHolder.innerHTML = '<span>Page '+(testState.stateIndex+1)+' of '+testState.stateMap.length+'</span>';
                     var inject = document.getElementById('interface-buttons');
                     inject.appendChild(pagecountHolder);
                     break;
@@ -148,8 +148,8 @@
         }
     }
 	
-	// Populate the comparitor object
-	interfaceContext.comparitor = new Comparitor(audioHolderObject);
+	// Populate the comparator object
+	interfaceContext.comparator = new comparator(audioHolderObject);
     if (audioHolderObject.showElementComments)
     {
         var commentHolder = document.createElement('div');
@@ -158,32 +158,32 @@
         // Generate one comment box per presented page
         for (var element of audioEngineContext.audioObjects)
         {
-            interfaceContext.createCommentBox(element);
+            interfaceContext.commentBoxes.createCommentBox(element);
         }
-        interfaceContext.showCommentBoxes(commentHolder,true);
+        interfaceContext.commentBoxes.showCommentBoxes(commentHolder,true);
     }
 	resizeWindow(null);
 }
 
-function Comparitor(audioHolderObject)
+function comparator(audioHolderObject)
 {	
-	this.comparitorBox = function(audioElement,id,text)
+	this.comparatorBox = function(audioElement,id,text)
 	{
 		this.parent = audioElement;
 		this.id = id;
 		this.value = 0;
 		this.disabled = true;
 		this.box = document.createElement('div');
-		this.box.className = 'comparitor-holder';
+		this.box.className = 'comparator-holder';
 		this.box.setAttribute('track-id',audioElement.id);
-		this.box.id = 'comparitor-'+text;
+		this.box.id = 'comparator-'+text;
 		this.selector = document.createElement('div');
-		this.selector.className = 'comparitor-selector disabled';
+		this.selector.className = 'comparator-selector disabled';
 		var selectorText = document.createElement('span');
 		selectorText.textContent = text;
 		this.selector.appendChild(selectorText);
 		this.playback = document.createElement('button');
-		this.playback.className = 'comparitor-button';
+		this.playback.className = 'comparator-button';
 		this.playback.disabled = true;
 		this.playback.textContent = "Listen";
 		this.box.appendChild(this.selector);
@@ -201,22 +201,31 @@
 				alert("Please listen to the samples before making a selection");
 				console.log("Please listen to the samples before making a selection");
 				return;
-			}
-			$(".comparitor-selector").removeClass('selected');
+            }
 			var id = event.currentTarget.parentElement.getAttribute('track-id');
-			interfaceContext.comparitor.selected = id;
-			$(event.currentTarget).addClass('selected');
-			for (var i=0; i<interfaceContext.comparitor.comparitors.length; i++)
-			{
-				var obj = interfaceContext.comparitor.comparitors[i];
-				if (i == id) {
-					obj.value = 1;
-				} else {
-					obj.value = 0;
-				}
-				obj.parent.metric.moved(time,obj.value);
-			}
-			console.log("Selected "+id+' ('+time+')');
+			interfaceContext.comparator.selected = id;
+            if ($(event.currentTarget).hasClass("selected")) {
+                $(".comparator-selector").removeClass('selected');
+                for (var i=0; i<interfaceContext.comparator.comparators.length; i++)
+                {
+                     var obj = interfaceContext.comparator.comparators[i];
+                    obj.parent.metric.moved(time,0);
+                }
+            } else {
+                $(".comparator-selector").removeClass('selected');
+                $(event.currentTarget).addClass('selected');
+                for (var i=0; i<interfaceContext.comparator.comparators.length; i++)
+                {
+                    var obj = interfaceContext.comparator.comparators[i];
+                    if (i == id) {
+                        obj.value = 1;
+                    } else {
+                        obj.value = 0;
+                    }
+                    obj.parent.metric.moved(time,obj.value);
+                }
+                console.log("Selected "+id+' ('+time+')');
+            }
 		};
         this.playback.setAttribute("playstate","ready");
 		this.playback.onclick = function(event)
@@ -250,9 +259,14 @@
 				this.playback.textContent = "Play";
 			}
 		};
+        this.error = function() {
+            // audioObject has an error!!
+            this.playback.textContent = "Error";
+            $(this.playback).addClass("error-colour");
+        }
         this.startPlayback = function()
         {
-            $('.comparitor-button').text('Listen');
+            $('.comparator-button').text('Listen');
             $(this.playback).text('Stop');
             this.playback.setAttribute("playstate","playing");
         };
@@ -282,7 +296,7 @@
 	
 	this.boxHolders = document.getElementById('box-holders');
 	this.boxHolders.innerHTML = null;
-	this.comparitors = [];
+	this.comparators = [];
 	this.selected = null;
 	
 	// First generate the Audio Objects for the Audio Engine
@@ -294,9 +308,9 @@
 			console.log("WARNING - AB cannot have fixed reference");
 		}
 		var audioObject = audioEngineContext.newTrack(element);
-		var node = new this.comparitorBox(audioObject,index,String.fromCharCode(65 + index));
+		var node = new this.comparatorBox(audioObject,index,String.fromCharCode(65 + index));
 		audioObject.bindInterface(node);
-		this.comparitors.push(node);
+		this.comparators.push(node);
 		this.boxHolders.appendChild(node.box);
 	}
 	return this;
@@ -305,7 +319,7 @@
 function resizeWindow(event)
 {
 	document.getElementById('submit').style.left = (window.innerWidth-250)/2 + 'px';
-	var numObj = interfaceContext.comparitor.comparitors.length;
+	var numObj = interfaceContext.comparator.comparators.length;
 	var boxW = numObj*312;
     var diff = window.innerWidth - boxW;
     while (diff < 0)
--- a/interfaces/ape.js	Wed Feb 24 14:00:10 2016 +0000
+++ b/interfaces/ape.js	Tue Mar 08 14:44:14 2016 +0000
@@ -319,7 +319,7 @@
                     pagecountHolder = document.createElement('div');
                     pagecountHolder.id = 'page-count';
                 }
-                pagecountHolder.innerHTML = '<span>Page '+(audioHolderObject.presentedId+1)+' of '+specification.pages.length+'</span>';
+                pagecountHolder.innerHTML = '<span>Page '+(testState.stateIndex+1)+' of '+testState.stateMap.length+'</span>';
                 var inject = document.getElementById('interface-buttons');
                 inject.appendChild(pagecountHolder);
             } else if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'volume') {
@@ -356,7 +356,7 @@
 			// Create a slider per track
 			var sliderNode = new sliderObject(audioObject,interfaceObj);
 			audioObject.bindInterface(sliderNode);
-            interfaceContext.createCommentBox(audioObject);
+            interfaceContext.commentBoxes.createCommentBox(audioObject);
 		}
 	});
 	
@@ -433,7 +433,7 @@
 	
 	
 	if (audioHolderObject.showElementComments) {
-		interfaceContext.showCommentBoxes(feedbackHolder,true);
+		interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder,true);
 	}
 	
 	$(audioHolderObject.commentQuestions).each(function(index,element) {
@@ -644,6 +644,11 @@
 	{
 		return true;
 	};
+    this.error = function() {
+            // audioObject has an error!!
+        this.playback.textContent = "Error";
+        $(this.playback).addClass("error-colour");
+    }
 }
 
 function outsideReferenceDOM(audioObject,index,inject)
@@ -713,6 +718,11 @@
 	{
 		return false;
 	};
+    this.error = function() {
+            // audioObject has an error!!
+        this.outsideReferenceHolder.textContent = "Error";
+        $(this.outsideReferenceHolder).addClass("error-colour");
+    }
 }
 
 function buttonSubmitClick()
--- a/interfaces/blank.js	Wed Feb 24 14:00:10 2016 +0000
+++ b/interfaces/blank.js	Tue Mar 08 14:44:14 2016 +0000
@@ -57,6 +57,9 @@
 		// Use storage.document.createElement('value'); to generate the XML node.
 		
 	};
+    this.error = function() {
+        // If there is an error with the audioObject, this will be called to indicate a failure
+    }
 };
 
 function resizeWindow(event)
--- a/interfaces/discrete.js	Wed Feb 24 14:00:10 2016 +0000
+++ b/interfaces/discrete.js	Tue Mar 08 14:44:14 2016 +0000
@@ -149,7 +149,7 @@
                         pagecountHolder = document.createElement('div');
                         pagecountHolder.id = 'page-count';
                     }
-                    pagecountHolder.innerHTML = '<span>Page '+(page.presentedId+1)+' of '+specification.pages.length+'</span>';
+                    pagecountHolder.innerHTML = '<span>Page '+(testState.stateIndex+1)+' of '+testState.stateMap.length+'</span>';
                     var inject = document.getElementById('interface-buttons');
                     inject.appendChild(pagecountHolder);
                     break;
@@ -201,7 +201,7 @@
 			var sliderObj = new discreteObject(audioObject,label,interfaceScales);
 			sliderBox.appendChild(sliderObj.holder);
 			audioObject.bindInterface(sliderObj);
-            interfaceContext.createCommentBox(audioObject);
+            interfaceContext.commentBoxes.createCommentBox(audioObject);
 			label += 1;
 		}
         
@@ -209,7 +209,7 @@
 	
     if (page.showElementComments)
     {
-        interfaceContext.showCommentBoxes(feedbackHolder,true);
+        interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder,true);
     }
     
 	// Auto-align
@@ -378,6 +378,11 @@
 		node.textContent = this.getValue();
 		return node;
 	};
+    this.error = function() {
+            // audioObject has an error!!
+        this.playback.textContent = "Error";
+        $(this.playback).addClass("error-colour");
+    }
 };
 
 function outsideReferenceDOM(audioObject,index,inject)
@@ -446,6 +451,11 @@
 	{
 		return false;
 	};
+    this.error = function() {
+            // audioObject has an error!!
+        this.outsideReferenceHolder.textContent = "Error";
+        $(this.outsideReferenceHolder).addClass("error-colour");
+    }
 }
 
 function resizeWindow(event)
--- a/interfaces/horizontal-sliders.js	Wed Feb 24 14:00:10 2016 +0000
+++ b/interfaces/horizontal-sliders.js	Tue Mar 08 14:44:14 2016 +0000
@@ -150,7 +150,7 @@
                         pagecountHolder = document.createElement('div');
                         pagecountHolder.id = 'page-count';
                     }
-                    pagecountHolder.innerHTML = '<span>Page '+(page.presentedId+1)+' of '+specification.pages.length+'</span>';
+                    pagecountHolder.innerHTML = '<span>Page '+(testState.stateIndex+1)+' of '+testState.stateMap.length+'</span>';
                     var inject = document.getElementById('interface-buttons');
                     inject.appendChild(pagecountHolder);
                     break;
@@ -210,14 +210,14 @@
 			}
 			sliderBox.appendChild(sliderObj.holder);
 			audioObject.bindInterface(sliderObj);
-            interfaceContext.createCommentBox(audioObject);
+            interfaceContext.commentBoxes.createCommentBox(audioObject);
 			label += 1;
 		}
         
 	});
 	if (page.showElementComments)
     {
-        interfaceContext.showCommentBoxes(feedbackHolder,true);
+        interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder,true);
     }
 	// Auto-align
 	resizeWindow(null);
@@ -331,6 +331,11 @@
         node.textContent = this.slider.value;
         return node;
 	};
+    this.error = function() {
+            // audioObject has an error!!
+        this.playback.textContent = "Error";
+        $(this.playback).addClass("error-colour");
+    }
 };
 
 function outsideReferenceDOM(audioObject,index,inject)
@@ -394,6 +399,11 @@
 	{
 		return false;
 	};
+    this.error = function() {
+            // audioObject has an error!!
+        this.outsideReferenceHolder.textContent = "Error";
+        $(this.outsideReferenceHolder).addClass("error-colour");
+    }
 }
 
 function resizeWindow(event)
--- a/interfaces/mushra.js	Wed Feb 24 14:00:10 2016 +0000
+++ b/interfaces/mushra.js	Tue Mar 08 14:44:14 2016 +0000
@@ -149,7 +149,7 @@
                         pagecountHolder = document.createElement('div');
                         pagecountHolder.id = 'page-count';
                     }
-                    pagecountHolder.innerHTML = '<span>Page '+(audioHolderObject.presentedId+1)+' of '+specification.pages.length+'</span>';
+                    pagecountHolder.innerHTML = '<span>Page '+(testState.stateIndex+1)+' of '+testState.stateMap.length+'</span>';
                     var inject = document.getElementById('interface-buttons');
                     inject.appendChild(pagecountHolder);
                     break;
@@ -182,11 +182,6 @@
 	currentTestHolder.id = audioHolderObject.id;
 	currentTestHolder.repeatCount = audioHolderObject.repeatCount;
 	
-	$(audioHolderObject.commentQuestions).each(function(index,element) {
-		var node = interfaceContext.createCommentQuestion(element);
-		feedbackHolder.appendChild(node.holder);
-	});
-	
 	// Find all the audioElements from the audioHolder
 	var label = 0;
 	$(audioHolderObject.audioElements).each(function(index,element){
@@ -213,11 +208,20 @@
 			}
 			sliderBox.appendChild(sliderObj.holder);
 			audioObject.bindInterface(sliderObj);
-            interfaceContext.createCommentBox(audioObject);
+            interfaceContext.commentBoxes.createCommentBox(audioObject);
 			label += 1;
 		}
         
 	});
+    
+    if (audioHolderObject.showElementComments) {
+		interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder,true);
+	}
+	
+	$(audioHolderObject.commentQuestions).each(function(index,element) {
+		var node = interfaceContext.createCommentQuestion(element);
+		feedbackHolder.appendChild(node.holder);
+	});
 	
 	// Auto-align
 	resizeWindow(null);
@@ -339,6 +343,11 @@
 	{
 		return true;
 	};
+    this.error = function() {
+            // audioObject has an error!!
+        this.playback.textContent = "Error";
+        $(this.playback).addClass("error-colour");
+    }
 }
 
 function outsideReferenceDOM(audioObject,index,inject)
@@ -402,6 +411,11 @@
 	{
 		return false;
 	};
+    this.error = function() {
+            // audioObject has an error!!
+        this.outsideReferenceHolder.textContent = "Error";
+        $(this.outsideReferenceHolder).addClass("error-colour");
+    }
 }
 
 function resizeWindow(event)
--- a/loudness.js	Wed Feb 24 14:00:10 2016 +0000
+++ b/loudness.js	Tue Mar 08 14:44:14 2016 +0000
@@ -53,7 +53,6 @@
 	processSource.connect(KFilter);
 	KFilter.connect(HPFilter);
 	HPFilter.connect(offlineContext.destination);
-	processSource.start();
 	offlineContext.oncomplete = function(renderedBuffer) {
 		// Have the renderedBuffer information, now continue processing
 		if (typeof renderedBuffer.renderedBuffer == 'object') {
@@ -77,6 +76,7 @@
 		}
         buffer.ready();
 	};
+    processSource.start(0);
 	offlineContext.startRendering();
 }
 
--- a/save.php	Wed Feb 24 14:00:10 2016 +0000
+++ b/save.php	Tue Mar 08 14:44:14 2016 +0000
@@ -1,4 +1,11 @@
 <?php
+	error_reporting(0);
+    try{
+        date_default_timezone_get();
+    }
+    catch(Exception $e){
+        date_default_timezone_set('UTC'); // Sets to UTC if not specified anywhere in .ini
+    }
 	header('Access-Control-Allow-Origin: *');
 	header("Content-type: text/xml");
 	$postText = file_get_contents('php://input');
@@ -14,7 +21,7 @@
 		return;
 	}
 	$wbytes = fwrite($fileHandle, $postText);
-	if ($wbytes == FALSE)
+	if ($wbytes === FALSE)
 	{
 		// FileWrite failed
 		$xml = '<response state="error"><message>Could not write file "saves/'.$xmlfile.'"</message></response>';
@@ -26,4 +33,4 @@
 	// Return JSON confirmation data
 	$xml = '<response state="OK"><message>OK</message><file bytes="'.$wbytes.'">"saves/'.$xmlfile.'"</file></response>';
 	echo $xml;
-?>
\ No newline at end of file
+?>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/comment_parser.html	Tue Mar 08 14:44:14 2016 +0000
@@ -0,0 +1,72 @@
+<html lang="en">
+    <head>
+        <meta charset="utf-8" />
+        <script type="text/javascript">
+            function getXML()
+            {
+                var XMLHttp = new XMLHttpRequest();
+                XMLHttp.open("GET","comment_parser.php?format=XML",true);
+                XMLHttp.onload = function() {
+                    // Now we have the XML data, extract
+                    var parse = new DOMParser();
+                    var ajax = parse.parseFromString(XMLHttp.response,'text/xml');
+                    
+                    var parent = document.createElement("div");
+                    parent.appendChild(ajax.children[0]);
+                    var file = [parent.innerHTML];
+                    var bb = new Blob(file,{type : 'application/xml'});
+                    generateLink(bb,".xml");
+                }
+                XMLHttp.send();
+            }
+            
+            function getJSON()
+            {
+                var XMLHttp = new XMLHttpRequest();
+                XMLHttp.open("GET","comment_parser.php?format=JSON",true);
+                XMLHttp.onload = function() {
+                    // Now we have the XML data, extract
+                    var file = [XMLHttp.response];
+                    var bb = new Blob(file,{type : 'application/json'});
+                    generateLink(bb,".json");
+                }
+                XMLHttp.send();
+            }
+            
+            function getCSV()
+            {
+                var XMLHttp = new XMLHttpRequest();
+                XMLHttp.open("GET","comment_parser.php?format=CSV",true);
+                XMLHttp.onload = function() {
+                    // Now we have the XML data, extract
+                    var file = [XMLHttp.response];
+                    var bb = new Blob(file,{type : 'text/csv'});
+                    generateLink(bb,".csv");
+                }
+                XMLHttp.send();
+            }
+            
+            function generateLink(blobfile,fmt)
+            {
+                var dnlk = window.URL.createObjectURL(blobfile);
+                var a = document.createElement("a");
+                a.hidden = '';
+                a.href = dnlk;
+                a.download = "save"+fmt;
+                a.textContent = "Save File";
+                document.getElementById("download").appendChild(a);
+            }
+        </script>
+    </head>
+    <body>
+        <h1>WAET Test Results Analysis</h1>
+        <h2>Comment Extraction</h2>
+        <p>All of the XMLs in the server 'saves/' directory are automatically parsed and downloaded, extracting only the comments. Simply select the comments you wish to extract below and your desired data format.</p>
+        <div id="download"></div>
+        <div>
+            <button onclick="getXML();">XML</button>
+            <button onclick="getJSON();">JSON</button>
+            <button onclick="getCSV();">CSV</button>
+        </div>
+    </body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/comment_parser.php	Tue Mar 08 14:44:14 2016 +0000
@@ -0,0 +1,146 @@
+<?php
+// Comment Parser for PHP
+class audioElement {
+    function __construct($id) {
+        $this->id = $id;
+        $this->comments = array();
+    }
+    function addComment($str) {
+        array_push($this->comments,$str);
+    }
+}
+
+class testPage {
+    function __construct($id) {
+        $this->id = $id;
+        $this->elements = array();
+    }
+}
+// XML Saves location - assumes it will be saves/
+$saves = glob("../saves/*.xml");
+$comment_struct = array();
+if (is_array($saves))
+{
+    foreach($saves as $filename) {
+        $xml_string = file_get_contents($filename, FILE_TEXT);
+        $xml_object = simplexml_load_string($xml_string);
+        if ($xml_object == false) {
+            echo "<h1>FATAL</h1> <span>could not parse file ".$filename.": </span>";
+            foreach(libxml_get_errors() as $error) {
+                echo "<br>", $error->message;
+            }
+        } else {
+            // Iterate over each audioHolder node
+            foreach($xml_object->page as $pageInstance)
+            {
+                // Find the page in the comment_struct
+                $page_struct = null;
+                foreach($comment_struct as $comment_struct_page)
+                {
+                    if ($pageInstance['id'] == $comment_struct_page->id)
+                    {
+                        $page_struct = $comment_struct_page;
+                        break;
+                    }
+                }
+                if ($page_struct == null) {
+                    array_push($comment_struct,new testPage($pageInstance['id']));
+                    $page_struct = $comment_struct[count($comment_struct)-1];
+                }
+                // Get the audioelements of the page
+                foreach($pageInstance->audioelement as $fragment)
+                {
+                    // Find the page in the comment_struct
+                    $element_struct = null;
+                    foreach($page_struct->elements as $page_struct_element)
+                    {
+                        if ($fragment['id'] == $page_struct_element->id)
+                        {
+                            $element_struct = $page_struct_element;
+                            break;
+                        }
+                    }
+                    if ($element_struct == null) {
+                        array_push($page_struct->elements,new audioElement($fragment['id']));
+                        $element_struct = $page_struct->elements[count($page_struct->elements)-1];
+                    }
+                    $element_struct->addComment($fragment->comment->response);
+                }
+            }
+        }
+    }
+    // Now we have a sub <xml> containing all comment data
+    switch($_GET['format']) {
+        case "XML":
+            // Convert to an XML
+            $doc_struct = new SimpleXMLElement('<waetprocess/>');
+            foreach($comment_struct as $page_struct)
+            {
+                $doc_page = $doc_struct->addChild("page");
+                $doc_page->addAttribute("id",$page_struct->id);
+                foreach($page_struct->elements as $element_struct)
+                {
+                    $doc_element = $doc_page->addChild("audioelement");
+                    $doc_element->addAttribute("id",$element_struct->id);
+                    foreach($element_struct->comments as $comment)
+                    {
+                        $doc_comment = $doc_element->addChild("comment",$comment);
+                    }
+                }
+            }
+            echo $doc_struct->asXML();
+            break;
+        case "JSON":
+            // Convert to JSON
+            $doc_string = '{ "pages": [';
+            for($page_index = 0; $page_index < count($comment_struct); $page_index++ )
+            {
+                $page_struct = $comment_struct[$page_index];
+                $doc_page = '{"id": "'.$page_struct->id.'", "elements": [';
+                for($element_index = 0; $element_index < count($page_struct->elements); $element_index++ )
+                {
+                    $element_struct = $page_struct->elements[$element_index];
+                    $doc_element = '{"id": "'.$element_struct->id.'", "comments": [';
+                    for($comment_index = 0; $comment_index < count($element_struct->comments); $comment_index++ )
+                    {
+                        $doc_comment = '"'.$element_struct->comments[$comment_index].'"';
+                        if ($comment_index < count($element_struct->comments)-1) {
+                            $doc_comment = $doc_comment.',';
+                        }
+                        $doc_element = $doc_element.$doc_comment;
+                    }
+                    $doc_element = $doc_element.']}';
+                    if ($element_index < count($page_struct->elements)-1) {
+                        $doc_element = $doc_element.',';
+                    }
+                    $doc_page = $doc_page.$doc_element;
+                }
+                $doc_page = $doc_page.']}';
+                if ($page_index < count($comment_struct)-1) {
+                    $doc_page = $doc_page.',';
+                }
+                $doc_string = $doc_string.$doc_page;
+            }
+            $doc_string = $doc_string."]}";
+            echo $doc_string;
+            break;
+        case "CSV":
+            // Conver to CSV
+            // The CSV has three columns: page, element, comment
+            $doc_string = "page,element,comment"."\r\n";
+            foreach($comment_struct as $page_struct)
+            {
+                foreach($page_struct->elements as $element_struct)
+                {
+                    foreach($element_struct->comments as $comment)
+                    {
+                        $doc_string = $doc_string.$page_struct->id.",".$element_struct->id.",".$comment."\r\n";
+                    }
+                }
+            }
+            echo $doc_string;
+    }
+} else {
+    echo "FATAL - No saved XML files discovered";
+}
+?>
\ No newline at end of file
--- a/scripts/comment_parser.py	Wed Feb 24 14:00:10 2016 +0000
+++ b/scripts/comment_parser.py	Tue Mar 08 14:44:14 2016 +0000
@@ -41,11 +41,11 @@
         root = tree.getroot()
         
         # get list of all page names
-        for audioholder in root.findall("./audioholder"):   # iterate over pages
+        for audioholder in root.findall("./page"):   # iterate over pages
             page_name = audioholder.get('id')               # get page name
             
             if page_name is None: # ignore 'empty' audio_holders
-                print "WARNING: " + file + " contains empty audio holder. (comment_parser.py)"
+                print "WARNING: " + file + " contains empty page. (comment_parser.py)"
                 break
 
             # create folder [page_name] if not yet created
--- a/scripts/evaluation_stats.py	Wed Feb 24 14:00:10 2016 +0000
+++ b/scripts/evaluation_stats.py	Tue Mar 08 14:44:14 2016 +0000
@@ -55,7 +55,7 @@
         page_number = 0
         
         # get list of all page names
-        for audioholder in root.findall("./audioholder"):   # iterate over pages
+        for audioholder in root.findall("./page"):   # iterate over pages
             page_name = audioholder.get('id')               # get page name
             
             if page_name is None: # ignore 'empty' audio_holders
--- a/scripts/generate_report.py	Wed Feb 24 14:00:10 2016 +0000
+++ b/scripts/generate_report.py	Tue Mar 08 14:44:14 2016 +0000
@@ -150,7 +150,7 @@
         #TODO add plot of age
                 
         # get list of all page names
-        for audioholder in root.findall("./audioholder"):   # iterate over pages
+        for audioholder in root.findall("./page"):   # iterate over pages
             page_name = audioholder.get('id')               # get page name
             
             if page_name is None: # ignore 'empty' audio_holders
@@ -528,4 +528,4 @@
     os.remove(folder_name + 'Report.toc')
 except OSError:
     pass
-    
\ No newline at end of file
+    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/score_parser.php	Tue Mar 08 14:44:14 2016 +0000
@@ -0,0 +1,190 @@
+<?php
+// Value parser for WAET XML
+// testPage --> axis --> element --> value
+class nestedObject {
+    function __construct($id) {
+        $this->id = $id;
+        $this->nest = array();
+        $this->type = null;
+        $this->num = 0;
+    }
+    function addNewChild($id) {
+        if ($this->type == null) {
+            $this->type = "nest";
+        }
+        if ($this->type == "nest") {
+            $obj = new nestedObject($id);
+            array_push($this->nest,$obj);
+            $this->num = count($this->nest);
+            return $this->nest[$this->num-1];
+        }
+        return null;
+    }
+    function findChild($checkId) {
+        if ($this->type == "nest"){
+            foreach($this->nest as $child)
+            {
+                if (strcmp($checkId,$child->id) == 0) {
+                    return $child;
+                }
+            }
+        }
+        return null;
+    }
+    function addValue($val) {
+        if ($this->type == null) {
+            $this->type = "value";
+        }
+        if ($this->type == "value") {
+            array_push($this->nest,$val);
+            $this->num = count($this->nest);
+            return $this->nest[$this->num-1];
+        }
+        return null;
+    }
+}
+
+// Build the root nest object to hold the testPages
+$root = new nestedObject("root");
+
+// XML Saves location - assumes it will be saves/
+$saves = glob("../saves/*.xml");
+if (is_array($saves))
+{
+    foreach($saves as $filename) {
+        $xml_string = file_get_contents($filename, FILE_TEXT);
+        $xml_object = simplexml_load_string($xml_string);
+        if ($xml_object == false) {
+            echo "<h1>FATAL</h1> <span>could not parse file ".$filename.": </span>";
+            foreach(libxml_get_errors() as $error) {
+                echo "<br>", $error->message;
+            }
+        } else {
+            // Iterate over each $page node
+            foreach($xml_object->page as $pageInstance)
+            {
+                // Find in the nest
+                $pageInstanceId = $pageInstance['id'];
+                $page_nest = $root->findChild($pageInstanceId);
+                if ($page_nest == null) {
+                    $page_nest = $root->addNewChild($pageInstanceId);
+                }
+                
+                // Iterate over each $element node
+                foreach($pageInstance->audioelement as $element) {
+                    // Find our specific element tag
+                    $elementId = $element['id'];
+                    $element_nest = $page_nest->findChild($elementId);
+                    if ($element_nest == null) {
+                        $element_nest = $page_nest->addNewChild($elementId);
+                    }
+                    // Now get the <value> tags
+                    foreach($element->value as $value) {
+                        $axis_nest = null;
+                        $axisName = "default";
+                        if (isset($value['interface-name']))
+                        {
+                            // Find the axis nest
+                            $axisName = $value['interface-name'];
+                        }
+                        
+                        $axis_nest = $element_nest->findChild($axisName);
+                        if ($axis_nest == null) {
+                            $axis_nest = $element_nest->addNewChild($axisName);
+                        }
+                        // Now push our value
+                        $axis_nest->addValue($value);
+                    }
+                }
+            }
+        }
+    }
+    // We now have a structure in $root. EXPORT IT
+    switch($_GET['format']) {
+        case "XML":
+            // Convert to XML
+            $doc_root = new SimpleXMLElement('<waetprocess/>');
+            foreach($root->nest as $page) {
+                $doc_page = $doc_root->addChild("page");
+                $doc_page->addAttribute("id",$page->id);
+                foreach($page->nest as $element) {
+                    $doc_element = $doc_page->addChild("audioelement");
+                    $doc_element->addAttribute("id",$element->id);
+                    foreach($element->nest as $axis) {
+                        $doc_axis = $doc_element->addChild("interface");
+                        $doc_axis->addAttribute("name",$axis->id);
+                        foreach($axis->nest as $value) {
+                            $doc_axis->addChild("value",$value);
+                        }
+                    }
+                }
+            }
+            echo $doc_root->asXML();
+            break;
+        case "JSON":
+            // Convert to JSON
+            $doc_root = '{ "pages": [';
+            for ($pageIndex = 0; $pageIndex < $root->num; $pageIndex++)
+            {
+                $page = $root->nest[$pageIndex];
+                $doc_page = '{ "id": "'.$page->id.'", "elements": [';
+                for($elementIndex = 0; $elementIndex < $page->num; $elementIndex++)
+                {
+                    $element = $page->nest[$elementIndex];
+                    $doc_element = '{ "id": "'.$element->id.'", "axis": [';
+                    for($axisIndex = 0; $axisIndex < $element->num; $axisIndex++)
+                    {
+                        $axis = $element->nest[$axisIndex];
+                        $doc_axis = '{ "name": "'.$axis->id.'", "values": [';
+                        for ($valueIndex = 0; $valueIndex < $axis->num; $valueIndex++)
+                        {
+                            $doc_axis = $doc_axis."".strval($axis->nest[$valueIndex]);
+                            if ($valueIndex < $axis->num-1) {
+                                $doc_axis = $doc_axis.', ';
+                            }
+                        }
+                        $doc_axis = $doc_axis.']}';
+                        if ($axisIndex < $element->num-1) {
+                            $doc_axis = $doc_axis.', ';
+                        }
+                        $doc_element = $doc_element.$doc_axis;
+                    }
+                    $doc_element = $doc_element.']}';
+                    if ($elementIndex < $page->num-1) {
+                        $doc_element = $doc_element.', ';
+                    }
+                    $doc_page = $doc_page.$doc_element;
+                }
+                $doc_page = $doc_page.']}';
+                if ($pageIndex < $root->num-1) {
+                    $doc_page = $doc_page.', ';
+                }
+                $doc_root = $doc_root.$doc_page;
+            }
+            $doc_root = $doc_root.']}';
+            echo $doc_root;
+            break;
+        case "CSV":
+            // Convert to CSV
+            // CSV Columts: page, axis, element, value
+            $doc_string = "page,element,axis,value"."\r\n";
+            foreach($root->nest as $page){
+                foreach($page->nest as $element) {
+                    foreach($element->nest as $axis) {
+                        foreach($axis->nest as $value) {
+                            $doc_string = $doc_string.$page->id.',';
+                            $doc_string = $doc_string.$element->id.',';
+                            $doc_string = $doc_string.$axis->id.',';
+                            $doc_string = $doc_string.$value;
+                            $doc_string = $doc_string."\r\n";
+                        }
+                    }
+                }
+            }
+            echo $doc_string;
+    }
+} else {
+    echo "FATAL - No saved XML files discovered";
+}
+
+?>
\ No newline at end of file
--- a/scripts/score_parser.py	Wed Feb 24 14:00:10 2016 +0000
+++ b/scripts/score_parser.py	Tue Mar 08 14:44:14 2016 +0000
@@ -43,7 +43,7 @@
         subject_id = file_name[:-4] # file name (without extension) as subject ID
 
         # get list of all pages this subject evaluated
-        for audioholder in root.findall("./audioholder"):    # iterate over pages
+        for audioholder in root.findall("./page"):    # iterate over pages
             page_name = audioholder.get('id') # get page name
                        
             if page_name is None: # ignore 'empty' audio_holders
--- a/scripts/timeline_view_movement.py	Wed Feb 24 14:00:10 2016 +0000
+++ b/scripts/timeline_view_movement.py	Tue Mar 08 14:44:14 2016 +0000
@@ -67,7 +67,7 @@
         # ONE TIMELINE PER PAGE - make new plot per page
 
         # get list of all page names
-        for audioholder in root.findall("./audioholder"):   # iterate over pages
+        for audioholder in root.findall("./page"):   # iterate over pages
             page_name = audioholder.get('id')               # get page name
             plot_empty = True                               # check if any data is plotted
             
@@ -308,4 +308,4 @@
             
                 plt.savefig(timeline_folder+subject_id+"-"+page_name+".pdf", bbox_inches='tight')
                 plt.close()
-            
\ No newline at end of file
+            
--- a/test-schema.xsd	Wed Feb 24 14:00:10 2016 +0000
+++ b/test-schema.xsd	Tue Mar 08 14:44:14 2016 +0000
@@ -47,7 +47,7 @@
         <xs:element ref="survey" minOccurs="0" maxOccurs="2"/>
       </xs:sequence>
       <xs:attribute ref="id" use="required"/>
-      <xs:attribute name="hostURL" type="xs:anyURI"/>
+      <xs:attribute name="hostURL" type="xs:anyURI" default=""/>
       <xs:attribute name="randomiseOrder" type="xs:boolean" default="false"/>
       <xs:attribute name="repeatCount" type="xs:nonNegativeInteger" default="0"/>
       <xs:attribute name="loop" type="xs:boolean" default="false"/>
@@ -168,7 +168,7 @@
   <xs:element name="survey">
     <xs:complexType>
       <xs:sequence>
-        <xs:element name="surveyentry" maxOccurs="unbounded">
+        <xs:element name="surveyentry" minOccurs="0" maxOccurs="unbounded">
           <xs:complexType>
             <xs:sequence>
               <xs:element ref="statement" minOccurs="1" maxOccurs="1"/>
--- a/test_create/attributes.json	Wed Feb 24 14:00:10 2016 +0000
+++ b/test_create/attributes.json	Tue Mar 08 14:44:14 2016 +0000
@@ -6,7 +6,7 @@
     "projectReturn": "Results Return URL",
     "randomiseOrder": "Randomise Order",
     "testPages": "Test Pages",
-    "loudness": "Target Loudess (LUFS)",
+    "loudness": "Target Loudness (LUFS)",
     "sampleRate": "Required Sample Rate",
     "hostURL": "Element URL Prefix",
     "repeatCount": "Repeat Count",
@@ -20,4 +20,4 @@
     "gain": "Gain (dB)",
     "marker": "Marker",
     "boxsize": "Box Size"
-}
\ No newline at end of file
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test_create/custom.css	Tue Mar 08 14:44:14 2016 +0000
@@ -0,0 +1,23 @@
+
+div#content > div.node{
+    background-color: rgb(200,228,151);
+}
+
+div#content > div#setup{
+    background-color: coral;
+}
+
+input:disabled+span{
+    text-decoration: line-through;
+}
+
+div.attribute{
+    float: none;
+}
+div.attribute input{
+    max-width: 100%;
+    width: 300px;
+}
+div.attribute input[type=radio], div.attribute input[type=checkbox]{
+    width: 10px;
+}
\ No newline at end of file
--- a/test_create/style.css	Wed Feb 24 14:00:10 2016 +0000
+++ b/test_create/style.css	Tue Mar 08 14:44:14 2016 +0000
@@ -25,13 +25,20 @@
     font-size: 2em;
 }
 
-button#popup-proceed {
+button.popup-button {
     width: 60px;
     height: 27px;
     padding: 5px;
     position: absolute;
+    bottom: 10px;
+}
+
+button#popup-proceed {
     right: 10px;
-    bottom: 10px;
+}
+
+button#popup-back {
+    left: 10px;
 }
 
 div.drag-area {
@@ -70,6 +77,16 @@
     color: rgb(100,100,100);
 }
 
+
+div#content > div.node{
+    background-color: rgb(200,228,151);
+}
+
+div#content > div#setup{
+    background-color: coral;
+}
+
+
 div.node {
     float: left;
     padding: 10px;
@@ -87,7 +104,7 @@
 }
 div.node-attributes {
     min-width: 92%;
-    float: left;
+    float: none;
     padding: 10px;
 }
 div.attribute {
@@ -103,9 +120,16 @@
     min-width: 92%;
 }
 div.attribute input {
-    max-width: 100px;
+    max-width: 100%;
+    width: 300px;
     margin-right: 10px;
 }
 div.attribute input[type=number] {
     width: 80px;
+}
+div.attribute input[type=radio], div.attribute input[type=checkbox]{
+    width: 10px;
+}
+input:disabled+label{
+    text-decoration: line-through;
 }
\ No newline at end of file
--- a/test_create/test_core.js	Wed Feb 24 14:00:10 2016 +0000
+++ b/test_create/test_core.js	Tue Mar 08 14:44:14 2016 +0000
@@ -136,14 +136,30 @@
         
         this.proceedButton = document.createElement("button");
         this.proceedButton.id = "popup-proceed";
+        this.proceedButton.className = "popup-button";
         this.proceedButton.textContent = "Next";
         this.proceedButton.onclick = function()
         {
             popupObject.popupContent.innerHTML = null;
-            popupObject.shownObject.continue();
+            if(typeof popupObject.shownObject.continue == "function") {
+                popupObject.shownObject.continue();
+            } else {
+                popupObject.hide();
+            }
         };
         this.object.appendChild(this.proceedButton);
         
+        this.backButton = document.createElement("button");
+        this.backButton.id = "popup-back";
+        this.backButton.className = "popup-button";
+        this.backButton.textContent = "Back";
+        this.backButton.onclick = function()
+        {
+            popupObject.popupContent.innerHTML = null;
+            popupObject.shownObject.back();
+        };
+        this.object.appendChild(this.backButton);
+        
         this.shownObject;
 
         this.resize = function()
@@ -158,17 +174,22 @@
         {
             this.object.style.visibility = "visible";
             this.blanket.style.visibility = "visible";
+            if (typeof this.shownObject.back == "function") {
+                this.backButton.style.visibility = "visible";
+            } else {
+                this.backButton.style.visibility = "hidden";
+            }
         }
 
         this.hide = function()
         {
             this.object.style.visibility = "hidden";
             this.blanket.style.visibility = "hidden";
+            this.backButton.style.visibility = "hidden";
         }
 
         this.postNode = function(postObject)
         {
-            this.show();
             //Passed object must have the following:
             // Title: text to show in the title
             // Content: HTML DOM to show on the page
@@ -176,6 +197,17 @@
             this.titleDOM.textContent = postObject.title;
             this.popupContent.appendChild(postObject.content);
             this.shownObject = postObject;
+            if (typeof this.shownObject.back == "function") {
+                this.backButton.style.visibility = "visible";
+            } else {
+                this.backButton.style.visibility = "hidden";
+            }
+            if (typeof this.shownObject.continue == "function") {
+                this.proceedButton.textContent = "Next";
+            } else {
+                this.proceedButton.textContent = "Finish";
+            }
+            this.show();
         }
 
         this.resize();
@@ -259,9 +291,19 @@
             {
                 var testXML = interfaceSpecs.getElementsByTagName("tests")[0].getAllElementsByName(this.select.value)[0];
                 specification.interface = testXML.getAttribute("interface");
+                if (specification.interfaces == null)
+                {
+                    specification.interfaces = new specification.interfaceNode();
+                }
+                if (specification.metrics == null)  {
+                    specification.metrics = new specification.metricNode();
+                }
                 popupStateNodes.state[2].generate();
                 popupObject.postNode(popupStateNodes.state[2]);
             }
+            this.back = function() {
+                popupObject.postNode(popupStateNodes.state[0]);
+            }
         }
         this.state[2] = new function()
         {
@@ -277,8 +319,12 @@
             this.options = [];
             this.testXML = null;
             this.interfaceXML = null;
+            this.dynamicContent = document.createElement("div");
+            this.content.appendChild(this.dynamicContent);
             this.generate = function()
             {
+                this.options = [];
+                this.dynamicContent.innerHTML = null;
                 var interfaceName = popupStateNodes.state[1].select.value;
                 this.checkText = interfaceSpecs.getElementsByTagName("global")[0].getAllElementsByTagName("checks")[0];
                 this.testXML = interfaceSpecs.getElementsByTagName("tests")[0].getAllElementsByName(interfaceName)[0];
@@ -297,73 +343,94 @@
                     } else {
                         testNode = undefined;
                     }
-                    var optH = document.createElement('div');
-                    optH.className = "popup-checkbox";
-                    var checkbox = document.createElement('input');
-                    checkbox.type = "checkbox";
-                    var text = document.createElement('span');
-                    checkbox.setAttribute('name',checkName);
-                    if (interfaceNode.getAttribute('default') == 'on')
-                    {
-                        checkbox.checked = true;
+                    var obj = {
+                        root: document.createElement("div"),
+                        text: document.createElement("label"),
+                        input: document.createElement("input"),
+                        parent: this,
+                        name: checkName,
+                        handleEvent: function(event) {
+                            if (this.input.checked) {
+                                // Add to specification.interfaces.option
+                                var included = specification.interfaces.options.find(function(element,index,array){
+                                    if (element.name == this.name) {return true;} else {return false;}
+                                },this);
+                                if (included == null) {
+                                    specification.interfaces.options.push({type:"check",name:this.name});
+                                }
+                            } else {
+                                // Remove from specification.interfaces.option
+                                var position = specification.interfaces.options.findIndex(function(element,index,array){
+                                    if (element.name == this.name) {return true;} else {return false;}
+                                },this);
+                                if (position >= 0) {
+                                    specification.interfaces.options.splice(position,1);
+                                }
+                            }
+                        }
                     }
-                    if (interfaceNode.getAttribute('support') == "none")
-                    {
-                        checkbox.disabled = true;
-                        checkbox.checked = false;
-                        optH.className = "popup-checkbox disabled";
-                    } else if (interfaceNode.getAttribute('support') == "mandatory")
-                    {
-                        checkbox.disabled = true;
-                        checkbox.checked = true;
-                        optH.className = "popup-checkbox disabled";
-                    }
+                    
+                    obj.input.addEventListener("click",obj);
+                    obj.root.className = "popup-checkbox";
+                    obj.input.type = "checkbox";
+                    obj.input.setAttribute('id',checkName);
+                    obj.text.setAttribute("for",checkName);
+                    obj.text.textContent = this.checkText.getAllElementsByName(checkName)[0].textContent;
+                    obj.root.appendChild(obj.input);
+                    obj.root.appendChild(obj.text);
                     if(testNode != undefined)
                     {
-                        if (interfaceNode.getAttribute('default') == 'on')
+                        if (testNode.getAttribute('default') == 'on')
                         {
-                            checkbox.checked = true;
+                            obj.input.checked = true;
                         }
                         if (testNode.getAttribute('support') == "none")
                         {
-                            checkbox.disabled = true;
-                            checkbox.checked = false;
-                            optH.className = "popup-checkbox disabled";
+                            obj.input.disabled = true;
+                            obj.input.checked = false;
+                            obj.root.className = "popup-checkbox disabled";
                         }else if (interfaceNode.getAttribute('support') == "mandatory")
                         {
-                            checkbox.disabled = true;
-                            checkbox.checked = true;
-                            optH.className = "popup-checkbox disabled";
+                            obj.input.disabled = true;
+                            obj.input.checked = true;
+                            obj.root.className = "popup-checkbox disabled";
+                        }
+                    } else {
+                        if (interfaceNode.getAttribute('default') == 'on')
+                        {
+                            obj.input.checked = true;
+                        }
+                        if (interfaceNode.getAttribute('support') == "none")
+                        {
+                            obj.input.disabled = true;
+                            obj.input.checked = false;
+                            obj.root.className = "popup-checkbox disabled";
+                        } else if (interfaceNode.getAttribute('support') == "mandatory")
+                        {
+                            obj.input.disabled = true;
+                            obj.input.checked = true;
+                            obj.root.className = "popup-checkbox disabled";
                         }
                     }
-                    text.textContent = popupStateNodes.state[2].checkText.getAllElementsByName(checkName)[0].textContent;
-                    optH.appendChild(checkbox);
-                    optH.appendChild(text);
-                    this.options.push(optH);
-                    this.content.appendChild(optH);
+                    var included = specification.interfaces.options.find(function(element,index,array){
+                        if (element.name == this.name) {return true;} else {return false;}
+                    },obj);
+                    if (included != undefined) {
+                        obj.input.checked = true;
+                    }
+                    obj.handleEvent();
+                    this.options.push(obj);
+                    this.dynamicContent.appendChild(obj.root);
                 }
             }
             this.continue = function()
             {
-                if (specification.interfaces == null)
-                {
-                    specification.interfaces = new specification.interfaceNode();
-                }
-                for (var object of this.options)
-                {
-                    var checkbox = object.children[0];
-                    if (checkbox.checked)
-                    {
-                        var option = {
-                            type: "check",
-                            name: checkbox.getAttribute('name')
-                        };
-                        specification.interfaces.options.push(option);
-                    }
-                }
                 popupStateNodes.state[3].generate();
                 popupObject.postNode(popupStateNodes.state[3]);
             }
+            this.back = function() {
+                popupObject.postNode(popupStateNodes.state[1]);
+            }
         }
         this.state[3] = new function()
         {
@@ -379,8 +446,12 @@
             this.checkText;
             this.testXML;
             this.interfaceXML;
+            this.dynamicContent = document.createElement("div");
+            this.content.appendChild(this.dynamicContent);
             this.generate = function()
             {
+                this.options = [];
+                this.dynamicContent.innerHTML = null;
                 var interfaceName = popupStateNodes.state[1].select.value;
                 this.checkText = interfaceSpecs.getElementsByTagName("global")[0].getAllElementsByTagName("metrics")[0];
                 this.testXML = interfaceSpecs.getElementsByTagName("tests")[0].getAllElementsByName(interfaceName)[0];
@@ -399,68 +470,94 @@
                     } else {
                         testNode = undefined;
                     }
-                    var optH = document.createElement('div');
-                    optH.className = "popup-checkbox";
-                    var checkbox = document.createElement('input');
-                    checkbox.type = "checkbox";
-                    var text = document.createElement('span');
-                    checkbox.setAttribute('name',checkName);
-                    if (interfaceNode.getAttribute('default') == 'on')
-                    {
-                        checkbox.checked = true;
+                    var obj = {
+                        root: document.createElement("div"),
+                        text: document.createElement("label"),
+                        input: document.createElement("input"),
+                        parent: this,
+                        name: checkName,
+                        handleEvent: function(event) {
+                            if (this.input.checked) {
+                                // Add to specification.interfaces.option
+                                var included = specification.metrics.enabled.find(function(element,index,array){
+                                    if (element == this.name) {return true;} else {return false;}
+                                },this);
+                                if (included == null) {
+                                    specification.metrics.enabled.push(this.name);
+                                }
+                            } else {
+                                // Remove from specification.interfaces.option
+                                var position = specification.metrics.enabled.findIndex(function(element,index,array){
+                                    if (element == this.name) {return true;} else {return false;}
+                                },this);
+                                if (position >= 0) {
+                                    specification.metrics.enabled.splice(position,1);
+                                }
+                            }
+                        }
                     }
-                    if (interfaceNode.getAttribute('support') == "none")
-                    {
-                        checkbox.disabled = true;
-                        checkbox.checked = false;
-                        optH.className = "popup-checkbox disabled";
-                    } else if (interfaceNode.getAttribute('support') == "mandatory")
-                    {
-                        checkbox.disabled = true;
-                        checkbox.checked = true;
-                        optH.className = "popup-checkbox disabled";
-                    }
+                    
+                    obj.input.addEventListener("click",obj);
+                    obj.root.className = "popup-checkbox";
+                    obj.input.type = "checkbox";
+                    obj.input.setAttribute('id',checkName);
+                    obj.text.setAttribute("for",checkName);
+                    obj.text.textContent = this.checkText.getAllElementsByName(checkName)[0].textContent;
+                    obj.root.appendChild(obj.input);
+                    obj.root.appendChild(obj.text);
                     if(testNode != undefined)
                     {
-                        if (interfaceNode.getAttribute('default') == 'on')
+                        if (testNode.getAttribute('default') == 'on')
                         {
-                            checkbox.checked = true;
+                            obj.input.checked = true;
                         }
                         if (testNode.getAttribute('support') == "none")
                         {
-                            checkbox.disabled = true;
-                            checkbox.checked = false;
-                            optH.className = "popup-checkbox disabled";
+                            obj.input.disabled = true;
+                            obj.input.checked = false;
+                            obj.root.className = "popup-checkbox disabled";
                         }else if (interfaceNode.getAttribute('support') == "mandatory")
                         {
-                            checkbox.disabled = true;
-                            checkbox.checked = true;
-                            optH.className = "popup-checkbox disabled";
+                            obj.input.disabled = true;
+                            obj.input.checked = true;
+                            obj.root.className = "popup-checkbox disabled";
+                        }
+                    } else {
+                        if (interfaceNode.getAttribute('default') == 'on')
+                        {
+                            obj.input.checked = true;
+                        }
+                        if (interfaceNode.getAttribute('support') == "none")
+                        {
+                            obj.input.disabled = true;
+                            obj.input.checked = false;
+                            obj.root.className = "popup-checkbox disabled";
+                        } else if (interfaceNode.getAttribute('support') == "mandatory")
+                        {
+                            obj.input.disabled = true;
+                            obj.input.checked = true;
+                            obj.root.className = "popup-checkbox disabled";
                         }
                     }
-                    text.textContent = popupStateNodes.state[3].checkText.getAllElementsByName(checkName)[0].textContent;
-                    optH.appendChild(checkbox);
-                    optH.appendChild(text);
-                    this.options.push(optH);
-                    this.content.appendChild(optH);
+                    var included = specification.metrics.enabled.find(function(element,index,array){
+                        if (element == this.name) {return true;} else {return false;}
+                    },obj);
+                    obj.handleEvent();
+                    if (included != undefined) {
+                        obj.input.checked = true;
+                    }
+                    this.options.push(obj);
+                    this.dynamicContent.appendChild(obj.root);
                 }
             }
             this.continue = function()
             {
-                if (specification.metrics == null)  {
-                    specification.metrics = new specification.metricNode();
-                }
-                for (var object of this.options)
-                {
-                    var checkbox = object.children[0];
-                    if (checkbox.checked)
-                    {
-                        specification.metrics.enabled.push(checkbox.getAttribute('name'));
-                    }
-                }
                 popupStateNodes.state[4].generate();
                 popupObject.postNode(popupStateNodes.state[4]);
             }
+            this.back = function() {
+                popupObject.postNode(popupStateNodes.state[2]);
+            }
         }
         this.state[4] = new function()
         {
@@ -476,13 +573,17 @@
             this.checkText;
             this.testXML;
             this.interfaceXML;
+            this.dynamicContent = document.createElement("div");
+            this.content.appendChild(this.dynamicContent);
             this.generate = function()
             {
+                this.options = [];
+                this.dynamicContent.innerHTML = null;
                 var interfaceName = popupStateNodes.state[1].select.value;
                 this.checkText = interfaceSpecs.getElementsByTagName("global")[0].getAllElementsByTagName("show")[0];
                 this.testXML = interfaceSpecs.getElementsByTagName("tests")[0].getAllElementsByName(interfaceName)[0];
                 this.interfaceXML = interfaceSpecs.getAllElementsByTagName("interfaces")[0].getAllElementsByName(this.testXML.getAttribute("interface"))[0].getAllElementsByTagName("show")[0];
-                this.testXML = this.testXML.getAllElementsByTagName("metrics");
+                this.testXML = this.testXML.getAllElementsByTagName("show");
                 for (var i=0; i<this.interfaceXML.children.length; i++)
                 {
                     var interfaceNode = this.interfaceXML.children[i];
@@ -496,73 +597,94 @@
                     } else {
                         testNode = undefined;
                     }
-                    var optH = document.createElement('div');
-                    optH.className = "popup-checkbox";
-                    var checkbox = document.createElement('input');
-                    checkbox.type = "checkbox";
-                    var text = document.createElement('span');
-                    checkbox.setAttribute('name',checkName);
-                    if (interfaceNode.getAttribute('default') == 'on')
-                    {
-                        checkbox.checked = true;
+                    var obj = {
+                        root: document.createElement("div"),
+                        text: document.createElement("label"),
+                        input: document.createElement("input"),
+                        parent: this,
+                        name: checkName,
+                        handleEvent: function(event) {
+                            if (this.input.checked) {
+                                // Add to specification.interfaces.option
+                                var included = specification.interfaces.options.find(function(element,index,array){
+                                    if (element.name == this.name) {return true;} else {return false;}
+                                },this);
+                                if (included == null) {
+                                    specification.interfaces.options.push({type:"show",name:this.name});
+                                }
+                            } else {
+                                // Remove from specification.interfaces.option
+                                var position = specification.interfaces.options.findIndex(function(element,index,array){
+                                    if (element.name == this.name) {return true;} else {return false;}
+                                },this);
+                                if (position >= 0) {
+                                    specification.interfaces.options.splice(position,1);
+                                }
+                            }
+                        }
                     }
-                    if (interfaceNode.getAttribute('support') == "none")
-                    {
-                        checkbox.disabled = true;
-                        checkbox.checked = false;
-                        optH.className = "popup-checkbox disabled";
-                    } else if (interfaceNode.getAttribute('support') == "mandatory")
-                    {
-                        checkbox.disabled = true;
-                        checkbox.checked = true;
-                        optH.className = "popup-checkbox disabled";
-                    }
+                    
+                    obj.input.addEventListener("click",obj);
+                    obj.root.className = "popup-checkbox";
+                    obj.input.type = "checkbox";
+                    obj.input.setAttribute('id',checkName);
+                    obj.text.setAttribute("for",checkName);
+                    obj.text.textContent = this.checkText.getAllElementsByName(checkName)[0].textContent;
+                    obj.root.appendChild(obj.input);
+                    obj.root.appendChild(obj.text);
                     if(testNode != undefined)
                     {
-                        if (interfaceNode.getAttribute('default') == 'on')
+                        if (testNode.getAttribute('default') == 'on')
                         {
-                            checkbox.checked = true;
+                            obj.input.checked = true;
                         }
                         if (testNode.getAttribute('support') == "none")
                         {
-                            checkbox.disabled = true;
-                            checkbox.checked = false;
-                            optH.className = "popup-checkbox disabled";
+                            obj.input.disabled = true;
+                            obj.input.checked = false;
+                            obj.root.className = "popup-checkbox disabled";
                         }else if (interfaceNode.getAttribute('support') == "mandatory")
                         {
-                            checkbox.disabled = true;
-                            checkbox.checked = true;
-                            optH.className = "popup-checkbox disabled";
+                            obj.input.disabled = true;
+                            obj.input.checked = true;
+                            obj.root.className = "popup-checkbox disabled";
+                        }
+                    } else {
+                        if (interfaceNode.getAttribute('default') == 'on')
+                        {
+                            obj.input.checked = true;
+                        }
+                        if (interfaceNode.getAttribute('support') == "none")
+                        {
+                            obj.input.disabled = true;
+                            obj.input.checked = false;
+                            obj.root.className = "popup-checkbox disabled";
+                        } else if (interfaceNode.getAttribute('support') == "mandatory")
+                        {
+                            obj.input.disabled = true;
+                            obj.input.checked = true;
+                            obj.root.className = "popup-checkbox disabled";
                         }
                     }
-                    text.textContent = this.checkText.getAllElementsByName(checkName)[0].textContent;
-                    optH.appendChild(checkbox);
-                    optH.appendChild(text);
-                    this.options.push(optH);
-                    this.content.appendChild(optH);
+                    var included = specification.interfaces.options.find(function(element,index,array){
+                        if (element.name == this.name) {return true;} else {return false;}
+                    },obj);
+                    if (included != undefined) {
+                        obj.input.checked = true;
+                    }
+                    obj.handleEvent();
+                    this.options.push(obj);
+                    this.dynamicContent.appendChild(obj.root);
                 }
             }
             this.continue = function()
             {
-                if (specification.interfaces == null)
-                {
-                    specification.interfaces = new specification.interfaceNode();
-                }
-                for (var object of this.options)
-                {
-                    var checkbox = object.children[0];
-                    if (checkbox.checked)
-                    {
-                        var option = {
-                            type: "show",
-                            name: checkbox.getAttribute('name')
-                        };
-                        specification.interfaces.options.push(option);
-                    }
-                }
                 popupObject.hide();
                 convert.convert(document.getElementById('content'));
             }
+            this.back = function() {
+                popupObject.postNode(popupStateNodes.state[3]);
+            }
         }
         this.state[5] = new function() {
             this.title = "Add/Edit Survey Element";
@@ -860,6 +982,24 @@
                     this.preset.input.appendChild(selectOption);
                 }
                 
+                this.addMarker = {
+                    root: document.createElement("button"),
+                    parent: this,
+                    handleEvent: function() {
+                        var marker = {
+                            position: 0,
+                            text: "text"
+                        };
+                        this.parent.scaleRoot.scales.push(marker);
+                        var markerNode = new this.parent.buildMarkerNode(this.parent,marker);
+                        document.getElementById("popup-option-holder").appendChild(markerNode.root);
+                        this.parent.markerNodes.push(markerNode);
+                    }
+                };
+                this.addMarker.root.textContent = "Add Marker";
+                this.addMarker.root.addEventListener("click",this.addMarker);
+                this.content.appendChild(this.addMarker.root);
+                
                 // Create Marker List
                 this.buildMarkerList();
             }
@@ -869,49 +1009,65 @@
                 this.markerNodes = [];
                 for (var i=0; i<this.scaleRoot.scales.length; i++)
                 {
-                    var markerNode = {};
-                    markerNode.root = document.createElement("div");
-                    markerNode.root.className = "popup-option-entry";
-                    markerNode.positionInput = document.createElement("input");
-                    markerNode.positionInput.min = 0;
-                    markerNode.positionInput.max = 100;
-                    markerNode.positionInput.value = this.scaleRoot.scales[i].position;
-                    markerNode.positionInput.setAttribute("name","position");
-                    markerNode.textInput = document.createElement("input");
-                    markerNode.textInput.setAttribute("name","text");
-                    markerNode.textInput.value = this.scaleRoot.scales[i].text;
-                    markerNode.specification = this.scaleRoot.scales[i];
-                    markerNode.parent = this;
-                    markerNode.handleEvent = function(event) {
-                        switch(event.currentTarget.getAttribute("name"))
-                        {
-                            case "position":
-                                this.specification.position = Number(event.currentTarget.value);
-                                break;
-                            case "text":
-                                this.specification.text = event.currentTarget.value;
-                                break;
-                        }
-                    }
-                    markerNode.positionInput.addEventListener("change",markerNode,false);
-                    markerNode.textInput.addEventListener("change",markerNode,false);
-                    
-                    var posText = document.createElement("span");
-                    posText.textContent = "Position: ";
-                    var textText = document.createElement("span");
-                    textText.textContent = "Text: ";
-                    markerNode.root.appendChild(posText);
-                    markerNode.root.appendChild(markerNode.positionInput);
-                    markerNode.root.appendChild(textText);
-                    markerNode.root.appendChild(markerNode.textInput);
+                    var markerNode = new this.buildMarkerNode(this,this.scaleRoot.scales[i]);
                     markerInject.appendChild(markerNode.root);
                     this.markerNodes.push(markerNode);
                     
                 }
             }
-            this.continue = function()
-            {
-                popupObject.hide();
+            
+            this.buildMarkerNode = function(parent,specification) {
+                this.root = document.createElement("div");
+                this.root.className = "popup-option-entry";
+                this.positionInput = document.createElement("input");
+                this.positionInput.min = 0;
+                this.positionInput.max = 100;
+                this.positionInput.value = specification.position;
+                this.positionInput.setAttribute("name","position");
+                this.textInput = document.createElement("input");
+                this.textInput.setAttribute("name","text");
+                this.textInput.value = specification.text;
+                this.specification = specification;
+                this.parent = parent;
+                this.handleEvent = function(event) {
+                    switch(event.currentTarget.getAttribute("name"))
+                    {
+                        case "position":
+                            this.specification.position = Number(event.currentTarget.value);
+                            break;
+                        case "text":
+                            this.specification.text = event.currentTarget.value;
+                            break;
+                    }
+                }
+                this.positionInput.addEventListener("change",this,false);
+                this.textInput.addEventListener("change",this,false);
+
+                var posText = document.createElement("span");
+                posText.textContent = "Position: ";
+                var textText = document.createElement("span");
+                textText.textContent = "Text: ";
+                this.root.appendChild(posText);
+                this.root.appendChild(this.positionInput);
+                this.root.appendChild(textText);
+                this.root.appendChild(this.textInput);
+
+                this.deleteMarker = {
+                    root: document.createElement("button"),
+                    parent: this,
+                    handleEvent: function() {
+                        var index = this.parent.parent.scaleRoot.scales.findIndex(function(element,index,array){
+                            if (element == this) {return true;} else {return false;}
+                        },this.parent.specification)
+                        if (index >= 0) {
+                            this.parent.parent.scaleRoot.scales.splice(index,1);
+                        }
+                        document.getElementById("popup-option-holder").removeChild(this.parent.root);
+                    }
+                }
+                this.deleteMarker.root.addEventListener("click",this.deleteMarker);
+                this.deleteMarker.root.textContent = "Delete Marker"
+                this.root.appendChild(this.deleteMarker.root);
             }
         }
     }
@@ -1117,7 +1273,7 @@
         
         // First perform the setupNode;
         var setupSchema = specification.schema.getAllElementsByName('setup')[0];
-        this.setupDOM = new this.createGeneralNodeDOM('setup','setup',null);
+        this.setupDOM = new this.createGeneralNodeDOM('Global Configuration','setup',null);
         this.injectDOM.appendChild(this.setupDOM.rootDOM);
         var setupAttributes = setupSchema.getAllElementsByTagName('xs:attribute');
         for (var i=0; i<setupAttributes.length; i++)
@@ -1133,7 +1289,7 @@
         this.interfaceDOM.build("Interface","setup-interface",this.setupDOM.rootDOM);
         
         // Now build the Metrics selection node
-        var metric = this.createGeneralNodeDOM("metrics","setup-metric",this.setupDOM);
+        var metric = this.createGeneralNodeDOM("Session Metrics","setup-metric",this.setupDOM);
         metric.rootDOM.removeChild(metric.attributeDOM);
         this.setupDOM.children.push(metric);
         this.setupDOM.childrenDOM.appendChild(metric.rootDOM);
@@ -1182,9 +1338,9 @@
             obj.text.textContent = checkText.children[i].textContent;
             metric.children.push(obj);
             metric.childrenDOM.appendChild(obj.root);
-            for (var i=0; i<specification.metrics.enabled.length; i++)
+            for (var j=0; j<specification.metrics.enabled.length; j++)
             {
-                if (specification.metrics.enabled[i] == obj.name)
+                if (specification.metrics.enabled[j] == obj.name)
                 {
                     obj.input.checked = true;
                     break;
@@ -1872,6 +2028,9 @@
         }
         
         // Build the components
+        if (this.specification.interfaces.length == 0) {
+            this.specification.interfaces.push(new specification.interfaceNode());
+        }
         for (var interfaceObj of this.specification.interfaces)
         {
             var newInterface = new this.parent.interfaceNode(this.parent,interfaceObj);
--- a/test_create/test_create.html	Wed Feb 24 14:00:10 2016 +0000
+++ b/test_create/test_create.html	Tue Mar 08 14:44:14 2016 +0000
@@ -2,7 +2,9 @@
 <head>
     <!-- This defines the test creator tool for the Web Audio Evaluation Toolbox -->
     <link rel='stylesheet' type="text/css" href="style.css"/>
+    <link rel='stylesheet' type="text/css" href="custom.css"/>
     <script type="text/javascript">
+        window.onbeforeunload = function (e) {var message = 'If you leave the page now, any unsaved changes will be lost', e = e || window.event; if (e) { e.returnValue = message;}return message;};
         // Copy of Specifiation node from Core.js
         function Specification() {
             // Handles the decoding of the project specification XML into a simple JavaScript Object.
@@ -228,7 +230,7 @@
 
                     this.exportXML = function(doc)
                     {
-                        var node = doc.createElement('surveyelement');
+                        var node = doc.createElement('surveyentry');
                         node.setAttribute('type',this.type);
                         var statement = doc.createElement('statement');
                         statement.textContent = this.statement;
@@ -239,15 +241,14 @@
                             break;
                         case "question":
                             node.id = this.id;
-                            node.setAttribute("mandatory",this.mandatory);
-                            node.setAttribute("boxsize",this.boxsize);
+                            if (this.mandatory != undefined) { node.setAttribute("mandatory",this.mandatory);}
+                            if (this.boxsize != undefined) {node.setAttribute("boxsize",this.boxsize);}
                             break;
                         case "number":
                             node.id = this.id;
-                            node.setAttribute("mandatory",this.mandatory);
-                            node.setAttribute("min", this.min);
-                            node.setAttribute("max", this.max);
-                            node.setAttribute("step", this.step);
+                            if (this.mandatory != undefined) { node.setAttribute("mandatory",this.mandatory);}
+                            if (this.min != undefined) {node.setAttribute("min", this.min);}
+                            if (this.max != undefined) {node.setAttribute("max", this.max);}
                             break;
                         case "checkbox":
                         case "radio":
@@ -572,9 +573,9 @@
                     this.id = null;
                     this.parent = null;
                     this.type = null;
-                    this.marker = false;
+                    this.marker = null;
                     this.enforce = false;
-                    this.gain = 1.0;
+                    this.gain = 0.0;
                     this.schema = specification.schema.getAllElementsByName('audioelement')[0];;
                     this.parent = null;
                     this.decode = function(parent,xml)
@@ -632,4 +633,4 @@
     <div id="blanket"></div>
     <div id="content"></div>
 </body>
-</html>
\ No newline at end of file
+</html>