Mercurial > hg > webaudioevaluationtool
changeset 607:328f24798462 multiple-tests-concatenation
working, hacked together.
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Fri, 11 Mar 2016 16:49:47 +0000 |
parents | 6833d8c2b52e |
children | 0256f3748b27 |
files | .hgignore assets/images/arrow-checkbox-unchecked.png assets/images/checkbox-checked.png assets/images/checkbox-unchecked-disabled.png assets/images/ok.png core.js example_eval/ABshort.xml example_eval/labelling.xml example_eval/post_survey.xml example_eval/pre_survey.xml index.html save.php test_base.php test_list.php |
diffstat | 14 files changed, 407 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Sun Mar 06 20:55:00 2016 +0000 +++ b/.hgignore Fri Mar 11 16:49:47 2016 +0000 @@ -50,4 +50,6 @@ re:^docs/DMRN+10/img/\._APE\.png$ re:^docs/DMRN+10/img/\._MUSHRA\.png$ example_eval/samples/* - +.hgrc +*.orig +
--- a/core.js Sun Mar 06 20:55:00 2016 +0000 +++ b/core.js Fri Mar 11 16:49:47 2016 +0000 @@ -15,9 +15,9 @@ var popup; // Hold the interfacePopup object var testState; var currentTrackOrder = []; // Hold the current XML tracks in their (randomised) order -var audioEngineContext; // The custome AudioEngine object -var projectReturn; // Hold the URL for the return - +var audioEngineContext; // The custom AudioEngine object +var projectReturn; +var returnUrl; // Holds the url to be redirected to at the end of the test // Add a prototype to the bufferSourceNode to reference to the audioObject holding it AudioBufferSourceNode.prototype.owner = undefined; @@ -338,11 +338,28 @@ a.textContent = "Save File"; popup.showPopup(); - popup.popupContent.innerHTML = "</span>Please save the file below to give to your test supervisor</span><br>"; + popup.popupContent.innerHTML = "<span>Please save the file below to give to your test supervisor</span><br>"; popup.popupContent.appendChild(a); } else { var xmlhttp = new XMLHttpRequest; - xmlhttp.open("POST",destURL,true); + destUrlFull = destURL; + var saveFilenamePrefix; + // parse the querystring of destUrl, get the "id" (if any) and append it to destUrl + var qs = returnUrl.split("?"); + if(qs.length == 2){ + qs = qs[1]; + qs = qs.split("&"); + for(var n = 0; n < qs.length; n++){ + var pair = qs[n].split("="); + if (pair[0] == "id") { + saveFilenamePrefix = pair[1]; + } + } + } + if(typeof(saveFilenamePrefix) !== "undefined"){ + destUrlFull+="?saveFilenamePrefix="+saveFilenamePrefix; + } + xmlhttp.open("POST",destUrlFull,true); xmlhttp.setRequestHeader('Content-Type', 'text/xml'); xmlhttp.onerror = function(){ console.log('Error saving file to server! Presenting download locally'); @@ -368,6 +385,9 @@ popup.popupContent.innerHTML = null; popup.popupContent.textContent = "Thank you!"; window.onbeforeunload=null; + if(typeof(returnUrl) !== "undefined"){ + window.location = returnUrl; + } } else { var message = response.getElementsByTagName('message')[0]; errorSessionDump(message.textContent);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/example_eval/ABshort.xml Fri Mar 11 16:49:47 2016 +0000 @@ -0,0 +1,30 @@ +<?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="1" loudness="-23" sampleRate="44100"> + <metric> + <metricenable>testTimer</metricenable> + <metricenable>elementTimer</metricenable> + <metricenable>elementInitialPosition</metricenable> + <metricenable>elementTracker</metricenable> + <metricenable>elementFlagListenedTo</metricenable> + <metricenable>elementFlagMoved</metricenable> + <metricenable>elementListenTracker</metricenable> + </metric> + <interface> + <interfaceoption type="check" name="fragmentMoved"/> + <interfaceoption type="check" name="scalerange" min="25" max="75"/> + <interfaceoption type="check" name="fragmentPlayed" /> + <interfaceoption type="show" name='playhead'/> + <interfaceoption type="show" name="page-count"/> + <interfaceoption type="show" name='volume'/> + </interface> + </setup> + <page id="test-0" hostURL="example_eval/" randomiseOrder="true" repeatCount="0" loop="false" showElementComments="true" loudness="-12"> + <commentboxprefix>Comment on fragment</commentboxprefix> + <interface> + <title>Which of these do you prefer</title> + </interface> + <audioelement url="3.wav" id="track-0"/> + <audioelement url="5.wav" id="track-1"/> + </page> +</waet> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/example_eval/labelling.xml Fri Mar 11 16:49:47 2016 +0000 @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<waet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test-schema.xsd"> + <setup interface="likert" projectReturn="save.php"> + <metric> + <metricenable>testTimer</metricenable> + <metricenable>elementTimer</metricenable> + <metricenable>elementInitialPosition</metricenable> + <metricenable>elementTracker</metricenable> + <metricenable>elementFlagListenedTo</metricenable> + <metricenable>elementFlagMoved</metricenable> + <metricenable>elementListenTracker</metricenable> + </metric> + <interface> + <interfaceoption type="check" name="fragmentMoved"/> + <interfaceoption type="check" name="scalerange" min="25" max="75"/> + <interfaceoption type="show" name="volume"/> + <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="-23"> + <interface> + <scales> + <scalelabel position="0">(1) Very Annoying</scalelabel> + <scalelabel position="25">(2) Annoying</scalelabel> + <scalelabel position="50">(3) Slightly Annoying</scalelabel> + <scalelabel position="75">(4) Audible but not Annoying</scalelabel> + <scalelabel position="100">(5) Inaudible</scalelabel> + </scales> + </interface> + <audioelement url="0.wav" id="track-1"/> + <audioelement url="2.wav" id="track-3" type="outside-reference"/> + </page> +</waet>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/example_eval/post_survey.xml Fri Mar 11 16:49:47 2016 +0000 @@ -0,0 +1,48 @@ +<?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="1" loudness="-23" sampleRate="44100"> + <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. May God be with you.</statement> + </surveyentry> + </survey> + <metric> + <metricenable>testTimer</metricenable> + <metricenable>elementTimer</metricenable> + <metricenable>elementInitialPosition</metricenable> + <metricenable>elementTracker</metricenable> + <metricenable>elementFlagListenedTo</metricenable> + <metricenable>elementFlagMoved</metricenable> + <metricenable>elementListenTracker</metricenable> + </metric> + <interface> + <interfaceoption type="show" name='playhead'/> + <interfaceoption type="show" name="page-count"/> + <interfaceoption type="show" name='volume'/> + <!--interfaceoption type="submit" name="post-submit-dialog"> + <a href="javascript:document.referrer">Click here to continue with the next test</a> + </interfaceoption--> + </interface> + </setup> + <page id="test-0" hostURL="example_eval/" randomiseOrder="true" repeatCount="0" loop="false" showElementComments="true" loudness="-12"> + <commentboxprefix>Comment on fragment</commentboxprefix> + <interface> + <title>SKIP THIS PAGE. I WANT 0 PAGES!!!!</title> + </interface> + <audioelement url="2.wav" id="track-0"/> + <audioelement url="1.wav" id="track-1"/> + </page> +</waet> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/example_eval/pre_survey.xml Fri Mar 11 16:49:47 2016 +0000 @@ -0,0 +1,51 @@ +<?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="1" 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 a preliminary test for a study on the Hammond organ. You will be presented with pairs of stimuli. For each pair you will be asked to single out the one note that was produced by a heavier touch. + + Feel free to add any comments on the stimuli in the boxes at the bottom of each page of the test. </statement> + </surveyentry> + </survey> + <metric> + <metricenable>testTimer</metricenable> + <metricenable>elementTimer</metricenable> + <metricenable>elementInitialPosition</metricenable> + <metricenable>elementTracker</metricenable> + <metricenable>elementFlagListenedTo</metricenable> + <metricenable>elementFlagMoved</metricenable> + <metricenable>elementListenTracker</metricenable> + </metric> + <interface> + <interfaceoption type="check" name="fragmentMoved"/> + <interfaceoption type="check" name="scalerange" min="25" max="75"/> + <interfaceoption type="check" name="fragmentPlayed" /> + <interfaceoption type="show" name='playhead'/> + <interfaceoption type="show" name="page-count"/> + <interfaceoption type="show" name='volume'/> + <!--interfaceoption type="submit" name="post-submit-dialog"> + <a href="javascript:document.referrer">Click here to continue with the next test</a> + </interfaceoption--> + </interface> + </setup> + <page id="test-0" hostURL="example_eval/" randomiseOrder="true" repeatCount="0" loop="false" showElementComments="true" loudness="-12"> + <commentboxprefix>Comment on fragment</commentboxprefix> + <interface> + <title>SKIP OVER THIS, I WANT ZERO PAGES!!!</title> + </interface> + <audioelement url="1.wav" id="track-0"/> + <audioelement url="1.wav" id="track-1"/> + </page> +</waet> \ No newline at end of file
--- a/index.html Sun Mar 06 20:55:00 2016 +0000 +++ b/index.html Fri Mar 11 16:49:47 2016 +0000 @@ -32,12 +32,17 @@ { // Split each request into searchQueries[i] = searchQueries[i].split('='); - if (searchQueries[i][0] == "url") + var key = searchQueries[i][0]; + var string = searchQueries[i][1]; + if (key === "url") { - url = searchQueries[i][1]; + url = string; + } + if (key === "returnUrl"){ + returnUrl = decodeURIComponent(string); } } - loadProjectSpec(url); + loadProjectSpec(url+"?"+Math.random()); // force resource reload, in case the server is lazy window.onbeforeunload = function() { return "Please only leave this page once you have completed the tests. Are you sure you have completed all testing?"; }; @@ -49,7 +54,8 @@ <!-- Load up the default page interface allowing for project setting loads, even if hard-coded--> <!-- Actual test interface design should be contained in the .js for ease of dynamic content--> <div id='topLevelBody'> - <span>Web Audio Evaluation Toolbox</span> + <span>Loading Web Audio Evaluation Toolbox ...</span> + <noscript>Javascript must be enabled in your browsers in order to be able to view this website</noscript> </div> <div id="popupHolder" class="popupHolder" style="visibility: hidden; z-index: -1"> <div id="popupContent">
--- a/save.php Sun Mar 06 20:55:00 2016 +0000 +++ b/save.php Fri Mar 11 16:49:47 2016 +0000 @@ -1,17 +1,18 @@ <?php error_reporting(0); - try{ - date_default_timezone_get(); - } - catch(Exception $e){ - date_default_timezone_set('UTC'); // Sets to UTC if not specified anywhere in .ini - } + try{ + date_default_timezone_get(); + } + catch(Exception $e){ + date_default_timezone_set('UTC'); // Sets to UTC if not specified anywhere in .ini + } + $saveFilenamePrefix = isset($_GET['saveFilenamePrefix']) ? $_GET['saveFilenamePrefix'].'-' : ''; header('Access-Control-Allow-Origin: *'); header("Content-type: text/xml"); $postText = file_get_contents('php://input'); $sha1_hash = sha1($postText); $datetime = date('ymdHis'); - $xmlfile = "save".$datetime."-".$sha1_hash.".xml"; + $xmlfile = $saveFilenamePrefix."save".$datetime."-".$sha1_hash.".xml"; $fileHandle = fopen("saves/".$xmlfile, 'w'); if ($fileHandle == FALSE) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test_base.php Fri Mar 11 16:49:47 2016 +0000 @@ -0,0 +1,169 @@ +<?php +function fisherYatesShuffle(&$items, $seed) // http://stackoverflow.com/questions/6557805/randomize-a-php-array-with-a-seed +{ + @mt_srand($seed); + for ($i = count($items) - 1; $i > 0; $i--) + { + $j = @mt_rand(0, $i); + $tmp = $items[$i]; + $items[$i] = $items[$j]; + $items[$j] = $tmp; + } +} +function url_origin( $s, $use_forwarded_host = false ) //http://stackoverflow.com/questions/6768793/get-the-full-url-in-php +{ + $ssl = ( ! empty( $s['HTTPS'] ) && $s['HTTPS'] == 'on' ); + $sp = strtolower( $s['SERVER_PROTOCOL'] ); + $protocol = substr( $sp, 0, strpos( $sp, '/' ) ) . ( ( $ssl ) ? 's' : '' ); + $port = $s['SERVER_PORT']; + $port = ( ( ! $ssl && $port=='80' ) || ( $ssl && $port=='443' ) ) ? '' : ':'.$port; + $host = ( $use_forwarded_host && isset( $s['HTTP_X_FORWARDED_HOST'] ) ) ? $s['HTTP_X_FORWARDED_HOST'] : ( isset( $s['HTTP_HOST'] ) ? $s['HTTP_HOST'] : null ); + $host = isset( $host ) ? $host : $s['SERVER_NAME'] . $port; + return $protocol . '://' . $host; +} + +function full_url( $s, $use_forwarded_host = false ) +{ + return url_origin( $s, $use_forwarded_host ) . $s['REQUEST_URI']; +} + $toAppendToUrl = ''; + if(isset($_GET["id"])){ + $id = $_GET["id"]; + } else { + $max = pow(2, 24); + $rand = openssl_random_pseudo_bytes($max); + $id = sha1($rand); + if(sizeof($_GET) == 0){ // if the query string is empty + $toAppendToUrl = '?'; // start the query string + } else { + $toAppendToUrl = '&'; // otherwise, append to it + } + $toAppendToUrl .= 'id='.$id; + } + if(isset($_GET["next"])){ + $next = $_GET["next"]; + } else { + $next = 0; + } + + $absoluteUrl = full_url($_SERVER).$toAppendToUrl; + // echo "<br \>".$absoluteUrl."<br \>"; + // if there is a "next" in the query string, create a version of $absoluteUrl with + // next:=next+1 + $absoluteUrlSplit = explode('?', $absoluteUrl); + $absoluteUrlNextPlusOne = $absoluteUrl; + if(sizeof($absoluteUrlSplit) === 2){ + $queryString = $absoluteUrlSplit[1]; + parse_str($queryString, $queryStringParsed); + $queryStringParsed['next'] += 1; + $queryString = http_build_query($queryStringParsed); + $absoluteUrlNextPlusOne = $absoluteUrlSplit[0]."?".$queryString; + } + $defaultTestEntry = Array('url' => null, 'string' => null, 'class' => 'disabled', 'a' => false, 'editable' => false); + + require_once('test_list.php'); //this returns $tests + + if($next == sizeof($tests)){ + // we are done + $bottomBox = 'The test is complete, thank you for your participation.'; + } else { + $bottomBox = 'If you want to have a break, come back to this page and continue from where you left, just come back to this URL:<br /><div id="currentUrl">'.$absoluteUrl.'</div>'; + } + // until this point, the content of $tests will always be the same for a given $id, + // regardless of how many times we visited this page. + for($n = 0; $n < sizeof($tests); $n++ ){ + //TODO: check if the corresponding file exists + // meantime, let us just rely on the GET variable 'next' + if($n <= $next){ + $tests[$n]['a'] = true; + $tests[$n]['class'] = 'enabled done'; + // if we are going to re-run a test, return to the same page + $tests[$n]['returnUrl'] = urlencode($absoluteUrl); + } + if($n == $next){ + $tests[$n]['editable'] = true; + $tests[$n]['class'] = 'enabled editable'; + // if we are going to run a new test, return to the same page with next:=next+1 + $tests[$n]['returnUrl'] = urlencode($absoluteUrlNextPlusOne); + } + } +?> +<html> +<head> + <style> +ul.tests-list li{ + margin: 10px 0 5px 0; + +} +.done { + list-style-image: url('assets/images/checkbox-checked.png'); +} +.done a { + color: green; +} +.editable{ + list-style-image: url('assets/images/arrow-checkbox-unchecked.png'); + list-style-position: inside; + margin-left: -30px; +} +.disabled{ + color: grey; + text-decoration: line-through; + list-style-image: url('assets/images/checkbox-unchecked-disabled.png'); +} +#currentUrl{ + font-weight: bold; + padding-left: 20px; + padding-top: 5px; +} + + </style> + <script src="jquery-2.1.4.js"></script> + <script> + function confirmEditing(e){ + var message = 'Are you sure you want to edit this item? All previous changes will be lost'; + return window.confirm(message); + } + var elements; + $(document).ready(function(){ + lis = $('ul'); + elements = $('li.done:not(.editable)', lis); + for(var n = 0; n < elements.length; n++){ + elements[n].onclick = confirmEditing; + } + history.pushState({}, null, location.pathname+location.search+'<?php echo $toAppendToUrl; ?>'); + + // elements = $('li:not(.editable.done)', lis); + // for(var element in elements){ + // element.onclick = confirmEditing; + // } + }); + </script> +</head> +<body> + +<ul class = "tests-list"> +<?php foreach($tests as $n => $test) : ?> + <li class="test-element <?php echo $test['class'] ?>"> +<?php +if($test['a'] === true) { + // parameters passed to the test are used to keep track of the state and should be returned back to + // this page when it is called again. + // These parameters are: + // id= keeps track of the user and of the sorting of the tests in this page + // next= keeps track of the first test not yet undertaken + + echo '<a href="'.$test['url'].'&returnUrl='.$test['returnUrl'].'">'.$n.' - '.$test['string'].'</a>'; +} else { + echo $n.' - '.$test['string']; +} +?> + </li> +<?php endforeach; ?> +</ul> + + <div id="bottomBox"> + <?php if($bottomBox!=='') echo $bottomBox ?> + </div> +</body> +</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test_list.php Fri Mar 11 16:49:47 2016 +0000 @@ -0,0 +1,29 @@ +<?php +// need to generate an array $tests containing the tests in the order they shuold be executed + $preSurvey = $defaultTestEntry; + $preSurvey['url'] = 'index.html?url=example_eval/pre_survey.xml'; + $preSurvey['string'] = 'Pre-survey'; + + $postSurvey = $defaultTestEntry; + $postSurvey['url'] = 'index.html?url=example_eval/post_survey.xml'; + $postSurvey['string'] = 'Post-survey'; + + $abTests = Array($defaultTestEntry, $defaultTestEntry, $defaultTestEntry, $defaultTestEntry); + $abTests[0]['url'] = 'index.html?url=example_eval/ABshort.xml'; + $abTests[0]['string'] = 'AB0'; + $abTests[1]['url'] = 'index.html?url=example_eval/ABshort.xml'; + $abTests[1]['string'] = 'AB1'; + $abTests[2]['url'] = 'index.html?url=example_eval/ABshort.xml'; + $abTests[2]['string'] = 'AB2'; + $abTests[3]['url'] = 'index.html?url=example_eval/ABshort.xml'; + $abTests[3]['string'] = 'AB3'; + + $likertTest = $defaultTestEntry; + $likertTest['url'] = 'index.html?url=example_eval/labelling.xml'; + $likertTest['string'] = 'Labelling'; + // the shuffling of the elements is bound to the last 8 characters of $id + $seed = hexdec(substr($id, -8)); + //shuffling only the order of the ABtests + fisherYatesShuffle($abTests, $seed); + $tests = array_merge(Array($preSurvey), $abTests, Array($likertTest), Array($postSurvey)); + \ No newline at end of file