commit df9fd70e935d842b8da4b8910bfc577e99df8fd5
parent 5e6139f8e0eabb75dee9d65edf842d9939f5fd92
Author: massi <mdsiboldi@gmail.com>
Date: Wed, 19 Jul 2023 02:20:56 -0700
combinators are gone, rescalers are gone
combinators are embedded in input logic now
rescalers will eventually be replaced by volume knobs on each unit.
Diffstat:
4 files changed, 44 insertions(+), 77 deletions(-)
diff --git a/src/lib/Slider.svelte b/src/lib/Slider.svelte
@@ -8,8 +8,6 @@
export let handleInput: (id: string, value: number) => void;
export let handleChange: () => void;
- $: props = { units, handleInput, handleChange };
-
$: getUnit = _getUnit.bind(null, units);
$: unit = getUnit(id);
$: sliderValue =
@@ -21,7 +19,6 @@
};
const onInput = (e: WithTarget<Event, HTMLInputElement>) => {
- console.log(e.currentTarget);
_handleInput(Number(e.currentTarget?.value));
};
</script>
@@ -40,42 +37,16 @@
on:input={onInput}
on:change={handleChange}
/>
- {:else if unit.kind === 'combinator'}
- <h3>{unit.kind}</h3>
- <div class="combinator-container">
- {#each unit.sources as input}
- <svelte:self id={input.id} {...props} />
- {/each}
- </div>
- {:else if unit.kind === 'noise'}
- <h3>{unit.kind}</h3>
- <svelte:self id={unit.amount.id} {...props} />
- {:else if unit.kind === 'osc'}
- <h3>{unit.kind}</h3>
- <h4>rate</h4>
- coarse
- <svelte:self id={unit.coarse[0].id} {...props} />
- fine
- <svelte:self id={unit.fine.id} {...props} />
- superfine
- <svelte:self id={unit.superfine.id} {...props} />
- <h4>amount</h4>
- <svelte:self id={unit.amount.id} {...props} />
{/if}
</div>
<style>
- .combinator-container {
- display: flex;
- flex-direction: row;
- }
.unit-container {
background: rgba(255, 255, 255, 0.3);
padding: 10px;
display: flexbox;
}
- h3,
- h4 {
+ h3 {
padding: 0;
margin: 0;
}
diff --git a/src/lib/engine.worker.ts b/src/lib/engine.worker.ts
@@ -19,10 +19,8 @@ let config: SynthConfig | undefined = undefined;
let unitState: UnitStateMap = new Map();
-// @ts-ignore dunno how to get OffscreenCanvas working
let canvas: OffscreenCanvas = new OffscreenCanvas(1, 1);
-// @ts-ignore dunno how to get message working
onmessage = (message: { data: EngineMessage }) => {
const { data } = message;
switch (data.kind) {
@@ -31,9 +29,7 @@ onmessage = (message: { data: EngineMessage }) => {
break;
}
case "window": {
- console.log(data.content);
- // @ts-ignore dunno how to get OffscreenCanvas working
- canvas = new OffscreenCanvas(content.width, content.height);
+ canvas = new OffscreenCanvas(data.content.width, data.content.height);
}
}
};
@@ -66,18 +62,9 @@ function setUnitState(id: UnitId, state: UnitState) {
unitState.set(id, state);
}
-function v(inOrIns: Input | Input[]): number {
- if (!config) {
- throw new Error("no config, can't get unit value.")
- }
-
- if (Array.isArray(inOrIns)) {
- return inOrIns.reduce((a, b) => a + v(b), 0);
- }
-
-
- const { id } = inOrIns;
- const unit: Unit = getUnit(config.units, id);
+function vUnit(x: { id: UnitId }): number {
+ const { id } = x;
+ const unit: Unit = getUnit(config!.units, id);
switch (unit.kind) {
case "osc": {
const position = getUnitState(id);
@@ -96,15 +83,19 @@ function v(inOrIns: Input | Input[]): number {
// range is whatever the control for it is???
return unit.value;
}
- case "combinator": {
- return unit.sources.reduce((a, b) => a + v(b), 0);
- }
case "noise": {
return Math.random() * v(unit.amount);
}
}
}
+function v(input: Input): number {
+ if (typeof input === "number") {
+ return input;
+ }
+ return input.reduce((a, b) => a + vUnit(b), 0);
+}
+
function update() {
// update all unit states
if (!config) {
@@ -121,7 +112,7 @@ function update() {
const superfine = rescale(
v(unit.superfine),
range.signal,
- range.osc.superfine,
+ range.osc.superfine
);
setUnitState(
id,
diff --git a/src/lib/types.ts b/src/lib/types.ts
@@ -26,7 +26,6 @@ export type EngineMessage = {
export type HigherUnit =
| OscUnit
- | CombinatorUnit
| NoiseUnit;
export type Unit =
@@ -35,13 +34,14 @@ export type Unit =
export type UnitId = string;
-export type Input = { id: UnitId };
+export type Output = { id: UnitId };
+export type Input = number | Output[];
export type Pos = { x: number; y: number };
export type OscUnit = {
kind: "osc";
- coarse: Input[];
+ coarse: Input;
fine: Input;
superfine: Input;
amount: Input;
@@ -59,18 +59,13 @@ export type ConstUnit = {
pos: Pos;
};
-export type CombinatorUnit = {
- kind: "combinator";
- sources: Input[];
-};
-
export type UnitMap = Map<UnitId, Unit>;
export type UnitStateMap = Map<UnitId, UnitState>;
export type UnitState = any;
export type Sinks = {
- l: Input | null;
- c: Input | null;
- h: Input | null;
+ l: Input;
+ c: Input;
+ h: Input;
};
type Range = {
@@ -219,3 +214,21 @@ export const ensure = {
},
},
};
+
+export const inp = {
+ toggle: (input: Input, output: Output): Input => {
+ if (typeof input === "number") {
+ return [output]
+ }
+ else {
+ const deduped = input.filter((o) => o.id !== output.id)
+ if (input.length === deduped.length) {
+ return [...input, output];
+ }
+ else {
+ // it's there and we removed it
+ return deduped;
+ }
+ }
+ }
+}
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
@@ -3,8 +3,8 @@
import { debounce } from 'lodash';
import Sink from '$lib/Sink.svelte';
import Slider from '$lib/Slider.svelte';
- import { ensure, rescale, range, is, getUnit as _getUnit } from '$lib/types';
- import type { Input, Unit, UnitId, ConstUnit, UnitMap, Sinks } from '$lib/types';
+ import { inp, ensure, rescale, range, is, getUnit as _getUnit } from '$lib/types';
+ import type { Output, Input, Unit, UnitId, ConstUnit, UnitMap, Sinks } from '$lib/types';
let cvs: HTMLCanvasElement | undefined;
let offscreenCanvas: OffscreenCanvas | undefined;
@@ -61,7 +61,7 @@
$: getUnit = _getUnit.bind(null, units);
let uid = 0;
let units: UnitMap = new Map();
- let sinks: Sinks = { l: null, c: null, h: null };
+ let sinks: Sinks = { l: 0, c: 0, h: 0 };
onMount(() => {
const doc: SerializedState = fromUrl();
@@ -100,7 +100,7 @@
const id = String(uid++);
units.set(id, unit);
units = units;
- return { id };
+ return [{ id }];
}
type EzUnit = Input | number | undefined;
@@ -130,18 +130,12 @@
): Input {
return addUnit({
kind: 'osc',
- coarse: [ez(coarse)],
+ coarse: ez(coarse),
fine: ez(fine),
superfine: superfine ? ez(superfine) : mk.c(0),
amount: ez(amount)
});
},
- add: function com(...ids: EzUnit[]) {
- return addUnit({
- kind: 'combinator',
- sources: ids.map(ez)
- });
- },
n: function noise(amt: EzUnit) {
return addUnit({ kind: 'noise', amount: ez(amt) });
}
@@ -155,8 +149,6 @@
}
};
- sinks = { l: null, c: null, h: null };
-
function updateUnit(k: UnitId, value: number) {
const unit = get.constUnit(k);
unit.value = value;
@@ -192,7 +184,7 @@
document.addEventListener('mouseup', handleMouseUp);
};
- let signalDragging: false | { id: UnitId } = false;
+ let signalDragging: false | Output = false;
const handleSignalStart = (obj: { id: UnitId }) => {
console.log('signal start', obj);
@@ -211,7 +203,7 @@
if (!signalDragging) {
throw new Error('cant connect sink to nonexistant signal');
}
- sinks[ch] = { id: signalDragging.id };
+ sinks[ch] = inp.toggle(sinks[ch], signalDragging);
engineWorker && engineWorker.postMessage({ kind: 'config', content: { sinks, units } });
console.log(sinks);
signalDragging = false;