changeset 212:b5cb42422f4a

Merge into main for bug fixes
author Nicholas Jillings <nicholas.jillings@eecs.qmul.ac.uk>
date Tue, 16 Jun 2015 14:51:44 +0100
parents 43dc4a1c3adf (current diff) 5d251b4aabd6 (diff)
children 0560fe84fde6
files
diffstat 3 files changed, 167 insertions(+), 48 deletions(-) [+]
line wrap: on
line diff
--- a/ape.js	Mon Jun 15 19:03:08 2015 +0100
+++ b/ape.js	Tue Jun 16 14:51:44 2015 +0100
@@ -176,6 +176,11 @@
 	feedbackHolder.innerHTML = null;
 	canvas.innerHTML = null;
 	
+	var playbackHolder = document.createElement('div');
+	playbackHolder.style.width = "100%";
+	playbackHolder.align = 'center';
+	playbackHolder.appendChild(interfaceContext.playhead.object);
+	feedbackHolder.appendChild(playbackHolder);
 	// Setup question title
 	var interfaceObj = audioHolderObject.interfaces;
 	var commentBoxPrefix = "Comment on track";
@@ -222,30 +227,9 @@
 
 	audioEngineContext.loopPlayback = loopPlayback;
 	// Create AudioEngine bindings for playback
-	if (loopPlayback) {
-		audioEngineContext.selectedTrack = function(id) {
-			for (var i=0; i<this.audioObjects.length; i++)
-			{
-				if (id == i) {
-					this.audioObjects[i].loopStart();
-				} else {
-					this.audioObjects[i].loopStop();
-				}
-			}
-		};
-	} else {
-		audioEngineContext.selectedTrack = function(id) {
-			for (var i=0; i<this.audioObjects.length; i++)
-			{
-				this.audioObjects[i].outputGain.gain.value = 0.0;
-				this.audioObjects[i].stop();
-			}
-			if (this.status == 1) {
-				this.audioObjects[id].outputGain.gain.value = 1.0;
-				this.audioObjects[id].play(audioContext.currentTime+0.01);
-			}
-		};
-	}
+	audioEngineContext.selectedTrack = function(id) {
+		console.log('Deprecated');
+	};
 	
 	currentTestHolder = document.createElement('audioHolder');
 	currentTestHolder.id = audioHolderObject.id;
@@ -261,6 +245,7 @@
 	
 	// Delete any previous audioObjects associated with the audioEngine
 	audioEngineContext.audioObjects = [];
+	interfaceContext.deleteCommentBoxes();
 	
 	// Find all the audioElements from the audioHolder
 	$(audioHolderObject.audioElements).each(function(index,element){
@@ -318,14 +303,20 @@
 		if (audioEngineContext.audioObjectsReady) {
 			// Cannot continue to issue play command until audioObjects reported as ready!
 			// Get the track ID from the object ID
-			var id = Number(event.srcElement.attributes['trackIndex'].value);
+			var element;
+			if (event.srcElement.nodeName == "SPAN") {
+				element = event.srcElement.parentNode;
+			} else {
+				element = event.srcElement;
+			}
+			var id = Number(element.attributes['trackIndex'].value);
 			//audioEngineContext.metric.sliderPlayed(id);
-			audioEngineContext.selectedTrack(id);
+			audioEngineContext.play(id);
             // Currently playing track red, rest green
             
             //document.getElementById('track-slider-'+index).style.backgroundColor = "#FF0000";
             $('.track-slider').removeClass('track-slider-playing');
-            $(event.srcElement).addClass('track-slider-playing');
+            $(element).addClass('track-slider-playing');
             $('.comment-div').removeClass('comment-box-playing');
             $('#comment-div-'+id).addClass('comment-box-playing');
 		}
--- a/core.css	Mon Jun 15 19:03:08 2015 +0100
+++ b/core.css	Tue Jun 16 14:51:44 2015 +0100
@@ -60,3 +60,25 @@
 	width: 618px;
 	margin-right:15px;
 }
+
+div.playhead {
+	width: 500px;
+	height: 50px;
+	background-color: #eee;
+	border-radius: 10px;
+	padding: 10px;
+}
+
+div.playhead-scrub-track {
+	width: 100%;
+	height: 10px;
+	border-style: solid;
+	border-width: 1px;
+}
+
+div#playhead-scrubber {
+	width: 10px;
+	height: 10px;
+	position: relative;
+	background-color: #000;
+}
--- a/core.js	Mon Jun 15 19:03:08 2015 +0100
+++ b/core.js	Tue Jun 16 14:51:44 2015 +0100
@@ -675,7 +675,7 @@
 	// Create store for new audioObjects
 	this.audioObjects = [];
 	
