summaryrefslogtreecommitdiff
path: root/client/lib/bandpass.js
diff options
context:
space:
mode:
Diffstat (limited to 'client/lib/bandpass.js')
-rw-r--r--client/lib/bandpass.js97
1 files changed, 97 insertions, 0 deletions
diff --git a/client/lib/bandpass.js b/client/lib/bandpass.js
new file mode 100644
index 0000000..3e1ed16
--- /dev/null
+++ b/client/lib/bandpass.js
@@ -0,0 +1,97 @@
+/**
+ * Bandpassed noise organ
+ * @module lib/bandpass.js;
+ */
+
+import Tone from "tone";
+import { roundInterval } from "./util";
+
+let root = 440;
+
+let oscillators = {};
+let output;
+let lastPlayed;
+let noise;
+
+function load(out) {
+ output = out;
+}
+function isPlaying(interval) {
+ const rounded = roundInterval(interval);
+ const osc = oscillators[rounded];
+ return osc && osc.playing;
+}
+function play(interval) {
+ if (!output) {
+ return;
+ }
+ if (!noise) {
+ noise = new Tone.Noise().start();
+ }
+ const rounded = roundInterval(interval);
+ const osc = (oscillators[rounded] = oscillators[rounded] || {});
+ if (!osc.el) {
+ osc.interval = interval;
+ osc.el = new Tone.Filter(interval * root, "bandpass");
+ osc.el.Q.value = 100;
+ }
+ noise.connect(osc.el);
+ osc.el.connect(output);
+ osc.playing = true;
+ lastPlayed = osc;
+ return osc;
+}
+
+function pause(interval) {
+ const rounded = roundInterval(interval);
+ if (!oscillators[rounded]) return;
+ const osc = (oscillators[rounded] = oscillators[rounded] || {});
+ osc.el.disconnect(output);
+ noise.disconnect(osc.el);
+ osc.playing = false;
+ return osc;
+}
+function toggle(interval) {
+ const rounded = roundInterval(interval);
+ const osc = (oscillators[rounded] = oscillators[rounded] || {});
+ if (osc && osc.playing) {
+ pause(interval);
+ } else {
+ play(interval);
+ }
+}
+
+function setRoot(newRoot) {
+ root = newRoot;
+ for (const osc of Object.values(oscillators)) {
+ osc.el.frequency.value = osc.interval * newRoot;
+ }
+}
+function stop() {
+ for (const osc of Object.values(oscillators)) {
+ if (!osc.playing) {
+ continue;
+ }
+ osc.el.disconnect(output);
+ noise.disconnect(osc.el);
+ osc.playing = false;
+ delete osc.el;
+ }
+ oscillators = {};
+}
+function getPlaying() {
+ return Object.values(oscillators)
+ .filter((osc) => osc.playing)
+ .map((osc) => osc.interval);
+}
+
+export default {
+ load,
+ isPlaying,
+ getPlaying,
+ play,
+ pause,
+ toggle,
+ stop,
+ setRoot,
+};