# HG changeset patch # User www-data # Date 1463412059 -3600 # Node ID 95dc0833eb0a834f8cdec47e370eccd7aed8fc35 # Parent 1ab42e36b6c8e4ee9a72fae8be6ccf6e9e6cd0d9# Parent a3099bdb056c40e9a5d8e014389f95b61c7192d7 Merge branch 'master' of https://github.com/BrechtDeMan/WebAudioEvaluationTool diff -r 1ab42e36b6c8 -r 95dc0833eb0a css/core.css --- a/css/core.css Mon May 16 14:20:50 2016 +0100 +++ b/css/core.css Mon May 16 16:20:59 2016 +0100 @@ -133,6 +133,46 @@ top: 0px; } +div#lightbox-root { + visibility: hidden; + z-index: 20; + top: 25px; + min-height: 50px; + max-height: 250px; +} + +div.lightbox-error { + margin: 25px; + margin-bottom: 50px; + padding: 5px; + border-radius: 5px; + background-color: rgb(255,220,220); + border: 2px rgb(200,0,0) solid; +} + +div.lightbox-warning { + margin: 25px; + margin-bottom: 50px; + padding: 5px; + border-radius: 5px; + background-color: rgb(255,255,220); + border: 2px rgb(255,250,0) solid; +} + +div.lightbox-message { + margin: 25px; + margin-bottom: 50px; + padding: 5px; + border-radius: 5px; + background-color: rgb(200,220,255); + border: 2px rgb(50,100,250) solid; +} + +div#lightbox-blanker { + visibility: hidden; + z-index: 19; +} + button.outside-reference { width:120px; height:20px; @@ -169,12 +209,25 @@ background-color: #000; } -div#master-volume-holder { - width: 250px; - float: left; +div.master-volume-holder-inline { + width: 100%; + padding: 5px; +} + +div.master-volume-holder-float { + position: absolute; + top: 20px; + left: 50px; + width: 250px%; + padding: 5px; +} + +div#master-volume-root { + margin:auto; border: black 1px solid; border-radius: 5px; - padding: 5px; + width: 250px; + height: 40px; } input#master-volume-control { diff -r 1ab42e36b6c8 -r 95dc0833eb0a interfaces/AB.js --- a/interfaces/AB.js Mon May 16 14:20:50 2016 +0100 +++ b/interfaces/AB.js Mon May 16 16:20:59 2016 +0100 @@ -9,6 +9,30 @@ // Custom comparator Object Interface.prototype.comparator = null; + + Interface.prototype.checkScaleRange = function(min, max) { + var page = testState.getCurrentTestPage(); + var audioObjects = audioEngineContext.audioObjects; + var state = true; + var str = "Please keep listening. "; + var minRanking = Infinity; + var maxRanking = -Infinity; + for (var ao of audioObjects) { + var rank = ao.interfaceDOM.getValue(); + if (rank < minRanking) {minRanking = rank;} + if (rank > maxRanking) {maxRanking = rank;} + } + if (maxRanking*100 < max) { + str += "At least one fragment must be selected." + state = false; + } + if (!state) { + console.log(str); + this.storeErrorNode(str); + interfaceContext.lightbox.post("Message",str); + } + return state; + } // The injection point into the HTML page interfaceContext.insertPoint = document.getElementById("topLevelBody"); @@ -163,6 +187,11 @@ interfaceContext.commentBoxes.showCommentBoxes(commentHolder,true); } resizeWindow(null); + + $(audioHolderObject.commentQuestions).each(function(index,element) { + var node = interfaceContext.createCommentQuestion(element); + commentHolder.appendChild(node.holder); + }); } function comparator(audioHolderObject) @@ -198,7 +227,7 @@ } if (audioEngineContext.status == 0) { - alert("Please listen to the samples before making a selection"); + interfaceContext.lightbox.post("Message","Please listen to the samples before making a selection"); console.log("Please listen to the samples before making a selection"); return; } @@ -411,7 +440,7 @@ { if (audioEngineContext.timer.testStarted == false) { - alert('You have not started the test! Please press start to begin the test!'); + interfaceContext.lightbox.post("Warning",'You have not started the test! Please click play on a sample to begin the test!'); return; } } diff -r 1ab42e36b6c8 -r 95dc0833eb0a interfaces/ABX.js --- a/interfaces/ABX.js Mon May 16 14:20:50 2016 +0100 +++ b/interfaces/ABX.js Mon May 16 16:20:59 2016 +0100 @@ -12,6 +12,30 @@ interfaceContext.insertPoint.innerHTML = null; // Clear the current schema + Interface.prototype.checkScaleRange = function(min, max) { + var page = testState.getCurrentTestPage(); + var audioObjects = audioEngineContext.audioObjects; + var state = true; + var str = "Please keep listening. "; + var minRanking = Infinity; + var maxRanking = -Infinity; + for (var ao of audioObjects) { + var rank = ao.interfaceDOM.getValue(); + if (rank < minRanking) {minRanking = rank;} + if (rank > maxRanking) {maxRanking = rank;} + } + if (maxRanking*100 < max) { + str += "At least one fragment must be selected." + state = false; + } + if (!state) { + console.log(str); + this.storeErrorNode(str); + interfaceContext.lightbox.post("Message",str); + } + return state; + } + // Custom comparator Object Interface.prototype.comparator = null; @@ -198,7 +222,7 @@ } if (audioEngineContext.status == 0) { - alert("Please listen to the samples before making a selection"); + interfaceContext.lightbox.post("Message", "Please listen to the samples before making a selection"); console.log("Please listen to the samples before making a selection"); return; } @@ -453,7 +477,7 @@ { if (audioEngineContext.timer.testStarted == false) { - alert('You have not started the test! Please press start to begin the test!'); + interfaceContext.lightbox.post("Warning",'You have not started the test! Please listen to a sample to begin the test!'); return; } } diff -r 1ab42e36b6c8 -r 95dc0833eb0a interfaces/ape.js --- a/interfaces/ape.js Mon May 16 14:20:50 2016 +0100 +++ b/interfaces/ape.js Mon May 16 16:20:59 2016 +0100 @@ -41,7 +41,7 @@ str = 'You have not played fragment ' + (audioEngineContext.audioObjects[hasBeenPlayed[0]].interfaceDOM.getPresentedId()) + ' yet. Please listen, rate and comment all samples before submitting.'; } this.storeErrorNode(str); - alert(str); + interfaceContext.lightbox.post("Message",str); return false; } return true; @@ -87,7 +87,7 @@ if (state != true) { this.storeErrorNode(str); - alert(str); + interfaceContext.lightbox.post("Message",str); console.log(str); } return state; @@ -124,7 +124,7 @@ str = 'You have not commented on fragment ' + (audioEngineContext.audioObjects[strNums[0]].interfaceDOM.getPresentedId()) + ' yet. Please listen, rate and comment all samples before submitting.'; } this.storeErrorNode(str); - alert(str); + interfaceContext.lightbox.post("Message",str); console.log(str); } } @@ -172,7 +172,7 @@ if (state != true) { this.storeErrorNode(str); - alert(str); + interfaceContext.lightbox.post("Message",str); console.log(str); } return state; @@ -811,7 +811,7 @@ { if (audioEngineContext.timer.testStarted == false) { - alert('You have not started the test! Please click a fragment to begin the test!'); + interfaceContext.lightbox.post("Warning",'You have not started the test! Please click a fragment to begin the test!'); return; } } diff -r 1ab42e36b6c8 -r 95dc0833eb0a interfaces/discrete.js --- a/interfaces/discrete.js Mon May 16 14:20:50 2016 +0100 +++ b/interfaces/discrete.js Mon May 16 16:20:59 2016 +0100 @@ -515,7 +515,7 @@ { if (audioEngineContext.timer.testStarted == false) { - alert('You have not started the test! Please press start to begin the test!'); + interfaceContext.lightbox.post("Warning",'You have not started the test! Please press start to begin the test!'); return; } } diff -r 1ab42e36b6c8 -r 95dc0833eb0a interfaces/horizontal-sliders.js --- a/interfaces/horizontal-sliders.js Mon May 16 14:20:50 2016 +0100 +++ b/interfaces/horizontal-sliders.js Mon May 16 16:20:59 2016 +0100 @@ -468,7 +468,7 @@ { if (audioEngineContext.timer.testStarted == false) { - alert('You have not started the test! Please press start to begin the test!'); + interfaceContext.lightbox.post("Warning",'You have not started the test! Please press start to begin the test!'); return; } } diff -r 1ab42e36b6c8 -r 95dc0833eb0a interfaces/mushra.js --- a/interfaces/mushra.js Mon May 16 14:20:50 2016 +0100 +++ b/interfaces/mushra.js Mon May 16 16:20:59 2016 +0100 @@ -492,7 +492,7 @@ { if (audioEngineContext.timer.testStarted == false) { - alert('You have not started the test! Please press start to begin the test!'); + interfaceContext.lightbox.post("Message",'You have not started the test! Please press start to begin the test!'); return; } } diff -r 1ab42e36b6c8 -r 95dc0833eb0a js/core.js --- a/js/core.js Mon May 16 14:20:50 2016 +0100 +++ b/js/core.js Mon May 16 16:20:59 2016 +0100 @@ -171,6 +171,7 @@ return "Please only leave this page once you have completed the tests. Are you sure you have completed all testing?"; }; } + interfaceContext.lightbox.resize(); }; function loadProjectSpec(url) { @@ -321,7 +322,7 @@ if (specification.sampleRate != undefined) { if (Number(specification.sampleRate) != audioContext.sampleRate) { var errStr = 'Sample rates do not match! Requested '+Number(specification.sampleRate)+', got '+audioContext.sampleRate+'. Please set the sample rate to match before completing this test.'; - alert(errStr); + interfaceContext.lightbox.post("Error",errStr); return; } } @@ -834,7 +835,7 @@ // Must extract the question data var textArea = $(popup.popupContent).find('textarea')[0]; if (node.specification.mandatory == true && textArea.value.length == 0) { - alert('This question is mandatory'); + interfaceContext.lightbox.post("Error","This Question is mandatory"); return; } else { // Save the text content @@ -866,7 +867,7 @@ { if (node.specification.mandatory == true) { - alert("This radio is mandatory"); + interfaceContext.lightbox.post("Error","Please select one option"); return; } break; @@ -880,20 +881,20 @@ } else if (node.specification.type == "number") { var input = this.popupContent.getElementsByTagName('input')[0]; if (node.mandatory == true && input.value.length == 0) { - alert('This question is mandatory. Please enter a number'); + interfaceContext.lightbox.post("Error",'This question is mandatory. Please enter a number'); return; } var enteredNumber = Number(input.value); if (isNaN(enteredNumber)) { - alert('Please enter a valid number'); + interfaceContext.lightbox.post("Error",'Please enter a valid number'); return; } if (enteredNumber < node.min && node.min != null) { - alert('Number is below the minimum value of '+node.min); + interfaceContext.lightbox.post("Error",'Number is below the minimum value of '+node.min); return; } if (enteredNumber > node.max && node.max != null) { - alert('Number is above the maximum value of '+node.max); + interfaceContext.lightbox.post("Error",'Number is above the maximum value of '+node.max); return; } node.response = input.value; @@ -1044,7 +1045,9 @@ if (this.stateIndex == null) { this.initialise(); } - storage.update(); + if (this.stateIndex > -2) { + storage.update(); + } if (this.stateIndex == -2) { this.stateIndex++; if (this.preTestSurvey != null) @@ -1202,6 +1205,8 @@ this.metric = new sessionMetrics(this,specification); this.loopPlayback = false; + this.synchPlayback = false; + this.pageSpecification = null; this.pageStore = null; @@ -1409,7 +1414,8 @@ } else { interfaceContext.playhead.setTimePerPixel(this.audioObjects[id]); } - if (this.loopPlayback) { + if (this.synchPlayback && this.loopPlayback) { + // Traditional looped playback var setTime = audioContext.currentTime+specification.crossFade; for (var i=0; i (ao.specification.marker/100) && ao.specification.marker > 0) { // Anchor is not set below console.log('Anchor node not below marker value'); - alert('Please keep listening'); + interfaceContext.lightbox.post("Message",'Please keep listening'); this.storeErrorNode('Anchor node not below marker value'); return false; } @@ -2742,7 +2819,7 @@ // Anchor is not set below console.log('Reference node not above marker value'); this.storeErrorNode('Reference node not above marker value'); - alert('Please keep listening'); + interfaceContext.lightbox.post("Message",'Please keep listening'); return false; } } @@ -2800,7 +2877,7 @@ str_start += ". Please keep listening"; console.log("[ALERT]: "+str_start); this.storeErrorNode("[ALERT]: "+str_start); - alert(str_start); + interfaceContext.lightbox.post("Error",str_start); } }; this.checkAllMoved = function() @@ -2829,7 +2906,7 @@ str += 'and '+failed[i]; } str +='.'; - alert(str); + interfaceContext.lightbox.post("Error",str); console.log(str); this.storeErrorNode(str); return false; @@ -2860,7 +2937,7 @@ str += 'and '+failed[i]; } str +='.'; - alert(str); + interfaceContext.lightbox.post("Error",str); console.log(str); this.storeErrorNode(str); return false; @@ -2872,8 +2949,6 @@ var str = "Please keep listening. "; var minRanking = Infinity; var maxRanking = -Infinity; - var interface = page.specification.interface; - var isAb = interface === "AB" || interface === "ABX"; for (var ao of audioObjects) { var rank = ao.interfaceDOM.getValue(); if (rank < minRanking) {minRanking = rank;} @@ -2883,21 +2958,18 @@ str += "At least one fragment must be below the "+min+" mark."; state = false; } - if (maxRanking*100 < max) { - if(isAb){ // if it is AB or ABX let's phrase it differently - str += "You must select a fragment before continuing"; - } else{ - str += "At least one fragment must be above the "+max+" mark." - } + if (maxRanking*100 < max) { + str += "At least one fragment must be above the "+max+" mark." state = false; } if (!state) { console.log(str); this.storeErrorNode(str); - alert(str); + interfaceContext.lightbox.post("Error",str); } return state; } + this.storeErrorNode = function(errorMessage) { var time = audioEngineContext.timer.getTestTime(); @@ -2973,6 +3045,10 @@ this.request.send(); }, update: function() { + if (this.key == null) { + console.log("Cannot save as key == null"); + return; + } this.parent.root.setAttribute("state","update"); var xmlhttp = new XMLHttpRequest(); var returnURL = ""; diff -r 1ab42e36b6c8 -r 95dc0833eb0a test_create/interface-specs.xml --- a/test_create/interface-specs.xml Mon May 16 14:20:50 2016 +0100 +++ b/test_create/interface-specs.xml Mon May 16 16:20:59 2016 +0100 @@ -262,12 +262,35 @@ - - - - - + + + Audio Perceptual Evaluation. A multi-stimulus test where each audio fragment is shown on one continuous slider. Fragments are randomnly positioned along the slider. The user clicks a fragment to play and drags to move. + + + + + Each element is given its own vertical slider with user defined scale markers. + + + + + Each element is given its own horizontal slider with user defined scale markers. + + + + + Each element is given a horizontal scale broken into a number of discrete choices. The number of choices is defined by the scale markers. + + + + + An N-way comparison test. Each element is given its own selector box. The user can select one element per page for submission. + + + + Multi-stimulus with hidden reference and anchor. Each fragment is shown on its own vertical slider. One fragment must be labelled as a reference and another labelled as an anchor. One external reference must also be shown. + @@ -289,6 +312,9 @@ + + Each stimulus is placed on a discrete scale equalling the number of fragments. The fragments are then ranked based on the question posed. Only one element can occupy a rank position + @@ -303,6 +329,9 @@ + + Each stimulus is placed on a discrete scale. The scale is fixed to the Likert scale options of 'Strongly Disagree', 'Disagree', 'Neutral', 'Agree' and 'Strongly Agree' + @@ -317,6 +346,9 @@ + + Each stimulus is placed on a vertical slider. The scale is fixed with the labels 'Imperceptible' to 'Very Annoying' + @@ -332,6 +364,9 @@ + + Each stimulus is placed on a horizontal slider and initialised to the value '0'. The scale operates from -50 to +5-. In the results this is normalised, like all other interfaces, from 0 (-50) to 1 (+50). + @@ -350,7 +385,11 @@ + + Absolute Category Rating. Each element is on a discrete scale of 'Bad', 'Poor', 'Fair', 'Good' and 'Excellent'. Each element must be given a rating. + + @@ -428,6 +467,9 @@ + + Each page has only two audio fragments. The user must select one of the two fragments to proceed. There can be one hidden reference. + @@ -441,7 +483,7 @@ - + diff -r 1ab42e36b6c8 -r 95dc0833eb0a test_create/test_core.js --- a/test_create/test_core.js Mon May 16 14:20:50 2016 +0100 +++ b/test_create/test_core.js Mon May 16 16:20:59 2016 +0100 @@ -5,6 +5,7 @@ var specification; var convert; var attributeText; +var page_lang = "en"; // Firefox does not have an XMLDocument.prototype.getElementsByName // and there is no searchAll style command, this custom function will @@ -278,6 +279,9 @@ spnH.appendChild(span); this.content.appendChild(spnH); this.select = document.createElement("select"); + this.content.appendChild(this.select); + this.description = document.createElement("p"); + this.content.appendChild(this.description); this.testsXML = interfaceSpecs.getElementsByTagName('tests')[0].children; for (var i=0; i