-	this.play = function() {
+	this.play = function(id) {
 		// Start the timer and set the audioEngine state to playing (1)
 		if (this.status == 0) {
 			// Check if all audioObjects are ready
@@ -684,13 +684,38 @@
 			}
 			if (this.audioObjectsReady == true) {
 				this.timer.startTest();
-				if (this.loopPlayback) {
-					for(var i=0; i<this.audioObjects.length; i++) {
-						this.audioObjects[i].play(this.timer.getTestTime()+1);
+				this.status = 1;
+			}
+		}
+		if (this.status== 1) {
+			if (id == undefined) {
+				id = -1;
+			} else {
+				interfaceContext.playhead.setTimePerPixel(this.audioObjects[id]);
+			}
+			if (this.loopPlayback) {
+				for (var i=0; i<this.audioObjects.length; i++)
+				{
+					this.audioObjects[i].play(this.timer.getTestTime()+1);
+					if (id == i) {
+						this.audioObjects[i].loopStart();
+					} else {
+						this.audioObjects[i].loopStop();
 					}
 				}
-				this.status = 1;
+			} else {
+				for (var i=0; i<this.audioObjects.length; i++)
+				{
+					if (i != id) {
+						this.audioObjects[i].outputGain.gain.value = 0.0;
+						this.audioObjects[i].stop();
+					} else if (i == id) {
+						this.audioObjects[id].outputGain.gain.value = 1.0;
+						this.audioObjects[id].play(audioContext.currentTime+0.01);
+					}
+				}
 			}
+			interfaceContext.playhead.start();
 		}
 	};
 	
@@ -701,11 +726,11 @@
 			{
 				this.audioObjects[i].stop();
 			}
+			interfaceContext.playhead.stop();
 			this.status = 0;
 		}
 	};
 	
-	
 	this.newTrack = function(element) {
 		// Pull data from given URL into new audio buffer
 		// URLs must either be from the same source OR be setup to 'Access-Control-Allow-Origin'
@@ -791,27 +816,29 @@
 	};
 	
 	this.play = function(startTime) {
-		this.bufferNode = audioContext.createBufferSource();
-		this.bufferNode.owner = this;
-		this.bufferNode.connect(this.outputGain);
-		this.bufferNode.buffer = this.buffer;
-		this.bufferNode.loop = audioEngineContext.loopPlayback;
-		this.bufferNode.onended = function() {
-			// Safari does not like using 'this' to reference the calling object!
-			event.srcElement.owner.metric.stopListening(audioEngineContext.timer.getTestTime());
-		};
-		if (this.bufferNode.loop == false) {
-			this.metric.startListening(audioEngineContext.timer.getTestTime());
+		if (this.bufferNode == undefined) {
+			this.bufferNode = audioContext.createBufferSource();
+			this.bufferNode.owner = this;
+			this.bufferNode.connect(this.outputGain);
+			this.bufferNode.buffer = this.buffer;
+			this.bufferNode.loop = audioEngineContext.loopPlayback;
+			this.bufferNode.onended = function() {
+				// Safari does not like using 'this' to reference the calling object!
+				event.srcElement.owner.metric.stopListening(audioEngineContext.timer.getTestTime(),event.srcElement.owner.getCurrentPosition());
+			};
+			if (this.bufferNode.loop == false) {
+				this.metric.startListening(audioEngineContext.timer.getTestTime());
+			}
+			this.bufferNode.start(startTime);
 		}
-		this.bufferNode.start(startTime);
 	};
 	
 	this.stop = function() {
 		if (this.bufferNode != undefined)
 		{
+			this.metric.stopListening(audioEngineContext.timer.getTestTime(),this.getCurrentPosition());
 			this.bufferNode.stop(0);
 			this.bufferNode = undefined;
-			this.metric.stopListening(audioEngineContext.timer.getTestTime());
 		}
 	};
 	
@@ -980,7 +1007,7 @@
 		}
 	};
 	
