diff --git a/src/autoplay.ts b/src/autoplay.ts
index cd8a7be..6323062 100644
--- a/src/autoplay.ts
+++ b/src/autoplay.ts
@@ -1,4 +1,5 @@
import { keys } from "./notes.js";
+import { tryThing } from "./shared.js";
// a4 is the reference note
// -9 is the offset of c3
@@ -8,12 +9,8 @@ const initialOffsetOctaves = -1;
const initialOffset = -9 + initialOffsetOctaves * 12;
let audioContext = new AudioContext();
-
-const autoplayEle = document.getElementById("autoplay") as HTMLButtonElement;
-const stopEle = document.getElementById("stopplay") as HTMLButtonElement;
-const inputEle = document.getElementById("input") as HTMLTextAreaElement;
-const delayEle = document.getElementById("delay") as HTMLInputElement;
-const errorEle = document.getElementById("error") as HTMLSpanElement;
+let gainNode = audioContext.createGain();
+gainNode.connect(audioContext.destination);
function play(notes: string, baseDelay: number) {
let delay = 0;
@@ -47,28 +44,44 @@ function play(notes: string, baseDelay: number) {
function playNote(i: number, delay: number, playFor: number) {
const oscillator = audioContext.createOscillator();
oscillator.type = "triangle";
- oscillator.connect(audioContext.destination);
+ oscillator.connect(gainNode);
oscillator.frequency.value = 2 ** ((initialOffset + i) / 12) * a4;
oscillator.start(audioContext.currentTime + delay / 1000);
oscillator.stop(audioContext.currentTime + (delay + playFor) / 1000);
}
+function setupAudioContext() {
+ audioContext.close();
+ audioContext = new AudioContext();
+ gainNode = audioContext.createGain();
+ gainNode.connect(audioContext.destination);
+ setVolume();
+}
+
+function setVolume() {
+ // check parse? but it's a range
+ const pct = parseInt(volumeEle.value, 10) / parseInt(volumeEle.max, 10);
+ gainNode.gain.setValueAtTime(pct, audioContext.currentTime);
+}
+
+const autoplayEle = document.getElementById("autoplay") as HTMLButtonElement;
+const stopEle = document.getElementById("stopplay") as HTMLButtonElement;
+const inputEle = document.getElementById("input") as HTMLTextAreaElement;
+const delayEle = document.getElementById("delay") as HTMLInputElement;
+const volumeEle = document.getElementById("volume") as HTMLInputElement;
+
+stopEle.addEventListener("click", () => setupAudioContext());
+
+setVolume();
+volumeEle.addEventListener("input", () => setVolume());
+
autoplayEle.addEventListener("click", () => {
- errorEle.innerText = "";
- try {
+ tryThing(() => {
const notes = inputEle.value;
const delay = 60000 / parseInt(delayEle.value, 10);
if (isNaN(delay)) {
throw new Error(`Invalid delay: ${delayEle.value}`);
}
play(notes, delay);
- } catch (e) {
- console.error(e);
- errorEle.innerText = String(e);
- }
-});
-
-stopEle.addEventListener("click", () => {
- audioContext.close();
- audioContext = new AudioContext();
+ });
});
diff --git a/src/index.html b/src/index.html
index 1bdb219..78b7439 100644
--- a/src/index.html
+++ b/src/index.html
@@ -32,9 +32,19 @@
[ and ] (even spaces and line breaks)
will add delay between notes.
Play -