summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorjulian laplace <julescarbon@gmail.com>2025-07-05 14:14:08 +0200
committerjulian laplace <julescarbon@gmail.com>2025-07-05 14:14:08 +0200
commitd82f99fd89e23fdb62598b616e39537360a10f74 (patch)
treee3d1b487816c50c83f79422a122d06c622769009 /client
parentf876a5c804221ab28654c33e6a2e95779c5c753e (diff)
better toggling
Diffstat (limited to 'client')
-rw-r--r--client/index.js32
-rw-r--r--client/lib/organ.js13
-rw-r--r--client/lib/util.js5
3 files changed, 36 insertions, 14 deletions
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 };