-	this.stopListening = function(time)
+	this.stopListening = function(time,bufferStopTime)
 	{
 		if (this.listenHold == true)
 		{
@@ -993,7 +1020,11 @@
 			var testTime = evnt.getElementsByTagName('testTime')[0];
 			var bufferTime = evnt.getElementsByTagName('bufferTime')[0];
 			testTime.setAttribute('stop',time);
-			bufferTime.setAttribute('stop',this.parent.getCurrentPosition());
+			if (bufferStopTime == undefined) {
+				bufferTime.setAttribute('stop',this.parent.getCurrentPosition());
+			} else {
+				bufferTime.setAttribute('stop',bufferStopTime);
+			}
 			console.log('slider ' + this.parent.id + ' played for (' + diff + ')'); // DEBUG/SAFETY: show played slider id
 		}
 	};
@@ -1649,6 +1680,10 @@
 		}
 	};
 	
+	this.deleteCommentBoxes = function() {
+		this.commentBoxes = [];
+	}
+	
 	this.createCommentQuestion = function(element) {
 		var node;
 		if (element.type == 'text') {
@@ -1661,5 +1696,76 @@
 		this.commentQuestions.push(node);
 		return node;
 	};
+	
+	this.playhead = new function()
+	{
+		this.object = document.createElement('div');
+		this.object.className = 'playhead';
+		this.object.align = 'left';
+		var curTime = document.createElement('div');
+		curTime.style.width = '50px';
+		this.curTimeSpan = document.createElement('span');
+		this.curTimeSpan.textContent = '00:00';
+		curTime.appendChild(this.curTimeSpan);
+		this.object.appendChild(curTime);
+		this.scrubberTrack = document.createElement('div');
+		this.scrubberTrack.className = 'playhead-scrub-track';
+		
+		this.scrubberHead = document.createElement('div');
+		this.scrubberHead.id = 'playhead-scrubber';
+		this.scrubberTrack.appendChild(this.scrubberHead);
+		this.object.appendChild(this.scrubberTrack);
+		
+		this.timePerPixel = 0;
+		this.maxTime = 0;
+		
+		this.playbackObject;
+		
+		this.setTimePerPixel = function(audioObject) {
+			//maxTime must be in seconds
+			this.playbackObject = audioObject;
+			this.maxTime = audioObject.buffer.duration;
+			var width = 490; //500 - 10, 5 each side of the tracker head
+			this.timePerPixel = this.maxTime/490;
+			if (this.maxTime < 60) {
+				this.curTimeSpan.textContent = '0.00';
+			} else {
+				this.curTimeSpan.textContent = '00:00';
+			}
+		};
+		
+		this.update = function() {
+			// Update the playhead position, startPlay must be called
+			if (this.timePerPixel > 0) {
+				var time = this.playbackObject.getCurrentPosition();
+				var width = 490;
+				var pix = Math.floor(time/this.timePerPixel);
+				this.scrubberHead.style.left = pix+'px';
+				if (this.maxTime > 60.0) {
+					var secs = time%60;
+					var mins = Math.floor((time-secs)/60);
+					secs = secs.toString();
+					secs = secs.substr(0,2);
+					mins = mins.toString();
+					this.curTimeSpan.textContent = mins+':'+secs;
+				} else {
+					time = time.toString();
+					this.curTimeSpan.textContent = time.substr(0,4);
+				}
+			}
+		};
+		
+		this.interval = undefined;
+		
+		this.start = function() {
+			if (this.playbackObject != undefined && this.interval == undefined) {
+				this.interval = setInterval(function(){interfaceContext.playhead.update();},100);
+			}
+		};
+		this.stop = function() {
+			clearInterval(this.interval);
+			this.interval = undefined;
+		};
+	};
 }