Mercurial > hg > webaudioevaluationtool
changeset 57:086a10f85fde Dev_main
Added Loop
author | Nicholas Jillings <n.g.r.jillings@se14.qmul.ac.uk> |
---|---|
date | Sat, 18 Apr 2015 15:36:10 +0100 |
parents | 83198a86b3bc |
children | c23050ad945a |
files | ape.js core.js docs/ProjectSpecificationDocument.tex example_eval/project.xml |
diffstat | 4 files changed, 108 insertions(+), 48 deletions(-) [+] |
line wrap: on
line diff
--- a/ape.js Fri Apr 17 10:06:20 2015 +0100 +++ b/ape.js Sat Apr 18 15:36:10 2015 +0100 @@ -322,6 +322,99 @@ } } + var loopPlayback = textXML.attributes['loop']; + if (loopPlayback != undefined) + { + loopPlayback = loopPlayback.value; + if (loopPlayback == 'true') { + loopPlayback = true; + } else { + loopPlayback = false; + } + } else { + loopPlayback = false; + } + audioEngineContext.loopPlayback = loopPlayback; + + // Create AudioEngine bindings for playback + if (loopPlayback) { + audioEngineContext.play = function() { + // Send play command to all playback buffers for synchronised start + // Also start timer callbacks to detect if playback has finished + if (this.status == 0) { + this.timer.startTest(); + // First get current clock + var timer = audioContext.currentTime; + // Add 3 seconds + timer += 3.0; + // Send play to all tracks + for (var i=0; i<this.audioObjects.length; i++) + { + this.audioObjects[i].play(timer); + } + this.status = 1; + } + }; + + audioEngineContext.stop = function() { + // Send stop and reset command to all playback buffers + if (this.status == 1) { + if (this.loopPlayback) { + for (var i=0; i<this.audioObjects.length; i++) + { + this.audioObjects[i].stop(); + } + } + this.status = 0; + } + }; + + audioEngineContext.selectedTrack = function(id) { + for (var i=0; i<this.audioObjects.length; i++) + { + if (id == i) { + this.audioObjects[i].outputGain.gain.value = 1.0; + } else { + this.audioObjects[i].outputGain.gain.value = 0.0; + } + } + }; + } else { + audioEngineContext.play = function() { + // Send play command to all playback buffers for synchronised start + // Also start timer callbacks to detect if playback has finished + if (this.status == 0) { + this.timer.startTest(); + this.status = 1; + } + }; + + audioEngineContext.stop = function() { + // Send stop and reset command to all playback buffers + if (this.status == 1) { + if (this.loopPlayback) { + for (var i=0; i<this.audioObjects.length; i++) + { + this.audioObjects[i].stop(); + } + } + this.status = 0; + } + }; + + audioEngineContext.selectedTrack = function(id) { + for (var i=0; i<this.audioObjects.length; i++) + { + if (id == i) { + this.audioObjects[i].outputGain.gain.value = 1.0; + this.audioObjects[i].play(audioContext.currentTime+0.01); + } else { + this.audioObjects[i].outputGain.gain.value = 0.0; + } + } + }; + } + currentTestHolder = document.createElement('audioHolder'); currentTestHolder.id = textXML.id; currentTestHolder.repeatCount = textXML.attributes['repeatCount'].value;
--- a/core.js Fri Apr 17 10:06:20 2015 +0100 +++ b/core.js Sat Apr 18 15:36:10 2015 +0100 @@ -32,6 +32,9 @@ var preTestQuestions = document.createElement('PreTest'); // Store any pre-test question response var postTestQuestions = document.createElement('PostTest'); // Store any post-test question response +// Add a prototype to the bufferSourceNode to reference to the audioObject holding it +AudioBufferSourceNode.prototype.owner = undefined; + window.onload = function() { // Function called once the browser has loaded all files. // This should perform any initial commands such as structure / loading documents @@ -126,49 +129,14 @@ // Create session metrics this.metric = new sessionMetrics(this); + this.loopPlayback = false; + // Create store for new audioObjects this.audioObjects = []; - this.play = function() { - // Send play command to all playback buffers for synchronised start - // Also start timer callbacks to detect if playback has finished - if (this.status == 0) { - this.timer.startTest(); - // First get current clock - var timer = audioContext.currentTime; - // Add 3 seconds - timer += 3.0; - - // Send play to all tracks - for (var i=0; i<this.audioObjects.length; i++) - { - this.audioObjects[i].play(timer); - } - this.status = 1; - } - }; + this.play = function(){}; - this.stop = function() { - // Send stop and reset command to all playback buffers - if (this.status == 1) { - for (var i=0; i<this.audioObjects.length; i++) - { - this.audioObjects[i].stop(); - } - this.status = 0; - } - }; - - this.selectedTrack = function(id) { - for (var i=0; i<this.audioObjects.length; i++) - { - if (id == i) { - this.audioObjects[i].outputGain.gain.value = 1.0; - } else { - this.audioObjects[i].outputGain.gain.value = 0.0; - } - } - }; + this.stop = function(){}; this.newTrack = function(url) { @@ -194,14 +162,13 @@ this.metric = new metricTracker(); // Create a buffer and external gain control to allow internal patching of effects and volume leveling. - this.bufferNode = audioContext.createBufferSource(); + this.bufferNode = undefined; this.outputGain = audioContext.createGain(); // Default output gain to be zero this.outputGain.gain.value = 0.0; // Connect buffer to the audio graph - this.bufferNode.connect(this.outputGain); this.outputGain.connect(audioEngineContext.outputGain); // the audiobuffer is not designed for multi-start playback @@ -209,15 +176,16 @@ this.buffer; this.play = function(startTime) { + this.bufferNode = audioContext.createBufferSource(); + this.bufferNode.connect(this.outputGain); + this.bufferNode.buffer = this.buffer; + this.bufferNode.loop = audioEngineContext.loopPlayback; this.bufferNode.start(startTime); }; this.stop = function() { this.bufferNode.stop(0); - this.bufferNode = audioContext.createBufferSource(); - this.bufferNode.connect(this.outputGain); - this.bufferNode.buffer = this.buffer; - this.bufferNode.loop = true; + this.bufferNode = undefined; }; this.constructTrack = function(url) { @@ -232,8 +200,6 @@ request.onloadend = function() { audioContext.decodeAudioData(request.response, function(decodedData) { audioObj.buffer = decodedData; - audioObj.bufferNode.buffer = audioObj.buffer; - audioObj.bufferNode.loop = true; audioObj.state = 1; }, function(){ // Should only be called if there was an error, but sometimes gets called continuously
--- a/docs/ProjectSpecificationDocument.tex Fri Apr 17 10:06:20 2015 +0100 +++ b/docs/ProjectSpecificationDocument.tex Sat Apr 18 15:36:10 2015 +0100 @@ -46,6 +46,7 @@ \item \texttt{sampleRate} - Optional, Number. If your test requires a specific sample rate, this should be set to the desired sample rate in Hertz. This does not set the browser to the correct sample rate, but forces the browser to check the sample rate matches. If this is undefined, no sample rate matching will occur. \item \texttt{randomiseOrder} - Optional, Boolean String. Defaults to false. Determine if the track order should be randomised. Must be true or false. \item \texttt{repeatCount} - Optional, Number. Defaults to 0 (ie: no repeats). The number of times a test should be repeated. +\item \texttt{loop} - Optional, Boolean String. Defaults to false. Enable if audioElements should loop their playback or not. \end{itemize} \subsection{Elements}
--- a/example_eval/project.xml Fri Apr 17 10:06:20 2015 +0100 +++ b/example_eval/project.xml Sat Apr 18 15:36:10 2015 +0100 @@ -18,7 +18,7 @@ <metricEnable>elementFlagMoved</metricEnable> </Metric> </setup> - <audioHolder id='0' hostURL="example_eval/" sampleRate="44100" randomiseOrder='true' repeatCount='1'> + <audioHolder id='0' hostURL="example_eval/" sampleRate="44100" randomiseOrder='true' repeatCount='1' loop='true'> <interface> <title>Example Test Question</title> <scale position="0">Min</scale>