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

View File

@@ -1,13 +1,14 @@
<html>
<head>
<meta name="viewport" conetnt="width=device-width, initial-scale=1">
<link rel="stylesheet" href="tuner.css">
<meta name="viewport" conetnt="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="tuner.css" />
<script src="tuner.js"></script>
<title>Tuner</title>
</head>
<body onload="setup()">
<h1 id="note">Listening...</h2>
<h2 id="tune"></h3>
<h1 id="note">Listening...</h1>
<h2 id="tune"></h2>
<div id="frequency"></div>
<div>(<span id="rate">??</span> kHz sample rate)</div>
</bdoy>
</body>
</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
// gives us finer-graned FFT buckets
@@ -9,7 +22,6 @@ let dom_rate;
let dom_note;
let dom_tune;
const setup = () => {
dom_frequency = document.getElementById("frequency");
dom_rate = document.getElementById("rate");
@@ -17,28 +29,27 @@ const setup = () => {
dom_tune = document.getElementById("tune");
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({
audio: true,
}).then(handleStream, err => {
console.error("Error calling getUserMedia", err);
});
};
navigator.mediaDevices
.getUserMedia({
audio: true
})
.then(handleStream, err => {
console.error("Error calling getUserMedia", err);
});
}
if (navigator.wakeLock && navigator.wakeLock.request) {
try {
navigator.wakeLock
.request('screen')
.then(wakeLock =>
setTimeout(() => wakeLock.release(), 60000)
);
.request("screen")
.then(wakeLock => setTimeout(() => wakeLock.release(), 60000));
} catch (err) {}
}
};
const handleStream = stream => {
const audioContext = new AudioContext({
sampleRate: TARGET_SAMPLE_RATE,
sampleRate: TARGET_SAMPLE_RATE
});
const analyser = audioContext.createAnalyser();
@@ -55,7 +66,6 @@ const handleStream = stream => {
setInterval(tune(analyser, data), 500);
};
const tune = (analyser, data) => () => {
analyser.getByteFrequencyData(data);
@@ -88,45 +98,35 @@ const tune = (analyser, data) => () => {
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 rounded = Math.round(semitones - 69);
const index = rounded >= 0
? rounded % 12
: (12 + (rounded % 12)) % 12
const index = rounded >= 0 ? rounded % 12 : (12 + (rounded % 12)) % 12;
return NOTE_NAMES[index];
}
};
const errorPercentage = (semitones, margin) => {
const rounded = Math.round(semitones);
const cents = Math.round((semitones - rounded) * 100);
const accuracy = Number.parseFloat(margin * 100).toFixed(1);
const sign = cents > 0 ? "+" : ""
const sign = cents > 0 ? "+" : "";
return `${sign}${cents} cents ± ${accuracy}`;
}
};
const semitonesToClassname = (semitones, margin) => {
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) {
return "";
}
return Math.round(semitones) > semitones
? "flat"
: "sharp";
}
return Math.round(semitones) > semitones ? "flat" : "sharp";
};