This commit is contained in:
Aaron Gutierrez
2021-12-27 18:07:37 -08:00
parent 7c39ec3c2b
commit 979c018317
3 changed files with 61 additions and 61 deletions

View File

@@ -1,38 +1,37 @@
body { body {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background: green; background: green;
color: white; color: white;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
font-family: sans-serif; font-family: sans-serif;
font-size: 2em; font-size: 2em;
height: 100vh; height: 100vh;
margin: 0; margin: 0;
overflow: hidden; overflow: hidden;
padding: 0; padding: 0;
width: 100vw; width: 100vw;
transition: background 0.25s ease-in; transition: background 0.25s ease-in;
} }
body.flat { body.flat {
background: blue; background: blue;
} }
body.sharp { body.sharp {
background: red; background: red;
} }
h1,
h1, h2 { h2 {
margin: 0; margin: 0;
} }
h1 { h1 {
font-size: 6em; font-size: 6em;
} }
h2 { h2 {
font-size: 3em; font-size: 3em;
} }

View File

@@ -1,13 +1,14 @@
<html> <html>
<head> <head>
<meta name="viewport" conetnt="width=device-width, initial-scale=1"> <meta name="viewport" conetnt="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="tuner.css"> <link rel="stylesheet" href="tuner.css" />
<script src="tuner.js"></script> <script src="tuner.js"></script>
<title>Tuner</title> <title>Tuner</title>
</head>
<body onload="setup()"> <body onload="setup()">
<h1 id="note">Listening...</h2> <h1 id="note">Listening...</h1>
<h2 id="tune"></h3> <h2 id="tune"></h2>
<div id="frequency"></div> <div id="frequency"></div>
<div>(<span id="rate">??</span> kHz sample rate)</div> <div>(<span id="rate">??</span> kHz sample rate)</div>
</bdoy> </body>
</html> </html>

View File

@@ -1,4 +1,17 @@
const NOTE_NAMES = ["A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#"] const NOTE_NAMES = [
"A",
"A#",
"B",
"C",
"C#",
"D",
"D#",
"E",
"F",
"F#",
"G",
"G#"
];
// We don't care about fundamenatls above 4kHz, so setting a lower sample rate // We don't care about fundamenatls above 4kHz, so setting a lower sample rate
// gives us finer-graned FFT buckets // gives us finer-graned FFT buckets
@@ -9,7 +22,6 @@ let dom_rate;
let dom_note; let dom_note;
let dom_tune; let dom_tune;
const setup = () => { const setup = () => {
dom_frequency = document.getElementById("frequency"); dom_frequency = document.getElementById("frequency");
dom_rate = document.getElementById("rate"); dom_rate = document.getElementById("rate");
@@ -17,28 +29,27 @@ const setup = () => {
dom_tune = document.getElementById("tune"); dom_tune = document.getElementById("tune");
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({ navigator.mediaDevices
audio: true, .getUserMedia({
}).then(handleStream, err => { audio: true
console.error("Error calling getUserMedia", err); })
}); .then(handleStream, err => {
}; console.error("Error calling getUserMedia", err);
});
}
if (navigator.wakeLock && navigator.wakeLock.request) { if (navigator.wakeLock && navigator.wakeLock.request) {
try { try {
navigator.wakeLock navigator.wakeLock
.request('screen') .request("screen")
.then(wakeLock => .then(wakeLock => setTimeout(() => wakeLock.release(), 60000));
setTimeout(() => wakeLock.release(), 60000)
);
} catch (err) {} } catch (err) {}
} }
}; };
const handleStream = stream => { const handleStream = stream => {
const audioContext = new AudioContext({ const audioContext = new AudioContext({
sampleRate: TARGET_SAMPLE_RATE, sampleRate: TARGET_SAMPLE_RATE
}); });
const analyser = audioContext.createAnalyser(); const analyser = audioContext.createAnalyser();
@@ -55,7 +66,6 @@ const handleStream = stream => {
setInterval(tune(analyser, data), 500); setInterval(tune(analyser, data), 500);
}; };
const tune = (analyser, data) => () => { const tune = (analyser, data) => () => {
analyser.getByteFrequencyData(data); analyser.getByteFrequencyData(data);
@@ -88,45 +98,35 @@ const tune = (analyser, data) => () => {
document.body.className = semitonesToClassname(semitones, margin); document.body.className = semitonesToClassname(semitones, margin);
}; };
const frequencyToSemitones = frequency => 12 * Math.log2(frequency / 440) + 69;
const frequencyToSemitones = frequency =>
12 * Math.log2(frequency / 440) + 69;
const semitonesToNote = semitones => { const semitonesToNote = semitones => {
const rounded = Math.round(semitones - 69); const rounded = Math.round(semitones - 69);
const index = rounded >= 0 const index = rounded >= 0 ? rounded % 12 : (12 + (rounded % 12)) % 12;
? rounded % 12
: (12 + (rounded % 12)) % 12
return NOTE_NAMES[index]; return NOTE_NAMES[index];
} };
const errorPercentage = (semitones, margin) => { const errorPercentage = (semitones, margin) => {
const rounded = Math.round(semitones); const rounded = Math.round(semitones);
const cents = Math.round((semitones - rounded) * 100); const cents = Math.round((semitones - rounded) * 100);
const accuracy = Number.parseFloat(margin * 100).toFixed(1); const accuracy = Number.parseFloat(margin * 100).toFixed(1);
const sign = cents > 0 ? "+" : "" const sign = cents > 0 ? "+" : "";
return `${sign}${cents} cents ± ${accuracy}`; return `${sign}${cents} cents ± ${accuracy}`;
} };
const semitonesToClassname = (semitones, margin) => { const semitonesToClassname = (semitones, margin) => {
const rounded = Math.round(semitones); const rounded = Math.round(semitones);
const error = Math.abs(semitones-rounded); const error = Math.abs(semitones - rounded);
const ok = margin > 0.05 ? margin : 0.05 const ok = margin > 0.05 ? margin : 0.05;
if (error <= ok) { if (error <= ok) {
return ""; return "";
} }
return Math.round(semitones) > semitones return Math.round(semitones) > semitones ? "flat" : "sharp";
? "flat" };
: "sharp";
}