changeset 3100:998e05c5769a

#171 Completed specification changes
author Nicholas Jillings <nicholas.jillings@mail.bcu.ac.uk>
date Wed, 17 Jan 2018 12:30:28 +0000
parents fc9718756d55
children cd34732a2e39
files js/specification.js test_create.html tests/examples/APE_example.xml xml/test-schema.xsd
diffstat 4 files changed, 251 insertions(+), 151 deletions(-) [+]
line wrap: on
line diff
--- a/js/specification.js	Tue Jan 16 16:11:35 2018 +0000
+++ b/js/specification.js	Wed Jan 17 12:30:28 2018 +0000
@@ -12,7 +12,6 @@
     this.poolSize = undefined;
     this.loudness = undefined;
     this.sampleRate = undefined;
-    this.calibration = undefined;
     this.crossFade = undefined;
     this.preSilence = undefined;
     this.postSilence = undefined;
@@ -131,8 +130,9 @@
             if (projectAttr !== null) {
                 this[attributeName] = projectAttr;
             }
-
         }
+        
+        this.calibration.decode(this, projectXML.getElementsByTagName('calibration')[0]);
 
         var exitTextNode = setupNode.getElementsByTagName('exitText');
         if (exitTextNode.length == 1) {
@@ -209,6 +209,7 @@
             exitTextNode.textContent = this.exitText;
             setup.appendChild(exitTextNode);
         }
+        setup.appendChild(this.calibration.encode(RootDocument));
         setup.appendChild(this.preTest.encode(RootDocument));
         setup.appendChild(this.postTest.encode(RootDocument));
         setup.appendChild(this.metrics.encode(RootDocument));
@@ -219,6 +220,83 @@
         return RootDocument;
     };
 
