Mercurial > hg > webaudioevaluationtool
changeset 773:d07bc42a716c
Buffers loaded into a pool and picked when needed.
author | Nicholas Jillings <n.g.r.jillings@se14.qmul.ac.uk> |
---|---|
date | Mon, 07 Dec 2015 18:26:12 +0000 |
parents | b1a5d3a0a41f |
children | 67c6048d920f |
files | ape.js core.js |
diffstat | 2 files changed, 106 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/ape.js Mon Dec 07 16:11:30 2015 +0100 +++ b/ape.js Mon Dec 07 18:26:12 2015 +0000 @@ -404,6 +404,10 @@ // Create a slider per track audioObject.interfaceDOM = new sliderObject(audioObject); + if (audioObject.state == 1) + { + audioObject.interfaceDOM.enable(); + } // Distribute it randomnly var w = window.innerWidth - (offset+8)*2;
--- a/core.js Mon Dec 07 16:11:30 2015 +0100 +++ b/core.js Mon Dec 07 18:26:12 2015 +0000 @@ -40,6 +40,8 @@ // Create the interface object interfaceContext = new Interface(specification); + // Define window callbacks for interface + window.onresize = function(event){interfaceContext.resizeWindow(event);}; }; function loadProjectSpec(url) { @@ -64,19 +66,6 @@ // Build the specification specification.decode(projectXML); - // Create the audio engine object - audioEngineContext = new AudioEngine(specification); - - testState.stateMap.push(specification.preTest); - - $(specification.audioHolders).each(function(index,elem){ - testState.stateMap.push(elem); - }); - - testState.stateMap.push(specification.postTest); - - - // Detect the interface to use and load the relevant javascripts. var interfaceJS = document.createElement('script'); interfaceJS.setAttribute("type","text/javascript"); @@ -104,8 +93,33 @@ } document.getElementsByTagName("head")[0].appendChild(interfaceJS); - // Define window callbacks for interface - window.onresize = function(event){interfaceContext.resizeWindow(event);}; + // Create the audio engine object + audioEngineContext = new AudioEngine(specification); + + testState.stateMap.push(specification.preTest); + + $(specification.audioHolders).each(function(index,elem){ + testState.stateMap.push(elem); + $(elem.audioElements).each(function(i,audioElem){ + var URL = audioElem.parent.hostURL + audioElem.url; + var buffer = null; + for (var i=0; i<audioEngineContext.buffers.length; i++) + { + if (URL == audioEngineContext.buffers[i].url) + { + buffer = audioEngineContext.buffers[i]; + break; + } + } + if (buffer == null) + { + buffer = new audioEngineContext.bufferObj(URL); + audioEngineContext.buffers.push(buffer); + } + }); + }); + + testState.stateMap.push(specification.postTest); } function createProjectSave(destURL) { @@ -703,6 +717,48 @@ // Create store for new audioObjects this.audioObjects = []; + this.buffers = []; + this.bufferObj = function(url) + { + this.url = url; + this.buffer = null; + this.xmlRequest = new XMLHttpRequest(); + this.users = []; + this.xmlRequest.open('GET',this.url,true); + this.xmlRequest.responseType = 'arraybuffer'; + + var bufferObj = this; + + // Create callback to decode the data asynchronously + this.xmlRequest.onloadend = function() { + audioContext.decodeAudioData(bufferObj.xmlRequest.response, function(decodedData) { + bufferObj.buffer = decodedData; + for (var i=0; i<bufferObj.users.length; i++) + { + bufferObj.users[i].state = 1; + if (bufferObj.users[i].interfaceDOM != null) + { + bufferObj.users[i].interfaceDOM.enable(); + } + } + }, function(){ + // Should only be called if there was an error, but sometimes gets called continuously + // Check here if the error is genuine + if (bufferObj.buffer == undefined) { + // Genuine error + console.log('FATAL - Error loading buffer on '+audioObj.id); + if (request.status == 404) + { + console.log('FATAL - Fragment '+audioObj.id+' 404 error'); + console.log('URL: '+audioObj.url); + errorSessionDump('Fragment '+audioObj.id+' 404 error'); + } + } + }); + }; + this.xmlRequest.send(); + }; + this.play = function(id) { // Start the timer and set the audioEngine state to playing (1) if (this.status == 0 && this.loopPlayback) { @@ -772,9 +828,30 @@ audioObjectId = this.audioObjects.length; this.audioObjects[audioObjectId] = new audioObject(audioObjectId); - // AudioObject will get track itself. + // Check if audioObject buffer is currently stored by full URL + var URL = element.parent.hostURL + element.url; + var buffer = null; + for (var i=0; i<this.buffers.length; i++) + { + if (URL == this.buffers[i].url) + { + buffer = this.buffers[i]; + break; + } + } + if (buffer == null) + { + console.log("[WARN]: Buffer was not loaded in pre-test!"); + buffer = new this.bufferObj(URL); + this.buffers.push(buffer); + } this.audioObjects[audioObjectId].specification = element; - this.audioObjects[audioObjectId].constructTrack(element.parent.hostURL + element.url); + this.audioObjects[audioObjectId].buffer = buffer; + if (buffer.buffer != null) + { + this.audioObjects[audioObjectId].state = 1; + } + buffer.users.push(this.audioObjects[audioObjectId]); return this.audioObjects[audioObjectId]; }; @@ -782,6 +859,10 @@ this.state = 0; this.audioObjectsReady = false; this.metric.reset(); + for (var i=0; i < this.buffers.length; i++) + { + this.buffers[i].users = []; + } this.audioObjects = []; }; @@ -885,11 +966,11 @@ }; this.play = function(startTime) { - if (this.bufferNode == undefined) { + if (this.bufferNode == undefined && this.buffer.buffer != undefined) { this.bufferNode = audioContext.createBufferSource(); this.bufferNode.owner = this; this.bufferNode.connect(this.outputGain); - this.bufferNode.buffer = this.buffer; + this.bufferNode.buffer = this.buffer.buffer; this.bufferNode.loop = audioEngineContext.loopPlayback; this.bufferNode.onended = function(event) { // Safari does not like using 'this' to reference the calling object! @@ -917,7 +998,7 @@ if (this.bufferNode != undefined) { if (this.bufferNode.loop == true) { if (audioEngineContext.status == 1) { - return (time-this.metric.listenStart)%this.buffer.duration; + return (time-this.metric.listenStart)%this.buffer.buffer.duration; } else { return 0; } @@ -2434,7 +2515,7 @@ this.setTimePerPixel = function(audioObject) { //maxTime must be in seconds this.playbackObject = audioObject; - this.maxTime = audioObject.buffer.duration; + this.maxTime = audioObject.buffer.buffer.duration; var width = 490; //500 - 10, 5 each side of the tracker head this.timePerPixel = this.maxTime/490; if (this.maxTime < 60) {