# HG changeset patch # User Nicholas Jillings # Date 1428859239 -3600 # Node ID b5cd02cb262f02596ed58c78dd588c67e2ec9a26 # Parent 211d3e0eeafe4b07f53a6a367d67980e5ae7323a Added preliminary metrics functions diff -r 211d3e0eeafe -r b5cd02cb262f ape.js --- a/ape.js Sat Apr 11 11:45:04 2015 +0100 +++ b/ape.js Sun Apr 12 18:20:39 2015 +0100 @@ -101,6 +101,7 @@ // Create playback start/stop points var playback = document.createElement("button"); playback.innerHTML = 'Start'; + playback.id = 'playback-button'; // onclick function. Check if it is playing or not, call the correct function in the // audioEngine, change the button text to reflect the next state. playback.onclick = function() { @@ -116,6 +117,7 @@ var submit = document.createElement("button"); submit.innerHTML = 'Submit'; submit.onclick = buttonSubmitClick; + submit.id = 'submit-button'; // Append the interface buttons into the interfaceButtons object. interfaceButtons.appendChild(playback); interfaceButtons.appendChild(submit); @@ -305,11 +307,17 @@ trackSliderObj.innerHTML = ''+index+''; trackSliderObj.draggable = true; trackSliderObj.ondragend = dragEnd; + trackSliderObj.ondragstart = function() + { + var id = Number(this.id.substr(13,2)); // Maximum theoretical tracks is 99! + audioEngineContext.metric.sliderMoveStart(id); + }; // Onclick, switch playback to that track trackSliderObj.onclick = function() { // Get the track ID from the object ID var id = Number(this.id.substr(13,2)); // Maximum theoretical tracks is 99! + audioEngineContext.metric.sliderPlayed(id); audioEngineContext.selectedTrack(id); }; @@ -492,6 +500,7 @@ this.style.left = window.innerWidth-50 + 'px'; } } + audioEngineContext.metric.sliderMoved(); } function advanceState() @@ -553,9 +562,14 @@ function buttonSubmitClick() { + if (audioEngineContext.status == 1) { + var playback = document.getElementById('playback-button'); + playback.click(); // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options + } if (currentState.substr(0,7) == 'testRun') { + audioEngineContext.timer.stopTest(); advanceState(); } } diff -r 211d3e0eeafe -r b5cd02cb262f core.js --- a/core.js Sat Apr 11 11:45:04 2015 +0100 +++ b/core.js Sun Apr 12 18:20:39 2015 +0100 @@ -121,6 +121,11 @@ this.outputGain.connect(audioContext.destination); this.fooGain.connect(audioContext.destination); + // Create the timer Object + this.timer = new timer(); + // Create session metrics + this.metric = new sessionMetrics(this); + // Create store for new audioObjects this.audioObjects = []; @@ -128,6 +133,7 @@ // 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 @@ -170,7 +176,7 @@ // URLs must either be from the same source OR be setup to 'Access-Control-Allow-Origin' // Create the audioObject with ID of the new track length; - audioObjectId = this.audioObjects.length + audioObjectId = this.audioObjects.length; this.audioObjects[audioObjectId] = new audioObject(audioObjectId); // AudioObject will get track itself. @@ -185,6 +191,7 @@ this.id = id; this.state = 0; // 0 - no data, 1 - ready this.url = null; // Hold the URL given for the output back to the results. + this.metric = new metricTracker(); // Create a buffer and external gain control to allow internal patching of effects and volume leveling. this.bufferNode = audioContext.createBufferSource(); @@ -240,4 +247,132 @@ request.send(); }; -} \ No newline at end of file +} + +function timer() +{ + /* Timer object used in audioEngine to keep track of session timings + * Uses the timer of the web audio API, so sample resolution + */ + this.testStarted = false; + this.testStartTime = 0; + this.testDuration = 0; + this.minimumTestTime = 0; // No minimum test time + this.startTest = function() + { + if (this.testStarted == false) + { + this.testStartTime = audioContext.currentTime; + this.testStarted = true; + this.updateTestTime(); + } + }; + this.stopTest = function() + { + if (this.testStarted) + { + this.testDuration = this.getTestTime(); + this.testStarted = false; + } else { + console.log('ERR: Test tried to end before beginning'); + } + }; + this.updateTestTime = function() + { + if (this.testStarted) + { + this.testDuration = audioContext.currentTime - this.testStartTime; + } + }; + this.getTestTime = function() + { + this.updateTestTime(); + return this.testDuration; + }; +} + +function sessionMetrics(engine) +{ + /* Used by audioEngine to link to audioObjects to minimise the timer call timers; + */ + this.engine = engine; + this.lastClicked = -1; + this.data = -1; + + this.sliderMoveStart = function(id) + { + if (this.data == -1) + { + this.data = id; + } else { + console.log('ERROR: Metric tracker detecting two moves!'); + this.data = -1; + } + }; + this.sliderMoved = function() + { + var time = engine.timer.getTestTime(); + var id = this.data; + this.data = -1; + var sliderObj = document.getElementsByClassName('track-slider')[id]; + var position = Number(sliderObj.style.left.substr(0,sliderObj.style.left.length-2)); + if (engine.timer.testStarted) + { + engine.audioObjects[id].metric.moved(time,position); + } else { + engine.audioObjects[id].metric.initialised(position); + } + }; + + this.sliderPlayed = function(id) + { + var time = engine.timer.getTestTime(); + if (engine.timer.testStarted) + { + if (this.lastClicked >= 0) + { + engine.audioObjects[this.lastClicked].metric.listening(time); + } + this.lastClicked = id; + engine.audioObjects[id].metric.listening(time); + } + }; +} + +function metricTracker() +{ + /* Custom object to track and collect metric data + * Used only inside the audioObjects object. + */ + + this.listenedTimer = 0; + this.listenStart = 0; + this.initialPosition = 0; + this.movementTracker = []; + this.wasListenedTo = false; + this.wasMoved = false; + this.hasComments = false; + + this.initialised = function(position) + { + this.initialPosition = position; + }; + + this.moved = function(time,position) + { + this.wasMoved = true; + this.movementTracker[this.movementTracker.length] = [time, position]; + }; + + this.listening = function(time) + { + if (this.listenStart == 0) + { + this.wasListenedTo = true; + this.listenStart = time; + } else { + this.listenedTimer += (time - this.listenStart); + this.listenStart = 0; + } + }; +}