comparison js/core.js @ 2615:8b8f3f3ce68e

#101. Working implementatin, loads correct initial buffer. WIP
author Nicholas Jillings <nicholas.jillings@mail.bcu.ac.uk>
date Tue, 15 Nov 2016 15:27:45 +0000
parents 756d12f5c330
children ac08e4a3a94b
comparison
equal deleted inserted replaced
2614:ae5e8818eff0 2615:8b8f3f3ce68e
1486 // Create store for new audioObjects 1486 // Create store for new audioObjects
1487 this.audioObjects = []; 1487 this.audioObjects = [];
1488 1488
1489 this.buffers = []; 1489 this.buffers = [];
1490 this.bufferObj = function () { 1490 this.bufferObj = function () {
1491 this.url = null; 1491 var currentUrlIndex = 0;
1492 this.urls = [];
1492 this.buffer = null; 1493 this.buffer = null;
1493 this.xmlRequest = new XMLHttpRequest();
1494 this.xmlRequest.parent = this;
1495 this.users = []; 1494 this.users = [];
1496 this.progress = 0; 1495 this.progress = 0;
1497 this.status = 0; 1496 this.status = 0;
1498 this.ready = function () { 1497 this.ready = function () {
1499 if (this.status >= 2) { 1498 if (this.status >= 2) {
1504 if (this.users[i].interfaceDOM != null) { 1503 if (this.users[i].interfaceDOM != null) {
1505 this.users[i].bufferLoaded(this); 1504 this.users[i].bufferLoaded(this);
1506 } 1505 }
1507 } 1506 }
1508 }; 1507 };
1509 this.getMedia = function (url) { 1508 this.getMedia = function (urls) {
1510 this.url = url; 1509 var self = this;
1511 this.xmlRequest.open('GET', this.url, true); 1510
1512 this.xmlRequest.responseType = 'arraybuffer'; 1511 function get(fqurl) {
1513 1512 return new Promise(function (resolve, reject) {
1514 var bufferObj = this; 1513 var req = new XMLHttpRequest();
1514 req.open('GET', fqurl, true);
1515 req.responseType = 'arraybuffer';
1516 req.onload = function () {
1517 if (req.status == 200) {
1518 resolve(req.response);
1519 }
1520 };
1521 req.onerror = function () {
1522 reject(new Error(req.statusText));
1523 };
1524
1525 req.addEventListener("progress", progressCallback.bind(self));
1526 req.send();
1527 });
1528 }
1529
1530 function getNextURL() {
1531 currentUrlIndex++;
1532 var self = this;
1533 if (currentURLIndex == this.urls.length) {
1534 processError();
1535 } else {
1536 return get(this.urls[currentUrlIndex]).then(processAudio.bind(self)).catch(getNextURL.bind(self));
1537 }
1538 }
1515 1539
1516 // Create callback to decode the data asynchronously 1540 // Create callback to decode the data asynchronously
1517 this.xmlRequest.onloadend = function () { 1541 function processAudio(response) {
1518 // Use inbuilt WAVE decoder first 1542 var self = this;
1519 if (this.status == -1) { 1543 return audioContext.decodeAudioData(response, function (decodedData) {
1520 return; 1544 self.buffer = decodedData;
1521 } 1545 self.status = 2;
1522 var waveObj = new WAVE(); 1546 calculateLoudness(self, "I");
1523 audioContext.decodeAudioData(bufferObj.xmlRequest.response, function (decodedData) { 1547 return true;
1524 bufferObj.buffer = decodedData;
1525 bufferObj.status = 2;
1526 calculateLoudness(bufferObj, "I");
1527 }, function (e) { 1548 }, function (e) {
1528 var waveObj = new WAVE(); 1549 var waveObj = new WAVE();
1529 if (waveObj.open(bufferObj.xmlRequest.response) == 0) { 1550 if (waveObj.open(response) == 0) {
1530 bufferObj.buffer = audioContext.createBuffer(waveObj.num_channels, waveObj.num_samples, waveObj.sample_rate); 1551 self.buffer = audioContext.createBuffer(waveObj.num_channels, waveObj.num_samples, waveObj.sample_rate);
1531 for (var c = 0; c < waveObj.num_channels; c++) { 1552 for (var c = 0; c < waveObj.num_channels; c++) {
1532 var buffer_ptr = bufferObj.buffer.getChannelData(c); 1553 var buffer_ptr = self.buffer.getChannelData(c);
1533 for (var n = 0; n < waveObj.num_samples; n++) { 1554 for (var n = 0; n < waveObj.num_samples; n++) {
1534 buffer_ptr[n] = waveObj.decoded_data[c][n]; 1555 buffer_ptr[n] = waveObj.decoded_data[c][n];
1535 } 1556 }
1536 } 1557 }
1537 1558
1538 delete waveObj; 1559 delete waveObj;
1539 } 1560 }
1540 if (bufferObj.buffer != undefined) { 1561 if (self.buffer != undefined) {
1541 bufferObj.status = 2; 1562 self.status = 2;
1542 calculateLoudness(bufferObj, "I"); 1563 calculateLoudness(self, "I");
1564 return true;
1543 } 1565 }
1566 return false;
1544 }); 1567 });
1545 }; 1568 }
1546 1569
1547 // Create callback for any error in loading 1570 // Create callback for any error in loading
1548 this.xmlRequest.onerror = function () { 1571 function processError() {
1549 this.parent.status = -1; 1572 this.status = -1;
1550 for (var i = 0; i < this.parent.users.length; i++) { 1573 for (var i = 0; i < this.users.length; i++) {
1551 this.parent.users[i].state = -1; 1574 this.users[i].state = -1;
1552 if (this.parent.users[i].interfaceDOM != null) { 1575 if (this.users[i].interfaceDOM != null) {
1553 this.parent.users[i].bufferLoaded(this); 1576 this.users[i].bufferLoaded(this);
1554 } 1577 }
1555 } 1578 }
1556 interfaceContext.lightbox.post("Error", "Could not load resource " + this.parent.url); 1579 interfaceContext.lightbox.post("Error", "Could not load resource " + this.url);
1557 } 1580 }
1558 1581
1559 this.progress = 0; 1582 function progressCallback(event) {
1560 this.progressCallback = function (event) {
1561 if (event.lengthComputable) { 1583 if (event.lengthComputable) {
1562 this.parent.progress = event.loaded / event.total; 1584 this.progress = event.loaded / event.total;
1563 for (var i = 0; i < this.parent.users.length; i++) { 1585 for (var i = 0; i < this.users.length; i++) {
1564 if (this.parent.users[i].interfaceDOM != null) { 1586 if (this.users[i].interfaceDOM != null) {
1565 if (typeof this.parent.users[i].interfaceDOM.updateLoading === "function") { 1587 if (typeof this.users[i].interfaceDOM.updateLoading === "function") {
1566 this.parent.users[i].interfaceDOM.updateLoading(this.parent.progress * 100); 1588 this.users[i].interfaceDOM.updateLoading(this.progress * 100);
1567 } 1589 }
1568 } 1590 }
1569 } 1591 }
1570 } 1592 }
1571 }; 1593 };
1572 this.xmlRequest.addEventListener("progress", this.progressCallback); 1594
1595 this.urls = urls;
1596 currentUrlIndex = 0;
1597
1598 this.progress = 0;
1573 this.status = 1; 1599 this.status = 1;
1574 this.xmlRequest.send(); 1600 get(this.urls[currentUrlIndex]).then(processAudio.bind(self)).catch(getNextURL.bind(self));
1575 }; 1601 };
1576 1602
1577 this.registerAudioObject = function (audioObject) { 1603 this.registerAudioObject = function (audioObject) {
1578 // Called by an audioObject to register to the buffer for use 1604 // Called by an audioObject to register to the buffer for use
1579 // First check if already in the register pool 1605 // First check if already in the register pool
1653 break; 1679 break;
1654 } 1680 }
1655 } 1681 }
1656 if (buffer == null) { 1682 if (buffer == null) {
1657 buffer = new this.bufferObj(); 1683 buffer = new this.bufferObj();
1658 buffer.getMedia(URL); 1684 var urls = [URL];
1685 element.alternatives.forEach(function (e) {
1686 urls.push(e.url);
1687 });
1688 buffer.getMedia(urls);
1659 this.buffers.push(buffer); 1689 this.buffers.push(buffer);
1660 } 1690 }
1661 } 1691 }
1662 }; 1692 };
1663 1693
1723 1753
1724 // Check if audioObject buffer is currently stored by full URL 1754 // Check if audioObject buffer is currently stored by full URL
1725 var URL = testState.currentStateMap.hostURL + element.url; 1755 var URL = testState.currentStateMap.hostURL + element.url;
1726 var buffer = null; 1756 var buffer = null;
1727 for (var i = 0; i < this.buffers.length; i++) { 1757 for (var i = 0; i < this.buffers.length; i++) {
1728 if (URL == this.buffers[i].url) { 1758 if (this.buffers[i].urls.includes(URL)) {
1729 buffer = this.buffers[i]; 1759 buffer = this.buffers[i];
1730 break; 1760 break;
1731 } 1761 }
1732 } 1762 }
1733 if (buffer == null) { 1763 if (buffer == null) {