comparison js/core.js @ 2678:e446c9b43cd9

#180. More JSHint corrections
author Nicholas Jillings <nicholas.jillings@mail.bcu.ac.uk>
date Wed, 01 Mar 2017 10:24:06 +0000
parents 68bc1003770a
children 628f447a021b
comparison
equal deleted inserted replaced
2677:68bc1003770a 2678:e446c9b43cd9
1212 this.initialise = function () { 1212 this.initialise = function () {
1213 1213
1214 // Get the data from Specification 1214 // Get the data from Specification
1215 var pagePool = []; 1215 var pagePool = [];
1216 var pageInclude = []; 1216 var pageInclude = [];
1217 for (var page of specification.pages) { 1217 for (var i = 0; i < specification.pages.length; i++) {
1218 var page = specification.pages[i];
1218 if (page.alwaysInclude) { 1219 if (page.alwaysInclude) {
1219 pageInclude.push(page); 1220 pageInclude.push(page);
1220 } else { 1221 } else {
1221 pagePool.push(page); 1222 pagePool.push(page);
1222 } 1223 }
1226 var numPages = specification.poolSize; 1227 var numPages = specification.poolSize;
1227 if (numPages > pagePool.length) { 1228 if (numPages > pagePool.length) {
1228 console.log("WARNING - You have specified more pages in <setup poolSize> than you have created!!"); 1229 console.log("WARNING - You have specified more pages in <setup poolSize> than you have created!!");
1229 numPages = specification.pages.length; 1230 numPages = specification.pages.length;
1230 } 1231 }
1231 if (specification.poolSize == 0) { 1232 if (specification.poolSize === 0) {
1232 numPages = specification.pages.length; 1233 numPages = specification.pages.length;
1233 } 1234 }
1234 numPages -= pageInclude.length; 1235 numPages -= pageInclude.length;
1235 1236
1236 if (numPages > 0) { 1237 if (numPages > 0) {
1252 } 1253 }
1253 for (var i = 0; i < pageInclude.length; i++) { 1254 for (var i = 0; i < pageInclude.length; i++) {
1254 pageInclude[i].presentedId = i; 1255 pageInclude[i].presentedId = i;
1255 this.stateMap.push(pageInclude[i]); 1256 this.stateMap.push(pageInclude[i]);
1256 // For each selected page, we must get the sub pool 1257 // For each selected page, we must get the sub pool
1257 if (pageInclude[i].poolSize != 0 && pageInclude[i].poolSize != pageInclude[i].audioElements.length) { 1258 if (pageInclude[i].poolSize !== 0 && pageInclude[i].poolSize !== pageInclude[i].audioElements.length) {
1258 var elemInclude = []; 1259 var elemInclude = [];
1259 var elemPool = []; 1260 var elemPool = [];
1260 for (var elem of pageInclude[i].audioElements) { 1261 for (var elem of pageInclude[i].audioElements) {
1261 if (elem.alwaysInclude || elem.type != "normal") { 1262 if (elem.alwaysInclude || elem.type != "normal") {
1262 elemInclude.push(elem); 1263 elemInclude.push(elem);
1269 } 1270 }
1270 storage.createTestPageStore(pageInclude[i]); 1271 storage.createTestPageStore(pageInclude[i]);
1271 audioEngineContext.loadPageData(pageInclude[i]); 1272 audioEngineContext.loadPageData(pageInclude[i]);
1272 } 1273 }
1273 1274
1274 if (specification.preTest != null) { 1275 if (specification.preTest !== null) {
1275 this.preTestSurvey = specification.preTest; 1276 this.preTestSurvey = specification.preTest;
1276 } 1277 }
1277 if (specification.postTest != null) { 1278 if (specification.postTest !== null) {
1278 this.postTestSurvey = specification.postTest; 1279 this.postTestSurvey = specification.postTest;
1279 } 1280 }
1280 1281
1281 if (this.stateMap.length > 0) { 1282 if (this.stateMap.length > 0) {
1282 if (this.stateIndex != null) { 1283 if (this.stateIndex !== null) {
1283 console.log('NOTE - State already initialise'); 1284 console.log('NOTE - State already initialise');
1284 } 1285 }
1285 this.stateIndex = -2; 1286 this.stateIndex = -2;
1286 console.log('Starting test...'); 1287 console.log('Starting test...');
1287 } else { 1288 } else {
1288 console.log('FATAL - StateMap not correctly constructed. EMPTY_STATE_MAP'); 1289 console.log('FATAL - StateMap not correctly constructed. EMPTY_STATE_MAP');
1289 } 1290 }
1290 }; 1291 };
1291 this.advanceState = function () { 1292 this.advanceState = function () {
1292 if (this.stateIndex == null) { 1293 if (this.stateIndex === null) {
1293 this.initialise(); 1294 this.initialise();
1294 } 1295 }
1295 if (this.stateIndex > -2) { 1296 if (this.stateIndex > -2) {
1296 storage.update(); 1297 storage.update();
1297 } 1298 }
1298 if (this.stateIndex == -2) { 1299 if (this.stateIndex == -2) {
1299 this.stateIndex++; 1300 this.stateIndex++;
1300 if (this.preTestSurvey != null) { 1301 if (this.preTestSurvey !== null) {
1301 popup.initState(this.preTestSurvey, storage.globalPreTest); 1302 popup.initState(this.preTestSurvey, storage.globalPreTest);
1302 } else { 1303 } else {
1303 this.advanceState(); 1304 this.advanceState();
1304 } 1305 }
1305 } else if (this.stateIndex == -1) { 1306 } else if (this.stateIndex == -1) {
1315 } 1316 }
1316 } else if (this.stateIndex == this.stateMap.length) { 1317 } else if (this.stateIndex == this.stateMap.length) {
1317 // All test pages complete, post test 1318 // All test pages complete, post test
1318 console.log('Ending test ...'); 1319 console.log('Ending test ...');
1319 this.stateIndex++; 1320 this.stateIndex++;
1320 if (this.postTestSurvey == null) { 1321 if (this.postTestSurvey === null) {
1321 this.advanceState(); 1322 this.advanceState();
1322 } else { 1323 } else {
1323 popup.initState(this.postTestSurvey, storage.globalPostTest); 1324 popup.initState(this.postTestSurvey, storage.globalPostTest);
1324 } 1325 }
1325 } else if (this.stateIndex > this.stateMap.length) { 1326 } else if (this.stateIndex > this.stateMap.length) {
1326 createProjectSave(specification.projectReturn); 1327 createProjectSave(specification.projectReturn);
1327 } else { 1328 } else {
1328 popup.hidePopup(); 1329 popup.hidePopup();
1329 if (this.currentStateMap == null) { 1330 if (this.currentStateMap === null) {
1330 this.currentStateMap = this.stateMap[this.stateIndex]; 1331 this.currentStateMap = this.stateMap[this.stateIndex];
1331 // Find and extract the outside reference 1332 // Find and extract the outside reference
1332 var elements = [], 1333 var elements = [],
1333 ref = []; 1334 ref = [];
1334 var elem; 1335 var elem;
1344 elements = randomiseOrder(elements); 1345 elements = randomiseOrder(elements);
1345 } 1346 }
1346 this.currentStateMap.audioElements = elements.concat(ref); 1347 this.currentStateMap.audioElements = elements.concat(ref);
1347 1348
1348 this.currentStore = storage.testPages[this.stateIndex]; 1349 this.currentStore = storage.testPages[this.stateIndex];
1349 if (this.currentStateMap.preTest != null) { 1350 if (this.currentStateMap.preTest !== null) {
1350 this.currentStatePosition = 'pre'; 1351 this.currentStatePosition = 'pre';
1351 popup.initState(this.currentStateMap.preTest, storage.testPages[this.stateIndex].preTest); 1352 popup.initState(this.currentStateMap.preTest, storage.testPages[this.stateIndex].preTest);
1352 } else { 1353 } else {
1353 this.currentStatePosition = 'test'; 1354 this.currentStatePosition = 'test';
1354 } 1355 }
1361 break; 1362 break;
1362 case 'test': 1363 case 'test':
1363 this.currentStatePosition = 'post'; 1364 this.currentStatePosition = 'post';
1364 // Save the data 1365 // Save the data
1365 this.testPageCompleted(); 1366 this.testPageCompleted();
1366 if (this.currentStateMap.postTest == null) { 1367 if (this.currentStateMap.postTest === null) {
1367 this.advanceState(); 1368 this.advanceState();
1368 return; 1369 return;
1369 } else { 1370 } else {
1370 popup.initState(this.currentStateMap.postTest, storage.testPages[this.stateIndex].postTest); 1371 popup.initState(this.currentStateMap.postTest, storage.testPages[this.stateIndex].postTest);
1371 } 1372 }
1373 case 'post': 1374 case 'post':
1374 this.stateIndex++; 1375 this.stateIndex++;
1375 this.currentStateMap = null; 1376 this.currentStateMap = null;
1376 this.advanceState(); 1377 this.advanceState();
1377 break; 1378 break;
1378 }; 1379 }
1379 } 1380 }
1380 }; 1381 };
1381 1382
1382 this.testPageCompleted = function () { 1383 this.testPageCompleted = function () {
1383 // Function called each time a test page has been completed 1384 // Function called each time a test page has been completed
1407 if (this.stateIndex >= 0 && this.stateIndex < this.stateMap.length) { 1408 if (this.stateIndex >= 0 && this.stateIndex < this.stateMap.length) {
1408 return this.currentStateMap; 1409 return this.currentStateMap;
1409 } else { 1410 } else {
1410 return null; 1411 return null;
1411 } 1412 }
1412 } 1413 };
1413 this.getCurrentTestPageStore = function () { 1414 this.getCurrentTestPageStore = function () {
1414 if (this.stateIndex >= 0 && this.stateIndex < this.stateMap.length) { 1415 if (this.stateIndex >= 0 && this.stateIndex < this.stateMap.length) {
1415 return this.currentStore; 1416 return this.currentStore;
1416 } else { 1417 } else {
1417 return null; 1418 return null;
1418 } 1419 }
1419 } 1420 };
1420 } 1421 }
1421 1422
1422 function AudioEngine(specification) { 1423 function AudioEngine(specification) {
1423 1424
1424 // Create two output paths, the main outputGain and fooGain. 1425 // Create two output paths, the main outputGain and fooGain.
1469 if (this.status >= 2) { 1470 if (this.status >= 2) {
1470 this.status = 3; 1471 this.status = 3;
1471 } 1472 }
1472 for (var i = 0; i < this.users.length; i++) { 1473 for (var i = 0; i < this.users.length; i++) {
1473 this.users[i].state = 1; 1474 this.users[i].state = 1;
1474 if (this.users[i].interfaceDOM != null) { 1475 if (this.users[i].interfaceDOM !== null) {
1475 this.users[i].bufferLoaded(this); 1476 this.users[i].bufferLoaded(this);
1476 } 1477 }
1477 } 1478 }
1478 }; 1479 };
1479 this.setUrls = function (obj) { 1480 this.setUrls = function (obj) {
1497 if (urls[i].url == checkUrl) { 1498 if (urls[i].url == checkUrl) {
1498 return true; 1499 return true;
1499 } 1500 }
1500 } 1501 }
1501 return false; 1502 return false;
1502 } 1503 };
1503 this.getMedia = function () { 1504 this.getMedia = function () {
1504 var self = this; 1505 var self = this;
1505 var currentUrlIndex = 0; 1506 var currentUrlIndex = 0;
1506 1507
1507 function get(fqurl) { 1508 function get(fqurl) {
1541 self.status = 2; 1542 self.status = 2;
1542 calculateLoudness(self, "I"); 1543 calculateLoudness(self, "I");
1543 return true; 1544 return true;
1544 }, function (e) { 1545 }, function (e) {
1545 var waveObj = new WAVE(); 1546 var waveObj = new WAVE();
1546 if (waveObj.open(response) == 0) { 1547 if (waveObj.open(response) === 0) {
1547 self.buffer = audioContext.createBuffer(waveObj.num_channels, waveObj.num_samples, waveObj.sample_rate); 1548 self.buffer = audioContext.createBuffer(waveObj.num_channels, waveObj.num_samples, waveObj.sample_rate);
1548 for (var c = 0; c < waveObj.num_channels; c++) { 1549 for (var c = 0; c < waveObj.num_channels; c++) {
1549 var buffer_ptr = self.buffer.getChannelData(c); 1550 var buffer_ptr = self.buffer.getChannelData(c);
1550 for (var n = 0; n < waveObj.num_samples; n++) { 1551 for (var n = 0; n < waveObj.num_samples; n++) {
1551 buffer_ptr[n] = waveObj.decoded_data[c][n]; 1552 buffer_ptr[n] = waveObj.decoded_data[c][n];
1552 } 1553 }
1553 } 1554 }
1554
1555 delete waveObj;
1556 } 1555 }
1557 if (self.buffer != undefined) { 1556 if (self.buffer !== undefined) {
1558 self.status = 2; 1557 self.status = 2;
1559 calculateLoudness(self, "I"); 1558 calculateLoudness(self, "I");
1560 return true; 1559 return true;
1561 } 1560 }
1561 waveObj = undefined;
1562 return false; 1562 return false;
1563 }); 1563 });
1564 } 1564 }
1565 1565
1566 // Create callback for any error in loading 1566 // Create callback for any error in loading
1567 function processError() { 1567 function processError() {
1568 this.status = -1; 1568 this.status = -1;
1569 for (var i = 0; i < this.users.length; i++) { 1569 for (var i = 0; i < this.users.length; i++) {
1570 this.users[i].state = -1; 1570 this.users[i].state = -1;
1571 if (this.users[i].interfaceDOM != null) { 1571 if (this.users[i].interfaceDOM !== null) {
1572 this.users[i].bufferLoaded(this); 1572 this.users[i].bufferLoaded(this);
1573 } 1573 }
1574 } 1574 }
1575 interfaceContext.lightbox.post("Error", "Could not load resource " + urls[currentUrlIndex].url); 1575 interfaceContext.lightbox.post("Error", "Could not load resource " + urls[currentUrlIndex].url);
1576 } 1576 }
1577 1577
1578 function progressCallback(event) { 1578 function progressCallback(event) {
1579 if (event.lengthComputable) { 1579 if (event.lengthComputable) {
1580 this.progress = event.loaded / event.total; 1580 this.progress = event.loaded / event.total;
1581 for (var i = 0; i < this.users.length; i++) { 1581 for (var i = 0; i < this.users.length; i++) {
1582 if (this.users[i].interfaceDOM != null) { 1582 if (this.users[i].interfaceDOM !== null) {
1583 if (typeof this.users[i].interfaceDOM.updateLoading === "function") { 1583 if (typeof this.users[i].interfaceDOM.updateLoading === "function") {
1584 this.users[i].interfaceDOM.updateLoading(this.progress * 100); 1584 this.users[i].interfaceDOM.updateLoading(this.progress * 100);
1585 } 1585 }
1586 } 1586 }
1587 } 1587 }
1609 } 1609 }
1610 }; 1610 };
1611 1611
1612 this.copyBuffer = function (preSilenceTime, postSilenceTime) { 1612 this.copyBuffer = function (preSilenceTime, postSilenceTime) {
1613 // Copies the entire bufferObj. 1613 // Copies the entire bufferObj.
1614 if (preSilenceTime == undefined) { 1614 if (preSilenceTime === undefined) {
1615 preSilenceTime = 0; 1615 preSilenceTime = 0;
1616 } 1616 }
1617 if (postSilenceTime == undefined) { 1617 if (postSilenceTime === undefined) {
1618 postSilenceTime = 0; 1618 postSilenceTime = 0;
1619 } 1619 }
1620 var preSilenceSamples = secondsToSamples(preSilenceTime, this.buffer.sampleRate); 1620 var preSilenceSamples = secondsToSamples(preSilenceTime, this.buffer.sampleRate);
1621 var postSilenceSamples = secondsToSamples(postSilenceTime, this.buffer.sampleRate); 1621 var postSilenceSamples = secondsToSamples(postSilenceTime, this.buffer.sampleRate);
1622 var newLength = this.buffer.length + preSilenceSamples + postSilenceSamples; 1622 var newLength = this.buffer.length + preSilenceSamples + postSilenceSamples;
1623 var copybuffer = audioContext.createBuffer(this.buffer.numberOfChannels, newLength, this.buffer.sampleRate); 1623 var copybuffer = audioContext.createBuffer(this.buffer.numberOfChannels, newLength, this.buffer.sampleRate);
1624 // Now we can use some efficient background copy schemes if we are just padding the end 1624 // Now we can use some efficient background copy schemes if we are just padding the end
1625 if (preSilenceSamples == 0 && typeof copybuffer.copyToChannel == "function") { 1625 if (preSilenceSamples === 0 && typeof copybuffer.copyToChannel === "function") {
1626 for (var c = 0; c < this.buffer.numberOfChannels; c++) { 1626 for (var c = 0; c < this.buffer.numberOfChannels; c++) {
1627 copybuffer.copyToChannel(this.buffer.getChannelData(c), c); 1627 copybuffer.copyToChannel(this.buffer.getChannelData(c), c);
1628 } 1628 }
1629 } else { 1629 } else {
1630 for (var c = 0; c < this.buffer.numberOfChannels; c++) { 1630 for (var c = 0; c < this.buffer.numberOfChannels; c++) {
1636 } 1636 }
1637 // Copy in the rest of the buffer information 1637 // Copy in the rest of the buffer information
1638 copybuffer.lufs = this.buffer.lufs; 1638 copybuffer.lufs = this.buffer.lufs;
1639 copybuffer.playbackGain = this.buffer.playbackGain; 1639 copybuffer.playbackGain = this.buffer.playbackGain;
1640 return copybuffer; 1640 return copybuffer;
1641 } 1641 };
1642 1642
1643 this.cropBuffer = function (startTime, stopTime) { 1643 this.cropBuffer = function (startTime, stopTime) {
1644 // Copy and return the cropped buffer 1644 // Copy and return the cropped buffer
1645 var start_sample = Math.floor(startTime * this.buffer.sampleRate); 1645 var start_sample = Math.floor(startTime * this.buffer.sampleRate);
1646 var stop_sample = Math.floor(stopTime * this.buffer.sampleRate); 1646 var stop_sample = Math.floor(stopTime * this.buffer.sampleRate);
1657 for (var n = 0; n < newLength; n++) 1657 for (var n = 0; n < newLength; n++)
1658 dst[n] = buffer[n + start_sample]; 1658 dst[n] = buffer[n + start_sample];
1659 } 1659 }
1660 } 1660 }
1661 return copybuffer; 1661 return copybuffer;
1662 } 1662 };
1663 }; 1663 };
1664 1664
1665 this.loadPageData = function (page) { 1665 this.loadPageData = function (page) {
1666 // Load the URL from pages 1666 // Load the URL from pages
1667 for (var element of page.audioElements) { 1667 for (var element of page.audioElements) {
1671 if (buffObj.hasUrl(URL)) { 1671 if (buffObj.hasUrl(URL)) {
1672 buffer = buffObj; 1672 buffer = buffObj;
1673 break; 1673 break;
1674 } 1674 }
1675 } 1675 }
1676 if (buffer == null) { 1676 if (buffer === null) {
1677 buffer = new this.bufferObj(); 1677 buffer = new this.bufferObj();
1678 var urls = [{ 1678 var urls = [{
1679 url: URL, 1679 url: URL,
1680 sampleRate: element.sampleRate 1680 sampleRate: element.sampleRate
1681 }]; 1681 }];
1692 } 1692 }
1693 }; 1693 };
1694 1694
1695 this.play = function (id) { 1695 this.play = function (id) {
1696 // Start the timer and set the audioEngine state to playing (1) 1696 // Start the timer and set the audioEngine state to playing (1)
1697 if (this.status == 0) { 1697 if (this.status === 0) {
1698 // Check if all audioObjects are ready 1698 // Check if all audioObjects are ready
1699 this.bufferReady(id); 1699 this.bufferReady(id);
1700 } else { 1700 } else {
1701 this.status = 1; 1701 this.status = 1;
1702 } 1702 }
1703 if (this.status == 1) { 1703 if (this.status === 1) {
1704 this.timer.startTest(); 1704 this.timer.startTest();
1705 if (id == undefined) { 1705 if (id === undefined) {
1706 id = -1; 1706 id = -1;
1707 console.error('FATAL - Passed id was undefined - AudioEngineContext.play(id)'); 1707 console.error('FATAL - Passed id was undefined - AudioEngineContext.play(id)');
1708 return; 1708 return;
1709 } else { 1709 } else {
1710 interfaceContext.playhead.setTimePerPixel(this.audioObjects[id]); 1710 interfaceContext.playhead.setTimePerPixel(this.audioObjects[id]);
1759 if (this.buffers[i].hasUrl(URL)) { 1759 if (this.buffers[i].hasUrl(URL)) {
1760 buffer = this.buffers[i]; 1760 buffer = this.buffers[i];
1761 break; 1761 break;
1762 } 1762 }
1763 } 1763 }
1764 if (buffer == null) { 1764 if (buffer === null) {
1765 console.log("[WARN]: Buffer was not loaded in pre-test! " + URL); 1765 console.log("[WARN]: Buffer was not loaded in pre-test! " + URL);
1766 buffer = new this.bufferObj(); 1766 buffer = new this.bufferObj();
1767 this.buffers.push(buffer); 1767 this.buffers.push(buffer);
1768 buffer.getMedia(URL); 1768 buffer.getMedia(URL);
1769 } 1769 }
1797 }; 1797 };
1798 1798
1799 this.checkAllPlayed = function () { 1799 this.checkAllPlayed = function () {
1800 arr = []; 1800 arr = [];
1801 for (var id = 0; id < this.audioObjects.length; id++) { 1801 for (var id = 0; id < this.audioObjects.length; id++) {
1802 if (this.audioObjects[id].metric.wasListenedTo == false) { 1802 if (this.audioObjects[id].metric.wasListenedTo === false) {
1803 arr.push(this.audioObjects[id].id); 1803 arr.push(this.audioObjects[id].id);
1804 } 1804 }
1805 } 1805 }
1806 return arr; 1806 return arr;
1807 }; 1807 };
1808 1808
1809 this.checkAllReady = function () { 1809 this.checkAllReady = function () {
1810 var ready = true; 1810 var ready = true;
1811 for (var i = 0; i < this.audioObjects.length; i++) { 1811 for (var i = 0; i < this.audioObjects.length; i++) {
1812 if (this.audioObjects[i].state == 0) { 1812 if (this.audioObjects[i].state === 0) {
1813 // Track not ready 1813 // Track not ready
1814 console.log('WAIT -- audioObject ' + i + ' not ready yet!'); 1814 console.log('WAIT -- audioObject ' + i + ' not ready yet!');
1815 ready = false; 1815 ready = false;
1816 }; 1816 }
1817 } 1817 }
1818 return ready; 1818 return ready;
1819 }; 1819 };
1820 1820
1821 this.setSynchronousLoop = function () { 1821 this.setSynchronousLoop = function () {
1844 } 1844 }
1845 this.status = 1; 1845 this.status = 1;
1846 return true; 1846 return true;
1847 } 1847 }
1848 return false; 1848 return false;
1849 } 1849 };
1850 1850
1851 this.exportXML = function () { 1851 this.exportXML = function () {
1852 1852
1853 }; 1853 };
1854 1854
1886 // Called by the associated buffer when it has finished loading, will then 'bind' the buffer to the 1886 // Called by the associated buffer when it has finished loading, will then 'bind' the buffer to the
1887 // audioObject and trigger the interfaceDOM.enable() function for user feedback 1887 // audioObject and trigger the interfaceDOM.enable() function for user feedback
1888 if (callee.status == -1) { 1888 if (callee.status == -1) {
1889 // ERROR 1889 // ERROR
1890 this.state = -1; 1890 this.state = -1;
1891 if (this.interfaceDOM != null) { 1891 if (this.interfaceDOM !== null) {
1892 this.interfaceDOM.error(); 1892 this.interfaceDOM.error();
1893 } 1893 }
1894 this.buffer = callee; 1894 this.buffer = callee;
1895 return; 1895 return;
1896 } 1896 }
1900 var startTime = this.specification.startTime; 1900 var startTime = this.specification.startTime;
1901 var stopTime = this.specification.stopTime; 1901 var stopTime = this.specification.stopTime;
1902 var copybuffer = new callee.constructor(); 1902 var copybuffer = new callee.constructor();
1903 1903
1904 copybuffer.buffer = callee.cropBuffer(startTime || 0, stopTime || callee.buffer.duration); 1904 copybuffer.buffer = callee.cropBuffer(startTime || 0, stopTime || callee.buffer.duration);
1905 if (preSilenceTime != 0 || postSilenceTime != 0) { 1905 if (preSilenceTime !== 0 || postSilenceTime !== 0) {
1906 copybuffer.buffer = copybuffer.copyBuffer(preSilenceTime, postSilenceTime); 1906 copybuffer.buffer = copybuffer.copyBuffer(preSilenceTime, postSilenceTime);
1907 } 1907 }
1908 1908
1909 copybuffer.lufs = callee.buffer.lufs; 1909 copybuffer.lufs = callee.buffer.lufs;
1910 this.buffer = copybuffer; 1910 this.buffer = copybuffer;
1913 if (typeof targetLUFS === "number" && isFinite(targetLUFS)) { 1913 if (typeof targetLUFS === "number" && isFinite(targetLUFS)) {
1914 this.buffer.buffer.playbackGain = decibelToLinear(targetLUFS - this.buffer.buffer.lufs); 1914 this.buffer.buffer.playbackGain = decibelToLinear(targetLUFS - this.buffer.buffer.lufs);
1915 } else { 1915 } else {
1916 this.buffer.buffer.playbackGain = 1.0; 1916 this.buffer.buffer.playbackGain = 1.0;
1917 } 1917 }
1918 if (this.interfaceDOM != null) { 1918 if (this.interfaceDOM !== null) {
1919 this.interfaceDOM.enable(); 1919 this.interfaceDOM.enable();
1920 } 1920 }
1921 this.onplayGain = decibelToLinear(this.specification.gain) * (this.buffer.buffer.playbackGain || 1.0); 1921 this.onplayGain = decibelToLinear(this.specification.gain) * (this.buffer.buffer.playbackGain || 1.0);
1922 this.storeDOM.setAttribute('playGain', linearToDecibel(this.onplayGain)); 1922 this.storeDOM.setAttribute('playGain', linearToDecibel(this.onplayGain));
1923 this.state = 1; 1923 this.state = 1;
1942 this.metric.startListening(audioEngineContext.timer.getTestTime()); 1942 this.metric.startListening(audioEngineContext.timer.getTestTime());
1943 this.interfaceDOM.startPlayback(); 1943 this.interfaceDOM.startPlayback();
1944 }; 1944 };
1945 1945
1946 this.loopStop = function (setTime) { 1946 this.loopStop = function (setTime) {
1947 if (this.outputGain.gain.value != 0.0) { 1947 if (this.outputGain.gain.value !== 0.0) {
1948 this.outputGain.gain.linearRampToValueAtTime(0.0, setTime); 1948 this.outputGain.gain.linearRampToValueAtTime(0.0, setTime);
1949 this.metric.stopListening(audioEngineContext.timer.getTestTime()); 1949 this.metric.stopListening(audioEngineContext.timer.getTestTime());
1950 } 1950 }
1951 this.interfaceDOM.stopPlayback(); 1951 this.interfaceDOM.stopPlayback();
1952 }; 1952 };
1953 1953
1954 this.play = function (startTime) { 1954 this.play = function (startTime) {
1955 if (this.bufferNode == undefined && this.buffer.buffer != undefined) { 1955 if (this.bufferNode === undefined && this.buffer.buffer !== undefined) {
1956 this.bufferNode = audioContext.createBufferSource(); 1956 this.bufferNode = audioContext.createBufferSource();
1957 this.bufferNode.owner = this; 1957 this.bufferNode.owner = this;
1958 this.bufferNode.connect(this.outputGain); 1958 this.bufferNode.connect(this.outputGain);
1959 this.bufferNode.buffer = this.buffer.buffer; 1959 this.bufferNode.buffer = this.buffer.buffer;
1960 this.bufferNode.loop = audioEngineContext.loopPlayback; 1960 this.bufferNode.loop = audioEngineContext.loopPlayback;
1961 this.bufferNode.onended = function (event) { 1961 this.bufferNode.onended = function (event) {
1962 // Safari does not like using 'this' to reference the calling object! 1962 // Safari does not like using 'this' to reference the calling object!
1963 //event.currentTarget.owner.metric.stopListening(audioEngineContext.timer.getTestTime(),event.currentTarget.owner.getCurrentPosition()); 1963 //event.currentTarget.owner.metric.stopListening(audioEngineContext.timer.getTestTime(),event.currentTarget.owner.getCurrentPosition());
1964 if (event.currentTarget != null) { 1964 if (event.currentTarget !== null) {
1965 event.currentTarget.owner.stop(audioContext.currentTime + 1); 1965 event.currentTarget.owner.stop(audioContext.currentTime + 1);
1966 } 1966 }
1967 }; 1967 };
1968 this.outputGain.gain.cancelScheduledValues(audioContext.currentTime); 1968 this.outputGain.gain.cancelScheduledValues(audioContext.currentTime);
1969 if (!audioEngineContext.loopPlayback || !audioEngineContext.synchPlayback) { 1969 if (!audioEngineContext.loopPlayback || !audioEngineContext.synchPlayback) {
1984 } 1984 }
1985 }; 1985 };
1986 1986
1987 this.stop = function (stopTime) { 1987 this.stop = function (stopTime) {
1988 this.outputGain.gain.cancelScheduledValues(audioContext.currentTime); 1988 this.outputGain.gain.cancelScheduledValues(audioContext.currentTime);
1989 if (this.bufferNode != undefined) { 1989 if (this.bufferNode !== undefined) {
1990 this.metric.stopListening(audioEngineContext.timer.getTestTime(), this.getCurrentPosition()); 1990 this.metric.stopListening(audioEngineContext.timer.getTestTime(), this.getCurrentPosition());
1991 this.bufferNode.stop(stopTime); 1991 this.bufferNode.stop(stopTime);
1992 this.bufferNode = undefined; 1992 this.bufferNode = undefined;
1993 } 1993 }
1994 this.outputGain.gain.linearRampToValueAtTime(0.0, stopTime); 1994 this.outputGain.gain.linearRampToValueAtTime(0.0, stopTime);
1995 this.interfaceDOM.stopPlayback(); 1995 this.interfaceDOM.stopPlayback();
1996 }; 1996 };
1997 1997
1998 this.getCurrentPosition = function () { 1998 this.getCurrentPosition = function () {
1999 var time = audioEngineContext.timer.getTestTime(); 1999 var time = audioEngineContext.timer.getTestTime();
2000 if (this.bufferNode != undefined) { 2000 if (this.bufferNode !== undefined) {
2001 var position = (time - this.bufferNode.playbackStartTime) % this.buffer.buffer.duration; 2001 var position = (time - this.bufferNode.playbackStartTime) % this.buffer.buffer.duration;
2002 if (isNaN(position)) { 2002 if (isNaN(position)) {
2003 return 0; 2003 return 0;
2004 } 2004 }
2005 return position; 2005 return position;
2015 file.setAttribute('sampleCount', this.buffer.buffer.length); 2015 file.setAttribute('sampleCount', this.buffer.buffer.length);
2016 file.setAttribute('duration', this.buffer.buffer.duration); 2016 file.setAttribute('duration', this.buffer.buffer.duration);
2017 this.storeDOM.appendChild(file); 2017 this.storeDOM.appendChild(file);
2018 if (this.specification.type != 'outside-reference') { 2018 if (this.specification.type != 'outside-reference') {
2019 var interfaceXML = this.interfaceDOM.exportXMLDOM(this); 2019 var interfaceXML = this.interfaceDOM.exportXMLDOM(this);
2020 if (interfaceXML != null) { 2020 if (interfaceXML !== null) {
2021 if (interfaceXML.length == undefined) { 2021 if (interfaceXML.length === undefined) {
2022 this.storeDOM.appendChild(interfaceXML); 2022 this.storeDOM.appendChild(interfaceXML);
2023 } else { 2023 } else {
2024 for (var i = 0; i < interfaceXML.length; i++) { 2024 for (var i = 0; i < interfaceXML.length; i++) {
2025 this.storeDOM.appendChild(interfaceXML[i]); 2025 this.storeDOM.appendChild(interfaceXML[i]);
2026 } 2026 }
2027 } 2027 }
2028 } 2028 }
2029 if (this.commentDOM != null) { 2029 if (this.commentDOM !== null) {
2030 this.storeDOM.appendChild(this.commentDOM.exportXMLDOM(this)); 2030 this.storeDOM.appendChild(this.commentDOM.exportXMLDOM(this));
2031 } 2031 }
2032 } 2032 }
2033 var nodes = this.metric.exportXMLDOM(); 2033 var nodes = this.metric.exportXMLDOM();
2034 var mroot = this.storeDOM.getElementsByTagName('metric')[0]; 2034 var mroot = this.storeDOM.getElementsByTagName('metric')[0];
2045 this.testStarted = false; 2045 this.testStarted = false;
2046 this.testStartTime = 0; 2046 this.testStartTime = 0;
2047 this.testDuration = 0; 2047 this.testDuration = 0;
2048 this.minimumTestTime = 0; // No minimum test time 2048 this.minimumTestTime = 0; // No minimum test time
2049 this.startTest = function () { 2049 this.startTest = function () {
2050 if (this.testStarted == false) { 2050 if (this.testStarted === false) {
2051 this.testStartTime = audioContext.currentTime; 2051 this.testStartTime = audioContext.currentTime;
2052 this.testStarted = true; 2052 this.testStarted = true;
2053 this.updateTestTime(); 2053 this.updateTestTime();
2054 audioEngineContext.metric.initialiseTest(); 2054 audioEngineContext.metric.initialiseTest();
2055 } 2055 }
2153 } 2153 }
2154 this.movementTracker[this.movementTracker.length] = [time, position]; 2154 this.movementTracker[this.movementTracker.length] = [time, position];
2155 }; 2155 };
2156 2156
2157 this.startListening = function (time) { 2157 this.startListening = function (time) {
2158 if (this.listenHold == false) { 2158 if (this.listenHold === false) {
2159 this.wasListenedTo = true; 2159 this.wasListenedTo = true;
2160 this.listenStart = time; 2160 this.listenStart = time;
2161 this.listenHold = true; 2161 this.listenHold = true;
2162 2162
2163 var evnt = document.createElement('event'); 2163 var evnt = document.createElement('event');
2172 console.log('slider ' + this.parent.id + ' played (' + time + ')'); // DEBUG/SAFETY: show played slider id 2172 console.log('slider ' + this.parent.id + ' played (' + time + ')'); // DEBUG/SAFETY: show played slider id
2173 } 2173 }
2174 }; 2174 };
2175 2175
2176 this.stopListening = function (time, bufferStopTime) { 2176 this.stopListening = function (time, bufferStopTime) {
2177 if (this.listenHold == true) { 2177 if (this.listenHold === true) {
2178 var diff = time - this.listenStart; 2178 var diff = time - this.listenStart;
2179 this.listenedTimer += (diff); 2179 this.listenedTimer += (diff);
2180 this.listenStart = 0; 2180 this.listenStart = 0;
2181 this.listenHold = false; 2181 this.listenHold = false;
2182 2182
2183 var evnt = this.listenTracker[this.listenTracker.length - 1]; 2183 var evnt = this.listenTracker[this.listenTracker.length - 1];
2184 var testTime = evnt.getElementsByTagName('testTime')[0]; 2184 var testTime = evnt.getElementsByTagName('testTime')[0];
2185 var bufferTime = evnt.getElementsByTagName('bufferTime')[0]; 2185 var bufferTime = evnt.getElementsByTagName('bufferTime')[0];
2186 testTime.setAttribute('stop', time); 2186 testTime.setAttribute('stop', time);
2187 if (bufferStopTime == undefined) { 2187 if (bufferStopTime === undefined) {
2188 bufferTime.setAttribute('stop', this.parent.getCurrentPosition()); 2188 bufferTime.setAttribute('stop', this.parent.getCurrentPosition());
2189 } else { 2189 } else {
2190 bufferTime.setAttribute('stop', bufferStopTime); 2190 bufferTime.setAttribute('stop', bufferStopTime);
2191 } 2191 }
2192 console.log('slider ' + this.parent.id + ' played for (' + diff + ')'); // DEBUG/SAFETY: show played slider id 2192 console.log('slider ' + this.parent.id + ' played for (' + diff + ')'); // DEBUG/SAFETY: show played slider id
2239 storeDOM.push(flagMoved); 2239 storeDOM.push(flagMoved);
2240 } 2240 }
2241 if (audioEngineContext.metric.enableFlagComments) { 2241 if (audioEngineContext.metric.enableFlagComments) {
2242 var flagComments = storage.document.createElement('metricresult'); 2242 var flagComments = storage.document.createElement('metricresult');
2243 flagComments.setAttribute('name', 'elementFlagComments'); 2243 flagComments.setAttribute('name', 'elementFlagComments');
2244 if (this.parent.commentDOM == null) { 2244 if (this.parent.commentDOM === null) {
2245 flag.textContent = 'false'; 2245 flag.textContent = 'false';
2246 } else if (this.parent.commentDOM.textContent.length == 0) { 2246 } else if (this.parent.commentDOM.textContent.length === 0) {
2247 flag.textContent = 'false'; 2247 flag.textContent = 'false';
2248 } else { 2248 } else {
2249 flag.textContet = 'true'; 2249 flag.textContet = 'true';
2250 } 2250 }
2251 storeDOM.push(flagComments); 2251 storeDOM.push(flagComments);
2328 2328
2329 hold.appendChild(date); 2329 hold.appendChild(date);
2330 hold.appendChild(time); 2330 hold.appendChild(time);
2331 return hold; 2331 return hold;
2332 2332
2333 } 2333 };
2334 2334
2335 this.lightbox = { 2335 this.lightbox = {
2336 parent: this, 2336 parent: this,
2337 root: document.createElement("div"), 2337 root: document.createElement("div"),
2338 content: document.createElement("div"), 2338 content: document.createElement("div"),
2370 } 2370 }
2371 }, 2371 },
2372 resize: function (event) { 2372 resize: function (event) {
2373 this.root.style.left = (window.innerWidth / 2) - 250 + 'px'; 2373 this.root.style.left = (window.innerWidth / 2) - 250 + 'px';
2374 } 2374 }
2375 } 2375 };
2376 2376
2377 this.lightbox.root.appendChild(this.lightbox.content); 2377 this.lightbox.root.appendChild(this.lightbox.content);
2378 this.lightbox.root.appendChild(this.lightbox.accept); 2378 this.lightbox.root.appendChild(this.lightbox.accept);
2379 this.lightbox.root.className = "popupHolder"; 2379 this.lightbox.root.className = "popupHolder";
2380 this.lightbox.root.id = "lightbox-root"; 2380 this.lightbox.root.id = "lightbox-root";
2459 inject.appendChild(box.trackComment); 2459 inject.appendChild(box.trackComment);
2460 } 2460 }
2461 }; 2461 };
2462 2462
2463 this.deleteCommentBoxes = function () { 2463 this.deleteCommentBoxes = function () {
2464 if (this.injectPoint != null) { 2464 if (this.injectPoint !== null) {
2465 for (var box of this.boxes) { 2465 for (var box of this.boxes) {
2466 this.injectPoint.removeChild(box.trackComment); 2466 this.injectPoint.removeChild(box.trackComment);
2467 } 2467 }
2468 this.injectPoint = null; 2468 this.injectPoint = null;
2469 } 2469 }
2470 this.boxes = []; 2470 this.boxes = [];
2471 }; 2471 };
2472 } 2472 };
2473 2473
2474 this.commentQuestions = []; 2474 this.commentQuestions = [];
2475 2475
2476 this.commentBox = function (commentQuestion) { 2476 this.commentBox = function (commentQuestion) {
2477 this.specification = commentQuestion; 2477 this.specification = commentQuestion;
2577 root.setAttribute('type', this.specification.type); 2577 root.setAttribute('type', this.specification.type);
2578 var question = document.createElement('question'); 2578 var question = document.createElement('question');
2579 question.textContent = this.string.textContent; 2579 question.textContent = this.string.textContent;
2580 var response = document.createElement('response'); 2580 var response = document.createElement('response');
2581 var i = 0; 2581 var i = 0;
2582 while (this.options[i].checked == false) { 2582 while (this.options[i].checked === false) {
2583 i++; 2583 i++;
2584 if (i >= this.options.length) { 2584 if (i >= this.options.length) {
2585 break; 2585 break;
2586 } 2586 }
2587 } 2587 }
2614 var text = text.firstChild; 2614 var text = text.firstChild;
2615 options.style.marginRight = spanMargin; 2615 options.style.marginRight = spanMargin;
2616 options.style.marginLeft = spanMargin; 2616 options.style.marginLeft = spanMargin;
2617 text.style.marginRight = spanMargin; 2617 text.style.marginRight = spanMargin;
2618 text.style.marginLeft = spanMargin; 2618 text.style.marginLeft = spanMargin;
2619 while (options.nextSibling != undefined) { 2619 while (options.nextSibling !== undefined) {
2620 options = options.nextSibling; 2620 options = options.nextSibling;
2621 text = text.nextSibling; 2621 text = text.nextSibling;
2622 options.style.marginRight = spanMargin; 2622 options.style.marginRight = spanMargin;
2623 options.style.marginLeft = spanMargin; 2623 options.style.marginLeft = spanMargin;
2624 text.style.marginRight = spanMargin; 2624 text.style.marginRight = spanMargin;
2713 var text = text.firstChild; 2713 var text = text.firstChild;
2714 options.style.marginRight = spanMargin; 2714 options.style.marginRight = spanMargin;
2715 options.style.marginLeft = spanMargin; 2715 options.style.marginLeft = spanMargin;
2716 text.style.marginRight = spanMargin; 2716 text.style.marginRight = spanMargin;
2717 text.style.marginLeft = spanMargin; 2717 text.style.marginLeft = spanMargin;
2718 while (options.nextSibling != undefined) { 2718 while (options.nextSibling !== undefined) {
2719 options = options.nextSibling; 2719 options = options.nextSibling;
2720 text = text.nextSibling; 2720 text = text.nextSibling;
2721 options.style.marginRight = spanMargin; 2721 options.style.marginRight = spanMargin;
2722 options.style.marginLeft = spanMargin; 2722 options.style.marginLeft = spanMargin;
2723 text.style.marginRight = spanMargin; 2723 text.style.marginRight = spanMargin;
2853 }; 2853 };
2854 this.error = function () { 2854 this.error = function () {
2855 // audioObject has an error!! 2855 // audioObject has an error!!
2856 this.outsideReferenceHolder.textContent = "Error"; 2856 this.outsideReferenceHolder.textContent = "Error";
2857 this.outsideReferenceHolder.style.backgroundColor = "#F00"; 2857 this.outsideReferenceHolder.style.backgroundColor = "#F00";
2858 } 2858 };
2859 } 2859 };
2860 2860
2861 this.playhead = new function () { 2861 this.playhead = new function () {
2862 this.object = document.createElement('div'); 2862 this.object = document.createElement('div');
2863 this.object.className = 'playhead'; 2863 this.object.className = 'playhead';
2864 this.object.align = 'left'; 2864 this.object.align = 'left';
2925 }; 2925 };
2926 2926
2927 this.interval = undefined; 2927 this.interval = undefined;
2928 2928
2929 this.start = function () { 2929 this.start = function () {
2930 if (this.playbackObject != undefined && this.interval == undefined) { 2930 if (this.playbackObject !== undefined && this.interval === undefined) {
2931 if (this.maxTime < 60) { 2931 if (this.maxTime < 60) {
2932 this.interval = setInterval(function () { 2932 this.interval = setInterval(function () {
2933 interfaceContext.playhead.update(); 2933 interfaceContext.playhead.update();
2934 }, 10); 2934 }, 10);
2935 } else { 2935 } else {
2976 this.slider.onmousemove = function (event) { 2976 this.slider.onmousemove = function (event) {
2977 interfaceContext.volume.valueDB = event.currentTarget.value; 2977 interfaceContext.volume.valueDB = event.currentTarget.value;
2978 interfaceContext.volume.valueLin = decibelToLinear(interfaceContext.volume.valueDB); 2978 interfaceContext.volume.valueLin = decibelToLinear(interfaceContext.volume.valueDB);
2979 interfaceContext.volume.valueText.textContent = interfaceContext.volume.valueDB + 'dB'; 2979 interfaceContext.volume.valueText.textContent = interfaceContext.volume.valueDB + 'dB';
2980 audioEngineContext.outputGain.gain.value = interfaceContext.volume.valueLin; 2980 audioEngineContext.outputGain.gain.value = interfaceContext.volume.valueLin;
2981 } 2981 };
2982 this.slider.onmouseup = function (event) { 2982 this.slider.onmouseup = function (event) {
2983 var storePoint = testState.currentStore.XMLDOM.getElementsByTagName('metric')[0].getAllElementsByName('volumeTracker'); 2983 var storePoint = testState.currentStore.XMLDOM.getElementsByTagName('metric')[0].getAllElementsByName('volumeTracker');
2984 if (storePoint.length == 0) { 2984 if (storePoint.length === 0) {
2985 storePoint = storage.document.createElement('metricresult'); 2985 storePoint = storage.document.createElement('metricresult');
2986 storePoint.setAttribute('name', 'volumeTracker'); 2986 storePoint.setAttribute('name', 'volumeTracker');
2987 testState.currentStore.XMLDOM.getElementsByTagName('metric')[0].appendChild(storePoint); 2987 testState.currentStore.XMLDOM.getElementsByTagName('metric')[0].appendChild(storePoint);
2988 } else { 2988 } else {
2989 storePoint = storePoint[0]; 2989 storePoint = storePoint[0];
2991 var node = storage.document.createElement('movement'); 2991 var node = storage.document.createElement('movement');
2992 node.setAttribute('test-time', audioEngineContext.timer.getTestTime()); 2992 node.setAttribute('test-time', audioEngineContext.timer.getTestTime());
2993 node.setAttribute('volume', interfaceContext.volume.valueDB); 2993 node.setAttribute('volume', interfaceContext.volume.valueDB);
2994 node.setAttribute('format', 'dBFS'); 2994 node.setAttribute('format', 'dBFS');
2995 storePoint.appendChild(node); 2995 storePoint.appendChild(node);
2996 } 2996 };
2997 2997
2998 var title = document.createElement('div'); 2998 var title = document.createElement('div');
2999 title.innerHTML = '<span>Master Volume Control</span>'; 2999 title.innerHTML = '<span>Master Volume Control</span>';
3000 title.style.fontSize = '0.75em'; 3000 title.style.fontSize = '0.75em';
3001 title.style.width = "100%"; 3001 title.style.width = "100%";
3005 this.root.appendChild(this.slider); 3005 this.root.appendChild(this.slider);
3006 this.root.appendChild(this.valueText); 3006 this.root.appendChild(this.valueText);
3007 3007
3008 this.resize = function (event) { 3008 this.resize = function (event) {
3009 if (window.innerWidth < 1000) { 3009 if (window.innerWidth < 1000) {
3010 this.object.className = "master-volume-holder-inline" 3010 this.object.className = "master-volume-holder-inline";
3011 } else { 3011 } else {
3012 this.object.className = 'master-volume-holder-float'; 3012 this.object.className = 'master-volume-holder-float';
3013 } 3013 }
3014 } 3014 };
3015 } 3015 };
3016 3016
3017 this.calibrationModuleObject = null; 3017 this.calibrationModuleObject = null;
3018 this.calibrationModule = function () { 3018 this.calibrationModule = function () {
3019 // This creates an on-page calibration module 3019 // This creates an on-page calibration module
3020 this.storeDOM = storage.document.createElement("calibration"); 3020 this.storeDOM = storage.document.createElement("calibration");
3050 var value = Math.pow(10, this.input.value / 20); 3050 var value = Math.pow(10, this.input.value / 20);
3051 if (this.f == 1000) { 3051 if (this.f == 1000) {
3052 audioEngineContext.outputGain.gain.value = value; 3052 audioEngineContext.outputGain.gain.value = value;
3053 interfaceContext.volume.slider.value = this.input.value; 3053 interfaceContext.volume.slider.value = this.input.value;
3054 } else { 3054 } else {
3055 this.gain.gain.value = value 3055 this.gain.gain.value = value;
3056 } 3056 }
3057 break; 3057 break;
3058 } 3058 }
3059 }, 3059 },
3060 disconnect: function () { 3060 disconnect: function () {
3061 this.gain.disconnect(); 3061 this.gain.disconnect();
3062 } 3062 }
3063 } 3063 };
3064 obj.root.className = "calibration-slider"; 3064 obj.root.className = "calibration-slider";
3065 obj.root.appendChild(obj.input); 3065 obj.root.appendChild(obj.input);
3066 obj.oscillator.connect(obj.gain); 3066 obj.oscillator.connect(obj.gain);
3067 obj.gain.connect(audioEngineContext.outputGain); 3067 obj.gain.connect(audioEngineContext.outputGain);
3068 obj.gain.gain.value = Math.random() * 2; 3068 obj.gain.gain.value = Math.random() * 2;
3086 this.calibrationNodes.push(obj); 3086 this.calibrationNodes.push(obj);
3087 this.holder.appendChild(obj.root); 3087 this.holder.appendChild(obj.root);
3088 f0 *= 2; 3088 f0 *= 2;
3089 } 3089 }
3090 inject.appendChild(this.holder); 3090 inject.appendChild(this.holder);
3091 } 3091 };
3092 this.collect = function () { 3092 this.collect = function () {
3093 for (var obj of this.calibrationNodes) { 3093 for (var obj of this.calibrationNodes) {
3094 var node = storage.document.createElement("calibrationresult"); 3094 var node = storage.document.createElement("calibrationresult");
3095 node.setAttribute("frequency", obj.f); 3095 node.setAttribute("frequency", obj.f);
3096 node.setAttribute("range-min", obj.input.min); 3096 node.setAttribute("range-min", obj.input.min);
3097 node.setAttribute("range-max", obj.input.max); 3097 node.setAttribute("range-max", obj.input.max);
3098 node.setAttribute("gain-lin", obj.gain.gain.value); 3098 node.setAttribute("gain-lin", obj.gain.gain.value);
3099 this.storeDOM.appendChild(node); 3099 this.storeDOM.appendChild(node);
3100 } 3100 }
3101 } 3101 };
3102 } 3102 };
3103 3103
3104 3104
3105 // Global Checkers 3105 // Global Checkers
3106 // These functions will help enforce the checkers 3106 // These functions will help enforce the checkers
3107 this.checkHiddenAnchor = function () { 3107 this.checkHiddenAnchor = function () {
3156 if (delta >= time) { 3156 if (delta >= time) {
3157 passed = true; 3157 passed = true;
3158 break; 3158 break;
3159 } 3159 }
3160 } 3160 }
3161 if (passed == false) { 3161 if (passed === false) {
3162 check_pass = false; 3162 check_pass = false;
3163 console.log("Continue listening to track-" + object.interfaceDOM.getPresentedId()); 3163 console.log("Continue listening to track-" + object.interfaceDOM.getPresentedId());
3164 error_obj.push(object.interfaceDOM.getPresentedId()); 3164 error_obj.push(object.interfaceDOM.getPresentedId());
3165 } 3165 }
3166 } 3166 }
3167 if (check_pass == false) { 3167 if (check_pass === false) {
3168 var str_start = "You have not completely listened to fragments "; 3168 var str_start = "You have not completely listened to fragments ";
3169 for (var i = 0; i < error_obj.length; i++) { 3169 for (var i = 0; i < error_obj.length; i++) {
3170 str_start += error_obj[i]; 3170 str_start += error_obj[i];
3171 if (i != error_obj.length - 1) { 3171 if (i != error_obj.length - 1) {
3172 str_start += ', '; 3172 str_start += ', ';
3182 }; 3182 };
3183 this.checkAllMoved = function () { 3183 this.checkAllMoved = function () {
3184 var str = "You have not moved "; 3184 var str = "You have not moved ";
3185 var failed = []; 3185 var failed = [];
3186 for (var ao of audioEngineContext.audioObjects) { 3186 for (var ao of audioEngineContext.audioObjects) {
3187 if (ao.metric.wasMoved == false && ao.interfaceDOM.canMove() == true) { 3187 if (ao.metric.wasMoved === false && ao.interfaceDOM.canMove() === true) {
3188 failed.push(ao.interfaceDOM.getPresentedId()); 3188 failed.push(ao.interfaceDOM.getPresentedId());
3189 } 3189 }
3190 } 3190 }
3191 if (failed.length == 0) { 3191 if (failed.length === 0) {
3192 return true; 3192 return true;
3193 } else if (failed.length == 1) { 3193 } else if (failed.length == 1) {
3194 str += 'track ' + failed[0]; 3194 str += 'track ' + failed[0];
3195 } else { 3195 } else {
3196 str += 'tracks '; 3196 str += 'tracks ';
3207 }; 3207 };
3208 this.checkAllPlayed = function () { 3208 this.checkAllPlayed = function () {
3209 var str = "You have not played "; 3209 var str = "You have not played ";
3210 var failed = []; 3210 var failed = [];
3211 for (var ao of audioEngineContext.audioObjects) { 3211 for (var ao of audioEngineContext.audioObjects) {
3212 if (ao.metric.wasListenedTo == false) { 3212 if (ao.metric.wasListenedTo === false) {
3213 failed.push(ao.interfaceDOM.getPresentedId()); 3213 failed.push(ao.interfaceDOM.getPresentedId());
3214 } 3214 }
3215 } 3215 }
3216 if (failed.length == 0) { 3216 if (failed.length === 0) {
3217 return true; 3217 return true;
3218 } else if (failed.length == 1) { 3218 } else if (failed.length == 1) {
3219 str += 'track ' + failed[0]; 3219 str += 'track ' + failed[0];
3220 } else { 3220 } else {
3221 str += 'tracks '; 3221 str += 'tracks ';
3243 this.storeErrorNode(str); 3243 this.storeErrorNode(str);
3244 return false; 3244 return false;
3245 } 3245 }
3246 } 3246 }
3247 return true; 3247 return true;
3248 } 3248 };
3249 this.checkScaleRange = function (min, max) { 3249 this.checkScaleRange = function (min, max) {
3250 var page = testState.getCurrentTestPage(); 3250 var page = testState.getCurrentTestPage();
3251 var audioObjects = audioEngineContext.audioObjects; 3251 var audioObjects = audioEngineContext.audioObjects;
3252 var state = true; 3252 var state = true;
3253 var str = "Please keep listening. "; 3253 var str = "Please keep listening. ";
3265 if (minRanking * 100 > min) { 3265 if (minRanking * 100 > min) {
3266 str += "At least one fragment must be below the " + min + " mark."; 3266 str += "At least one fragment must be below the " + min + " mark.";
3267 state = false; 3267 state = false;
3268 } 3268 }
3269 if (maxRanking * 100 < max) { 3269 if (maxRanking * 100 < max) {
3270 str += "At least one fragment must be above the " + max + " mark." 3270 str += "At least one fragment must be above the " + max + " mark.";
3271 state = false; 3271 state = false;
3272 } 3272 }
3273 if (!state) { 3273 if (!state) {
3274 console.log(str); 3274 console.log(str);
3275 this.storeErrorNode(str); 3275 this.storeErrorNode(str);
3276 interfaceContext.lightbox.post("Error", str); 3276 interfaceContext.lightbox.post("Error", str);
3277 } 3277 }
3278 return state; 3278 return state;
3279 } 3279 };
3280 3280
3281 this.storeErrorNode = function (errorMessage) { 3281 this.storeErrorNode = function (errorMessage) {
3282 var time = audioEngineContext.timer.getTestTime(); 3282 var time = audioEngineContext.timer.getTestTime();
3283 var node = storage.document.createElement('error'); 3283 var node = storage.document.createElement('error');
3284 node.setAttribute('time', time); 3284 node.setAttribute('time', time);
3299 case "letter": 3299 case "letter":
3300 return String.fromCharCode((index + offset) % 26 + 97); 3300 return String.fromCharCode((index + offset) % 26 + 97);
3301 case "capital": 3301 case "capital":
3302 return String.fromCharCode((index + offset) % 26 + 65); 3302 return String.fromCharCode((index + offset) % 26 + 65);
3303 case "samediff": 3303 case "samediff":
3304 if (index == 0) { 3304 if (index === 0) {
3305 return "Same"; 3305 return "Same";
3306 } else if (index == 1) { 3306 } else if (index == 1) {
3307 return "Difference"; 3307 return "Difference";
3308 } else {
3309 return "";
3310 } 3308 }
3309 return "";
3311 case "number": 3310 case "number":
3312 return String(index + offset); 3311 return String(index + offset);
3313 default: 3312 default:
3314 return ""; 3313 return "";
3315 } 3314 }
3316 } 3315 }
3317 3316
3318 if (typeof labelStart !== "string" || labelStart.length == 0) { 3317 if (typeof labelStart !== "string" || labelStart.length === 0) {
3319 labelStart = String.fromCharCode(0); 3318 labelStart = String.fromCharCode(0);
3320 } 3319 }
3321 3320
3322 switch (labelType) { 3321 switch (labelType) {
3323 case "letter": 3322 case "letter":
3355 } 3354 }
3356 return a; 3355 return a;
3357 } else { 3356 } else {
3358 throw ("Invalid arguments"); 3357 throw ("Invalid arguments");
3359 } 3358 }
3360 } 3359 };
3361 3360
3362 this.getCombinedInterfaces = function (page) { 3361 this.getCombinedInterfaces = function (page) {
3363 // Combine the interfaces with the global interface nodes 3362 // Combine the interfaces with the global interface nodes
3364 var global = specification.interfaces, 3363 var global = specification.interfaces,
3365 local = page.interfaces; 3364 local = page.interfaces;
3380 // Use the global default scales 3379 // Use the global default scales
3381 locInt.scales = global.scales; 3380 locInt.scales = global.scales;
3382 } 3381 }
3383 }); 3382 });
3384 return local; 3383 return local;
3385 } 3384 };
3386 } 3385 }
3387 3386
3388 function Storage() { 3387 function Storage() {
3389 // Holds results in XML format until ready for collection 3388 // Holds results in XML format until ready for collection
3390 this.globalPreTest = null; 3389 this.globalPreTest = null;
3393 this.document = null; 3392 this.document = null;
3394 this.root = null; 3393 this.root = null;
3395 this.state = 0; 3394 this.state = 0;
3396 3395
3397 this.initialise = function (existingStore) { 3396 this.initialise = function (existingStore) {
3398 if (existingStore == undefined) { 3397 if (existingStore === undefined) {
3399 // We need to get the sessionKey 3398 // We need to get the sessionKey
3400 this.SessionKey.requestKey(); 3399 this.SessionKey.requestKey();
3401 this.document = document.implementation.createDocument(null, "waetresult", null); 3400 this.document = document.implementation.createDocument(null, "waetresult", null);
3402 this.root = this.document.childNodes[0]; 3401 this.root = this.document.childNodes[0];
3403 var projectDocument = specification.projectXML; 3402 var projectDocument = specification.projectXML;
3409 } else { 3408 } else {
3410 this.document = existingStore; 3409 this.document = existingStore;
3411 this.root = existingStore.firstChild; 3410 this.root = existingStore.firstChild;
3412 this.SessionKey.key = this.root.getAttribute("key"); 3411 this.SessionKey.key = this.root.getAttribute("key");
3413 } 3412 }
3414 if (specification.preTest != undefined) { 3413 if (specification.preTest !== undefined) {
3415 this.globalPreTest = new this.surveyNode(this, this.root, specification.preTest); 3414 this.globalPreTest = new this.surveyNode(this, this.root, specification.preTest);
3416 } 3415 }
3417 if (specification.postTest != undefined) { 3416 if (specification.postTest !== undefined) {
3418 this.globalPostTest = new this.surveyNode(this, this.root, specification.postTest); 3417 this.globalPostTest = new this.surveyNode(this, this.root, specification.postTest);
3419 } 3418 }
3420 }; 3419 };
3421 3420
3422 this.SessionKey = { 3421 this.SessionKey = {
3424 request: new XMLHttpRequest(), 3423 request: new XMLHttpRequest(),
3425 parent: this, 3424 parent: this,
3426 handleEvent: function () { 3425 handleEvent: function () {
3427 var parse = new DOMParser(); 3426 var parse = new DOMParser();
3428 var xml = parse.parseFromString(this.request.response, "text/xml"); 3427 var xml = parse.parseFromString(this.request.response, "text/xml");
3429 if (this.request.response.length == 0) { 3428 if (this.request.response.length === 0) {
3430 console.error("An unspecified error occured, no server key could be generated"); 3429 console.error("An unspecified error occured, no server key could be generated");
3431 return; 3430 return;
3432 } 3431 }
3433 if (xml.getElementsByTagName("state").length > 0) { 3432 if (xml.getElementsByTagName("state").length > 0) {
3434 if (xml.getElementsByTagName("state")[0].textContent == "OK") { 3433 if (xml.getElementsByTagName("state")[0].textContent == "OK") {
3457 this.request.open("GET", returnURL + "php/requestKey.php", true); 3456 this.request.open("GET", returnURL + "php/requestKey.php", true);
3458 this.request.addEventListener("load", this); 3457 this.request.addEventListener("load", this);
3459 this.request.send(); 3458 this.request.send();
3460 }, 3459 },
3461 update: function () { 3460 update: function () {
3462 if (this.key == null) { 3461 if (this.key === null) {
3463 console.log("Cannot save as key == null"); 3462 console.log("Cannot save as key == null");
3464 return; 3463 return;
3465 } 3464 }
3466 this.parent.root.setAttribute("state", "update"); 3465 this.parent.root.setAttribute("state", "update");
3467 var xmlhttp = new XMLHttpRequest(); 3466 var xmlhttp = new XMLHttpRequest();
3492 } else { 3491 } else {
3493 var message = response.getElementsByTagName("message"); 3492 var message = response.getElementsByTagName("message");
3494 console.log("Intermediate save: Error! " + message.textContent); 3493 console.log("Intermediate save: Error! " + message.textContent);
3495 } 3494 }
3496 } 3495 }
3497 } 3496 };
3498 xmlhttp.send([hold.innerHTML]); 3497 xmlhttp.send([hold.innerHTML]);
3499 } 3498 }
3500 } 3499 };
3501 3500
3502 this.createTestPageStore = function (specification) { 3501 this.createTestPageStore = function (specification) {
3503 var store = new this.pageNode(this, specification); 3502 var store = new this.pageNode(this, specification);
3504 this.testPages.push(store); 3503 this.testPages.push(store);
3505 return this.testPages[this.testPages.length - 1]; 3504 return this.testPages[this.testPages.length - 1];
3527 // ID is the position 3526 // ID is the position
3528 if (node.specification.type == 'statement') { 3527 if (node.specification.type == 'statement') {
3529 return; 3528 return;
3530 } 3529 }
3531 var surveyresult = this.XMLDOM.firstChild; 3530 var surveyresult = this.XMLDOM.firstChild;
3532 while (surveyresult != null) { 3531 while (surveyresult !== null) {
3533 if (surveyresult.getAttribute("ref") == node.specification.id) { 3532 if (surveyresult.getAttribute("ref") == node.specification.id) {
3534 break; 3533 break;
3535 } 3534 }
3536 surveyresult = surveyresult.nextElementSibling; 3535 surveyresult = surveyresult.nextElementSibling;
3537 } 3536 }
3550 child.textContent = node.response.text; 3549 child.textContent = node.response.text;
3551 } 3550 }
3552 surveyresult.appendChild(child); 3551 surveyresult.appendChild(child);
3553 break; 3552 break;
3554 case "checkbox": 3553 case "checkbox":
3555 if (node.response == undefined) { 3554 if (node.response === undefined) {
3556 surveyresult.appendChild(this.parent.document.createElement('response')); 3555 surveyresult.appendChild(this.parent.document.createElement('response'));
3557 break; 3556 break;
3558 } 3557 }
3559 for (var i = 0; i < node.response.length; i++) { 3558 for (var i = 0; i < node.response.length; i++) {
3560 var checkNode = this.parent.document.createElement('response'); 3559 var checkNode = this.parent.document.createElement('response');
3566 } 3565 }
3567 }; 3566 };
3568 this.complete = function () { 3567 this.complete = function () {
3569 this.state = "complete"; 3568 this.state = "complete";
3570 this.XMLDOM.setAttribute("state", this.state); 3569 this.XMLDOM.setAttribute("state", this.state);
3571 } 3570 };
3572 }; 3571 };
3573 3572
3574 this.pageNode = function (parent, specification) { 3573 this.pageNode = function (parent, specification) {
3575 // Create one store per test page 3574 // Create one store per test page
3576 this.specification = specification; 3575 this.specification = specification;
3578 this.state = "empty"; 3577 this.state = "empty";
3579 this.XMLDOM = this.parent.document.createElement('page'); 3578 this.XMLDOM = this.parent.document.createElement('page');
3580 this.XMLDOM.setAttribute('ref', specification.id); 3579 this.XMLDOM.setAttribute('ref', specification.id);
3581 this.XMLDOM.setAttribute('presentedId', specification.presentedId); 3580 this.XMLDOM.setAttribute('presentedId', specification.presentedId);
3582 this.XMLDOM.setAttribute("state", this.state); 3581 this.XMLDOM.setAttribute("state", this.state);
3583 if (specification.preTest != undefined) { 3582 if (specification.preTest !== undefined) {
3584 this.preTest = new this.parent.surveyNode(this.parent, this.XMLDOM, this.specification.preTest); 3583 this.preTest = new this.parent.surveyNode(this.parent, this.XMLDOM, this.specification.preTest);
3585 } 3584 }
3586 if (specification.postTest != undefined) { 3585 if (specification.postTest !== undefined) {
3587 this.postTest = new this.parent.surveyNode(this.parent, this.XMLDOM, this.specification.postTest); 3586 this.postTest = new this.parent.surveyNode(this.parent, this.XMLDOM, this.specification.postTest);
3588 } 3587 }
3589 3588
3590 // Add any page metrics 3589 // Add any page metrics
3591 var page_metric = this.parent.document.createElement('metric'); 3590 var page_metric = this.parent.document.createElement('metric');
3593 3592
3594 // Add the audioelement 3593 // Add the audioelement
3595 for (var element of this.specification.audioElements) { 3594 for (var element of this.specification.audioElements) {
3596 var aeNode = this.parent.document.createElement('audioelement'); 3595 var aeNode = this.parent.document.createElement('audioelement');
3597 aeNode.setAttribute('ref', element.id); 3596 aeNode.setAttribute('ref', element.id);
3598 if (element.name != undefined) { 3597 if (element.name !== undefined) {
3599 aeNode.setAttribute('name', element.name) 3598 aeNode.setAttribute('name', element.name);
3600 }; 3599 }
3601 aeNode.setAttribute('type', element.type); 3600 aeNode.setAttribute('type', element.type);
3602 aeNode.setAttribute('url', element.url); 3601 aeNode.setAttribute('url', element.url);
3603 aeNode.setAttribute('fqurl', qualifyURL(element.url)); 3602 aeNode.setAttribute('fqurl', qualifyURL(element.url));
3604 aeNode.setAttribute('gain', element.gain); 3603 aeNode.setAttribute('gain', element.gain);
3605 if (element.type == 'anchor' || element.type == 'reference') { 3604 if (element.type == 'anchor' || element.type == 'reference') {
3615 this.parent.root.appendChild(this.XMLDOM); 3614 this.parent.root.appendChild(this.XMLDOM);
3616 3615
3617 this.complete = function () { 3616 this.complete = function () {
3618 this.state = "complete"; 3617 this.state = "complete";
3619 this.XMLDOM.setAttribute("state", "complete"); 3618 this.XMLDOM.setAttribute("state", "complete");
3620 } 3619 };
3621 }; 3620 };
3622 this.update = function () { 3621 this.update = function () {
3623 this.SessionKey.update(); 3622 this.SessionKey.update();
3624 } 3623 };
3625 this.finish = function () { 3624 this.finish = function () {
3626 if (this.state == 0) { 3625 if (this.state === 0) {
3627 this.update(); 3626 this.update();
3628 } 3627 }
3629 this.state = 1; 3628 this.state = 1;
3630 this.root.setAttribute("state", "complete"); 3629 this.root.setAttribute("state", "complete");
3631 return this.root; 3630 return this.root;