+    this.calibration = (function () {
+        var frequencies = false,
+            levels = false,
+            channels = false,
+            schema = undefined;
+        var Calibration = {};
+        Object.defineProperties(Calibration, {
+            "parent": {
+                "value": this
+            },
+            "schema": {
+                "get": function () {
+                    return schema;
+                },
+                "set": function (t) {
+                    if (schema === undefined) {
+                        schema = t;
+                    } else {
+                        throw ("Cannot set readonly");
+                    }
+                }
+            },
+            "checkFrequencies": {
+                "get": function () {
+                    return frequencies;
+                },
+                "set": function (t) {
+                    frequencies = (t === true);
+                }
+            },
+            "checkLevels": {
+                "get": function () {
+                    return levels;
+                },
+                "set": function (t) {
+                    levels = (t === true);
+                }
+            },
+            "checkChannels": {
+                "get": function () {
+                    return channels;
+                },
+                "set": function (t) {
+                    channels = (t === true);
+                }
+            },
+            "encode": {
+                "value": function (doc) {
+                    var node = doc.createElement("calibration");
+                    node.setAttribute("checkFrequencies", frequencies);
+                    node.setAttribute("checkLevels", levels);
+                    node.setAttribute("checkChannels", channels);
+                    return node;
+                }
+            },
+            "decode": {
+                "value": function (parent, xml) {
+                    this.schema = schemaRoot.querySelector("[name=calibration]");
+                    var attributeMap = this.schema.querySelectorAll('attribute'),
+                        i;
+                    for (i in attributeMap) {
+                        if (isNaN(Number(i)) === true) {
+                            break;
+                        }
+                        var attributeName = attributeMap[i].getAttribute('name') || attributeMap[i].getAttribute('ref');
+                        var projectAttr = xml.getAttribute(attributeName);
+                        projectAttr = processAttribute(projectAttr, attributeMap[i]);
+                        if (projectAttr !== null) {
+                            this[attributeName] = projectAttr;
+                        }
+                    }
+                }
+            }
+        });
+        return Calibration;
+    })();
+
     function surveyNode(specification) {
         this.location = undefined;
         this.options = [];
--- a/test_create.html	Tue Jan 16 16:11:35 2018 +0000
+++ b/test_create.html	Wed Jan 17 12:30:28 2018 +0000
@@ -74,10 +74,6 @@
                     <span>Fixed Sampling Rate: </span>
                     <input type="number" ng-model="specification.sampleRate" min="0" placeholder="{{placeholder('sampleRate')}}" />
                 </div>
-                <div class="attribute" data-container="body" data-toggle="popover" data-placement="bottom" data-trigger="hover" data-content="Show a 'method of adjustment' audio calibration before testing.">
-                    <span>Pre-Test audio calibration: </span>
-                    <input type="checkbox" ng-model="specification.calibration" />
-                </div>
                 <div class="attribute" data-container="body" data-toggle="popover" data-placement="bottom" data-trigger="hover" data-content="Default cross-fade time when switching between elements. Can be over-ridden on each page">
                     <span>Global Cross-fade time: </span>
                     <input type="number" ng-model="specification.crossFade" min="0" step="0.1" placeholder="{{placeholder('crossFade')}}" />
@@ -107,6 +103,23 @@
                 <h2>Test Completed Message</h2>
                 <textarea ng-model="specification.exitText" data-container="body" data-toggle="popover" data-placement="bottom" data-trigger="hover" data-content="Once the test is completed, you can show a message to the user. Markdown syntax is supported for formatting."></textarea>
             </div>
+            <div class="node">
+                <h2>Pre-Test Calibrations</h2>
+                <div class="attributes">
+                    <div class="attribute" data-container="body" data-toggle="popover" data-placement="bottom" data-trigger="hover" data-content="Perform a frequency listening response">
+                        <span>Check Frequency Response</span>
+                        <input type="checkbox" value="testTimer" ng-model="specification.calibration.checkFrequencies" />
+                    </div>
+                    <div class="attribute" data-container="body" data-toggle="popover" data-placement="bottom" data-trigger="hover" data-content="Set the output levels">
+                        <span>Check Levels</span>
+                        <input type="checkbox" value="testTimer" ng-model="specification.calibration.checkLevels" />
+                    </div>
+                    <div class="attribute" data-container="body" data-toggle="popover" data-placement="bottom" data-trigger="hover" data-content="Check L/R configuration">
+                        <span>Check Channels</span>
+                        <input type="checkbox" value="testTimer" ng-model="specification.calibration.checkChannels" />
+                    </div>
+                </div>
+            </div>
             <div id="metricsNode" class="node">
                 <h3>Session Metrics</h3>
                 <div class="attributes">
--- a/tests/examples/APE_example.xml	Tue Jan 16 16:11:35 2018 +0000
+++ b/tests/examples/APE_example.xml	Wed Jan 17 12:30:28 2018 +0000
@@ -1,145 +1,146 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
-<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">
-            <surveyquestion id="sessionId" mandatory="true">
-                <statement>Please enter your name.</statement>
-                <conditional check="equals" value="John" jumpToOnPass="test-intro" jumpToOnFail="checkboxtest" />
-            </surveyquestion>
-            <surveycheckbox id="checkboxtest" mandatory="true" min="2" max="4" randomise="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>
-            </surveycheckbox>
-            <surveyquestion id="instrument" mandatory="false">
-                <statement>What instrument did you play?</statement>
-            </surveyquestion>
-            <surveystatement id="test-intro">
-                <statement>This is an example of an 'APE'-style test, with two pages, using the test stimuli in 'example_eval/'.</statement>
-            </surveystatement>
-        </survey>
-        <survey location="after">
-            <surveyquestion id="location" mandatory="true" boxsize="large">
-                <statement>Please enter your location. (example mandatory text question)</statement>
-            </surveyquestion>
-            <surveynumber id="age" min="0">
-                <statement>Please enter your age (example non-mandatory number question)</statement>
-            </surveynumber>
-            <surveyradio 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>
-            </surveyradio>
-            <surveystatement id="thankyou">
-                <statement>Thank you for taking this listening test. Please click 'submit' and your results will appear in the 'saves/' folder.</statement>
-            </surveystatement>
-        </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' synchronous="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' synchronous="true" 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" />
-        <commentquestions>
-            <commentquestion id='mixingExperience'>
-                <statement>What is your general experience with numbers?</statement>
-            </commentquestion>
-            <commentradio id="preference">
-                <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>
-            </commentradio>
-            <commentcheckbox id="character">
-                <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>
-            </commentcheckbox>
-        </commentquestions>
-        <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>
+    <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 checkFrequencies="true" checkLevels="true" checkChannels="true" />
+            <survey location="before">
+                <surveyquestion id="sessionId" mandatory="true">
+                    <statement>Please enter your name.</statement>
+                    <conditional check="equals" value="John" jumpToOnPass="test-intro" jumpToOnFail="checkboxtest" />
+                </surveyquestion>
+                <surveycheckbox id="checkboxtest" mandatory="true" min="2" max="4" randomise="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>
+                </surveycheckbox>
+                <surveyquestion id="instrument" mandatory="false">
+                    <statement>What instrument did you play?</statement>
+                </surveyquestion>
+                <surveystatement id="test-intro">
+                    <statement>This is an example of an 'APE'-style test, with two pages, using the test stimuli in 'example_eval/'.</statement>
+                </surveystatement>
+            </survey>
+            <survey location="after">
+                <surveyquestion id="location" mandatory="true" boxsize="large">
+                    <statement>Please enter your location. (example mandatory text question)</statement>
+                </surveyquestion>
+                <surveynumber id="age" min="0">
+                    <statement>Please enter your age (example non-mandatory number question)</statement>
+                </surveynumber>
+                <surveyradio 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>
+                </surveyradio>
+                <surveystatement id="thankyou">
+                    <statement>Thank you for taking this listening test. Please click 'submit' and your results will appear in the 'saves/' folder.</statement>
+                </surveystatement>
+            </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' synchronous="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' synchronous="true" 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" />
+            <commentquestions>
+                <commentquestion id='mixingExperience'>
+                    <statement>What is your general experience with numbers?</statement>
+                </commentquestion>
+                <commentradio id="preference">
+                    <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>
+                </commentradio>
+                <commentcheckbox id="character">
+                    <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>
+                </commentcheckbox>
+            </commentquestions>
+            <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>
--- a/xml/test-schema.xsd	Tue Jan 16 16:11:35 2018 +0000
+++ b/xml/test-schema.xsd	Wed Jan 17 12:30:28 2018 +0000
@@ -48,6 +48,7 @@
             <xs:complexType>
                 <xs:sequence>
                     <xs:element name="exitText" type="xs:string" minOccurs="0" maxOccurs="1" />
+                    <xs:element ref="calibration" minOccurs="0" maxOccurs="1" />
                     <xs:element ref="survey" minOccurs="0" maxOccurs="2" />
                     <xs:element ref="metric" maxOccurs="1" />
                     <xs:element ref="interface" maxOccurs="1" />
@@ -59,7 +60,6 @@
                 <xs:attribute ref="poolSize" />
                 <xs:attribute name="loudness" type="xs:nonPositiveInteger" use="optional" />
                 <xs:attribute name="sampleRate" type="xs:positiveInteger" use="optional" />
-                <xs:attribute name="calibration" type="xs:boolean" default="false" />
                 <xs:attribute name="crossFade" default="0.0">
                     <xs:simpleType>
                         <xs:restriction base="xs:decimal">
@@ -76,6 +76,14 @@
             </xs:complexType>
         </xs:element>
 
+        <xs:element name="calibration">
+            <xs:complexType>
+                <xs:attribute name="checkFrequencies" type="xs:boolean" default="false" />
+                <xs:attribute name="checkLevels" type="xs:boolean" default="false" />
+                <xs:attribute name="checkChannels" type="xs:boolean" default="false" />
+            </xs:complexType>
+        </xs:element>
+
         <xs:element name="page">
             <xs:complexType>
                 <xs:sequence>