Mercurial > hg > webaudioevaluationtool
changeset 964:9c09cb530ec1
Major Update. All new state machine to track the session state and hold session data. Will enable new interfaces to be built on top and have the same common structures.
author | Nicholas Jillings <nicholas.jillings@eecs.qmul.ac.uk> |
---|---|
date | Wed, 27 May 2015 16:45:48 +0100 |
parents | ba734075da2d |
children | 2dc61bd6494e |
files | ape.js core.js example_eval/project.xml |
diffstat | 3 files changed, 164 insertions(+), 100 deletions(-) [+] |
line wrap: on
line diff
--- a/ape.js Wed May 27 11:49:20 2015 +0100 +++ b/ape.js Wed May 27 16:45:48 2015 +0100 @@ -30,12 +30,25 @@ var xmlSetup = xmlDoc.find('setup'); // Should put in an error function here incase of malprocessed or malformed XML + // Create pre and post test questions + + var preTest = xmlSetup.find('PreTest'); + var postTest = xmlSetup.find('PostTest'); + preTest = preTest[0]; + postTest = postTest[0]; + + if (preTest == undefined) {preTest = document.createElement("preTest");} + if (postTest == undefined){postTest= document.createElement("postTest");} + + testState.stateMap.push(preTest); + // Extract the different test XML DOM trees var audioHolders = xmlDoc.find('audioHolder'); + var testXMLSetups = []; audioHolders.each(function(index,element) { var repeatN = element.attributes['repeatCount'].value; for (var r=0; r<=repeatN; r++) { - testXMLSetups[testXMLSetups.length] = element; + testXMLSetups.push(element); } }); @@ -55,6 +68,12 @@ { testXMLSetups = randomiseOrder(testXMLSetups); } + + $(testXMLSetups).each(function(index,elem){ + testState.stateMap.push(elem); + }) + + testState.stateMap.push(postTest); // Obtain the metrics enabled var metricNode = xmlSetup.find('Metric'); @@ -232,23 +251,8 @@ testContent.style.zIndex = 1; insertPoint.innerHTML = null; // Clear the current schema - // Create pre and post test questions - - var preTest = xmlSetup.find('PreTest'); - var postTest = xmlSetup.find('PostTest'); - preTest = preTest[0]; - postTest = postTest[0]; - currentState = 'preTest'; - // Create Pre-Test Box - if (preTest != undefined && preTest.childElementCount >= 1) - { - //popup.showPopup(); - //preTestPopupStart(preTest); - popup.initState(preTest); - } - // Inject into HTML testContent.appendChild(title); // Insert the title testContent.appendChild(pagetitle); @@ -258,17 +262,17 @@ insertPoint.appendChild(testContent); // Load the full interface - + testState.initialise(); + testState.advanceState(); } -function loadTest(id) +function loadTest(textXML) { // Reset audioEngineContext.Metric globals for new test audioEngineContext.newTestPage(); - // Used to load a specific test page - var textXML = testXMLSetups[id]; + var id = textXML.id; var feedbackHolder = document.getElementById('feedbackHolder'); var canvas = document.getElementById('slider'); @@ -483,19 +487,6 @@ trackComment.appendChild(trackCommentBox); feedbackHolder.appendChild(trackComment); }); - - // Now process any pre-test commands - - var preTest = $(testXMLSetups[id]).find('PreTest')[0]; - if (preTest.childElementCount > 0) - { - currentState = 'testRunPre-'+id; - //preTestPopupStart(preTest); - popup.initState(preTest); - //popup.showPopup(); - } else { - currentState = 'testRun-'+id; - } } @@ -534,12 +525,7 @@ return; } } - if (currentState.substr(0,7) == 'testRun') - { - hasBeenPlayed = []; // clear array to prepare for next test - audioEngineContext.timer.stopTest(); - advanceState(); - } + testState.advanceState(); } else // if a fragment has not been played yet { str = ""; @@ -605,13 +591,13 @@ }); } -function pageXMLSave(testId) +function pageXMLSave(store, testXML, testId) { // Saves a specific test page - var xmlDoc = currentTestHolder; + var xmlDoc = store; // Check if any session wide metrics are enabled - var commentShow = testXMLSetups[testId].attributes['elementComments']; + var commentShow = testXML.attributes['elementComments']; if (commentShow != undefined) { if (commentShow.value == 'false') {commentShow = false;} else {commentShow = true;} @@ -716,21 +702,5 @@ cqHolder.appendChild(comment); xmlDoc.appendChild(cqHolder); } - testResultsHolders[testId] = xmlDoc; -} - -// Only other global function which must be defined in the interface class. Determines how to create the XML document. -function interfaceXMLSave(){ - // Create the XML string to be exported with results - var xmlDoc = document.createElement("BrowserEvaluationResult"); - xmlDoc.appendChild(returnDateNode()); - for (var i=0; i<testResultsHolders.length; i++) - { - xmlDoc.appendChild(testResultsHolders[i]); - } - // Append Pre/Post Questions - xmlDoc.appendChild(preTestQuestions); - xmlDoc.appendChild(postTestQuestions); - - return xmlDoc; + store = xmlDoc; } \ No newline at end of file
--- a/core.js Wed May 27 11:49:20 2015 +0100 +++ b/core.js Wed May 27 16:45:48 2015 +0100 @@ -9,15 +9,16 @@ var audioContext; // Hold the browser web audio API var projectXML; // Hold the parsed setup XML var popup; // Hold the interfacePopup object +var testState; var currentState; // Keep track of the current state (pre/post test, which test, final test? first test?) -var testXMLSetups = []; // Hold the parsed test instances -var testResultsHolders =[]; // Hold the results from each test for publishing to XML +//var testXMLSetups = []; // Hold the parsed test instances +//var testResultsHolders =[]; // Hold the results from each test for publishing to XML var currentTrackOrder = []; // Hold the current XML tracks in their (randomised) order -var currentTestHolder; // Hold any intermediate results during test - metrics +//var currentTestHolder; // Hold any intermediate results during test - metrics var audioEngineContext; // The custome AudioEngine object var projectReturn; // Hold the URL for the return -var preTestQuestions = document.createElement('PreTest'); // Store any pre-test question response -var postTestQuestions = document.createElement('PostTest'); // Store any post-test question response +//var preTestQuestions = document.createElement('PreTest'); // Store any pre-test question response +//var postTestQuestions = document.createElement('PostTest'); // Store any post-test question response // Add a prototype to the bufferSourceNode to reference to the audioObject holding it AudioBufferSourceNode.prototype.owner = undefined; @@ -31,6 +32,9 @@ var AudioContext = window.AudioContext || window.webkitAudioContext; audioContext = new AudioContext; + // Create test state + testState = new stateMachine(); + // Create the audio engine object audioEngineContext = new AudioEngine(); @@ -163,6 +167,11 @@ } else { // Reached the end of the popupOptions this.hidePopup(); + if (this.responses.nodeName == testState.stateResults[testState.stateIndex].nodeName) { + testState.stateResults[testState.stateIndex] = this.responses; + } else { + testState.stateResults[testState.stateIndex].appendChild(this.responses); + } advanceState(); } } @@ -170,44 +179,114 @@ function advanceState() { - console.log(currentState); - if (currentState == 'preTest') - { - // End of pre-test, begin the test - preTestQuestions = popup.responses; - loadTest(0); - } else if (currentState == 'postTest') { - postTestQuestions = popup.responses; - console.log('ALL COLLECTED!'); - createProjectSave(projectReturn); - }else if (currentState.substr(0,10) == 'testRunPre') - { - // Start the test - var testId = currentState.substr(11,currentState.length-10); - currentState = 'testRun-'+testId; - currentTestHolder.appendChild(popup.responses); - //audioEngineContext.timer.startTest(); - //audioEngineContext.play(); - } else if (currentState.substr(0,11) == 'testRunPost') - { - var testId = currentState.substr(12,currentState.length-11); - currentTestHolder.appendChild(popup.responses); - testEnded(testId); - } else if (currentState.substr(0,7) == 'testRun') - { - var testId = currentState.substr(8,currentState.length-7); - // Check if we have any post tests to perform - var postXML = $(testXMLSetups[testId]).find('PostTest')[0]; - if (postXML == undefined || postXML.childElementCount == 0) { - testEnded(testId); + // Just for complete clarity + testState.advanceState(); +} + +function stateMachine() +{ + // Object prototype for tracking and managing the test state + this.stateMap = []; + this.stateIndex = null; + this.currentStateMap = []; + this.currentIndex = null; + this.currentTestId = 0; + this.stateResults = []; + this.initialise = function(){ + if (this.stateMap.length > 0) { + if(this.stateIndex != null) { + console.log('NOTE - State already initialise'); + } + this.stateIndex = -1; + var that = this; + for (var id=0; id<this.stateMap.length; id++){ + var name = this.stateMap[id].nodeName; + var obj = document.createElement(name); + this.stateResults.push(obj); + } + } else { + conolse.log('FATAL - StateMap not correctly constructed. EMPTY_STATE_MAP'); } - else if (postXML.childElementCount > 0) - { - currentState = 'testRunPost-'+testId; - popup.initState(postXML); + }; + this.advanceState = function(){ + if (this.stateIndex == null) { + this.initialise(); + } + if (this.stateIndex == -1) { + console.log('Starting test...'); + } + if (this.currentIndex == null){ + if (this.currentStateMap.nodeName == "audioHolder") { + // Save current page + this.testPageCompleted(this.stateResults[this.stateIndex],this.currentStateMap,this.currentTestId); + this.currentTestId++; + } + this.stateIndex++; + if (this.stateIndex >= this.stateMap.length) { + console.log('Test Completed'); + createProjectSave(projectReturn); + } else { + this.currentStateMap = this.stateMap[this.stateIndex]; + if (this.currentStateMap.nodeName == "audioHolder") { + console.log('Loading test page'); + loadTest(this.currentStateMap); + this.initialiseInnerState(this.currentStateMap); + } else if (this.currentStateMap.nodeName == "PreTest" || this.currentStateMap.nodeName == "PostTest") { + if (this.currentStateMap.childElementCount >= 1) { + popup.initState(this.currentStateMap); + } else { + this.advanceState(); + } + } else { + this.advanceState(); + } + } + } else { + this.advanceInnerState(); + } + }; + + this.testPageCompleted = function(store, testXML, testId) { + // Function called each time a test page has been completed + // Can be used to over-rule default behaviour + + pageXMLSave(store, testXML, testId); + } + + this.initialiseInnerState = function(testXML) { + // Parses the received testXML for pre and post test options + this.currentStateMap = []; + var preTest = $(testXML).find('PreTest')[0]; + var postTest = $(testXML).find('PostTest')[0]; + if (preTest == undefined) {preTest = document.createElement("preTest");} + if (postTest == undefined){postTest= document.createElement("postTest");} + this.currentStateMap.push(preTest); + this.currentStateMap.push(testXML); + this.currentStateMap.push(postTest); + this.currentIndex = -1; + this.advanceInnerState(); + } + + this.advanceInnerState = function() { + this.currentIndex++; + if (this.currentIndex >= this.currentStateMap.length) { + this.currentIndex = null; + this.currentStateMap = this.stateMap[this.stateIndex]; + this.advanceState(); + } else { + if (this.currentStateMap[this.currentIndex].nodeName == "audioHolder") { + console.log("Loading test page"+this.currentTestId); + } else if (this.currentStateMap[this.currentIndex].nodeName == "PreTest") { + popup.initState(this.currentStateMap[this.currentIndex]); + } else if (this.currentStateMap[this.currentIndex].nodeName == "PostTest") { + popup.initState(this.currentStateMap[this.currentIndex]); + } else { + this.advanceInnerState(); + } } } - console.log(currentState); + + this.previousState = function(){}; } function testEnded(testId) @@ -303,6 +382,19 @@ return submitDiv; } +// Only other global function which must be defined in the interface class. Determines how to create the XML document. +function interfaceXMLSave(){ + // Create the XML string to be exported with results + var xmlDoc = document.createElement("BrowserEvaluationResult"); + xmlDoc.appendChild(returnDateNode()); + for (var i=0; i<testState.stateResults.length; i++) + { + xmlDoc.appendChild(testState.stateResults[i]); + } + + return xmlDoc; +} + function AudioEngine() { // Create two output paths, the main outputGain and fooGain. @@ -634,4 +726,4 @@ hold.appendChild(time); return hold -} +} \ No newline at end of file
--- a/example_eval/project.xml Wed May 27 11:49:20 2015 +0100 +++ b/example_eval/project.xml Wed May 27 16:45:48 2015 +0100 @@ -38,9 +38,11 @@ <audioElements url="9.wav" id="9"/> <audioElements url="10.wav" id="10"/>--> <CommentQuestion id='mixingExperiance'>What is your mixing experiance</CommentQuestion> + <!-- <PreTest> <statement>Start the Test 3</statement> </PreTest> + --> <PostTest> <question id="genre" mandatory="true">Please enter the genre</question> </PostTest>