Mercurial > hg > webaudioevaluationtool
changeset 459:f6c9f9e5400e Dev_main
Added AB test interface
author | Nicholas Jillings <n.g.r.jillings@se14.qmul.ac.uk> |
---|---|
date | Mon, 11 Jan 2016 16:32:26 +0000 |
parents | 46b4af266cdf |
children | fd941017792b |
files | AB.css AB.js ape.js core.js example_eval/AB_example.xml index.html mushra.js |
diffstat | 7 files changed, 208 insertions(+), 37 deletions(-) [+] |
line wrap: on
line diff
--- a/AB.css Mon Jan 11 13:56:30 2016 +0000 +++ b/AB.css Mon Jan 11 16:32:26 2016 +0000 @@ -31,23 +31,39 @@ background-color: #ddd } +button.big-button { + width: 250px; + height: 40px; + font-size: 1.2em; +} + div.comparitor-holder { width: 260px; height: 300px; border: black 1px solid; position: absolute; + padding-top: 5px; } div.comparitor-selector { - width: 250px; + width: 248px; height: 250px; border: black 1px solid; position: relative; + background-color: #FF0000; } -div.comparitor-button { +div.selected { + background-color: #008000; +} + +div.comparitor-selector span { + font-size: 4em; +} + +button.comparitor-button { width: 250px; - height: 50px; + height: 38px; position: relative; - background-color: #FF0000; + margin-top: 5px; }
--- a/AB.js Mon Jan 11 13:56:30 2016 +0000 +++ b/AB.js Mon Jan 11 16:32:26 2016 +0000 @@ -65,6 +65,46 @@ var feedbackHolder = document.createElement('div'); feedbackHolder.id = 'feedbackHolder'; + // Construct the AB Boxes + var boxes = document.createElement('div'); + boxes.align = "center"; + var boxA = document.createElement('div'); + boxA.className = 'comparitor-holder'; + boxA.id = 'comparitor-A'; + var selector = document.createElement('div'); + selector.className = 'comparitor-selector'; + selector.innerHTML = '<span>A</span>'; + var playback = document.createElement('button'); + playback.className = 'comparitor-button'; + playback.textContent = "Listen"; + boxA.appendChild(selector); + boxA.appendChild(playback); + boxes.appendChild(boxA); + + var boxB = document.createElement('div'); + boxB.className = 'comparitor-holder'; + boxB.id = 'comparitor-B'; + var selector = document.createElement('div'); + selector.className = 'comparitor-selector'; + selector.innerHTML = '<span>B</span>'; + var playback = document.createElement('button'); + playback.className = 'comparitor-button'; + playback.textContent = "Listen"; + boxB.appendChild(selector); + boxB.appendChild(playback); + boxes.appendChild(boxB); + + var submit = document.createElement('button'); + submit.id = "submit"; + submit.onclick = function() {interfaceContext.comparitor.submitButton();}; + submit.className = "big-button"; + submit.textContent = "submit"; + submit.style.position = "absolute"; + submit.style.top = '466px'; + + feedbackHolder.appendChild(boxes); + feedbackHolder.appendChild(submit); + // Inject into HTML testContent.appendChild(title); // Insert the title testContent.appendChild(pagetitle); @@ -75,6 +115,7 @@ // Load the full interface testState.initialise(); testState.advanceState(); + resizeWindow(null); } function loadTest(audioHolderObject) @@ -94,6 +135,7 @@ // Populate the comparitor object interfaceContext.comparitor = new Comparitor(audioHolderObject); + interfaceContext.comparitor.progress(); } function Comparitor(audioHolderObject) @@ -101,23 +143,20 @@ this.pairs = []; this.listened = [false, false]; this.selected = null; - this.index = 0; - this.feedbackHolder = document.getElementById('feedbackHolder'); - this.injectA = document.createElement('div'); - this.injectA.id = 'inject-A'; - this.injectB = document.createElement('div'); - this.injectB.id = 'inject-B'; - this.submitButton = document.createElement('button'); + this.index = -1; + this.currentPair = null; this.progress = function() { + this.index++; if (this.index >= this.pairs.length) { buttonSubmitClick(); return; } + $(".comparitor-selector").removeClass('selected'); this.listened = [false, false]; this.selected = null; - var pair = this.pairs[this.index]; + this.currentPair = this.pairs[this.index]; }; // First generate the Audio Objects for the Audio Engine @@ -144,14 +183,38 @@ this.pairs.push(pair); } } - this.feedbackHolder.innerHTML = null; - this.feedbackHolder.appendChild(this.injectA); - this.feedbackHolder.appendChild(this.injectB); - this.feedbackHolder.appendChild(this.submitButton); - this.submitButton.id = 'submit'; - this.submitButton.onclick = function() + // Generate Interface Bindings + $('.comparitor-selector').click(function(){ + $(".comparitor-selector").removeClass('selected'); + if (interfaceContext.comparitor.currentPair != null) + { + var side = this.parentElement.id.split('-')[1]; + var pair = interfaceContext.comparitor.currentPair; + var selected = eval('interfaceContext.comparitor.currentPair.'+side); + interfaceContext.comparitor.selected = selected; + $(this).addClass('selected'); + } + }); + + $('.comparitor-button').click(function(){ + $('.comparitor-button').text('Listen'); + if (interfaceContext.comparitor.currentPair != null) + { + var side = this.parentElement.id.split('-')[1]; + var pair = interfaceContext.comparitor.currentPair; + var selected = eval('interfaceContext.comparitor.currentPair.'+side); + audioEngineContext.play(selected.id); + $(this).text('Playing'); + if (side == 'A') {interfaceContext.comparitor.listened[0] = true;} + else if (side == 'B') {interfaceContext.comparitor.listened[1] = true;} + } + }); + + this.submitButton = function() { + audioEngineContext.stop(); + $('.comparitor-button').text('Listen'); // Check both A and B have been listened to if (this.listened[0] == false || this.listened[1] == false) { @@ -165,7 +228,15 @@ alert("Select either A or B before submitting"); return; } - this.pairs[this.index].A + this.pairs[this.index].A.interfaceDOM.results.push({ + compair: this.pairs[this.index].B.specification.id, + choice: this.selected + }); + this.pairs[this.index].B.interfaceDOM.results.push({ + compair: this.pairs[this.index].A.specification.id, + choice: this.selected + }); + this.progress(); }; return this; } @@ -174,25 +245,36 @@ { // The Interface Object for the comparitor this.parent = audioObject; - this.holder = document.createElement('div'); - this.play = document.createElement('button'); - this.select = document.createElement('div'); - - this.holder.className = "comparitor-holder"; - this.holder.appendChild(this.select); - this.holder.appendChild(this.play); - this.holder.align = "center"; - this.holder.setAttribute('trackIndex',audioObject.id); - - this.play.className = "comparitor-button"; - this.play.textContent = "Listen"; - - this.select.className = "comparitor-selector"; + this.results = []; + this.state = 0; + this.enable = function() + { + this.state = 1; + }; + this.exportXMLDOM = function(audioObject) { + var obj = []; + for (var result of this.results) + { + var node = storage.document.createElement('value'); + node.setAttribute('comparitorId',result.compair); + node.setAttribute('selectedId',result.choice.specification.id); + node.textContent = result.choice.specification.id; + obj.push(node); + } + return obj; + }; + this.getValue = function() { + return 0; + }; } function resizeWindow(event) { - + var totalWidth = 620; + var diff = (window.innerWidth - totalWidth)/2; + document.getElementById('comparitor-A').style.left = diff +'px'; + document.getElementById('comparitor-B').style.left = diff +360 +'px'; + document.getElementById('submit').style.left = (window.innerWidth-250)/2 + 'px'; } function buttonSubmitClick() // TODO: Only when all songs have been played!
--- a/ape.js Mon Jan 11 13:56:30 2016 +0000 +++ b/ape.js Mon Jan 11 16:32:26 2016 +0000 @@ -636,7 +636,7 @@ // Called by the audioObject holding this element. Must be present var obj = []; $(this.trackSliderObjects).each(function(i,trackObj){ - var node = document.createElement('value'); + var node = storage.document.createElement('value'); node.setAttribute("interface-name",trackObj.getAttribute("interface-name")); node.textContent = convSliderPosToRate(trackObj); obj.push(node);
--- a/core.js Mon Jan 11 13:56:30 2016 +0000 +++ b/core.js Mon Jan 11 16:32:26 2016 +0000 @@ -1232,7 +1232,9 @@ this.storeDOM.appendChild(interfaceXML[i]); } } - this.storeDOM.appendChild(this.commentDOM.exportXMLDOM(this)); + if (this.commentDOM != null) { + this.storeDOM.appendChild(this.commentDOM.exportXMLDOM(this)); + } } var nodes = this.metric.exportXMLDOM(); var mroot = this.storeDOM.getElementsByTagName('metric')[0];
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/example_eval/AB_example.xml Mon Jan 11 16:32:26 2016 +0000 @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="utf-8"?> +<waet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test-schema.xsd"> + <setup interface="AB" projectReturn="save.php" randomiseOrder='true' testPages="2" loudness="-23" sampleRate="44100"> + <survey location="before"> + <surveyentry type="question" id="sessionId" mandatory="true"> + <statement>Please enter your name.</statement> + </surveyentry> + <surveyentry type="checkbox" id="checkboxtest" mandatory="true"> + <statement>Please select with which activities you have any experience (example checkbox question)</statement> + <option name="musician">Playing a musical instrument</option> + <option name="soundengineer">Recording or mixing audio</option> + <option name="developer">Developing audio software</option> + <option name="hwdesigner">Designing or building audio hardware</option> + <option name="researcher">Research in the field of audio</option> + </surveyentry> + <surveyentry type="statement"> + <statement>This is an example of an 'APE'-style test, with two pages, using the test stimuli in 'example_eval/'.</statement> + </surveyentry> + </survey> + <survey location="after"> + <surveyentry type="question" id="location" mandatory="true" boxsize="large"> + <statement>Please enter your location. (example mandatory text question)</statement> + </surveyentry> + <surveyentry type="number" id="age" min="0"> + <statement>Please enter your age (example non-mandatory number question)</statement> + </surveyentry> + <surveyentry type="radio" id="rating"> + <statement>Please rate this interface (example radio button question)</statement> + <option name="bad">Bad</option> + <option name="poor">Poor</option> + <option name="good">Good</option> + <option name="great">Great</option> + </surveyentry> + <surveyentry type="statement"> + <statement>Thank you for taking this listening test. Please click 'submit' and your results will appear in the 'saves/' folder.</statement> + </surveyentry> + </survey> + <metric> + <metricenable>testTimer</metricenable> + <metricenable>elementTimer</metricenable> + <metricenable>elementFlagListenedTo</metricenable> + <metricenable>elementListenTracker</metricenable> + </metric> + <interface> + <interfaceoption type="check" name="fragmentMoved"/> + <interfaceoption type="check" name="scalerange" min="25" max="75"/> + <interfaceoption type="show" name='playhead'/> + <interfaceoption type="show" name="page-count"/> + </interface> + </setup> + <page id='test-0' hostURL="example_eval/" randomiseOrder='true' repeatCount='0' loop='true' showElementComments='true' loudness="-12"> + <commentboxprefix>Comment on fragment</commentboxprefix> + <interface> + <title>Depth</title> + </interface> + <audioelement url="0.wav" id="track-0" type="anchor"/> + <audioelement url="1.wav" id="track-1"/> + <audioelement url="2.wav" id="track-2"/> + <survey location="before"> + <surveyentry type="statement"> + <statement>Example of an 'APE' style interface with hidden anchor 'zero' (which needs to be below 20%), looping of the samples, randomisation of marker labels, mandatory moving of every sample, and a forced scale usage of at least 25%-75%.</statement> + </surveyentry> + </survey> + <survey location="after"> + <surveyentry type="question" id="genre-0" mandatory="true"> + <statement>Please enter the genre.</statement> + </surveyentry> + </survey> + </page> +</waet> \ No newline at end of file
--- a/index.html Mon Jan 11 13:56:30 2016 +0000 +++ b/index.html Mon Jan 11 16:32:26 2016 +0000 @@ -53,6 +53,7 @@ <ul> <li><a href="index.html?url=example_eval/project.xml" target="_blank">APE interface test example</a></li> <li><a href="index.html?url=example_eval/mushra_example.xml" target="_blank">MUSHRA interface test example</a></li> + <li><a href="index.html?url=example_eval/AB_example.xml" target="_blank">AB interface test example</a></li> <li><a href="test_create/test_create.html" target="_blank">Test creator</a></li> <li><a href="analyse.html" target="_blank">Analysis and diagnostics of results</a></li> </ul>
--- a/mushra.js Mon Jan 11 13:56:30 2016 +0000 +++ b/mushra.js Mon Jan 11 16:32:26 2016 +0000 @@ -279,7 +279,7 @@ this.exportXMLDOM = function(audioObject) { // Called by the audioObject holding this element. Must be present - var node = document.createElement('value'); + var node = storage.document.createElement('value'); node.textContent = this.slider.value; return node; };