annotate ape.js @ 950:05e7edb032b9

Fix Bug #1241 and #1213: Added checks each time new test page is loaded that all audioObjects have decoded. Writes to browser console WAIT and does not issue any play command if any audioObjects not ready.
author Nicholas Jillings <n.g.r.jillings@se14.qmul.ac.uk>
date Mon, 25 May 2015 11:14:12 +0100
parents 48e05b7a16e0
children 55bf2500f278
rev   line source
BrechtDeMan@938 1 /**
BrechtDeMan@938 2 * ape.js
BrechtDeMan@938 3 * Create the APE interface
BrechtDeMan@938 4 */
BrechtDeMan@938 5
BrechtDeMan@938 6 var currentState; // Keep track of the current state (pre/post test, which test, final test? first test?)
BrechtDeMan@938 7 // preTest - In preTest state
BrechtDeMan@938 8 // testRun-ID - In test running, test Id number at the end 'testRun-2'
BrechtDeMan@938 9 // testRunPost-ID - Post test of test ID
BrechtDeMan@938 10 // testRunPre-ID - Pre-test of test ID
BrechtDeMan@938 11 // postTest - End of test, final submission!
BrechtDeMan@938 12
BrechtDeMan@938 13
BrechtDeMan@938 14 // Once this is loaded and parsed, begin execution
BrechtDeMan@938 15 loadInterface(projectXML);
BrechtDeMan@938 16
BrechtDeMan@938 17 function loadInterface(xmlDoc) {
BrechtDeMan@938 18
BrechtDeMan@938 19 // Get the dimensions of the screen available to the page
BrechtDeMan@938 20 var width = window.innerWidth;
BrechtDeMan@938 21 var height = window.innerHeight;
BrechtDeMan@938 22
BrechtDeMan@938 23 // The injection point into the HTML page
BrechtDeMan@938 24 var insertPoint = document.getElementById("topLevelBody");
BrechtDeMan@938 25 var testContent = document.createElement('div');
BrechtDeMan@938 26 testContent.id = 'testContent';
BrechtDeMan@938 27
BrechtDeMan@938 28
BrechtDeMan@938 29 // Decode parts of the xmlDoc that are needed
BrechtDeMan@938 30 // xmlDoc MUST already be parsed by jQuery!
BrechtDeMan@938 31 var xmlSetup = xmlDoc.find('setup');
BrechtDeMan@938 32 // Should put in an error function here incase of malprocessed or malformed XML
BrechtDeMan@938 33
BrechtDeMan@938 34 // Extract the different test XML DOM trees
BrechtDeMan@938 35 var audioHolders = xmlDoc.find('audioHolder');
BrechtDeMan@938 36 audioHolders.each(function(index,element) {
BrechtDeMan@938 37 var repeatN = element.attributes['repeatCount'].value;
BrechtDeMan@938 38 for (var r=0; r<=repeatN; r++) {
BrechtDeMan@938 39 testXMLSetups[testXMLSetups.length] = element;
BrechtDeMan@938 40 }
BrechtDeMan@938 41 });
BrechtDeMan@938 42
BrechtDeMan@938 43 // New check if we need to randomise the test order
BrechtDeMan@938 44 var randomise = xmlSetup[0].attributes['randomiseOrder'];
BrechtDeMan@938 45 if (randomise != undefined) {
nicholas@946 46 if (randomise.value === 'true'){
nicholas@946 47 randomise = true;
nicholas@946 48 } else {
nicholas@946 49 randomise = false;
nicholas@946 50 }
BrechtDeMan@938 51 } else {
BrechtDeMan@938 52 randomise = false;
BrechtDeMan@938 53 }
nicholas@946 54
BrechtDeMan@938 55 if (randomise)
BrechtDeMan@938 56 {
BrechtDeMan@938 57 testXMLSetups = randomiseOrder(testXMLSetups);
BrechtDeMan@938 58 }
BrechtDeMan@938 59
BrechtDeMan@938 60 // Obtain the metrics enabled
BrechtDeMan@938 61 var metricNode = xmlSetup.find('Metric');
BrechtDeMan@938 62 var metricNode = metricNode.find('metricEnable');
BrechtDeMan@938 63 metricNode.each(function(index,node){
BrechtDeMan@938 64 var enabled = node.textContent;
BrechtDeMan@938 65 switch(enabled)
BrechtDeMan@938 66 {
BrechtDeMan@938 67 case 'testTimer':
BrechtDeMan@938 68 sessionMetrics.prototype.enableTestTimer = true;
BrechtDeMan@938 69 break;
BrechtDeMan@938 70 case 'elementTimer':
BrechtDeMan@938 71 sessionMetrics.prototype.enableElementTimer = true;
BrechtDeMan@938 72 break;
BrechtDeMan@938 73 case 'elementTracker':
BrechtDeMan@938 74 sessionMetrics.prototype.enableElementTracker = true;
BrechtDeMan@938 75 break;
BrechtDeMan@938 76 case 'elementInitalPosition':
BrechtDeMan@938 77 sessionMetrics.prototype.enableElementInitialPosition = true;
BrechtDeMan@938 78 break;
BrechtDeMan@938 79 case 'elementFlagListenedTo':
BrechtDeMan@938 80 sessionMetrics.prototype.enableFlagListenedTo = true;
BrechtDeMan@938 81 break;
BrechtDeMan@938 82 case 'elementFlagMoved':
BrechtDeMan@938 83 sessionMetrics.prototype.enableFlagMoved = true;
BrechtDeMan@938 84 break;
BrechtDeMan@938 85 case 'elementFlagComments':
BrechtDeMan@938 86 sessionMetrics.prototype.enableFlagComments = true;
BrechtDeMan@938 87 break;
BrechtDeMan@938 88 }
BrechtDeMan@938 89 });
BrechtDeMan@938 90
BrechtDeMan@938 91 // Create APE specific metric functions
BrechtDeMan@938 92 audioEngineContext.metric.initialiseTest = function()
BrechtDeMan@938 93 {
BrechtDeMan@938 94 var sliders = document.getElementsByClassName('track-slider');
BrechtDeMan@938 95 for (var i=0; i<sliders.length; i++)
BrechtDeMan@938 96 {
BrechtDeMan@938 97 audioEngineContext.audioObjects[i].metric.initialised(convSliderPosToRate(i));
BrechtDeMan@938 98 }
BrechtDeMan@938 99 };
BrechtDeMan@938 100
BrechtDeMan@938 101 audioEngineContext.metric.sliderMoveStart = function(id)
BrechtDeMan@938 102 {
BrechtDeMan@938 103 if (this.data == -1)
BrechtDeMan@938 104 {
BrechtDeMan@938 105 this.data = id;
BrechtDeMan@938 106 } else {
BrechtDeMan@938 107 console.log('ERROR: Metric tracker detecting two moves!');
BrechtDeMan@938 108 this.data = -1;
BrechtDeMan@938 109 }
BrechtDeMan@938 110 };
BrechtDeMan@938 111 audioEngineContext.metric.sliderMoved = function()
BrechtDeMan@938 112 {
BrechtDeMan@938 113 var time = audioEngineContext.timer.getTestTime();
BrechtDeMan@938 114 var id = this.data;
BrechtDeMan@938 115 this.data = -1;
BrechtDeMan@938 116 var position = convSliderPosToRate(id);
BrechtDeMan@938 117 if (audioEngineContext.timer.testStarted)
BrechtDeMan@938 118 {
BrechtDeMan@938 119 audioEngineContext.audioObjects[id].metric.moved(time,position);
BrechtDeMan@938 120 }
BrechtDeMan@938 121 };
BrechtDeMan@938 122
BrechtDeMan@938 123 audioEngineContext.metric.sliderPlayed = function(id)
BrechtDeMan@938 124 {
BrechtDeMan@938 125 var time = audioEngineContext.timer.getTestTime();
BrechtDeMan@938 126 if (audioEngineContext.timer.testStarted)
BrechtDeMan@938 127 {
BrechtDeMan@938 128 if (this.lastClicked >= 0)
BrechtDeMan@938 129 {
BrechtDeMan@938 130 audioEngineContext.audioObjects[this.lastClicked].metric.listening(time);
BrechtDeMan@938 131 }
BrechtDeMan@938 132 this.lastClicked = id;
BrechtDeMan@938 133 audioEngineContext.audioObjects[id].metric.listening(time);
BrechtDeMan@938 134 }
BrechtDeMan@938 135 };
BrechtDeMan@938 136
BrechtDeMan@938 137 // Create the top div for the Title element
BrechtDeMan@938 138 var titleAttr = xmlSetup[0].attributes['title'];
BrechtDeMan@938 139 var title = document.createElement('div');
BrechtDeMan@938 140 title.className = "title";
BrechtDeMan@938 141 title.align = "center";
BrechtDeMan@938 142 var titleSpan = document.createElement('span');
BrechtDeMan@938 143
BrechtDeMan@938 144 // Set title to that defined in XML, else set to default
BrechtDeMan@938 145 if (titleAttr != undefined) {
BrechtDeMan@938 146 titleSpan.innerHTML = titleAttr.value;
BrechtDeMan@938 147 } else {
BrechtDeMan@938 148 titleSpan.innerHTML = 'Listening test';
BrechtDeMan@938 149 }
BrechtDeMan@938 150 // Insert the titleSpan element into the title div element.
BrechtDeMan@938 151 title.appendChild(titleSpan);
BrechtDeMan@938 152
BrechtDeMan@938 153 var pagetitle = document.createElement('div');
BrechtDeMan@938 154 pagetitle.className = "pageTitle";
BrechtDeMan@938 155 pagetitle.align = "center";
BrechtDeMan@938 156 var titleSpan = document.createElement('span');
BrechtDeMan@938 157 titleSpan.id = "pageTitle";
BrechtDeMan@938 158 pagetitle.appendChild(titleSpan);
BrechtDeMan@938 159
BrechtDeMan@938 160 // Store the return URL path in global projectReturn
BrechtDeMan@938 161 projectReturn = xmlSetup[0].attributes['projectReturn'].value;
BrechtDeMan@938 162
BrechtDeMan@938 163 // Create Interface buttons!
BrechtDeMan@938 164 var interfaceButtons = document.createElement('div');
BrechtDeMan@938 165 interfaceButtons.id = 'interface-buttons';
BrechtDeMan@938 166
BrechtDeMan@938 167 // MANUAL DOWNLOAD POINT
BrechtDeMan@938 168 // If project return is null, this MUST be specified as the location to create the download link
BrechtDeMan@938 169 var downloadPoint = document.createElement('div');
BrechtDeMan@938 170 downloadPoint.id = 'download-point';
BrechtDeMan@938 171
BrechtDeMan@938 172 // Create playback start/stop points
BrechtDeMan@938 173 var playback = document.createElement("button");
BrechtDeMan@939 174 playback.innerHTML = 'Stop';
BrechtDeMan@938 175 playback.id = 'playback-button';
BrechtDeMan@938 176 // onclick function. Check if it is playing or not, call the correct function in the
BrechtDeMan@938 177 // audioEngine, change the button text to reflect the next state.
BrechtDeMan@938 178 playback.onclick = function() {
BrechtDeMan@939 179 if (audioEngineContext.status == 1) {
BrechtDeMan@939 180 audioEngineContext.stop();
BrechtDeMan@938 181 this.innerHTML = 'Stop';
BrechtDeMan@938 182 }
BrechtDeMan@938 183 };
BrechtDeMan@938 184 // Create Submit (save) button
BrechtDeMan@938 185 var submit = document.createElement("button");
BrechtDeMan@938 186 submit.innerHTML = 'Submit';
BrechtDeMan@938 187 submit.onclick = buttonSubmitClick;
BrechtDeMan@938 188 submit.id = 'submit-button';
BrechtDeMan@938 189 // Append the interface buttons into the interfaceButtons object.
BrechtDeMan@938 190 interfaceButtons.appendChild(playback);
BrechtDeMan@938 191 interfaceButtons.appendChild(submit);
BrechtDeMan@938 192 interfaceButtons.appendChild(downloadPoint);
BrechtDeMan@938 193
BrechtDeMan@938 194 // Now create the slider and HTML5 canvas boxes
BrechtDeMan@938 195
BrechtDeMan@938 196 // Create the div box to center align
BrechtDeMan@938 197 var sliderBox = document.createElement('div');
BrechtDeMan@938 198 sliderBox.className = 'sliderCanvasDiv';
BrechtDeMan@938 199 sliderBox.id = 'sliderCanvasHolder';
BrechtDeMan@938 200 sliderBox.align = 'center';
BrechtDeMan@938 201
BrechtDeMan@938 202 // Create the slider box to hold the slider elements
BrechtDeMan@938 203 var canvas = document.createElement('div');
BrechtDeMan@938 204 canvas.id = 'slider';
BrechtDeMan@938 205 // Must have a known EXACT width, as this is used later to determine the ratings
BrechtDeMan@938 206 canvas.style.width = width - 100 +"px";
BrechtDeMan@938 207 canvas.align = "left";
BrechtDeMan@938 208 sliderBox.appendChild(canvas);
BrechtDeMan@938 209
BrechtDeMan@938 210 // Create the div to hold any scale objects
BrechtDeMan@938 211 var scale = document.createElement('div');
BrechtDeMan@938 212 scale.className = 'sliderScale';
BrechtDeMan@938 213 scale.id = 'sliderScaleHolder';
BrechtDeMan@938 214 scale.align = 'left';
BrechtDeMan@938 215 sliderBox.appendChild(scale);
BrechtDeMan@938 216
BrechtDeMan@938 217 // Global parent for the comment boxes on the page
BrechtDeMan@938 218 var feedbackHolder = document.createElement('div');
BrechtDeMan@938 219 feedbackHolder.id = 'feedbackHolder';
BrechtDeMan@938 220
BrechtDeMan@938 221 testContent.style.zIndex = 1;
BrechtDeMan@938 222 insertPoint.innerHTML = null; // Clear the current schema
BrechtDeMan@938 223
BrechtDeMan@938 224 // Create pre and post test questions
BrechtDeMan@938 225 var blank = document.createElement('div');
BrechtDeMan@938 226 blank.className = 'testHalt';
BrechtDeMan@938 227
BrechtDeMan@938 228 var popupHolder = document.createElement('div');
BrechtDeMan@938 229 popupHolder.id = 'popupHolder';
BrechtDeMan@938 230 popupHolder.className = 'popupHolder';
BrechtDeMan@938 231 popupHolder.style.position = 'absolute';
BrechtDeMan@938 232 popupHolder.style.left = (window.innerWidth/2)-250 + 'px';
BrechtDeMan@938 233 popupHolder.style.top = (window.innerHeight/2)-125 + 'px';
BrechtDeMan@938 234 insertPoint.appendChild(popupHolder);
BrechtDeMan@938 235 insertPoint.appendChild(blank);
BrechtDeMan@938 236 hidePopup();
BrechtDeMan@938 237
BrechtDeMan@938 238 var preTest = xmlSetup.find('PreTest');
BrechtDeMan@938 239 var postTest = xmlSetup.find('PostTest');
BrechtDeMan@938 240 preTest = preTest[0];
BrechtDeMan@938 241 postTest = postTest[0];
BrechtDeMan@938 242
BrechtDeMan@938 243 currentState = 'preTest';
BrechtDeMan@938 244
BrechtDeMan@938 245 // Create Pre-Test Box
nicholas@942 246 if (preTest != undefined && preTest.childElementCount >= 1)
BrechtDeMan@938 247 {
BrechtDeMan@938 248 showPopup();
BrechtDeMan@938 249 preTestPopupStart(preTest);
BrechtDeMan@938 250 }
BrechtDeMan@938 251
BrechtDeMan@938 252 // Inject into HTML
BrechtDeMan@938 253 testContent.appendChild(title); // Insert the title
BrechtDeMan@938 254 testContent.appendChild(pagetitle);
BrechtDeMan@938 255 testContent.appendChild(interfaceButtons);
BrechtDeMan@938 256 testContent.appendChild(sliderBox);
BrechtDeMan@938 257 testContent.appendChild(feedbackHolder);
BrechtDeMan@938 258 insertPoint.appendChild(testContent);
BrechtDeMan@938 259
BrechtDeMan@938 260 // Load the full interface
BrechtDeMan@938 261
BrechtDeMan@938 262 }
BrechtDeMan@938 263
BrechtDeMan@938 264 function loadTest(id)
BrechtDeMan@938 265 {
nicholas@947 266
nicholas@947 267 // Reset audioEngineContext.Metric globals for new test
n@950 268 audioEngineContext.newTestPage();
nicholas@947 269
BrechtDeMan@938 270 // Used to load a specific test page
BrechtDeMan@938 271 var textXML = testXMLSetups[id];
BrechtDeMan@938 272
BrechtDeMan@938 273 var feedbackHolder = document.getElementById('feedbackHolder');
BrechtDeMan@938 274 var canvas = document.getElementById('slider');
BrechtDeMan@938 275 feedbackHolder.innerHTML = null;
BrechtDeMan@938 276 canvas.innerHTML = null;
BrechtDeMan@938 277
BrechtDeMan@938 278 // Setup question title
BrechtDeMan@938 279 var interfaceObj = $(textXML).find('interface');
BrechtDeMan@938 280 var titleNode = interfaceObj.find('title');
BrechtDeMan@938 281 if (titleNode[0] != undefined)
BrechtDeMan@938 282 {
BrechtDeMan@938 283 document.getElementById('pageTitle').textContent = titleNode[0].textContent;
BrechtDeMan@938 284 }
BrechtDeMan@938 285 var positionScale = canvas.style.width.substr(0,canvas.style.width.length-2);
BrechtDeMan@938 286 var offset = 50-8; // Half the offset of the slider (window width -100) minus the body padding of 8
BrechtDeMan@938 287 // TODO: AUTOMATE ABOVE!!
BrechtDeMan@938 288 var scale = document.getElementById('sliderScaleHolder');
BrechtDeMan@938 289 scale.innerHTML = null;
BrechtDeMan@938 290 interfaceObj.find('scale').each(function(index,scaleObj){
BrechtDeMan@938 291 var position = Number(scaleObj.attributes['position'].value)*0.01;
BrechtDeMan@938 292 var pixelPosition = (position*positionScale)+offset;
BrechtDeMan@938 293 var scaleDOM = document.createElement('span');
BrechtDeMan@938 294 scaleDOM.textContent = scaleObj.textContent;
BrechtDeMan@938 295 scale.appendChild(scaleDOM);
BrechtDeMan@938 296 scaleDOM.style.left = Math.floor((pixelPosition-($(scaleDOM).width()/2)))+'px';
BrechtDeMan@938 297 });
BrechtDeMan@938 298
BrechtDeMan@938 299 // Extract the hostURL attribute. If not set, create an empty string.
BrechtDeMan@938 300 var hostURL = textXML.attributes['hostURL'];
BrechtDeMan@938 301 if (hostURL == undefined) {
BrechtDeMan@938 302 hostURL = "";
BrechtDeMan@938 303 } else {
BrechtDeMan@938 304 hostURL = hostURL.value;
BrechtDeMan@938 305 }
BrechtDeMan@938 306 // Extract the sampleRate. If set, convert the string to a Number.
BrechtDeMan@938 307 var hostFs = textXML.attributes['sampleRate'];
BrechtDeMan@938 308 if (hostFs != undefined) {
BrechtDeMan@938 309 hostFs = Number(hostFs.value);
BrechtDeMan@938 310 }
BrechtDeMan@938 311
BrechtDeMan@938 312 /// CHECK FOR SAMPLE RATE COMPATIBILITY
BrechtDeMan@938 313 if (hostFs != undefined) {
BrechtDeMan@938 314 if (Number(hostFs) != audioContext.sampleRate) {
BrechtDeMan@938 315 var errStr = 'Sample rates do not match! Requested '+Number(hostFs)+', got '+audioContext.sampleRate+'. Please set the sample rate to match before completing this test.';
BrechtDeMan@938 316 alert(errStr);
BrechtDeMan@938 317 return;
BrechtDeMan@938 318 }
BrechtDeMan@938 319 }
BrechtDeMan@938 320
BrechtDeMan@938 321 var commentShow = textXML.attributes['elementComments'];
BrechtDeMan@938 322 if (commentShow != undefined) {
BrechtDeMan@938 323 if (commentShow.value == 'false') {commentShow = false;}
BrechtDeMan@938 324 else {commentShow = true;}
BrechtDeMan@938 325 } else {commentShow = true;}
BrechtDeMan@938 326
BrechtDeMan@938 327 var loopPlayback = textXML.attributes['loop'];
BrechtDeMan@938 328 if (loopPlayback != undefined)
BrechtDeMan@938 329 {
BrechtDeMan@938 330 loopPlayback = loopPlayback.value;
BrechtDeMan@938 331 if (loopPlayback == 'true') {
BrechtDeMan@938 332 loopPlayback = true;
BrechtDeMan@938 333 } else {
BrechtDeMan@938 334 loopPlayback = false;
BrechtDeMan@938 335 }
BrechtDeMan@938 336 } else {
BrechtDeMan@938 337 loopPlayback = false;
BrechtDeMan@938 338 }
BrechtDeMan@938 339 audioEngineContext.loopPlayback = loopPlayback;
nicholas@947 340 loopPlayback = false;
BrechtDeMan@938 341 // Create AudioEngine bindings for playback
BrechtDeMan@938 342 if (loopPlayback) {
BrechtDeMan@938 343 audioEngineContext.selectedTrack = function(id) {
BrechtDeMan@938 344 for (var i=0; i<this.audioObjects.length; i++)
BrechtDeMan@938 345 {
BrechtDeMan@938 346 if (id == i) {
BrechtDeMan@938 347 this.audioObjects[i].outputGain.gain.value = 1.0;
BrechtDeMan@938 348 } else {
BrechtDeMan@938 349 this.audioObjects[i].outputGain.gain.value = 0.0;
BrechtDeMan@938 350 }
BrechtDeMan@938 351 }
BrechtDeMan@938 352 };
BrechtDeMan@938 353 } else {
BrechtDeMan@938 354 audioEngineContext.selectedTrack = function(id) {
BrechtDeMan@938 355 for (var i=0; i<this.audioObjects.length; i++)
BrechtDeMan@938 356 {
BrechtDeMan@937 357 this.audioObjects[i].outputGain.gain.value = 0.0;
BrechtDeMan@937 358 this.audioObjects[i].stop();
BrechtDeMan@937 359 }
BrechtDeMan@937 360 if (this.status == 1) {
BrechtDeMan@937 361 this.audioObjects[id].outputGain.gain.value = 1.0;
BrechtDeMan@937 362 this.audioObjects[id].play(audioContext.currentTime+0.01);
BrechtDeMan@938 363 }
BrechtDeMan@938 364 };
BrechtDeMan@938 365 }
BrechtDeMan@938 366
BrechtDeMan@938 367 currentTestHolder = document.createElement('audioHolder');
BrechtDeMan@938 368 currentTestHolder.id = textXML.id;
BrechtDeMan@938 369 currentTestHolder.repeatCount = textXML.attributes['repeatCount'].value;
BrechtDeMan@938 370 var currentPreTestHolder = document.createElement('preTest');
BrechtDeMan@938 371 var currentPostTestHolder = document.createElement('postTest');
BrechtDeMan@938 372 currentTestHolder.appendChild(currentPreTestHolder);
BrechtDeMan@938 373 currentTestHolder.appendChild(currentPostTestHolder);
BrechtDeMan@938 374
BrechtDeMan@938 375 var randomise = textXML.attributes['randomiseOrder'];
BrechtDeMan@938 376 if (randomise != undefined) {randomise = randomise.value;}
BrechtDeMan@938 377 else {randomise = false;}
BrechtDeMan@938 378
BrechtDeMan@938 379 var audioElements = $(textXML).find('audioElements');
BrechtDeMan@938 380 currentTrackOrder = [];
BrechtDeMan@938 381 audioElements.each(function(index,element){
BrechtDeMan@938 382 // Find any blind-repeats
BrechtDeMan@938 383 // Not implemented yet, but just in case
BrechtDeMan@938 384 currentTrackOrder[index] = element;
BrechtDeMan@938 385 });
BrechtDeMan@938 386 if (randomise) {
BrechtDeMan@938 387 currentTrackOrder = randomiseOrder(currentTrackOrder);
BrechtDeMan@938 388 }
BrechtDeMan@938 389
BrechtDeMan@938 390 // Delete any previous audioObjects associated with the audioEngine
BrechtDeMan@938 391 audioEngineContext.audioObjects = [];
BrechtDeMan@938 392
BrechtDeMan@938 393 // Find all the audioElements from the audioHolder
BrechtDeMan@938 394 $(currentTrackOrder).each(function(index,element){
BrechtDeMan@938 395 // Find URL of track
BrechtDeMan@938 396 // In this jQuery loop, variable 'this' holds the current audioElement.
BrechtDeMan@938 397
BrechtDeMan@938 398 // Now load each audio sample. First create the new track by passing the full URL
BrechtDeMan@938 399 var trackURL = hostURL + this.attributes['url'].value;
BrechtDeMan@938 400 audioEngineContext.newTrack(trackURL);
BrechtDeMan@938 401
BrechtDeMan@938 402 if (commentShow) {
BrechtDeMan@938 403 // Create document objects to hold the comment boxes
BrechtDeMan@938 404 var trackComment = document.createElement('div');
BrechtDeMan@938 405 trackComment.className = 'comment-div';
BrechtDeMan@938 406 // Create a string next to each comment asking for a comment
BrechtDeMan@938 407 var trackString = document.createElement('span');
BrechtDeMan@938 408 trackString.innerHTML = 'Comment on track '+index;
BrechtDeMan@938 409 // Create the HTML5 comment box 'textarea'
BrechtDeMan@938 410 var trackCommentBox = document.createElement('textarea');
BrechtDeMan@938 411 trackCommentBox.rows = '4';
BrechtDeMan@938 412 trackCommentBox.cols = '100';
BrechtDeMan@938 413 trackCommentBox.name = 'trackComment'+index;
BrechtDeMan@938 414 trackCommentBox.className = 'trackComment';
BrechtDeMan@938 415 var br = document.createElement('br');
BrechtDeMan@938 416 // Add to the holder.
BrechtDeMan@938 417 trackComment.appendChild(trackString);
BrechtDeMan@938 418 trackComment.appendChild(br);
BrechtDeMan@938 419 trackComment.appendChild(trackCommentBox);
BrechtDeMan@938 420 feedbackHolder.appendChild(trackComment);
BrechtDeMan@938 421 }
BrechtDeMan@938 422
BrechtDeMan@938 423 // Create a slider per track
BrechtDeMan@938 424
BrechtDeMan@938 425 var trackSliderObj = document.createElement('div');
BrechtDeMan@938 426 trackSliderObj.className = 'track-slider';
BrechtDeMan@938 427 trackSliderObj.id = 'track-slider-'+index;
BrechtDeMan@938 428 // Distribute it randomnly
BrechtDeMan@938 429 var w = window.innerWidth - 100;
BrechtDeMan@938 430 w = Math.random()*w;
BrechtDeMan@938 431 trackSliderObj.style.left = Math.floor(w)+50+'px';
BrechtDeMan@938 432 trackSliderObj.innerHTML = '<span>'+index+'</span>';
BrechtDeMan@938 433 trackSliderObj.draggable = true;
BrechtDeMan@938 434 trackSliderObj.ondragend = dragEnd;
BrechtDeMan@938 435 trackSliderObj.ondragstart = function()
BrechtDeMan@938 436 {
BrechtDeMan@938 437 var id = Number(this.id.substr(13,2)); // Maximum theoretical tracks is 99!
BrechtDeMan@938 438 audioEngineContext.metric.sliderMoveStart(id);
BrechtDeMan@938 439 };
BrechtDeMan@938 440
BrechtDeMan@938 441 // Onclick, switch playback to that track
BrechtDeMan@938 442 trackSliderObj.onclick = function() {
nicholas@945 443 // Start the test on first click, that way timings are more accurate.
nicholas@945 444 audioEngineContext.play();
BrechtDeMan@938 445 // Get the track ID from the object ID
BrechtDeMan@938 446 var id = Number(this.id.substr(13,2)); // Maximum theoretical tracks is 99!
nicholas@947 447 //audioEngineContext.metric.sliderPlayed(id);
BrechtDeMan@938 448 audioEngineContext.selectedTrack(id);
BrechtDeMan@938 449 // Currently playing track red, rest green
BrechtDeMan@938 450 document.getElementById('track-slider-'+index).style.backgroundColor = "#FF0000";
BrechtDeMan@938 451 for (var i = 0; i<$(currentTrackOrder).length; i++)
BrechtDeMan@938 452 {
BrechtDeMan@940 453 if (i!=index) // Make all other sliders green
BrechtDeMan@938 454 {
BrechtDeMan@938 455 document.getElementById('track-slider-'+i).style.backgroundColor = "rgb(100,200,100)";
BrechtDeMan@938 456 }
BrechtDeMan@938 457
BrechtDeMan@938 458 }
BrechtDeMan@938 459 };
BrechtDeMan@938 460
BrechtDeMan@938 461 canvas.appendChild(trackSliderObj);
BrechtDeMan@940 462
BrechtDeMan@938 463 });
BrechtDeMan@938 464
BrechtDeMan@938 465 // Append any commentQuestion boxes
BrechtDeMan@938 466 var commentQuestions = $(textXML).find('CommentQuestion');
BrechtDeMan@938 467 $(commentQuestions).each(function(index,element) {
BrechtDeMan@938 468 // Create document objects to hold the comment boxes
BrechtDeMan@938 469 var trackComment = document.createElement('div');
BrechtDeMan@938 470 trackComment.className = 'comment-div commentQuestion';
BrechtDeMan@938 471 trackComment.id = element.attributes['id'].value;
BrechtDeMan@938 472 // Create a string next to each comment asking for a comment
BrechtDeMan@938 473 var trackString = document.createElement('span');
BrechtDeMan@938 474 trackString.innerHTML = element.textContent;
BrechtDeMan@938 475 // Create the HTML5 comment box 'textarea'
BrechtDeMan@938 476 var trackCommentBox = document.createElement('textarea');
BrechtDeMan@938 477 trackCommentBox.rows = '4';
BrechtDeMan@938 478 trackCommentBox.cols = '100';
BrechtDeMan@938 479 trackCommentBox.name = 'commentQuestion'+index;
BrechtDeMan@938 480 trackCommentBox.className = 'trackComment';
BrechtDeMan@938 481 var br = document.createElement('br');
BrechtDeMan@938 482 // Add to the holder.
BrechtDeMan@938 483 trackComment.appendChild(trackString);
BrechtDeMan@938 484 trackComment.appendChild(br);
BrechtDeMan@938 485 trackComment.appendChild(trackCommentBox);
BrechtDeMan@938 486 feedbackHolder.appendChild(trackComment);
BrechtDeMan@938 487 });
BrechtDeMan@938 488
BrechtDeMan@938 489 // Now process any pre-test commands
BrechtDeMan@938 490
BrechtDeMan@938 491 var preTest = $(testXMLSetups[id]).find('PreTest')[0];
nicholas@942 492 if (preTest.childElementCount > 0)
BrechtDeMan@938 493 {
BrechtDeMan@938 494 currentState = 'testRunPre-'+id;
BrechtDeMan@938 495 preTestPopupStart(preTest);
BrechtDeMan@938 496 showPopup();
BrechtDeMan@938 497 } else {
BrechtDeMan@938 498 currentState = 'testRun-'+id;
BrechtDeMan@938 499 }
BrechtDeMan@938 500 }
BrechtDeMan@938 501
BrechtDeMan@938 502 function preTestPopupStart(preTest)
BrechtDeMan@938 503 {
BrechtDeMan@938 504 var popupHolder = document.getElementById('popupHolder');
BrechtDeMan@938 505 popupHolder.innerHTML = null;
BrechtDeMan@938 506 // Parse the first box
BrechtDeMan@938 507 var preTestOption = document.createElement('div');
BrechtDeMan@938 508 preTestOption.id = 'preTest';
BrechtDeMan@938 509 preTestOption.style.marginTop = '25px';
BrechtDeMan@938 510 preTestOption.align = "center";
nicholas@942 511 var child = $(preTest).children()[0];
BrechtDeMan@938 512 if (child.nodeName == 'statement')
BrechtDeMan@938 513 {
nicholas@942 514 preTestOption.innerHTML = '<span>'+child.textContent+'</span>';
BrechtDeMan@938 515 } else if (child.nodeName == 'question')
BrechtDeMan@938 516 {
BrechtDeMan@938 517 var textHold = document.createElement('span');
nicholas@942 518 textHold.innerHTML = child.textContent;
BrechtDeMan@938 519 var textEnter = document.createElement('textarea');
n@949 520 textEnter.id = child.attributes['id'].value + 'response';
n@949 521 var br = document.createElement('br');
n@949 522 preTestOption.innerHTML = null;
BrechtDeMan@938 523 preTestOption.appendChild(textHold);
n@949 524 preTestOption.appendChild(br);
BrechtDeMan@938 525 preTestOption.appendChild(textEnter);
BrechtDeMan@938 526 }
BrechtDeMan@938 527 var nextButton = document.createElement('button');
BrechtDeMan@938 528 nextButton.className = 'popupButton';
BrechtDeMan@938 529 nextButton.value = '0';
BrechtDeMan@938 530 nextButton.innerHTML = 'Next';
BrechtDeMan@938 531 nextButton.onclick = popupButtonClick;
BrechtDeMan@938 532
BrechtDeMan@938 533 popupHolder.appendChild(preTestOption);
BrechtDeMan@938 534 popupHolder.appendChild(nextButton);
BrechtDeMan@938 535 }
BrechtDeMan@938 536
BrechtDeMan@938 537 function popupButtonClick()
BrechtDeMan@938 538 {
BrechtDeMan@938 539 // Global call from the 'Next' button click
BrechtDeMan@938 540 if (currentState == 'preTest')
BrechtDeMan@938 541 {
BrechtDeMan@938 542 // At the start of the preTest routine!
BrechtDeMan@938 543 var xmlTree = projectXML.find('setup');
BrechtDeMan@938 544 var preTest = xmlTree.find('PreTest')[0];
BrechtDeMan@938 545 this.value = preTestButtonClick(preTest,this.value);
BrechtDeMan@938 546 } else if (currentState.substr(0,10) == 'testRunPre')
BrechtDeMan@938 547 {
BrechtDeMan@938 548 //Specific test pre-test
BrechtDeMan@938 549 var testId = currentState.substr(11,currentState.length-10);
BrechtDeMan@938 550 var preTest = $(testXMLSetups[testId]).find('PreTest')[0];
BrechtDeMan@938 551 this.value = preTestButtonClick(preTest,this.value);
BrechtDeMan@938 552 } else if (currentState.substr(0,11) == 'testRunPost')
BrechtDeMan@938 553 {
BrechtDeMan@938 554 // Specific test post-test
BrechtDeMan@938 555 var testId = currentState.substr(12,currentState.length-11);
BrechtDeMan@938 556 var preTest = $(testXMLSetups[testId]).find('PostTest')[0];
BrechtDeMan@938 557 this.value = preTestButtonClick(preTest,this.value);
BrechtDeMan@938 558 } else if (currentState == 'postTest')
BrechtDeMan@938 559 {
BrechtDeMan@938 560 // At the end of the test, running global post test
BrechtDeMan@938 561 var xmlTree = projectXML.find('setup');
BrechtDeMan@938 562 var PostTest = xmlTree.find('PostTest')[0];
BrechtDeMan@938 563 this.value = preTestButtonClick(PostTest,this.value);
BrechtDeMan@938 564 }
BrechtDeMan@938 565 }
BrechtDeMan@938 566
BrechtDeMan@938 567 function preTestButtonClick(preTest,index)
BrechtDeMan@938 568 {
BrechtDeMan@938 569 // Called on click of pre-test button
BrechtDeMan@938 570 // Need to find and parse preTest again!
BrechtDeMan@938 571 var preTestOption = document.getElementById('preTest');
BrechtDeMan@938 572 // Check if current state is a question!
nicholas@942 573 if ($(preTest).children()[index].nodeName == 'question') {
nicholas@942 574 var questionId = $(preTest).children()[index].attributes['id'].value;
BrechtDeMan@938 575 var questionHold = document.createElement('comment');
BrechtDeMan@938 576 var questionResponse = document.getElementById(questionId + 'response');
nicholas@942 577 var mandatory = $(preTest).children()[index].attributes['mandatory'];
BrechtDeMan@938 578 if (mandatory != undefined){
BrechtDeMan@938 579 if (mandatory.value == 'true') {mandatory = true;}
BrechtDeMan@938 580 else {mandatory = false;}
BrechtDeMan@938 581 } else {mandatory = false;}
BrechtDeMan@938 582 if (mandatory == true && questionResponse.value.length == 0) {
BrechtDeMan@938 583 return index;
BrechtDeMan@938 584 }
BrechtDeMan@938 585 questionHold.id = questionId;
BrechtDeMan@938 586 questionHold.innerHTML = questionResponse.value;
BrechtDeMan@938 587 postPopupResponse(questionHold);
BrechtDeMan@938 588 }
BrechtDeMan@938 589 index++;
nicholas@942 590 if (index < preTest.childElementCount)
BrechtDeMan@938 591 {
BrechtDeMan@938 592 // More to process
nicholas@942 593 var child = $(preTest).children()[index];
BrechtDeMan@938 594 if (child.nodeName == 'statement')
BrechtDeMan@938 595 {
nicholas@942 596 preTestOption.innerHTML = '<span>'+child.textContent+'</span>';
BrechtDeMan@938 597 } else if (child.nodeName == 'question')
BrechtDeMan@938 598 {
BrechtDeMan@938 599 var textHold = document.createElement('span');
nicholas@942 600 textHold.innerHTML = child.textContent;
BrechtDeMan@938 601 var textEnter = document.createElement('textarea');
BrechtDeMan@938 602 textEnter.id = child.attributes['id'].value + 'response';
BrechtDeMan@938 603 var br = document.createElement('br');
BrechtDeMan@938 604 preTestOption.innerHTML = null;
BrechtDeMan@938 605 preTestOption.appendChild(textHold);
BrechtDeMan@938 606 preTestOption.appendChild(br);
BrechtDeMan@938 607 preTestOption.appendChild(textEnter);
BrechtDeMan@938 608 }
BrechtDeMan@938 609 } else {
BrechtDeMan@938 610 // Time to clear
BrechtDeMan@938 611 preTestOption.innerHTML = null;
BrechtDeMan@938 612 if (currentState != 'postTest') {
BrechtDeMan@938 613 hidePopup();
BrechtDeMan@938 614 // Progress the state!
BrechtDeMan@938 615 advanceState();
BrechtDeMan@938 616 } else {
BrechtDeMan@938 617 a = createProjectSave(projectReturn);
BrechtDeMan@938 618 preTestOption.appendChild(a);
BrechtDeMan@938 619 }
BrechtDeMan@938 620 }
BrechtDeMan@938 621 return index;
BrechtDeMan@938 622 }
BrechtDeMan@938 623
BrechtDeMan@938 624 function postPopupResponse(response)
BrechtDeMan@938 625 {
BrechtDeMan@938 626 if (currentState == 'preTest') {
BrechtDeMan@938 627 preTestQuestions.appendChild(response);
BrechtDeMan@938 628 } else if (currentState == 'postTest') {
BrechtDeMan@938 629 postTestQuestions.appendChild(response);
BrechtDeMan@938 630 } else {
BrechtDeMan@938 631 // Inside a specific test
BrechtDeMan@938 632 if (currentState.substr(0,10) == 'testRunPre') {
BrechtDeMan@938 633 // Pre Test
BrechtDeMan@938 634 var store = $(currentTestHolder).find('preTest');
BrechtDeMan@938 635 } else {
BrechtDeMan@938 636 // Post Test
BrechtDeMan@938 637 var store = $(currentTestHolder).find('postTest');
BrechtDeMan@938 638 }
BrechtDeMan@938 639 store[0].appendChild(response);
BrechtDeMan@938 640 }
BrechtDeMan@938 641 }
BrechtDeMan@938 642
BrechtDeMan@938 643 function showPopup()
BrechtDeMan@938 644 {
BrechtDeMan@938 645 var popupHolder = document.getElementById('popupHolder');
BrechtDeMan@938 646 popupHolder.style.zIndex = 3;
BrechtDeMan@938 647 popupHolder.style.visibility = 'visible';
BrechtDeMan@938 648 var blank = document.getElementsByClassName('testHalt')[0];
BrechtDeMan@938 649 blank.style.zIndex = 2;
BrechtDeMan@938 650 blank.style.visibility = 'visible';
BrechtDeMan@938 651 }
BrechtDeMan@938 652
BrechtDeMan@938 653 function hidePopup()
BrechtDeMan@938 654 {
BrechtDeMan@938 655 var popupHolder = document.getElementById('popupHolder');
BrechtDeMan@938 656 popupHolder.style.zIndex = -1;
BrechtDeMan@938 657 popupHolder.style.visibility = 'hidden';
BrechtDeMan@938 658 var blank = document.getElementsByClassName('testHalt')[0];
BrechtDeMan@938 659 blank.style.zIndex = -2;
BrechtDeMan@938 660 blank.style.visibility = 'hidden';
BrechtDeMan@938 661 }
BrechtDeMan@938 662
BrechtDeMan@938 663 function dragEnd(ev) {
BrechtDeMan@938 664 // Function call when a div has been dropped
BrechtDeMan@938 665 var slider = document.getElementById('slider');
BrechtDeMan@938 666 var w = slider.style.width;
BrechtDeMan@938 667 w = Number(w.substr(0,w.length-2));
BrechtDeMan@938 668 var x = ev.x;
BrechtDeMan@938 669 if (x >= 42 && x < w+42) {
BrechtDeMan@938 670 this.style.left = (x)+'px';
BrechtDeMan@938 671 } else {
BrechtDeMan@938 672 if (x<42) {
BrechtDeMan@938 673 this.style.left = '42px';
BrechtDeMan@938 674 } else {
BrechtDeMan@938 675 this.style.left = (w+42) + 'px';
BrechtDeMan@938 676 }
BrechtDeMan@938 677 }
BrechtDeMan@938 678 audioEngineContext.metric.sliderMoved();
BrechtDeMan@938 679 }
BrechtDeMan@938 680
BrechtDeMan@938 681 function advanceState()
BrechtDeMan@938 682 {
BrechtDeMan@938 683 console.log(currentState);
BrechtDeMan@938 684 if (currentState == 'preTest')
BrechtDeMan@938 685 {
BrechtDeMan@938 686 // End of pre-test, begin the test
BrechtDeMan@938 687 loadTest(0);
BrechtDeMan@938 688 } else if (currentState.substr(0,10) == 'testRunPre')
BrechtDeMan@938 689 {
BrechtDeMan@938 690 // Start the test
BrechtDeMan@938 691 var testId = currentState.substr(11,currentState.length-10);
BrechtDeMan@938 692 currentState = 'testRun-'+testId;
nicholas@944 693 //audioEngineContext.timer.startTest();
nicholas@945 694 //audioEngineContext.play();
BrechtDeMan@938 695 } else if (currentState.substr(0,11) == 'testRunPost')
BrechtDeMan@938 696 {
BrechtDeMan@938 697 var testId = currentState.substr(12,currentState.length-11);
BrechtDeMan@938 698 testEnded(testId);
BrechtDeMan@938 699 } else if (currentState.substr(0,7) == 'testRun')
BrechtDeMan@938 700 {
BrechtDeMan@938 701 var testId = currentState.substr(8,currentState.length-7);
BrechtDeMan@938 702 // Check if we have any post tests to perform
BrechtDeMan@938 703 var postXML = $(testXMLSetups[testId]).find('PostTest')[0];
n@950 704 if (postXML == undefined || postXML.childElementCount == 0) {
BrechtDeMan@938 705 testEnded(testId);
BrechtDeMan@938 706 }
nicholas@942 707 else if (postXML.childElementCount > 0)
BrechtDeMan@938 708 {
BrechtDeMan@938 709 currentState = 'testRunPost-'+testId;
BrechtDeMan@938 710 showPopup();
BrechtDeMan@938 711 preTestPopupStart(postXML);
BrechtDeMan@938 712 }
BrechtDeMan@938 713 else {
BrechtDeMan@938 714
BrechtDeMan@938 715
BrechtDeMan@938 716 // No post tests, check if we have another test to perform instead
BrechtDeMan@938 717
BrechtDeMan@938 718 }
BrechtDeMan@938 719 }
BrechtDeMan@938 720 console.log(currentState);
BrechtDeMan@938 721 }
BrechtDeMan@938 722
BrechtDeMan@938 723 function testEnded(testId)
BrechtDeMan@938 724 {
BrechtDeMan@938 725 pageXMLSave(testId);
BrechtDeMan@938 726 if (testXMLSetups.length-1 > testId)
BrechtDeMan@938 727 {
BrechtDeMan@938 728 // Yes we have another test to perform
BrechtDeMan@938 729 testId = (Number(testId)+1);
BrechtDeMan@938 730 currentState = 'testRun-'+testId;
BrechtDeMan@938 731 loadTest(testId);
BrechtDeMan@938 732 } else {
BrechtDeMan@938 733 console.log('Testing Completed!');
BrechtDeMan@938 734 currentState = 'postTest';
BrechtDeMan@938 735 // Check for any post tests
BrechtDeMan@938 736 var xmlSetup = projectXML.find('setup');
BrechtDeMan@938 737 var postTest = xmlSetup.find('PostTest')[0];
BrechtDeMan@938 738 showPopup();
BrechtDeMan@938 739 preTestPopupStart(postTest);
BrechtDeMan@938 740 }
BrechtDeMan@938 741 }
BrechtDeMan@938 742
BrechtDeMan@939 743 function buttonSubmitClick() // TODO: Only when all songs have been played!
BrechtDeMan@938 744 {
nicholas@944 745 hasBeenPlayed = audioEngineContext.checkAllPlayed();
nicholas@944 746 if (hasBeenPlayed.length == 0) {
nicholas@944 747 if (audioEngineContext.status == 1) {
nicholas@944 748 var playback = document.getElementById('playback-button');
nicholas@944 749 playback.click();
nicholas@944 750 // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options
nicholas@944 751 } else
nicholas@944 752 {
nicholas@944 753 if (audioEngineContext.timer.testStarted == false)
nicholas@944 754 {
nicholas@944 755 alert('You have not started the test! Please press start to begin the test!');
nicholas@944 756 return;
nicholas@944 757 }
nicholas@944 758 }
nicholas@944 759 if (currentState.substr(0,7) == 'testRun')
nicholas@944 760 {
nicholas@944 761 hasBeenPlayed = []; // clear array to prepare for next test
nicholas@944 762 audioEngineContext.timer.stopTest();
nicholas@944 763 advanceState();
nicholas@944 764 }
BrechtDeMan@940 765 } else // if a fragment has not been played yet
BrechtDeMan@940 766 {
nicholas@944 767 str = "";
nicholas@944 768 if (hasBeenPlayed.length > 1) {
nicholas@944 769 for (var i=0; i<hasBeenPlayed.length; i++) {
nicholas@944 770 str = str + hasBeenPlayed[i];
nicholas@944 771 if (i < hasBeenPlayed.length-2){
nicholas@944 772 str += ", ";
nicholas@944 773 } else if (i == hasBeenPlayed.length-2) {
nicholas@944 774 str += " or ";
nicholas@944 775 }
nicholas@944 776 }
nicholas@944 777 alert('You have not played fragments ' + str + ' yet. Please listen, rate and comment all samples before submitting.');
nicholas@944 778 } else {
nicholas@944 779 alert('You have not played fragment ' + hasBeenPlayed[0] + ' yet. Please listen, rate and comment all samples before submitting.');
nicholas@944 780 }
BrechtDeMan@940 781 return;
BrechtDeMan@940 782 }
BrechtDeMan@938 783 }
BrechtDeMan@938 784
BrechtDeMan@938 785 function convSliderPosToRate(id)
BrechtDeMan@938 786 {
BrechtDeMan@938 787 var w = document.getElementById('slider').style.width;
BrechtDeMan@938 788 var maxPix = w.substr(0,w.length-2);
BrechtDeMan@938 789 var slider = document.getElementsByClassName('track-slider')[id];
BrechtDeMan@938 790 var pix = slider.style.left;
BrechtDeMan@938 791 pix = pix.substr(0,pix.length-2);
BrechtDeMan@938 792 var rate = (pix-42)/maxPix;
BrechtDeMan@938 793 return rate;
BrechtDeMan@938 794 }
BrechtDeMan@938 795
BrechtDeMan@938 796 function pageXMLSave(testId)
BrechtDeMan@938 797 {
BrechtDeMan@938 798 // Saves a specific test page
BrechtDeMan@938 799 var xmlDoc = currentTestHolder;
BrechtDeMan@938 800 // Check if any session wide metrics are enabled
BrechtDeMan@938 801
BrechtDeMan@938 802 var commentShow = testXMLSetups[testId].attributes['elementComments'];
BrechtDeMan@938 803 if (commentShow != undefined) {
BrechtDeMan@938 804 if (commentShow.value == 'false') {commentShow = false;}
BrechtDeMan@938 805 else {commentShow = true;}
BrechtDeMan@938 806 } else {commentShow = true;}
BrechtDeMan@938 807
BrechtDeMan@938 808 var metric = document.createElement('metric');
BrechtDeMan@938 809 if (audioEngineContext.metric.enableTestTimer)
BrechtDeMan@938 810 {
BrechtDeMan@938 811 var testTime = document.createElement('metricResult');
BrechtDeMan@938 812 testTime.id = 'testTime';
BrechtDeMan@938 813 testTime.textContent = audioEngineContext.timer.testDuration;
BrechtDeMan@938 814 metric.appendChild(testTime);
BrechtDeMan@938 815 }
BrechtDeMan@938 816 xmlDoc.appendChild(metric);
BrechtDeMan@938 817 var trackSliderObjects = document.getElementsByClassName('track-slider');
BrechtDeMan@938 818 var commentObjects = document.getElementsByClassName('comment-div');
BrechtDeMan@938 819 for (var i=0; i<trackSliderObjects.length; i++)
BrechtDeMan@938 820 {
BrechtDeMan@938 821 var audioElement = document.createElement('audioElement');
BrechtDeMan@938 822 audioElement.id = currentTrackOrder[i].attributes['id'].value;
BrechtDeMan@938 823 audioElement.url = currentTrackOrder[i].attributes['url'].value;
BrechtDeMan@938 824 var value = document.createElement('value');
BrechtDeMan@938 825 value.innerHTML = convSliderPosToRate(i);
BrechtDeMan@938 826 if (commentShow) {
BrechtDeMan@938 827 var comment = document.createElement("comment");
BrechtDeMan@938 828 var question = document.createElement("question");
BrechtDeMan@938 829 var response = document.createElement("response");
BrechtDeMan@938 830 question.textContent = commentObjects[i].children[0].textContent;
BrechtDeMan@938 831 response.textContent = commentObjects[i].children[2].value;
BrechtDeMan@938 832 comment.appendChild(question);
BrechtDeMan@938 833 comment.appendChild(response);
BrechtDeMan@938 834 audioElement.appendChild(comment);
BrechtDeMan@938 835 }
BrechtDeMan@938 836 audioElement.appendChild(value);
BrechtDeMan@938 837 // Check for any per element metrics
BrechtDeMan@938 838 var metric = document.createElement('metric');
BrechtDeMan@938 839 var elementMetric = audioEngineContext.audioObjects[i].metric;
BrechtDeMan@938 840 if (audioEngineContext.metric.enableElementTimer) {
BrechtDeMan@938 841 var elementTimer = document.createElement('metricResult');
BrechtDeMan@938 842 elementTimer.id = 'elementTimer';
BrechtDeMan@938 843 elementTimer.textContent = elementMetric.listenedTimer;
BrechtDeMan@938 844 metric.appendChild(elementTimer);
BrechtDeMan@938 845 }
BrechtDeMan@938 846 if (audioEngineContext.metric.enableElementTracker) {
BrechtDeMan@938 847 var elementTrackerFull = document.createElement('metricResult');
BrechtDeMan@938 848 elementTrackerFull.id = 'elementTrackerFull';
BrechtDeMan@938 849 var data = elementMetric.movementTracker;
BrechtDeMan@938 850 for (var k=0; k<data.length; k++)
BrechtDeMan@938 851 {
BrechtDeMan@938 852 var timePos = document.createElement('timePos');
BrechtDeMan@938 853 timePos.id = k;
BrechtDeMan@938 854 var time = document.createElement('time');
BrechtDeMan@938 855 time.textContent = data[k][0];
BrechtDeMan@938 856 var position = document.createElement('position');
BrechtDeMan@938 857 position.textContent = data[k][1];
BrechtDeMan@938 858 timePos.appendChild(time);
BrechtDeMan@938 859 timePos.appendChild(position);
BrechtDeMan@938 860 elementTrackerFull.appendChild(timePos);
BrechtDeMan@938 861 }
BrechtDeMan@938 862 metric.appendChild(elementTrackerFull);
BrechtDeMan@938 863 }
BrechtDeMan@938 864 if (audioEngineContext.metric.enableElementInitialPosition) {
BrechtDeMan@938 865 var elementInitial = document.createElement('metricResult');
BrechtDeMan@938 866 elementInitial.id = 'elementInitialPosition';
BrechtDeMan@938 867 elementInitial.textContent = elementMetric.initialPosition;
BrechtDeMan@938 868 metric.appendChild(elementInitial);
BrechtDeMan@938 869 }
BrechtDeMan@938 870 if (audioEngineContext.metric.enableFlagListenedTo) {
BrechtDeMan@938 871 var flagListenedTo = document.createElement('metricResult');
BrechtDeMan@938 872 flagListenedTo.id = 'elementFlagListenedTo';
BrechtDeMan@938 873 flagListenedTo.textContent = elementMetric.wasListenedTo;
BrechtDeMan@938 874 metric.appendChild(flagListenedTo);
BrechtDeMan@938 875 }
BrechtDeMan@938 876 if (audioEngineContext.metric.enableFlagMoved) {
BrechtDeMan@938 877 var flagMoved = document.createElement('metricResult');
BrechtDeMan@938 878 flagMoved.id = 'elementFlagMoved';
BrechtDeMan@938 879 flagMoved.textContent = elementMetric.wasMoved;
BrechtDeMan@938 880 metric.appendChild(flagMoved);
BrechtDeMan@938 881 }
BrechtDeMan@938 882 if (audioEngineContext.metric.enableFlagComments) {
BrechtDeMan@938 883 var flagComments = document.createElement('metricResult');
BrechtDeMan@938 884 flagComments.id = 'elementFlagComments';
BrechtDeMan@938 885 if (response.textContent.length == 0) {flag.textContent = 'false';}
BrechtDeMan@938 886 else {flag.textContet = 'true';}
BrechtDeMan@938 887 metric.appendChild(flagComments);
BrechtDeMan@938 888 }
BrechtDeMan@938 889 audioElement.appendChild(metric);
BrechtDeMan@938 890 xmlDoc.appendChild(audioElement);
BrechtDeMan@938 891 }
BrechtDeMan@938 892 var commentQuestion = document.getElementsByClassName('commentQuestion');
BrechtDeMan@938 893 for (var i=0; i<commentQuestion.length; i++)
BrechtDeMan@938 894 {
BrechtDeMan@938 895 var cqHolder = document.createElement('CommentQuestion');
BrechtDeMan@938 896 var comment = document.createElement('comment');
BrechtDeMan@938 897 var question = document.createElement('question');
BrechtDeMan@938 898 cqHolder.id = commentQuestion[i].id;
BrechtDeMan@938 899 comment.textContent = commentQuestion[i].children[2].value;
BrechtDeMan@938 900 question.textContent = commentQuestion[i].children[0].textContent;
BrechtDeMan@938 901 cqHolder.appendChild(question);
BrechtDeMan@938 902 cqHolder.appendChild(comment);
BrechtDeMan@938 903 xmlDoc.appendChild(cqHolder);
BrechtDeMan@938 904 }
BrechtDeMan@938 905 testResultsHolders[testId] = xmlDoc;
BrechtDeMan@938 906 }
BrechtDeMan@938 907
BrechtDeMan@938 908 // Only other global function which must be defined in the interface class. Determines how to create the XML document.
BrechtDeMan@938 909 function interfaceXMLSave(){
BrechtDeMan@938 910 // Create the XML string to be exported with results
BrechtDeMan@938 911 var xmlDoc = document.createElement("BrowserEvaluationResult");
BrechtDeMan@938 912 for (var i=0; i<testResultsHolders.length; i++)
BrechtDeMan@938 913 {
BrechtDeMan@938 914 xmlDoc.appendChild(testResultsHolders[i]);
BrechtDeMan@938 915 }
BrechtDeMan@938 916 // Append Pre/Post Questions
BrechtDeMan@938 917 xmlDoc.appendChild(preTestQuestions);
BrechtDeMan@938 918 xmlDoc.appendChild(postTestQuestions);
BrechtDeMan@938 919
BrechtDeMan@938 920 return xmlDoc;
BrechtDeMan@938 921 }