changeset 3101:cd34732a2e39

#171 Implemented
author Nicholas Jillings <nicholas.jillings@mail.bcu.ac.uk>
date Wed, 17 Jan 2018 17:41:25 +0000
parents 998e05c5769a
children 972b55d81c1b
files js/core.js
diffstat 1 files changed, 195 insertions(+), 91 deletions(-) [+]
line wrap: on
line diff
--- a/js/core.js	Wed Jan 17 12:30:28 2018 +0000
+++ b/js/core.js	Wed Jan 17 17:41:25 2018 +0000
@@ -146,11 +146,12 @@
     // Create the specification object
     specification = new Specification();
 
+    // Create the storage object
+    storage = new Storage();
+
     // Create the interface object
     interfaceContext = new Interface(specification);
 
-    // Create the storage object
-    storage = new Storage();
     // Define window callbacks for interface
     window.onresize = function (event) {
         interfaceContext.resizeWindow(event);
@@ -1144,8 +1145,7 @@
 
     this.proceedClicked = function () {
         // Each time the popup button is clicked!
-        if (testState.stateIndex === 0 && specification.calibration) {
-            interfaceContext.calibrationModuleObject.collect();
+        if (testState.stateIndex === -1 && specification.calibration) {
             advanceState();
             return;
         }
@@ -1361,14 +1361,18 @@
                 this.advanceState();
             }
         } else if (this.stateIndex == -1) {
-            this.stateIndex++;
-            if (specification.calibration) {
+            if (interfaceContext.calibrationTests.checkFrequencies) {
                 popup.showPopup();
-                popup.popupTitle.textContent = "Calibration. Set the levels so all tones are of equal amplitude. Move your mouse over the sliders to hear the tones. The red slider is the reference tone";
-                interfaceContext.calibrationModuleObject = new interfaceContext.calibrationModule();
-                interfaceContext.calibrationModuleObject.build(popup.popupResponse);
+                popup.popupTitle.textContent = "Set the levels so all tones are of equal amplitude. Move your mouse over the sliders to hear the tones. The red slider is the reference tone";
+                interfaceContext.calibrationTests.performFrequencyCheck(popup.popupResponse);
+                popup.hidePreviousButton();
+            } else if (interfaceContext.calibrationTests.checkChannels) {
+                popup.showPopup();
+                popup.popupTitle.textContent = "Click play to start the audio, the click the button corresponding to where the sound appears to be coming from.";
+                interfaceContext.calibrationTests.performChannelCheck(popup.popupResponse);
                 popup.hidePreviousButton();
             } else {
+                this.stateIndex++;
                 this.advanceState();
             }
         } else if (this.stateIndex == this.stateMap.length) {
@@ -3216,93 +3220,193 @@
         return imageController;
     })();
 
-    this.calibrationModuleObject = null;
-    this.calibrationModule = function () {
-        // This creates an on-page calibration module
-        this.storeDOM = storage.document.createElement("calibration");
-        storage.root.appendChild(this.storeDOM);
-        // The calibration is a fixed state module
-        this.calibrationNodes = [];
-        this.holder = null;
-        this.build = function (inject) {
-            var f0 = 62.5;
-            this.holder = document.createElement("div");
-            this.holder.className = "calibration-holder";
-            this.calibrationNodes = [];
-            while (f0 < 20000) {
-                /* jshint loopfunc: true */
-                var obj = {
-                    root: document.createElement("div"),
-                    input: document.createElement("input"),
-                    oscillator: audioContext.createOscillator(),
-                    gain: audioContext.createGain(),
-                    f: f0,
-                    parent: this,
-                    handleEvent: function (event) {
-                        switch (event.type) {
-                            case "mouseenter":
-                                this.oscillator.start(0);
-                                break;
-                            case "mouseleave":
-                                this.oscillator.stop(0);
-                                this.oscillator = audioContext.createOscillator();
-                                this.oscillator.connect(this.gain);
-                                this.oscillator.frequency.value = this.f;
-                                break;
-                            case "mousemove":
-                                var value = Math.pow(10, this.input.value / 20);
-                                if (this.f == 1000) {
-                                    audioEngineContext.outputGain.gain.value = value;
-                                    interfaceContext.volume.slider.value = this.input.value;
-                                } else {
-                                    this.gain.gain.value = value;
+    this.calibrationTests = (function () {
+        function readonly(t) {
+            throw ("Cannot set read-only variable");
+        }
+
+        function getStorageRoot() {
+            var storageRoot = storage.root.querySelector("calibration");
+            if (storageRoot === undefined) {
+                storageRoot = storage.document.createElement("calibration");
+                storage.root.appendChild(storageRoot);
+            }
+            return storageRoot;
+        }
+        var calibrationObject = undefined,
+            _checkedFrequency = false,
+            _checkedChannels = false;
+
+        // Define the checkFrequencies test!
+        var checkFrequencyUnit = function (htmlRoot, storageRoot) {
+
+            function createFrequencyElement(frequency) {
+                return (function (frequency) {
+                    var range = document.createElement("input");
+                    range.type = "range";
+                    range.min = "-24";
+                    range.max = "24";
+                    range.step = "0.5";
+                    range.setAttribute("orient", "vertical");
+                    range.value = (Math.random() - 0.5) * 24;
+                    range.setAttribute("frequency", frequency);
+                    htmlRoot.append(range);
+
+                    var gain = audioContext.createGain();
+                    gain.connect(outputGain);
+                    gain.gain.value = Math.pow(10, Number(range.value) / 20.0);
+                    var osc = undefined;
+
+                    var store = storage.document.createElement("response");
+                    store.setAttribute("frequency", frequency);
+                    storageHook.appendChild(store);
+                    var interface = {};
+                    Object.defineProperties(interface, {
+                        "handleEvent": {
+                            "value": function (e) {
+                                if (e.type == "mouseenter") {
+                                    osc = audioContext.createOscillator();
+                                    osc.frequency.value = frequency;
+                                    osc.connect(gain);
+                                    osc.start();
+                                    console.log("start " + frequency);
+                                } else if (e.type == "mouseleave") {
+                                    console.log("stop " + frequency);
+                                    osc.stop();
+                                    osc = undefined;
                                 }
-                                break;
+                                store.textContent = e.currentTarget.value;
+                                gain.gain.value = Math.pow(10, Number(e.currentTarget.value) / 20.0);
+                            }
                         }
-                    },
-                    disconnect: function () {
-                        this.gain.disconnect();
+                    });
+                    range.addEventListener("mousemove", interface);
+                    range.addEventListener("mouseenter", interface);
+                    range.addEventListener("mouseleave", interface);
+                    return interface;
+                })(frequency);
+            }
+            var htmlHook = document.createElement("div");
+            htmlRoot.appendChild(htmlHook);
+            var storageHook = storage.document.createElement("frequency");
+            storageRoot.appendChild(storageHook);
+            var frequencies = [100, 200, 400, 800, 1200, 1600, 2000, 4000, 8000, 12000];
+            var outputGain = audioContext.createGain();
+            outputGain.gain.value = 0.25;
+            outputGain.connect(audioContext.destination);
+            this.sliders = frequencies.map(createFrequencyElement);
+        }
+
+        var checkChannelsUnit = function (htmlRoot, storageRoot) {
+
+            function onclick(ev) {
+                var storageHook = storage.document.querySelector("calibration").querySelector("channels");
+                storageHook.setAttribute("selected", ev.currentTarget.value);
+                storageHook.setAttribute("selectedText", ev.currentTarget.textContent);
+                osc.stop();
+                gainL = undefined;
+                gainR = undefined;
+                cmerge = undefined;
+                popup.proceedClicked();
+            }
+            var osc = audioContext.createOscillator();
+            var gainL = audioContext.createGain();
+            var gainR = audioContext.createGain();
+            gainL.channelCount = 1;
+            gainR.channelCount = 1;
+            var cmerge = audioContext.createChannelMerger(2);
+            osc.connect(gainL, 0, 0);
+            osc.connect(gainR, 0, 0);
+            gainL.connect(cmerge, 0, 0);
+            gainR.connect(cmerge, 0, 1);
+            cmerge.connect(audioContext.destination);
+            var play = document.createElement("button");
+            play.textContent = "Play Audio";
+            play.onclick = function () {
+                osc.start();
+                play.disabled = true;
+            }
+            htmlRoot.appendChild(play);
+            var choiceHolder = document.createElement("div");
+            var leftButton = document.createElement("button");
+            leftButton.textContent = "Left";
+            leftButton.value = "-1";
+            var centerButton = document.createElement("button");
+            centerButton.textContent = "Middle";
+            centerButton.value = "0";
+            var rightButton = document.createElement("button");
+            rightButton.textContent = "Right";
+            rightButton.value = "1";
+            choiceHolder.appendChild(leftButton);
+            choiceHolder.appendChild(centerButton);
+            choiceHolder.appendChild(rightButton);
+            htmlRoot.appendChild(choiceHolder);
+            leftButton.addEventListener("click", onclick);
+            centerButton.addEventListener("click", onclick);
+            rightButton.addEventListener("click", onclick);
+
+            var storageHook = storage.document.createElement("channels");
+            storageRoot.appendChild(storageHook);
+
+            var pan;
+            if (Math.random() > 0.5) {
+                pan = 1;
+                gainL.gain.value = 0.0;
+                gainR.gain.value = 0.25;
+                storageHook.setAttribute("presented", pan);
+                storageHook.setAttribute("presentedText", "Right");
+            } else {
+                pan = -1;
+                gainL.gain.value = 0.25;
+                gainR.gain.value = 0.0;
+                storageHook.setAttribute("presented", pan);
+                storageHook.setAttribute("presentedText", "Left");
+            }
+        }
+
+        var interface = {};
+        Object.defineProperties(interface, {
+            "calibrationObject": {
+                "get": function () {
+                    return calibrationObject
+                },
+                "set": readonly
+            },
+            "checkFrequencies": {
+                "get": function () {
+                    if (specification.calibration.checkFrequencies && _checkedFrequency === false) {
+                        return true;
                     }
-                };
-                obj.root.className = "calibration-slider";
-                obj.root.appendChild(obj.input);
-                obj.oscillator.connect(obj.gain);
-                obj.gain.connect(audioEngineContext.outputGain);
-                obj.gain.gain.value = Math.random() * 2;
-                obj.input.value = obj.gain.gain.value;
-                obj.input.setAttribute('orient', 'vertical');
-                obj.input.type = "range";
-                obj.input.min = -12;
-                obj.input.max = 0;
-                obj.input.step = 0.25;
-                if (f0 != 1000) {
-                    obj.input.value = (Math.random() * 12) - 6;
-                } else {
-                    obj.input.value = 0;
-                    obj.root.style.backgroundColor = "rgb(255,125,125)";
+                    return false;
+                },
+                "set": readonly
+            },
+            "checkChannels": {
+                "get": function () {
+                    if (specification.calibration.checkChannels && _checkedChannels === false) {
+                        return true;
+                    }
+                    return false;
+                },
+                "set": readonly
+            },
+            "performFrequencyCheck": {
+                "value": function (htmlRoot) {
+                    htmlRoot.innerHTML = "";
+                    calibrationObject = new checkFrequencyUnit(htmlRoot, getStorageRoot());
+                    _checkedFrequency = true;
                 }
-                obj.input.addEventListener("mousemove", obj);
-                obj.input.addEventListener("mouseenter", obj);
-                obj.input.addEventListener("mouseleave", obj);
-                obj.gain.gain.value = Math.pow(10, obj.input.value / 20);
-                obj.oscillator.frequency.value = f0;
-                this.calibrationNodes.push(obj);
-                this.holder.appendChild(obj.root);
-                f0 *= 2;
+            },
+            "performChannelCheck": {
+                "value": function (htmlRoot) {
+                    htmlRoot.innerHTML = "";
+                    calibrationObject = new checkChannelsUnit(htmlRoot, getStorageRoot());
+                    _checkedChannels = true;
+                }
             }
-            inject.appendChild(this.holder);
-        };
-        this.collect = function () {
-            this.calibrationNodes.forEach(function (obj) {
-                var node = storage.document.createElement("calibrationresult");
-                node.setAttribute("frequency", obj.f);
-                node.setAttribute("range-min", obj.input.min);
-                node.setAttribute("range-max", obj.input.max);
-                node.setAttribute("gain-lin", obj.gain.gain.value);
-                this.storeDOM.appendChild(node);
-            }, this);
-        };
-    };
+        })
+        return interface;
+    })();
 
 
     // Global Checkers