annotate ape.js @ 937:b5262d076f0b

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