From d82f99fd89e23fdb62598b616e39537360a10f74 Mon Sep 17 00:00:00 2001 From: julian laplace Date: Sat, 5 Jul 2025 14:14:08 +0200 Subject: better toggling --- client/index.js | 32 ++++++++++++++++++++++---------- client/lib/organ.js | 13 ++++++++++--- client/lib/util.js | 5 ++++- 3 files changed, 36 insertions(+), 14 deletions(-) (limited to 'client') diff --git a/client/index.js b/client/index.js index e8477ec..d4e805b 100644 --- a/client/index.js +++ b/client/index.js @@ -5,7 +5,7 @@ import color from "./lib/color"; import kalimba from "./lib/kalimba"; import organ from "./lib/organ"; import { getOutput } from "./lib/output"; -import { browser, requestAudioContext, choice } from "./lib/util"; +import { browser, requestAudioContext, choice, roundFreq } from "./lib/util"; import { PRIMES } from "./lib/primes"; // import life from "./lib/life"; @@ -53,8 +53,7 @@ function rebuild() { build(); } function play(freq) { - if (!freq.playing) { - freq.playing = true; + if (!organ.isPlaying(freq.frequency)) { let frequency = freq.frequency; // while (frequency < root) { // frequency *= 2; @@ -62,22 +61,30 @@ function play(freq) { // while (frequency > root) { // frequency /= 2; // } + const rounded = roundFreq(freq.frequency); organ.play(frequency); - freq.div.classList.add("playing"); + notes.forEach((row) => + row.forEach( + (note) => note.rounded === rounded && note.div.classList.add("playing"), + ), + ); } } function trigger(freq) { kalimba.play(freq.frequency); } function pause(freq) { - if (freq.playing) { - freq.playing = false; - organ.pause(freq.frequency); - freq.div.classList.remove("playing"); - } + organ.pause(freq.frequency); + const rounded = roundFreq(freq.frequency); + notes.forEach((row) => + row.forEach( + (note) => + note.rounded === rounded && note.div.classList.remove("playing"), + ), + ); } function toggle(freq) { - if (freq.playing) { + if (organ.isPlaying(freq.rounded) || freq.div.classList.contains("playing")) { pause(freq); } else { play(freq); @@ -101,6 +108,7 @@ function add(i, j) { const freq = { frequency, + rounded: roundFreq(frequency), div, i, j, @@ -142,6 +150,10 @@ function add(i, j) { } else { div.style.backgroundColor = color(frac, add + add_off, mul_off); } + + if (organ.isPlaying(frequency)) { + div.classList.add("playing"); + } }, }; diff --git a/client/lib/organ.js b/client/lib/organ.js index f67a3e8..9d0ac90 100644 --- a/client/lib/organ.js +++ b/client/lib/organ.js @@ -1,4 +1,5 @@ import Tone from "tone"; +import { roundFreq } from "./util"; const oscillators = {}; @@ -8,11 +9,17 @@ let lastPlayed; function load(out) { output = out; } + +function isPlaying(freq) { + const rounded = roundFreq(freq); + const osc = oscillators[rounded]; + return osc && osc.playing; +} function play(freq) { if (!output) { return; } - const rounded = Math.floor(freq); + const rounded = roundFreq(freq); const osc = (oscillators[rounded] = oscillators[rounded] || {}); if (!osc.el) { osc.el = new Tone.Oscillator(freq, "sine"); @@ -25,7 +32,7 @@ function play(freq) { } function pause(freq) { - const rounded = Math.floor(freq); + const rounded = roundFreq(freq); if (!oscillators[rounded]) return; const osc = (oscillators[rounded] = oscillators[rounded] || {}); if (osc.el) osc.el.stop(); @@ -33,4 +40,4 @@ function pause(freq) { return osc; } -export default { load, play, pause, oscillators }; +export default { load, isPlaying, play, pause, oscillators }; diff --git a/client/lib/util.js b/client/lib/util.js index b1ce162..7fad313 100644 --- a/client/lib/util.js +++ b/client/lib/util.js @@ -18,6 +18,9 @@ function choice(a) { function mod(n, m) { return n - m * Math.floor(n / m); } +function roundFreq(freq) { + return Math.round(freq * 100); +} function requestAudioContext(fn) { if (window.location.protocol !== "https:") { @@ -62,4 +65,4 @@ function requestAudioContext(fn) { } } -export { choice, mod, browser, requestAudioContext }; +export { choice, mod, browser, roundFreq, requestAudioContext }; -- cgit v1.2.3-70-g09d2