Mercurial > hg > webaudioevaluationtool
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) { |