Mercurial > hg > webaudioevaluationtool
changeset 2591:c0854362d09d
Merge branch 'master' into vnext
author | Nicholas Jillings <nicholas.jillings@mail.bcu.ac.uk> |
---|---|
date | Wed, 09 Nov 2016 13:48:36 +0000 |
parents | 278e6e54703b (current diff) 21110fddb0af (diff) |
children | 89f787e2e90c eeb2e6dce5f2 |
files | js/core.js python/generate_report.py tests/examples/APE_example.xml tests/examples/project.xml |
diffstat | 7 files changed, 338 insertions(+), 241 deletions(-) [+] |
line wrap: on
line diff
--- a/js/core.js Wed Nov 09 13:22:50 2016 +0000 +++ b/js/core.js Wed Nov 09 13:48:36 2016 +0000 @@ -1611,22 +1611,21 @@ } else { interfaceContext.playhead.setTimePerPixel(this.audioObjects[id]); } + var setTime = audioContext.currentTime; if (this.synchPlayback && this.loopPlayback) { // Traditional looped playback - var setTime = audioContext.currentTime + specification.crossFade; for (var i = 0; i < this.audioObjects.length; i++) { this.audioObjects[i].play(audioContext.currentTime); if (id == i) { this.audioObjects[i].loopStart(setTime); } else { - this.audioObjects[i].loopStop(setTime); + this.audioObjects[i].loopStop(setTime + specification.crossFade); } } } else { - var setTime = audioContext.currentTime + specification.crossFade; for (var i = 0; i < this.audioObjects.length; i++) { if (i != id) { - this.audioObjects[i].stop(setTime); + this.audioObjects[i].stop(setTime + specification.crossFade); } else if (i == id) { this.audioObjects[id].play(setTime); } @@ -1871,10 +1870,10 @@ this.outputGain.gain.cancelScheduledValues(audioContext.currentTime); if (!audioEngineContext.loopPlayback || !audioEngineContext.synchPlayback) { this.metric.startListening(audioEngineContext.timer.getTestTime()); - this.outputGain.gain.setValueAtTime(this.onplayGain, startTime); + this.outputGain.gain.linearRampToValueAtTime(this.onplayGain, startTime + specification.crossFade); this.interfaceDOM.startPlayback(); } else { - this.outputGain.gain.setValueAtTime(0.0, startTime); + this.outputGain.gain.linearRampToValueAtTime(0.0, startTime); } if (audioEngineContext.loopPlayback) { this.bufferNode.loopStart = this.specification.startTime || 0; @@ -1894,7 +1893,7 @@ this.bufferNode.stop(stopTime); this.bufferNode = undefined; } - this.outputGain.gain.setValueAtTime(0.0, stopTime); + this.outputGain.gain.linearRampToValueAtTime(0.0, stopTime); this.interfaceDOM.stopPlayback(); };
--- a/python/generate_report.py Wed Nov 09 13:22:50 2016 +0000 +++ b/python/generate_report.py Wed Nov 09 13:48:36 2016 +0000 @@ -64,6 +64,10 @@ gender = [] age = [] +# diagnostics +browser = [] +platform = [] + # get username if available for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'): user = os.environ.get(name) @@ -162,6 +166,20 @@ individual_table = '\n' # table with stats for this individual test file timeline_plots = '' # plots of timeline (movements and plays) + # diagnostics: browser + vendor = root.find("./navigator/vendor") + if vendor is not None and vendor.text is not None: + browser.append(vendor.text.replace(',','')) + else: + browser.append('UNAVAILABLE') + + # diagnostics: platform + platform_tag = root.find("./navigator/platform") + if platform_tag is not None and platform_tag.text is not None: + platform.append(platform_tag.text.replace('_','\_')) + else: + platform_tag.append('UNAVAILABLE') + # DEMO survey stats # get gender post_survey = root.find("./survey/[@location='post']") @@ -535,6 +553,104 @@ ''' # problem: some people entered twice? + +# pie chart of browser usage +browsers = ['Google Inc.', 'Apple Computer Inc.', 'UNAVAILABLE'] +# TODO: get the above automatically +browser_distribution = '' +for item in browsers: + number = browser.count(item) + if number>0: + browser_distribution += str("{:.2f}".format((100.0*number)/len(browser)))+\ + '/'+item.capitalize()+' ('+str(number)+'),\n' + +body += r''' + % Pie chart of browser distribution + \def\angle{0} + \def\radius{3} + \def\cyclelist{{"orange","blue","red","green"}} + \newcount\cyclecount \cyclecount=-1 + \newcount\ind \ind=-1 + \begin{figure}[htbp] + \begin{center}\begin{tikzpicture}[nodes = {font=\sffamily}] + \foreach \percent/\name in {'''+\ + browser_distribution+\ + r'''} {\ifx\percent\empty\else % If \percent is empty, do nothing + \global\advance\cyclecount by 1 % Advance cyclecount + \global\advance\ind by 1 % Advance list index + \ifnum6<\cyclecount % If cyclecount is larger than list + \global\cyclecount=0 % reset cyclecount and + \global\ind=0 % reset list index + \fi + \pgfmathparse{\cyclelist[\the\ind]} % Get color from cycle list + \edef\color{\pgfmathresult} % and store as \color + % Draw angle and set labels + \draw[fill={\color!50},draw={\color}] (0,0) -- (\angle:\radius) + arc (\angle:\angle+\percent*3.6:\radius) -- cycle; + \node at (\angle+0.5*\percent*3.6:0.7*\radius) {\percent\,\%}; + \node[pin=\angle+0.5*\percent*3.6:\name] + at (\angle+0.5*\percent*3.6:\radius) {}; + \pgfmathparse{\angle+\percent*3.6} % Advance angle + \xdef\angle{\pgfmathresult} % and store in \angle + \fi + }; + \end{tikzpicture} + \caption{Representation of browsers across subjects} + \label{default} + \end{center} + \end{figure} + + ''' + +# pie chart of platform usage +platforms = ['Win32', 'Win64', 'MacIntel', 'Linux i686', 'Linux x86\_64', 'UNAVAILABLE'] +# TODO: get the above automatically # order alphabetically +platform_distribution = '' +for item in platforms: + number = platform.count(item) + if number>0: + platform_distribution += str("{:.2f}".format((100.0*number)/len(platform)))+\ + '/'+item.capitalize()+' ('+str(number)+'),\n' + +body += r''' + % Pie chart of browser distribution + \def\angle{0} + \def\radius{3} + \def\cyclelist{{"orange","blue","red","green","cyan"}} + \newcount\cyclecount \cyclecount=-1 + \newcount\ind \ind=-1 + \begin{figure}[htbp] + \begin{center}\begin{tikzpicture}[nodes = {font=\sffamily}] + \foreach \percent/\name in {'''+\ + platform_distribution+\ + r'''} {\ifx\percent\empty\else % If \percent is empty, do nothing + \global\advance\cyclecount by 1 % Advance cyclecount + \global\advance\ind by 1 % Advance list index + \ifnum6<\cyclecount % If cyclecount is larger than list + \global\cyclecount=0 % reset cyclecount and + \global\ind=0 % reset list index + \fi + \pgfmathparse{\cyclelist[\the\ind]} % Get color from cycle list + \edef\color{\pgfmathresult} % and store as \color + % Draw angle and set labels + \draw[fill={\color!50},draw={\color}] (0,0) -- (\angle:\radius) + arc (\angle:\angle+\percent*3.6:\radius) -- cycle; + \node at (\angle+0.5*\percent*3.6:0.7*\radius) {\percent\,\%}; + \node[pin=\angle+0.5*\percent*3.6:\name] + at (\angle+0.5*\percent*3.6:\radius) {}; + \pgfmathparse{\angle+\percent*3.6} % Advance angle + \xdef\angle{\pgfmathresult} % and store in \angle + \fi + }; + \end{tikzpicture} + \caption{Representation of platforms across subjects} + \label{default} + \end{center} + \end{figure} + + ''' + + #TODO # time per page in function of number of fragments (plot) # time per participant in function of number of pages
--- a/python/score_parser.py Wed Nov 09 13:22:50 2016 +0000 +++ b/python/score_parser.py Wed Nov 09 13:48:36 2016 +0000 @@ -26,26 +26,28 @@ elif not os.access(os.path.dirname(folder_name), os.W_OK): #the file does exist but write privileges are not given print("No write privileges in folder '"+folder_name+"'.") + - # CODE -# remember which files have been opened this time -file_history = [] +storage = {} -# get every XML file in folder +# create folder 'ratings' if not yet created +if not os.path.exists(folder_name + '/ratings'): + os.makedirs(folder_name + '/ratings') + +# Get every XML file in the folder for file_name in os.listdir(folder_name): - if file_name.endswith(".xml"): + if (file_name.endswith(".xml")): tree = ET.parse(folder_name + '/' + file_name) root = tree.getroot() - - # get subject ID from XML file - subject_id = file_name[:-4] # file name (without extension) as subject ID - - # get list of all pages this subject evaluated - for page in root.findall("./page"): # iterate over pages - page_name = page.get('ref') # get page reference ID - + + subject_id = root.get('key'); + + # get the list of the pages this subject evaluated + for page in root.findall("./page"): # iterate over pages + page_name = page.get('ref') # get page ID + if page_name is None: # ignore 'empty' audio_holders print("WARNING: " + file_name + " contains empty audio holder. (score_parser.py)") break @@ -53,84 +55,64 @@ if page.get('state') != "complete": print("WARNING: " + file_name + " contains incomplete page " +page_name+ ". (score_parser.py)") break; - - file_name = folder_name+'/ratings/'+page_name+'-ratings.csv' # score file name - - # create folder 'ratings' if not yet created - if not os.path.exists(folder_name + '/ratings'): - os.makedirs(folder_name + '/ratings') - + + # Check if page in the store + if storage.get(page_name) == None: + storage[page_name] = {'header':[], 'axis':{}} # add to the store + + # Get the axis names + pageConfig = root.find('./waet/page/[@id="'+page_name+'"]') + for interface in pageConfig.findall('./interface'): # Get the <interface> noeds + interfaceName = interface.get("name"); # Get the axis name + if interfaceName == None: + interfaceName = "default" # If name not set, make name 'default' + if storage[page_name]['axis'].get(interfaceName) == None: + storage[page_name]['axis'][interfaceName] = {} # If not in store for page, add empty dict + storage[page_name]['axis'][interfaceName][subject_id] = [] # Add the store for the session + # header: fragment IDs in 'alphabetical' order # go to fragment column, or create new column if it doesn't exist yet - - # get array of audio elements and number of audio elements - audiolist = page.findall("./audioelement") - n_fragments = len(audiolist) - + # get alphabetical array of fragment IDs from this subject's XML fragmentnamelist = [] # make empty list - for audioelement in audiolist: # iterate over all audioelements + for audioelement in page.findall("./audioelement"): # iterate over all audioelements fragmentnamelist.append(audioelement.get('ref')) # add to list + + fragmentnamelist = sorted(fragmentnamelist); # Sort the list + storage[page_name]['header'] = fragmentnamelist; + + for fragmentname in fragmentnamelist: + audioElement = page.find("./audioelement/[@ref='"+ fragmentname+ "']") # Get the element + for value in audioElement.findall('./value'): + axisName = value.get('interface-name') + if axisName == None: + axisName = 'default' + axisStore = storage[page_name]['axis'][axisName] + if hasattr(value, 'text'): + axisStore[subject_id].append(value.text) + else: + axisStore[subject_id].append('') - - # if file exists, get header and add any 'new' fragments not yet in the header - if os.path.isfile(file_name): - with open(file_name, 'r') as readfile: - filereader = csv.reader(readfile, delimiter=',') - headerrow = next(filereader) - - # If file hasn't been opened yet this time, remove all rows except header - if file_name not in file_history: - with open(file_name, 'w') as writefile: - filewriter = csv.writer(writefile, delimiter=',') - headerrow = sorted(headerrow) - filewriter.writerow(headerrow) - file_history.append(file_name) - - # Which of the fragments are in fragmentnamelist but not in headerrow? - newfragments = list(set(fragmentnamelist)-set(headerrow)) - newfragments = sorted(newfragments) # new fragments in alphabetical order - # If not empty, read file and rewrite adding extra columns - if newfragments: # if not empty - with open('temp.csv', 'w') as writefile: - filewriter = csv.writer(writefile, delimiter=',') - filewriter.writerow(headerrow + newfragments) # write new header - with open(file_name, 'r') as readfile: - filereader = csv.reader(readfile, delimiter=',') - next(filereader) # skip header - for row in filereader: # rewrite row plus empty cells for every new fragment name - filewriter.writerow(row + ['']*len(newfragments)) - os.rename('temp.csv', file_name) # replace old file with temp file - headerrow = headerrow + newfragments - - - # if file does not exist yet, create file and make header - else: - headerrow = sorted(fragmentnamelist) # sort alphabetically - headerrow.insert(0,'') - fragmentnamelist = fragmentnamelist[1:] #HACKY FIX inserting in firstrow also affects fragmentnamelist - with open(file_name, 'w') as writefile: - filewriter = csv.writer(writefile, delimiter=',') - filewriter.writerow(headerrow) - file_history.append(file_name) - - # open file to write for this page - writefile = open(file_name, 'a') +# Now create the individual files +for page_name in storage: + for axis_name in storage[page_name]['axis']: + + file_name = folder_name+'/ratings/'+page_name+'-'+axis_name+'-ratings.csv' # score file name + + # I'm not as elegant, I say burn the files and start again + headerrow = list(storage[page_name]['header']) # Extract the element IDs + headerrow.insert(0,'file_keys') + with open(file_name, 'w') as writefile: filewriter = csv.writer(writefile, delimiter=',') - - # prepare row to be written for this subject for this page - ratingrow = [subject_id] - - # get scores related to fragment [id] - for fragmentname in headerrow[1:]: # iterate over fragments in header (skip first empty column) - elementvalue = page.find("./audioelement/[@ref='" - + fragmentname - + "']/value") - if hasattr(elementvalue, 'text'): # if rating for this fragment exists - ratingrow.append(elementvalue.text) # add to rating row - else: # if this subject has not rated this fragment - ratingrow.append('') # append empty cell - - # write row: [subject ID, rating fragment ID 1, ..., rating fragment ID M] - if any(ratingrow[1:]): # append to file if row non-empty (except subject name) - filewriter.writerow(ratingrow) + filewriter.writerow(headerrow) + + # open file to write the page + writefile = open(file_name, 'a') + filewriter = csv.writer(writefile, delimiter=',') + + for subject_id in storage[page_name]['axis'][axis_name]: + entry = [subject_id] + for value in storage[page_name]['axis'][axis_name][subject_id]: + entry.append(value) + filewriter.writerow(entry) + writefile.close() \ No newline at end of file
--- a/tests/examples/AB_example.xml Wed Nov 09 13:22:50 2016 +0000 +++ b/tests/examples/AB_example.xml Wed Nov 09 13:48:36 2016 +0000 @@ -14,7 +14,7 @@ <option name="researcher">Research in the field of audio</option> </surveyentry> <surveyentry type="statement" id="test-intro"> - <statement>This is an example of an 'AB'-style test, with two pages, using the test stimuli in 'example_eval/'.</statement> + <statement>This is an example of an 'AB'-style test, with two pages, using the test stimuli in 'example_eval/'. The 'playOne' configuration option means a fragment has to be finished playing before another fragment can be auditioned. </statement> </surveyentry> </survey> <survey location="after"> @@ -53,7 +53,7 @@ <interfaceoption type="show" name='comments'/> </interface> </setup> - <page id='test-0' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='true' loudness="-12"> + <page id='test-0' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='false' loudness="-12"> <commentboxprefix>Comment on fragment</commentboxprefix> <interface> <title>Depth</title>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/examples/APE_example.xml Wed Nov 09 13:48:36 2016 +0000 @@ -0,0 +1,143 @@ +<?xml version="1.0" encoding="utf-8"?> +<waet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test-schema.xsd"> + <setup interface="APE" projectReturn="save.php" randomiseOrder='true' poolSize="2" loudness="-23" calibration="true"> + <survey location="before"> + <surveyentry type="question" id="sessionId" mandatory="true"> + <statement>Please enter your name.</statement> + <conditional check="equals" value="John" jumpToOnPass="test-intro" jumpToOnFail="checkboxtest"/> + </surveyentry> + <surveyentry type="checkbox" id="checkboxtest" mandatory="true" min="2" max="4"> + <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="question" id="instrument" mandatory="false"> + <statement>What instrument did you play</statement> + </surveyentry> + <surveyentry type="statement" id="test-intro"> + <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" id="thankyou"> + <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>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="fragmentPlayed"/> + <interfaceoption type="check" name="scalerange" min="25" max="75"/> + <interfaceoption type="show" name='playhead'/> + <interfaceoption type="show" name="page-count"/> + <interfaceoption type="show" name="comments"/> + </interface> + </setup> + <page id='test-0' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='true' loudness="-12"> + <commentboxprefix>Comment on fragment</commentboxprefix> + <interface name="preference"> + <title>Preference</title> + <scales> + <scalelabel position="0">Min</scalelabel> + <scalelabel position="100">Max</scalelabel> + <scalelabel position="50">Middle</scalelabel> + <scalelabel position="20">20</scalelabel> + </scales> + </interface> + <interface name="depth"> + <title>Depth</title> + <scales> + <scalelabel position="0">Low</scalelabel> + <scalelabel position="100">High</scalelabel> + <scalelabel position="50">Middle</scalelabel> + <scalelabel position="50">Middle</scalelabel> + </scales> + </interface> + <audioelement url="0.wav" id="track-0" type="anchor"/> + <audioelement url="1.wav" id="track-1"/> + <audioelement url="2.wav" id="track-2"/> + <audioelement url="3.wav" id="track-3"/> + <audioelement url="4.wav" id="track-4"/> + <survey location="before"> + <surveyentry type="statement" id="test-0-intro"> + <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> + <page id='test-1' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='false' label="letter"> + <commentboxprefix>Comment on fragment</commentboxprefix> + <interface name="preference"> + <title>Example Test Question</title> + <scales> + <scalelabel position="0">Min</scalelabel> + <scalelabel position="100">Max</scalelabel> + <scalelabel position="50">Middle</scalelabel> + <scalelabel position="20">20</scalelabel> + </scales> + </interface> + <audioelement url="0.wav" gain="-6" id="track-5" type="anchor" marker="20"/> + <audioelement url="1.wav" gain="0.0" id="track-6" type="reference" marker="80"/> + <audioelement url="2.wav" gain="0.0" id="track-7"/> + <audioelement url="3.wav" gain="0.0" id="track-8"/> + <audioelement url="4.wav" gain="0.0" id="track-9"/> + <audioelement url="5.wav" gain="0.0" id="track-10"/> + <audioelement url="6.wav" gain="0.0" id="track-11" type="outside-reference"/> + <commentquestion id='mixingExperience' type="question"> + <statement>What is your general experience with numbers?</statement> + </commentquestion> + <commentquestion id="preference" type="radio"> + <statement>Please enter your overall preference</statement> + <option name="worst">Very Bad</option> + <option name="bad"></option> + <option name="OK">OK</option> + <option name="Good"></option> + <option name="Great">Great</option> + </commentquestion> + <commentquestion id="character" type="checkbox"> + <statement>Please describe the overall character</statement> + <option name="funky">Funky</option> + <option name="mellow">Mellow</option> + <option name="laidback">Laid back</option> + <option name="heavy">Heavy</option> + </commentquestion> + <survey location="before"> + <surveyentry type="statement" id="test-1-intro"> + <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-1" mandatory="true"> + <statement>Please enter the genre.</statement> + </surveyentry> + </survey> + </page> +</waet> \ No newline at end of file
--- a/tests/examples/mushra_example.xml Wed Nov 09 13:22:50 2016 +0000 +++ b/tests/examples/mushra_example.xml Wed Nov 09 13:48:36 2016 +0000 @@ -94,13 +94,13 @@ <scalelabel position="20">20</scalelabel> </scales> </interface> - <audioelement url="0.wav" gain="-6" id="track-5" type="anchor" marker="20"/> + <audioelement url="0.wav" gain="-6.0" id="track-5" type="anchor" marker="20"/> <audioelement url="1.wav" gain="0.0" id="track-6" type="reference" marker="80"/> <audioelement url="2.wav" gain="0.0" id="track-7"/> <audioelement url="3.wav" gain="0.0" id="track-8"/> <audioelement url="4.wav" gain="0.0" id="track-9"/> <audioelement url="5.wav" gain="0.0" id="track-10"/> - <audioelement url="6.wav" gain="0.0" id="track-11" type="outside-reference"/> + <audioelement url="1.wav" gain="0.0" id="track-11" type="outside-reference"/> <commentquestion id='mixingExperience' type="question"> <statement>What is your general experience with numbers?</statement> </commentquestion>
--- a/tests/examples/project.xml Wed Nov 09 13:22:50 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,143 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<waet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test-schema.xsd"> - <setup interface="APE" projectReturn="save.php" randomiseOrder='true' poolSize="2" loudness="-23" calibration="true"> - <survey location="before"> - <surveyentry type="question" id="sessionId" mandatory="true"> - <statement>Please enter your name.</statement> - <conditional check="equals" value="John" jumpToOnPass="test-intro" jumpToOnFail="checkboxtest"/> - </surveyentry> - <surveyentry type="checkbox" id="checkboxtest" mandatory="true" min="2" max="4"> - <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="question" id="instrument" mandatory="false"> - <statement>What instrument did you play</statement> - </surveyentry> - <surveyentry type="statement" id="test-intro"> - <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" id="thankyou"> - <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>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="fragmentPlayed"/> - <interfaceoption type="check" name="scalerange" min="25" max="75"/> - <interfaceoption type="show" name='playhead'/> - <interfaceoption type="show" name="page-count"/> - <interfaceoption type="show" name="comments"/> - </interface> - </setup> - <page id='test-0' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='true' loudness="-12"> - <commentboxprefix>Comment on fragment</commentboxprefix> - <interface name="preference"> - <title>Preference</title> - <scales> - <scalelabel position="0">Min</scalelabel> - <scalelabel position="100">Max</scalelabel> - <scalelabel position="50">Middle</scalelabel> - <scalelabel position="20">20</scalelabel> - </scales> - </interface> - <interface name="depth"> - <title>Depth</title> - <scales> - <scalelabel position="0">Low</scalelabel> - <scalelabel position="100">High</scalelabel> - <scalelabel position="50">Middle</scalelabel> - <scalelabel position="50">Middle</scalelabel> - </scales> - </interface> - <audioelement url="0.wav" id="track-0" type="anchor"/> - <audioelement url="1.wav" id="track-1"/> - <audioelement url="2.wav" id="track-2"/> - <audioelement url="3.wav" id="track-3"/> - <audioelement url="4.wav" id="track-4"/> - <survey location="before"> - <surveyentry type="statement" id="test-0-intro"> - <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> - <page id='test-1' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='false' label="letter"> - <commentboxprefix>Comment on fragment</commentboxprefix> - <interface name="preference"> - <title>Example Test Question</title> - <scales> - <scalelabel position="0">Min</scalelabel> - <scalelabel position="100">Max</scalelabel> - <scalelabel position="50">Middle</scalelabel> - <scalelabel position="20">20</scalelabel> - </scales> - </interface> - <audioelement url="0.wav" gain="-6" id="track-5" type="anchor" marker="20"/> - <audioelement url="1.wav" gain="0.0" id="track-6" type="reference" marker="80"/> - <audioelement url="2.wav" gain="0.0" id="track-7"/> - <audioelement url="3.wav" gain="0.0" id="track-8"/> - <audioelement url="4.wav" gain="0.0" id="track-9"/> - <audioelement url="5.wav" gain="0.0" id="track-10"/> - <audioelement url="6.wav" gain="0.0" id="track-11" type="outside-reference"/> - <commentquestion id='mixingExperience' type="question"> - <statement>What is your general experience with numbers?</statement> - </commentquestion> - <commentquestion id="preference" type="radio"> - <statement>Please enter your overall preference</statement> - <option name="worst">Very Bad</option> - <option name="bad"></option> - <option name="OK">OK</option> - <option name="Good"></option> - <option name="Great">Great</option> - </commentquestion> - <commentquestion id="character" type="checkbox"> - <statement>Please describe the overall character</statement> - <option name="funky">Funky</option> - <option name="mellow">Mellow</option> - <option name="laidback">Laid back</option> - <option name="heavy">Heavy</option> - </commentquestion> - <survey location="before"> - <surveyentry type="statement" id="test-1-intro"> - <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-1" mandatory="true"> - <statement>Please enter the genre.</statement> - </surveyentry> - </survey> - </page> -</waet> \ No newline at end of file