diff --git a/GODSTRUMENT_MANUAL_SOURCE.md b/GODSTRUMENT_MANUAL_SOURCE.md index ac64963..489334c 100644 --- a/GODSTRUMENT_MANUAL_SOURCE.md +++ b/GODSTRUMENT_MANUAL_SOURCE.md @@ -584,6 +584,8 @@ Because the orrery is rendered client-side, in each listener's own browser, **ev The matrix pours out clean control values whether or not anyone is listening. Choosing *how* to hear it is choosing which instrument the planet plays. +**The built-in voice, up close.** Press `โช` and the browser synth wakes. Its plucked notes ring with a **DX7-style FM tine** โ brighter the harder they're struck; its pads bloom into a **detuned supersaw**; a **Juno chorus** warms the whole thing. Prefer strings? Right-click the sky โ **๐ธ string voice** and every pluck becomes a real **Karplus-Strong** plucked string. And route anything to `crush` for a **12-bit-DAC bitcrusher** โ the planet degrading its own converter into lo-fi grit. (Every one of these was tuned by spectral analysis before it shipped โ rendered offline and measured, so it's in-tune and clean, not just plausible.) + **Zero โ the moods, the gentle front door.** On your very first visit the instrument greets you with **๐ first light** instead of the full flood: a bass line, soft hats, a small melody, modest space โ a thing shaped like a song, with the world still playing underneath it. Right-click the sky โ **๐ mood** to move between *first light*, *ambient drift* (no drums, all atmosphere, the planet as weather), and **the full storm** โ the factory instrument with every one of the world's hands on it at once. Ease in, then open the door. **One โ the built-in browser synth.** Click **โช** and a full voice rack wakes inside the page: **lead** (bitcoin's price and your market's average price both quantize to it โ minor pentatonic and G dorian), **bass** (quake depth chooses its notes in a low minor), **pad** (brightened by Tokyo's warmth, daylight, harmony, the birth rate, longer lives), **drone** (thickened by aircraft aloft, barometric pressure, Saturn's slow wheel, the weight of the national debt), and **perc** (BTC volatility and market activity drive the hats). Over them sit the effects the world modulates: **reverb** (earthquakes open the void, room light sizes it), **delay** (your hand's Y feeds it, Mercury retrograde smears it), **saturation** (Delhi's air becomes grit, hard aspects add dissonance, wildfires burn it, hunger grinds beneath), and **glitch** (every Wikipedia edit on Earth, every light flash, every new wildfire fires a burst). Nothing to install; the planet plays a synth in your tab. @@ -1005,3 +1007,9 @@ Every feed the world sends is one of eight temperaments; the shape dictates how - **๐ Juno-106 chorus** โ an always-on subtle BBD-style stereo chorus on the synth's master bus (two short delays warbled by slow LFOs, panned wide) that warms and widens the dry oscillators. - **โฌ Parameter locks (p-locks)** โ Pocket-Operator / Elektron style: a texture voice (filter, glitch, reverb, drive) gets a per-step `lock` lane that pins its value to a fixed level on that step (blocky, disjointed), overriding the world; drag a step below the lane to unlock it and hand that step back to the data. Applied in `computeDests` via `applyGroove`; travels with the patch. - **๐ Juno-106 chorus** โ an always-on subtle BBD-style stereo chorus on the synth's master bus (two short delays warbled by slow LFOs, panned wide) that warms and widens the dry oscillators. +- **โฌ Parameter locks (p-locks)** โ Pocket-Operator / Elektron style: a texture voice (filter, glitch, reverb, drive) gets a per-step `lock` lane that pins its value to a fixed level on that step (blocky, disjointed), overriding the world; drag a step below the lane to unlock it and hand that step back to the data. Applied in `computeDests` via `applyGroove`; travels with the patch. +- **๐ Juno-106 chorus** โ an always-on subtle BBD-style stereo chorus on the synth's master bus (two short delays warbled by slow LFOs, panned wide) that warms and widens the dry oscillators. +- **๐ FM tine** โ every plucked note (sequencer, hands, mind mode) is a sine carrier phase-modulated by a sine operator (DX7-style), index enveloped for a bright attack โ mellow tail and scaled by velocity (harder = brighter). Spectrally verified alias-free across the register. +- **๐น Supersaw pad** โ each of the pad's chord tones is a detuned 9-saw cluster (JP-8000 style) for a lush, wide wall. +- **๐ธ String voice** โ right-click the sky โ *string voice* swaps the FM tine for a real Karplus-Strong plucked string (an AudioWorklet: noise burst โ damped delay loop, sample-accurate). Spectrally verified stable and in-tune. +- **๐ 12-bit bitcrush** โ a world-drivable lo-fi stage on the synth's master bus (an AudioWorklet doing true bit-depth quantise + sample-rate reduction). Route anything to `crush` and the planet degrades its own DAC โ clean by default (16-bit). diff --git a/viz/index.html b/viz/index.html index eafee92..3325a12 100644 --- a/viz/index.html +++ b/viz/index.html @@ -1016,6 +1016,8 @@
The matrix pours out clean control values whether or not anyone is listening. Choosing how to hear it is choosing which instrument the planet plays.
+The built-in voice, up close. Press โช and the browser synth wakes. Its plucked notes ring with a DX7-style FM tine โ brighter the harder they're struck; its pads bloom into a detuned supersaw; a Juno chorus warms the whole thing. Prefer strings? Right-click the sky โ ๐ธ string voice and every pluck becomes a real Karplus-Strong plucked string. And route anything to crush for a 12-bit-DAC bitcrusher โ the planet degrading its own converter into lo-fi grit. (Every one of these was tuned by spectral analysis before it shipped โ rendered offline and measured, so it's in-tune and clean, not just plausible.)
+Zero โ the moods, the gentle front door. On your very first visit the instrument greets you with ๐ first light instead of the full flood: a bass line, soft hats, a small melody, modest space โ a thing shaped like a song, with the world still playing underneath it. Right-click the sky โ ๐ mood to move between first light, ambient drift (no drums, all atmosphere, the planet as weather), and the full storm โ the factory instrument with every one of the world's hands on it at once. Ease in, then open the door.
One โ the built-in browser synth. Click โช and a full voice rack wakes inside the page: lead (bitcoin's price and your market's average price both quantize to it โ minor pentatonic and G dorian), bass (quake depth chooses its notes in a low minor), pad (brightened by Tokyo's warmth, daylight, harmony, the birth rate, longer lives), drone (thickened by aircraft aloft, barometric pressure, Saturn's slow wheel, the weight of the national debt), and perc (BTC volatility and market activity drive the hats). Over them sit the effects the world modulates: reverb (earthquakes open the void, room light sizes it), delay (your hand's Y feeds it, Mercury retrograde smears it), saturation (Delhi's air becomes grit, hard aspects add dissonance, wildfires burn it, hunger grinds beneath), and glitch (every Wikipedia edit on Earth, every light flash, every new wildfire fires a burst). Nothing to install; the planet plays a synth in your tab.
@@ -5532,6 +5534,8 @@ () => openCV()); ctxItem((earthEchoOn ? "๐ earth echo: on" : "๐ earth echo โ the planet on tape"), () => earthEchoSet(!earthEchoOn)); + ctxItem("๐ธ string voice" + (Synth.stringVoice() ? " (on โ plucks ring like a string)" : " โ swap the FM tine for a Karplus string"), + () => Synth.stringVoice(!Synth.stringVoice())); ctxItem("โจ keys โ remap the keyboard", () => openKeys()); if (commune.room) { const gOwner = commune.alloc["@godtime"]; @@ -6869,6 +6873,11 @@ N.leadFilt.Q.setTargetAtTime(1 + d("wavetable.morph", 0) * 8, t, 0.1); S(N.padFilt.frequency, 220 + d("pad.brightness", 0) * 4200); S(N.padAmp.gain, d("pad.brightness", 0) * 0.07, 0.3); // ร9 detuned saws โ trimmed to hold the level + if (crusher) { // world-driven 12-bit-DAC crunch (default clean) + const cb = clamp(d("crush", 0), 0, 1); + crusher.parameters.get("bits").value = 16 - cb * 12; // 16 clean โ 4 crunchy + crusher.parameters.get("reduction").value = 1 + cb * 8; // 1 โ 9ร downsample + } S(N.droneAmp.gain, d("drone.voices", 0) * 0.08, 0.3); S(N.revSend.gain, (d("reverb.size", 0) * 0.5 + d("master.space", 0) * 0.5) * 0.30, 0.3); S(N.fb.gain, Math.min(0.55, d("delay.feedback", 0) * 0.6), 0.2); @@ -6919,9 +6928,25 @@ params(); } + // ---- AudioWorklet voices: a 12-bit-DAC bitcrusher on the master bus (world- + // drivable) and a sample-accurate Karplus-Strong string. Both need a worklet + // (native feedback + real sample-rate reduction are unstable/impossible with + // stock nodes โ the spectral harness proved it). Loaded async from a Blob URL. + const WORKLET_SRC = "class Bitcrush extends AudioWorkletProcessor{static get parameterDescriptors(){return[{name:'bits',defaultValue:16,minValue:1,maxValue:16,automationRate:'k-rate'},{name:'reduction',defaultValue:1,minValue:1,maxValue:64,automationRate:'k-rate'}];}constructor(){super();this.phase=0;this.hold=null;}process(inputs,outputs,p){const inp=inputs[0],out=outputs[0];if(!inp||!inp.length)return true;const b=p.bits[0],red=Math.max(1,Math.round(p.reduction[0])),lv=Math.pow(2,b),nC=out.length,nS=out[0].length;if(!this.hold)this.hold=new Float32Array(8);for(let i=0;i