comparison js/core.js @ 3101:cd34732a2e39

#171 Implemented
author Nicholas Jillings <nicholas.jillings@mail.bcu.ac.uk>
date Wed, 17 Jan 2018 17:41:25 +0000
parents 20de79c56ad7
children 972b55d81c1b
comparison
equal deleted inserted replaced
3100:998e05c5769a 3101:cd34732a2e39
144 popup = new interfacePopup(); 144 popup = new interfacePopup();
145 145
146 // Create the specification object 146 // Create the specification object
147 specification = new Specification(); 147 specification = new Specification();
148 148
149 // Create the storage object
150 storage = new Storage();
151
149 // Create the interface object 152 // Create the interface object
150 interfaceContext = new Interface(specification); 153 interfaceContext = new Interface(specification);
151 154
152 // Create the storage object
153 storage = new Storage();
154 // Define window callbacks for interface 155 // Define window callbacks for interface
155 window.onresize = function (event) { 156 window.onresize = function (event) {
156 interfaceContext.resizeWindow(event); 157 interfaceContext.resizeWindow(event);
157 }; 158 };
158 159
1142 } 1143 }
1143 }; 1144 };
1144 1145
1145 this.proceedClicked = function () { 1146 this.proceedClicked = function () {
1146 // Each time the popup button is clicked! 1147 // Each time the popup button is clicked!
1147 if (testState.stateIndex === 0 && specification.calibration) { 1148 if (testState.stateIndex === -1 && specification.calibration) {
1148 interfaceContext.calibrationModuleObject.collect();
1149 advanceState(); 1149 advanceState();
1150 return; 1150 return;
1151 } 1151 }
1152 var node = this.popupOptions[this.currentIndex], 1152 var node = this.popupOptions[this.currentIndex],
1153 pass = true, 1153 pass = true,
1359 popup.initState(this.preTestSurvey, storage.globalPreTest); 1359 popup.initState(this.preTestSurvey, storage.globalPreTest);
1360 } else { 1360 } else {
1361 this.advanceState(); 1361 this.advanceState();
1362 } 1362 }
1363 } else if (this.stateIndex == -1) { 1363 } else if (this.stateIndex == -1) {
1364 this.stateIndex++; 1364 if (interfaceContext.calibrationTests.checkFrequencies) {
1365 if (specification.calibration) {
1366 popup.showPopup(); 1365 popup.showPopup();
1367 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"; 1366 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";
1368 interfaceContext.calibrationModuleObject = new interfaceContext.calibrationModule(); 1367 interfaceContext.calibrationTests.performFrequencyCheck(popup.popupResponse);
1369 interfaceContext.calibrationModuleObject.build(popup.popupResponse); 1368 popup.hidePreviousButton();
1369 } else if (interfaceContext.calibrationTests.checkChannels) {
1370 popup.showPopup();
1371 popup.popupTitle.textContent = "Click play to start the audio, the click the button corresponding to where the sound appears to be coming from.";
1372 interfaceContext.calibrationTests.performChannelCheck(popup.popupResponse);
1370 popup.hidePreviousButton(); 1373 popup.hidePreviousButton();
1371 } else { 1374 } else {
1375 this.stateIndex++;
1372 this.advanceState(); 1376 this.advanceState();
1373 } 1377 }
1374 } else if (this.stateIndex == this.stateMap.length) { 1378 } else if (this.stateIndex == this.stateMap.length) {
1375 // All test pages complete, post test 1379 // All test pages complete, post test
1376 console.log('Ending test ...'); 1380 console.log('Ending test ...');
3214 imageController.img.src = src; 3218 imageController.img.src = src;
3215 }; 3219 };
3216 return imageController; 3220 return imageController;
3217 })(); 3221 })();
3218 3222
3219 this.calibrationModuleObject = null; 3223 this.calibrationTests = (function () {
3220 this.calibrationModule = function () { 3224 function readonly(t) {
3221 // This creates an on-page calibration module 3225 throw ("Cannot set read-only variable");
3222 this.storeDOM = storage.document.createElement("calibration"); 3226 }
3223 storage.root.appendChild(this.storeDOM); 3227
3224 // The calibration is a fixed state module 3228 function getStorageRoot() {
3225 this.calibrationNodes = []; 3229 var storageRoot = storage.root.querySelector("calibration");
3226 this.holder = null; 3230 if (storageRoot === undefined) {
3227 this.build = function (inject) { 3231 storageRoot = storage.document.createElement("calibration");
3228 var f0 = 62.5; 3232 storage.root.appendChild(storageRoot);
3229 this.holder = document.createElement("div"); 3233 }
3230 this.holder.className = "calibration-holder"; 3234 return storageRoot;
3231 this.calibrationNodes = []; 3235 }
3232 while (f0 < 20000) { 3236 var calibrationObject = undefined,
3233 /* jshint loopfunc: true */ 3237 _checkedFrequency = false,
3234 var obj = { 3238 _checkedChannels = false;
3235 root: document.createElement("div"), 3239
3236 input: document.createElement("input"), 3240 // Define the checkFrequencies test!
3237 oscillator: audioContext.createOscillator(), 3241 var checkFrequencyUnit = function (htmlRoot, storageRoot) {
3238 gain: audioContext.createGain(), 3242
3239 f: f0, 3243 function createFrequencyElement(frequency) {
3240 parent: this, 3244 return (function (frequency) {
3241 handleEvent: function (event) { 3245 var range = document.createElement("input");
3242 switch (event.type) { 3246 range.type = "range";
3243 case "mouseenter": 3247 range.min = "-24";
3244 this.oscillator.start(0); 3248 range.max = "24";
3245 break; 3249 range.step = "0.5";
3246 case "mouseleave": 3250 range.setAttribute("orient", "vertical");
3247 this.oscillator.stop(0); 3251 range.value = (Math.random() - 0.5) * 24;
3248 this.oscillator = audioContext.createOscillator(); 3252 range.setAttribute("frequency", frequency);
3249 this.oscillator.connect(this.gain); 3253 htmlRoot.append(range);
3250 this.oscillator.frequency.value = this.f; 3254
3251 break; 3255 var gain = audioContext.createGain();
3252 case "mousemove": 3256 gain.connect(outputGain);
3253 var value = Math.pow(10, this.input.value / 20); 3257 gain.gain.value = Math.pow(10, Number(range.value) / 20.0);
3254 if (this.f == 1000) { 3258 var osc = undefined;
3255 audioEngineContext.outputGain.gain.value = value; 3259
3256 interfaceContext.volume.slider.value = this.input.value; 3260 var store = storage.document.createElement("response");
3257 } else { 3261 store.setAttribute("frequency", frequency);
3258 this.gain.gain.value = value; 3262 storageHook.appendChild(store);
3263 var interface = {};
3264 Object.defineProperties(interface, {
3265 "handleEvent": {
3266 "value": function (e) {
3267 if (e.type == "mouseenter") {
3268 osc = audioContext.createOscillator();
3269 osc.frequency.value = frequency;
3270 osc.connect(gain);
3271 osc.start();
3272 console.log("start " + frequency);
3273 } else if (e.type == "mouseleave") {
3274 console.log("stop " + frequency);
3275 osc.stop();
3276 osc = undefined;
3259 } 3277 }
3260 break; 3278 store.textContent = e.currentTarget.value;
3279 gain.gain.value = Math.pow(10, Number(e.currentTarget.value) / 20.0);
3280 }
3261 } 3281 }
3262 }, 3282 });
3263 disconnect: function () { 3283 range.addEventListener("mousemove", interface);
3264 this.gain.disconnect(); 3284 range.addEventListener("mouseenter", interface);
3285 range.addEventListener("mouseleave", interface);
3286 return interface;
3287 })(frequency);
3288 }
3289 var htmlHook = document.createElement("div");
3290 htmlRoot.appendChild(htmlHook);
3291 var storageHook = storage.document.createElement("frequency");
3292 storageRoot.appendChild(storageHook);
3293 var frequencies = [100, 200, 400, 800, 1200, 1600, 2000, 4000, 8000, 12000];
3294 var outputGain = audioContext.createGain();
3295 outputGain.gain.value = 0.25;
3296 outputGain.connect(audioContext.destination);
3297 this.sliders = frequencies.map(createFrequencyElement);
3298 }
3299
3300 var checkChannelsUnit = function (htmlRoot, storageRoot) {
3301
3302 function onclick(ev) {
3303 var storageHook = storage.document.querySelector("calibration").querySelector("channels");
3304 storageHook.setAttribute("selected", ev.currentTarget.value);
3305 storageHook.setAttribute("selectedText", ev.currentTarget.textContent);
3306 osc.stop();
3307 gainL = undefined;
3308 gainR = undefined;
3309 cmerge = undefined;
3310 popup.proceedClicked();
3311 }
3312 var osc = audioContext.createOscillator();
3313 var gainL = audioContext.createGain();
3314 var gainR = audioContext.createGain();
3315 gainL.channelCount = 1;
3316 gainR.channelCount = 1;
3317 var cmerge = audioContext.createChannelMerger(2);
3318 osc.connect(gainL, 0, 0);
3319 osc.connect(gainR, 0, 0);
3320 gainL.connect(cmerge, 0, 0);
3321 gainR.connect(cmerge, 0, 1);
3322 cmerge.connect(audioContext.destination);
3323 var play = document.createElement("button");
3324 play.textContent = "Play Audio";
3325 play.onclick = function () {
3326 osc.start();
3327 play.disabled = true;
3328 }
3329 htmlRoot.appendChild(play);
3330 var choiceHolder = document.createElement("div");
3331 var leftButton = document.createElement("button");
3332 leftButton.textContent = "Left";
3333 leftButton.value = "-1";
3334 var centerButton = document.createElement("button");
3335 centerButton.textContent = "Middle";
3336 centerButton.value = "0";
3337 var rightButton = document.createElement("button");
3338 rightButton.textContent = "Right";
3339 rightButton.value = "1";
3340 choiceHolder.appendChild(leftButton);
3341 choiceHolder.appendChild(centerButton);
3342 choiceHolder.appendChild(rightButton);
3343 htmlRoot.appendChild(choiceHolder);
3344 leftButton.addEventListener("click", onclick);
3345 centerButton.addEventListener("click", onclick);
3346 rightButton.addEventListener("click", onclick);
3347
3348 var storageHook = storage.document.createElement("channels");
3349 storageRoot.appendChild(storageHook);
3350
3351 var pan;
3352 if (Math.random() > 0.5) {
3353 pan = 1;
3354 gainL.gain.value = 0.0;
3355 gainR.gain.value = 0.25;
3356 storageHook.setAttribute("presented", pan);
3357 storageHook.setAttribute("presentedText", "Right");
3358 } else {
3359 pan = -1;
3360 gainL.gain.value = 0.25;
3361 gainR.gain.value = 0.0;
3362 storageHook.setAttribute("presented", pan);
3363 storageHook.setAttribute("presentedText", "Left");
3364 }
3365 }
3366
3367 var interface = {};
3368 Object.defineProperties(interface, {
3369 "calibrationObject": {
3370 "get": function () {
3371 return calibrationObject
3372 },
3373 "set": readonly
3374 },
3375 "checkFrequencies": {
3376 "get": function () {
3377 if (specification.calibration.checkFrequencies && _checkedFrequency === false) {
3378 return true;
3265 } 3379 }
3266 }; 3380 return false;
3267 obj.root.className = "calibration-slider"; 3381 },
3268 obj.root.appendChild(obj.input); 3382 "set": readonly
3269 obj.oscillator.connect(obj.gain); 3383 },
3270 obj.gain.connect(audioEngineContext.outputGain); 3384 "checkChannels": {
3271 obj.gain.gain.value = Math.random() * 2; 3385 "get": function () {
3272 obj.input.value = obj.gain.gain.value; 3386 if (specification.calibration.checkChannels && _checkedChannels === false) {
3273 obj.input.setAttribute('orient', 'vertical'); 3387 return true;
3274 obj.input.type = "range"; 3388 }
3275 obj.input.min = -12; 3389 return false;
3276 obj.input.max = 0; 3390 },
3277 obj.input.step = 0.25; 3391 "set": readonly
3278 if (f0 != 1000) { 3392 },
3279 obj.input.value = (Math.random() * 12) - 6; 3393 "performFrequencyCheck": {
3280 } else { 3394 "value": function (htmlRoot) {
3281 obj.input.value = 0; 3395 htmlRoot.innerHTML = "";
3282 obj.root.style.backgroundColor = "rgb(255,125,125)"; 3396 calibrationObject = new checkFrequencyUnit(htmlRoot, getStorageRoot());
3283 } 3397 _checkedFrequency = true;
3284 obj.input.addEventListener("mousemove", obj); 3398 }
3285 obj.input.addEventListener("mouseenter", obj); 3399 },
3286 obj.input.addEventListener("mouseleave", obj); 3400 "performChannelCheck": {
3287 obj.gain.gain.value = Math.pow(10, obj.input.value / 20); 3401 "value": function (htmlRoot) {
3288 obj.oscillator.frequency.value = f0; 3402 htmlRoot.innerHTML = "";
3289 this.calibrationNodes.push(obj); 3403 calibrationObject = new checkChannelsUnit(htmlRoot, getStorageRoot());
3290 this.holder.appendChild(obj.root); 3404 _checkedChannels = true;
3291 f0 *= 2; 3405 }
3292 } 3406 }
3293 inject.appendChild(this.holder); 3407 })
3294 }; 3408 return interface;
3295 this.collect = function () { 3409 })();
3296 this.calibrationNodes.forEach(function (obj) {
3297 var node = storage.document.createElement("calibrationresult");
3298 node.setAttribute("frequency", obj.f);
3299 node.setAttribute("range-min", obj.input.min);
3300 node.setAttribute("range-max", obj.input.max);
3301 node.setAttribute("gain-lin", obj.gain.gain.value);
3302 this.storeDOM.appendChild(node);
3303 }, this);
3304 };
3305 };
3306 3410
3307 3411
3308 // Global Checkers 3412 // Global Checkers
3309 // These functions will help enforce the checkers 3413 // These functions will help enforce the checkers
3310 this.checkHiddenAnchor = function (message) { 3414 this.checkHiddenAnchor = function (message) {