From b546bfef82875d91dac4ad5d9e4fbb9c9c87d27b Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Tue, 6 Oct 2020 19:52:20 +0800 Subject: Random stuff (sensfreq). --- sensfreq/index.html | 95 +++++++++++++++++++++++++++++++++++++++++++ sensfreq/main.js | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 sensfreq/index.html create mode 100644 sensfreq/main.js (limited to 'sensfreq') diff --git a/sensfreq/index.html b/sensfreq/index.html new file mode 100644 index 0000000..7422b4a --- /dev/null +++ b/sensfreq/index.html @@ -0,0 +1,95 @@ + + + +SensFreq + + + + + + + + + + + + + +

SensFreq

+ + + + + + + + + + + + + +
Note to look for + +
Number of notes + +- + +
Octave range + +- + +
+Arpeggio
+
+ +
+ + + + + +
+
+Correct: * of *
+ +
+
+Disclaimer: this application cannot serve as a test for perfect pitch. Please do not go around and claim you have perfect pitch if you get 99.999% challenges right! +
+ + document.getElementById(s); + +let ans = false; +let nq = 0; +let nc = 0; + +function init() +{ + e("gench").disabled = false; + e("response").style.display="none"; + reset_stats(); + loadTheme(); +} + +function play_notes(freq, t, arpt) +{ + const stop_notes=function(g, o) + { + o.stop(); + g.disconnect(audioCtx.destination); + o.disconnect(g); + } + const play_note=function(f) + { + const gn = audioCtx.createGain(); + gn.gain.setValueAtTime(.5/freq.length, audioCtx.currentTime); + gn.gain.linearRampToValueAtTime(0, audioCtx.currentTime + t / 1000.); + gn.connect(audioCtx.destination); + const osc = audioCtx.createOscillator(); + osc.type = "sine"; + osc.frequency.setValueAtTime(f, audioCtx.currentTime); + osc.connect(gn); + osc.start(); + setTimeout(stop_notes.bind(null, gn, osc), t); + } + let i=0; + freq.forEach(function(f){setTimeout(play_note.bind(null, f), arpt * (i++));}); +} + +get_freq = n => 440 * Math.pow(Math.pow(2, 1./12), n-69) + +function generate_challenge() +{ + const nmin=Number(e("minnnotes").value); + const nmax=Number(e("maxnnotes").value); + const omin=Number(e("minorange").value); + const omax=Number(e("maxorange").value); + if (omax < omin || nmax < nmin) + { + alert("?"); + return; + } + const nnotes = Math.floor(Math.random() * (nmax - nmin + 1)) + nmin; + const minrange = 60 + omin * 12; + const maxrange = 71 + omax * 12; + + let f = []; + let l = []; + ans = false; + + if (Math.random() < 0.3) + { + const o = Math.floor(Math.random() * (omax - omin + 1)) + omin; + let n = 60 + Number(e("note").value) + o * 12; + f.push(get_freq(n)); + l.push(n); + ans = true; + } + while (f.length < nnotes) + { + let n = Math.floor(Math.random() * (maxrange - minrange + 1)) + minrange; + if (l.indexOf(n)!=-1) + continue; + ans |= ((n % 12) == Number(e("note").value)); + f.push(get_freq(n)); + } + f.sort((a,b)=>a-b); + play_notes(f, 1000, e("arp").checked ? 50 : 0); + e("gench").disabled = true; + e("response").style.display=""; +} + +function update_stats() +{ + e("stats").innerHTML=`You got ${nc} of the ${nq} challenges correct.` +} + +function reset_stats() +{ + nq = nc = 0; + update_stats(); +} + +function check_yes() +{ + if (ans) + ++nc; + ++nq; + e("gench").disabled = false; + e("response").style.display="none"; + update_stats(); +} + +function check_no() +{ + if (!ans) + ++nc; + ++nq; + e("gench").disabled = false; + e("response").style.display="none"; + update_stats(); +} -- cgit v1.2.3