aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2023-09-02 11:41:09 +0000
committers-ol <s+removethis@s-ol.nu>2023-09-02 11:41:09 +0000
commitee6ca5b32ea7e02a98e7cf5f150636a8d31b60cc (patch)
tree50c4be26c87cc73b882a3acdb98f7289ac5a154a
parentadd synthesizer (diff)
downloadisomorphic-kb-explorer-main.tar.gz
isomorphic-kb-explorer-main.zip
add synth panelHEADmain
Diffstat (limited to '')
-rw-r--r--index.html87
-rw-r--r--layout.js4
-rw-r--r--pattern.js4
-rw-r--r--style.css31
-rw-r--r--synth.js41
5 files changed, 121 insertions, 46 deletions
diff --git a/index.html b/index.html
index 6ada1a8..ca5ebe7 100644
--- a/index.html
+++ b/index.html
@@ -10,37 +10,58 @@
<canvas id="canvas-bg"></canvas>
<canvas id="canvas-fg"></canvas>
</main>
- <aside class="pattern controls">
- <div class="control control--preset">
- <label for="pattern-preset">pattern</label>
- <select id="pattern-preset">
- <option value="custom">(custom)</option>
- <optgroup label="scales">
- <option value="major-7" >major</option>
- <option value="minor-7" >minor</option>
- <option value="minor-harm-7">harmonic minor</option>
- <option value="minor-mel-7" >melodic minor</option>
- <option value="minor-hung-7">hungarian minor</option>
- <option value="penta" >pentatonic</option>
- </optgroup>
- <optgroup label="triads">
- <option value="major-3" >major</option>
- <option value="major-3+">augmented</option>
- <option value="minor-3" >minor</option>
- <option value="minor-3-">diminished</option>
- </optgroup>
- </select>
- </div>
- <div class="control">
- <label for="pattern-len">octave size</label>
- <input id="pattern-len" type="number" min="4" value="12" />
- </div>
- <div class="steps">
- <input type="checkbox" checked disabled />
- <input type="checkbox" />
- <input type="checkbox" />
- <input type="checkbox" />
- </div>
+ <aside class="pattern panel">
+ <section id="pattern" class="controls">
+ <div class="control control--preset">
+ <label for="pattern-preset">pattern</label>
+ <select id="pattern-preset">
+ <option value="custom">(custom)</option>
+ <optgroup label="scales">
+ <option value="major-7" >major</option>
+ <option value="minor-7" >minor</option>
+ <option value="minor-harm-7">harmonic minor</option>
+ <option value="minor-mel-7" >melodic minor</option>
+ <option value="minor-hung-7">hungarian minor</option>
+ <option value="penta" >pentatonic</option>
+ </optgroup>
+ <optgroup label="triads">
+ <option value="major-3" >major</option>
+ <option value="major-3+">augmented</option>
+ <option value="minor-3" >minor</option>
+ <option value="minor-3-">diminished</option>
+ </optgroup>
+ </select>
+ </div>
+ <div class="control">
+ <label for="pattern-len">octave size</label>
+ <input id="pattern-len" type="number" min="4" value="12" />
+ </div>
+ <div class="steps">
+ <input type="checkbox" checked disabled />
+ <input type="checkbox" />
+ <input type="checkbox" />
+ <input type="checkbox" />
+ </div>
+ </section>
+ <section id="synth" class="controls">
+ <div class="control control--toggle">
+ <label for="synth-enabled">synth</label>
+ <input id="synth-enabled" type="checkbox" checked />
+ </div>
+ <div class="control">
+ <label for="synth-freq">center freq</label>
+ <input id="synth-freq" type="number" min="0" value="110" />
+ </div>
+ <div class="control">
+ <label for="synth-voices">voices</label>
+ <input id="synth-voices" type="number" min="1" max="32" value="8" />
+ </div>
+ <div class="control control--toggle">
+ <label><a href="synth.html" target="_blank">options</a></label>
+ <button id="synth-opts-paste">paste</button>
+ <button id="synth-opts-reset">reset</button>
+ </div>
+ </section>
</aside>
<aside class="layout">
<svg
@@ -97,7 +118,7 @@
id="turn-cw" class="turn" transform="rotate(1.5)"
d="M 63.875 -112.84961 L 59.068359 -104.08203 C 69.570355 -98.323686 70.491716 -97.891327 78.669922 -89.982422 L 74.099609 -85.28125 L 96.498047 -79.628906 L 95.910156 -81.712891 L 90.216797 -101.85938 L 85.628906 -97.140625 C 76.875667 -105.51066 74.458477 -107.04659 63.875 -112.84961 z " />
</svg>
- <div class="controls">
+ <section id="layout" class="panel controls">
<div class="control control--preset">
<label for="layout-preset">layout</label>
<select id="layout-preset">
@@ -132,7 +153,7 @@
invert
</label>
</div>
- </div>
+ </section>
</aside>
<script type="module" src="main.js"></script>
</body>
diff --git a/layout.js b/layout.js
index 31edf7b..f00c806 100644
--- a/layout.js
+++ b/layout.js
@@ -1,9 +1,9 @@
-const panel = document.querySelector('aside.layout');
+const panel = document.getElementById('layout');
const svg = document.getElementById('diagram');
const arrows = Array.from(svg.querySelectorAll('.arrow'));
-const preset = panel.querySelector('.control--preset select');
+const preset = document.getElementById('layout-preset');
const controls = Array.from(panel.querySelectorAll('.control--axis'));
const steps = Array.from(panel.querySelectorAll('.control--axis > input'));
const dirs = Array.from(panel.querySelectorAll('.control--axis .dir input'));
diff --git a/pattern.js b/pattern.js
index 14ad005..23abfa9 100644
--- a/pattern.js
+++ b/pattern.js
@@ -1,6 +1,6 @@
-const panel = document.querySelector('aside.pattern');
+const panel = document.getElementById('pattern');
-const preset = panel.querySelector('.control--preset select');
+const preset = document.getElementById('pattern-preset');
const patternLength = document.getElementById('pattern-len');
const steps = panel.querySelector('.steps');
diff --git a/style.css b/style.css
index 3d00049..1fe469d 100644
--- a/style.css
+++ b/style.css
@@ -54,15 +54,35 @@ aside.layout > svg {
height: 100%;
}
-.controls {
+.panel {
display: flex;
flex-direction: column;
- justify-content: center;
+ gap: 0.75rem;
padding: 1rem 1.5rem;
- gap: 0.25rem;
background: #eeeeee;
}
+.panel section + section {
+ padding-top: 0.3rem;
+ border-top: 1px solid #b9bdc1;
+}
+
+.controls {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ overflow: hidden;
+ gap: 0.25rem;
+}
+
+.controls--minimized {
+ max-height: 1.25em;
+}
+
+#layout.controls {
+ justify-content: center;
+}
+
/* controls */
.control {
display: flex;
@@ -77,8 +97,6 @@ aside.layout > svg {
}
.control--preset {
- padding-bottom: 0.5rem;
- border-bottom: 1px solid #b9bdc1;
margin-bottom: 0.25rem;
}
@@ -86,10 +104,11 @@ aside.layout > svg {
flex: 1;
}
-.control--preset label:first-child {
+.controls .control:first-child label:first-child {
font-weight: bold;
}
+.control--toggle label:first-child,
.control--axis label:first-child {
flex: 1;
}
diff --git a/synth.js b/synth.js
index 74dc051..fdf2f87 100644
--- a/synth.js
+++ b/synth.js
@@ -1,6 +1,13 @@
import SimpleJSSynth from './simple-js-synth.js';
import * as pattern from './pattern.js';
+const panel = document.getElementById('synth');
+const enabled = document.getElementById('synth-enabled');
+const freq = document.getElementById('synth-freq');
+const poly = document.getElementById('synth-voices');
+const optsPaste = document.getElementById('synth-opts-paste');
+const optsReset = document.getElementById('synth-opts-reset');
+
const ctx = new window.AudioContext();
const opts = {};
@@ -19,23 +26,51 @@ export const setOptions = (o) => {
voices.push(SimpleJSSynth(ctx.destination, opts));
};
-setOptions({
+enabled.onchange = () => {
+ if (enabled.checked) ctx.resume();
+ else ctx.suspend();
+
+ panel.classList.toggle('controls--minimized', !enabled.checked);
+};
+
+freq.onchange = () => {
+ let frequency = +freq.value;
+ if (!frequency || frequency < 1) frequency = 110;
+ opts.frequency = frequency;
+};
+
+poly.onchange = () => {
+ let polyphony = +poly.value;
+ if (!polyphony || polyphony < 1) polyphony = 1;
+ setOptions({ polyphony });
+};
+
+optsPaste.onclick = () => {
+ const json = window.prompt("Please paste the JSON from the right panel of the synth page:");
+ setOptions(JSON.parse(json));
+};
+
+optsReset.onclick = () => setOptions({
osc1type: "sine", osc1vol: 0.2, osc1tune: 0,
osc2type: "square", osc2vol: 0.14, osc2tune: 12,
osc3type: "sine", osc3vol: 0.05, osc3tune: -6.7,
attack: 0, decay: 0.3, sustain: 0.5, susdecay: 5,
cutoff: 36,
+ frequency: 110,
polyphony: 8,
});
+optsReset.onclick();
+
export const on = (key, note, vol=1) => {
- ctx.resume()
+ if (!enabled.checked) return;
+ ctx.resume();
if (tones[key]?.note === note) return;
off(key);
- const freq = 110.0 * Math.pow(2, note / pattern.getLength());
+ const freq = opts.frequency * Math.pow(2, note / pattern.getLength());
const voice = voices.find(s => s.isReady());
if (!voice) return;