Mercurial > hg > webaudioevaluationtool
comparison core.js @ 278:8020152a36af
Pull into main
author | Nicholas Jillings <nicholas.jillings@eecs.qmul.ac.uk> |
---|---|
date | Fri, 24 Jul 2015 18:59:39 +0100 |
parents | 724f72092fa7 |
children | 7e9c38fa7499 |
comparison
equal
deleted
inserted
replaced
264:4345ba8a1b6e | 278:8020152a36af |
---|---|
103 this.popup.style.zIndex = 3; | 103 this.popup.style.zIndex = 3; |
104 this.popup.style.visibility = 'visible'; | 104 this.popup.style.visibility = 'visible'; |
105 var blank = document.getElementsByClassName('testHalt')[0]; | 105 var blank = document.getElementsByClassName('testHalt')[0]; |
106 blank.style.zIndex = 2; | 106 blank.style.zIndex = 2; |
107 blank.style.visibility = 'visible'; | 107 blank.style.visibility = 'visible'; |
108 $(window).keypress(function(e){ | |
109 if (e.keyCode == 13 && popup.popup.style.visibility == 'visible') | |
110 { | |
111 // Enter key pressed | |
112 var textarea = $(popup.popupContent).find('textarea'); | |
113 if (textarea.length != 0) | |
114 { | |
115 if (textarea[0] == document.activeElement) | |
116 {return;} | |
117 } | |
118 popup.buttonProceed.onclick(); | |
119 } | |
120 }); | |
108 }; | 121 }; |
109 | 122 |
110 this.hidePopup = function(){ | 123 this.hidePopup = function(){ |
111 this.popup.style.zIndex = -1; | 124 this.popup.style.zIndex = -1; |
112 this.popup.style.visibility = 'hidden'; | 125 this.popup.style.visibility = 'hidden'; |
210 if (node.step != null) {input.step = node.step;} | 223 if (node.step != null) {input.step = node.step;} |
211 this.popupContent.appendChild(input); | 224 this.popupContent.appendChild(input); |
212 } | 225 } |
213 this.popupContent.appendChild(this.buttonProceed); | 226 this.popupContent.appendChild(this.buttonProceed); |
214 if(this.currentIndex+1 == this.popupOptions.length) { | 227 if(this.currentIndex+1 == this.popupOptions.length) { |
215 this.buttonProceed.textContent = 'Submit'; | 228 if (this.responses.nodeName == "PRETEST") { |
229 this.buttonProceed.textContent = 'Start'; | |
230 } else { | |
231 this.buttonProceed.textContent = 'Submit'; | |
232 } | |
216 } else { | 233 } else { |
217 this.buttonProceed.textContent = 'Next'; | 234 this.buttonProceed.textContent = 'Next'; |
218 } | 235 } |
219 if(this.currentIndex > 0) | 236 if(this.currentIndex > 0) |
220 this.popupContent.appendChild(this.buttonPrevious); | 237 this.popupContent.appendChild(this.buttonPrevious); |
535 | 552 |
536 // New check if we need to randomise the test order | 553 // New check if we need to randomise the test order |
537 if (specification.randomiseOrder) | 554 if (specification.randomiseOrder) |
538 { | 555 { |
539 specification.audioHolders = randomiseOrder(specification.audioHolders); | 556 specification.audioHolders = randomiseOrder(specification.audioHolders); |
557 for (var i=0; i<specification.audioHolders.length; i++) | |
558 { | |
559 specification.audioHolders[i].presentedId = i; | |
560 } | |
540 } | 561 } |
541 | 562 |
542 $(specification.audioHolders).each(function(index,elem){ | 563 $(specification.audioHolders).each(function(index,elem){ |
543 testState.stateMap.push(elem); | 564 testState.stateMap.push(elem); |
544 }); | 565 }); |
629 }; | 650 }; |
630 xmlhttp.onreadystatechange = function() { | 651 xmlhttp.onreadystatechange = function() { |
631 console.log(xmlhttp.status); | 652 console.log(xmlhttp.status); |
632 if (xmlhttp.status != 200 && xmlhttp.readyState == 4) { | 653 if (xmlhttp.status != 200 && xmlhttp.readyState == 4) { |
633 createProjectSave(null); | 654 createProjectSave(null); |
655 } else { | |
656 popup.showPopup(); | |
657 popup.popupContent.innerHTML = null; | |
658 popup.popupContent.textContent = "Thank you for performing this listening test"; | |
634 } | 659 } |
635 }; | 660 }; |
636 xmlhttp.send(file); | 661 xmlhttp.send(file); |
637 } | 662 } |
638 } | 663 } |
711 if (this.audioObjectsReady == false) { | 736 if (this.audioObjectsReady == false) { |
712 this.audioObjectsReady = this.checkAllReady(); | 737 this.audioObjectsReady = this.checkAllReady(); |
713 } | 738 } |
714 if (this.audioObjectsReady == true) { | 739 if (this.audioObjectsReady == true) { |
715 this.timer.startTest(); | 740 this.timer.startTest(); |
741 if (this.loopPlayback) | |
742 {this.setSynchronousLoop();} | |
716 this.status = 1; | 743 this.status = 1; |
717 } | 744 } |
718 } | 745 } |
719 if (this.status== 1) { | 746 if (this.status== 1) { |
720 if (id == undefined) { | 747 if (id == undefined) { |
799 console.log('WAIT -- audioObject '+i+' not ready yet!'); | 826 console.log('WAIT -- audioObject '+i+' not ready yet!'); |
800 ready = false; | 827 ready = false; |
801 }; | 828 }; |
802 } | 829 } |
803 return ready; | 830 return ready; |
831 }; | |
832 | |
833 this.setSynchronousLoop = function() { | |
834 // Pads the signals so they are all exactly the same length | |
835 if (this.audioObjectsReady) | |
836 { | |
837 var length = 0; | |
838 var lens = []; | |
839 var maxId; | |
840 for (var i=0; i<this.audioObjects.length; i++) | |
841 { | |
842 lens.push(this.audioObjects[i].buffer.length); | |
843 if (length < this.audioObjects[i].buffer.length) | |
844 { | |
845 length = this.audioObjects[i].buffer.length; | |
846 maxId = i; | |
847 } | |
848 } | |
849 // Perform difference | |
850 for (var i=0; i<lens.length; i++) | |
851 { | |
852 lens[i] = length - lens[i]; | |
853 } | |
854 // Extract the audio and zero-pad | |
855 for (var i=0; i<lens.length; i++) | |
856 { | |
857 var orig = this.audioObjects[i].buffer; | |
858 var hold = audioContext.createBuffer(orig.numberOfChannels,length,orig.sampleRate); | |
859 for (var c=0; c<orig.numberOfChannels; c++) | |
860 { | |
861 var inData = hold.getChannelData(c); | |
862 var outData = orig.getChannelData(c); | |
863 for (var n=0; n<orig.length; n++) | |
864 {inData[n] = outData[n];} | |
865 } | |
866 this.audioObjects[i].buffer = hold; | |
867 delete orig; | |
868 } | |
869 } | |
804 }; | 870 }; |
805 | 871 |
806 } | 872 } |
807 | 873 |
808 function audioObject(id) { | 874 function audioObject(id) { |
903 // Create callback to decode the data asynchronously | 969 // Create callback to decode the data asynchronously |
904 request.onloadend = function() { | 970 request.onloadend = function() { |
905 audioContext.decodeAudioData(request.response, function(decodedData) { | 971 audioContext.decodeAudioData(request.response, function(decodedData) { |
906 audioObj.buffer = decodedData; | 972 audioObj.buffer = decodedData; |
907 audioObj.state = 1; | 973 audioObj.state = 1; |
974 if (audioObj.specification.type != 'outsidereference') | |
975 {audioObj.interfaceDOM.enable();} | |
908 }, function(){ | 976 }, function(){ |
909 // Should only be called if there was an error, but sometimes gets called continuously | 977 // Should only be called if there was an error, but sometimes gets called continuously |
910 // Check here if the error is genuine | 978 // Check here if the error is genuine |
911 if (audioObj.state == 0 || audioObj.buffer == undefined) { | 979 if (audioObj.state == 0 || audioObj.buffer == undefined) { |
912 // Genuine error | 980 // Genuine error |
934 file.setAttribute('duration',this.buffer.duration); | 1002 file.setAttribute('duration',this.buffer.duration); |
935 root.appendChild(file); | 1003 root.appendChild(file); |
936 if (this.specification.type != 'outsidereference') { | 1004 if (this.specification.type != 'outsidereference') { |
937 root.appendChild(this.interfaceDOM.exportXMLDOM(this)); | 1005 root.appendChild(this.interfaceDOM.exportXMLDOM(this)); |
938 root.appendChild(this.commentDOM.exportXMLDOM(this)); | 1006 root.appendChild(this.commentDOM.exportXMLDOM(this)); |
1007 if(this.specification.type == 'anchor') { | |
1008 root.setAttribute('anchor',true); | |
1009 } else if(this.specification.type == 'reference') { | |
1010 root.setAttribute('reference',true); | |
1011 } | |
939 } | 1012 } |
940 root.appendChild(this.metric.exportXMLDOM()); | 1013 root.appendChild(this.metric.exportXMLDOM()); |
941 return root; | 1014 return root; |
942 }; | 1015 }; |
943 } | 1016 } |
1310 this.max = Number(this.max); | 1383 this.max = Number(this.max); |
1311 } | 1384 } |
1312 } | 1385 } |
1313 } else if (this.type == 'anchor' || this.type == 'reference') { | 1386 } else if (this.type == 'anchor' || this.type == 'reference') { |
1314 this.value = Number(child.textContent); | 1387 this.value = Number(child.textContent); |
1388 this.enforce = child.getAttribute('enforce'); | |
1389 if (this.enforce == 'true') {this.enforce = true;} | |
1390 else {this.enforce = false;} | |
1315 } | 1391 } |
1316 }; | 1392 }; |
1317 this.options = []; | 1393 this.options = []; |
1318 if (commonInterfaceNode != undefined) { | 1394 if (commonInterfaceNode != undefined) { |
1319 var child = commonInterfaceNode.firstElementChild; | 1395 var child = commonInterfaceNode.firstElementChild; |
1403 this.enabled = name; | 1479 this.enabled = name; |
1404 }; | 1480 }; |
1405 | 1481 |
1406 this.audioHolderNode = function(parent,xml) { | 1482 this.audioHolderNode = function(parent,xml) { |
1407 this.type = 'audioHolder'; | 1483 this.type = 'audioHolder'; |
1484 this.presentedId = parent.audioHolders.length; | |
1408 this.interfaceNode = function(DOM) { | 1485 this.interfaceNode = function(DOM) { |
1409 var title = DOM.getElementsByTagName('title'); | 1486 var title = DOM.getElementsByTagName('title'); |
1410 if (title.length == 0) {this.title = null;} | 1487 if (title.length == 0) {this.title = null;} |
1411 else {this.title = title[0].textContent;} | 1488 else {this.title = title[0].textContent;} |
1412 this.options = parent.commonInterface.options; | 1489 this.options = parent.commonInterface.options; |
1432 else {this.reference = false;} | 1509 else {this.reference = false;} |
1433 | 1510 |
1434 this.marker = xml.getAttribute('marker'); | 1511 this.marker = xml.getAttribute('marker'); |
1435 if (this.marker == null) {this.marker = undefined;} | 1512 if (this.marker == null) {this.marker = undefined;} |
1436 | 1513 |
1437 if (this.anchor == true && this.marker == undefined) { | 1514 if (this.anchor == true) { |
1515 if (this.marker != undefined) {this.enforce = true;} | |
1516 else {this.enforce = enforceAnchor;} | |
1438 this.marker = anchor; | 1517 this.marker = anchor; |
1439 } | 1518 } |
1440 else if (this.reference == true && this.marker == undefined) { | 1519 else if (this.reference == true) { |
1520 if (this.marker != undefined) {this.enforce = true;} | |
1521 else {this.enforce = enforceReference;} | |
1441 this.marker = reference; | 1522 this.marker = reference; |
1442 } | 1523 } |
1443 | 1524 |
1444 if (this.marker != undefined) { | 1525 if (this.marker != undefined) { |
1445 this.marker = Number(this.marker); | 1526 this.marker = Number(this.marker); |
1499 else {this.loop == false;} | 1580 else {this.loop == false;} |
1500 if (xml.getAttribute('elementComments') == "true") {this.elementComments = true;} | 1581 if (xml.getAttribute('elementComments') == "true") {this.elementComments = true;} |
1501 else {this.elementComments = false;} | 1582 else {this.elementComments = false;} |
1502 | 1583 |
1503 var anchor = xml.getElementsByTagName('anchor'); | 1584 var anchor = xml.getElementsByTagName('anchor'); |
1585 var enforceAnchor = false; | |
1504 if (anchor.length == 0) { | 1586 if (anchor.length == 0) { |
1505 // Find anchor in commonInterface; | 1587 // Find anchor in commonInterface; |
1506 for (var i=0; i<parent.commonInterface.options.length; i++) { | 1588 for (var i=0; i<parent.commonInterface.options.length; i++) { |
1507 if(parent.commonInterface.options[i].type == 'anchor') { | 1589 if(parent.commonInterface.options[i].type == 'anchor') { |
1508 anchor = parent.commonInterface.options[i].value; | 1590 anchor = parent.commonInterface.options[i].value; |
1591 enforceAnchor = parent.commonInterface.options[i].enforce; | |
1509 break; | 1592 break; |
1510 } | 1593 } |
1511 } | 1594 } |
1512 if (typeof(anchor) == "object") { | 1595 if (typeof(anchor) == "object") { |
1513 anchor = null; | 1596 anchor = null; |
1515 } else { | 1598 } else { |
1516 anchor = anchor[0].textContent; | 1599 anchor = anchor[0].textContent; |
1517 } | 1600 } |
1518 | 1601 |
1519 var reference = xml.getElementsByTagName('anchor'); | 1602 var reference = xml.getElementsByTagName('anchor'); |
1603 var enforceReference = false; | |
1520 if (reference.length == 0) { | 1604 if (reference.length == 0) { |
1521 // Find anchor in commonInterface; | 1605 // Find anchor in commonInterface; |
1522 for (var i=0; i<parent.commonInterface.options.length; i++) { | 1606 for (var i=0; i<parent.commonInterface.options.length; i++) { |
1523 if(parent.commonInterface.options[i].type == 'reference') { | 1607 if(parent.commonInterface.options[i].type == 'reference') { |
1524 reference = parent.commonInterface.options[i].value; | 1608 reference = parent.commonInterface.options[i].value; |
1609 enforceReference = parent.commonInterface.options[i].enforce; | |
1525 break; | 1610 break; |
1526 } | 1611 } |
1527 } | 1612 } |
1528 if (typeof(reference) == "object") { | 1613 if (typeof(reference) == "object") { |
1529 reference = null; | 1614 reference = null; |
1941 | 2026 |
1942 this.update = function() { | 2027 this.update = function() { |
1943 // Update the playhead position, startPlay must be called | 2028 // Update the playhead position, startPlay must be called |
1944 if (this.timePerPixel > 0) { | 2029 if (this.timePerPixel > 0) { |
1945 var time = this.playbackObject.getCurrentPosition(); | 2030 var time = this.playbackObject.getCurrentPosition(); |
1946 var width = 490; | 2031 if (time > 0) { |
1947 var pix = Math.floor(time/this.timePerPixel); | 2032 var width = 490; |
1948 this.scrubberHead.style.left = pix+'px'; | 2033 var pix = Math.floor(time/this.timePerPixel); |
1949 if (this.maxTime > 60.0) { | 2034 this.scrubberHead.style.left = pix+'px'; |
1950 var secs = time%60; | 2035 if (this.maxTime > 60.0) { |
1951 var mins = Math.floor((time-secs)/60); | 2036 var secs = time%60; |
1952 secs = secs.toString(); | 2037 var mins = Math.floor((time-secs)/60); |
1953 secs = secs.substr(0,2); | 2038 secs = secs.toString(); |
1954 mins = mins.toString(); | 2039 secs = secs.substr(0,2); |
1955 this.curTimeSpan.textContent = mins+':'+secs; | 2040 mins = mins.toString(); |
2041 this.curTimeSpan.textContent = mins+':'+secs; | |
2042 } else { | |
2043 time = time.toString(); | |
2044 this.curTimeSpan.textContent = time.substr(0,4); | |
2045 } | |
1956 } else { | 2046 } else { |
1957 time = time.toString(); | 2047 this.scrubberHead.style.left = '0px'; |
1958 this.curTimeSpan.textContent = time.substr(0,4); | 2048 if (this.maxTime < 60) { |
2049 this.curTimeSpan.textContent = '0.00'; | |
2050 } else { | |
2051 this.curTimeSpan.textContent = '00:00'; | |
2052 } | |
1959 } | 2053 } |
1960 } | 2054 } |
1961 }; | 2055 }; |
1962 | 2056 |
1963 this.interval = undefined; | 2057 this.interval = undefined; |
1964 | 2058 |
1965 this.start = function() { | 2059 this.start = function() { |
1966 if (this.playbackObject != undefined && this.interval == undefined) { | 2060 if (this.playbackObject != undefined && this.interval == undefined) { |
1967 this.interval = setInterval(function(){interfaceContext.playhead.update();},100); | 2061 if (this.maxTime < 60) { |
2062 this.interval = setInterval(function(){interfaceContext.playhead.update();},10); | |
2063 } else { | |
2064 this.interval = setInterval(function(){interfaceContext.playhead.update();},100); | |
2065 } | |
1968 } | 2066 } |
1969 }; | 2067 }; |
1970 this.stop = function() { | 2068 this.stop = function() { |
1971 clearInterval(this.interval); | 2069 clearInterval(this.interval); |
1972 this.interval = undefined; | 2070 this.interval = undefined; |
2071 if (this.maxTime < 60) { | |
2072 this.curTimeSpan.textContent = '0.00'; | |
2073 } else { | |
2074 this.curTimeSpan.textContent = '00:00'; | |
2075 } | |
1973 }; | 2076 }; |
1974 }; | 2077 }; |
1975 | 2078 |
1976 // Global Checkers | 2079 // Global Checkers |
1977 // These functions will help enforce the checkers | 2080 // These functions will help enforce the checkers |
1979 { | 2082 { |
1980 var audioHolder = testState.currentStateMap[testState.currentIndex]; | 2083 var audioHolder = testState.currentStateMap[testState.currentIndex]; |
1981 if (audioHolder.anchorId != null) | 2084 if (audioHolder.anchorId != null) |
1982 { | 2085 { |
1983 var audioObject = audioEngineContext.audioObjects[audioHolder.anchorId]; | 2086 var audioObject = audioEngineContext.audioObjects[audioHolder.anchorId]; |
1984 if (audioObject.interfaceDOM.getValue() > audioObject.specification.marker) | 2087 if (audioObject.interfaceDOM.getValue() > audioObject.specification.marker && audioObject.interfaceDOM.enforce == true) |
1985 { | 2088 { |
1986 // Anchor is not set below | 2089 // Anchor is not set below |
1987 console.log('Anchor node not below marker value'); | 2090 console.log('Anchor node not below marker value'); |
1988 alert('Please keep listening'); | 2091 alert('Please keep listening'); |
1989 return false; | 2092 return false; |
1996 { | 2099 { |
1997 var audioHolder = testState.currentStateMap[testState.currentIndex]; | 2100 var audioHolder = testState.currentStateMap[testState.currentIndex]; |
1998 if (audioHolder.referenceId != null) | 2101 if (audioHolder.referenceId != null) |
1999 { | 2102 { |
2000 var audioObject = audioEngineContext.audioObjects[audioHolder.referenceId]; | 2103 var audioObject = audioEngineContext.audioObjects[audioHolder.referenceId]; |
2001 if (audioObject.interfaceDOM.getValue() < audioObject.specification.marker) | 2104 if (audioObject.interfaceDOM.getValue() < audioObject.specification.marker && audioObject.interfaceDOM.enforce == true) |
2002 { | 2105 { |
2003 // Anchor is not set below | 2106 // Anchor is not set below |
2004 console.log('Reference node not above marker value'); | 2107 console.log('Reference node not above marker value'); |
2005 alert('Please keep listening'); | 2108 alert('Please keep listening'); |
2006 return false; | 2109 return false; |