From 1938874707eeac37dec7d7dc6c25b024d00692c3 Mon Sep 17 00:00:00 2001 From: type-two Date: Fri, 10 Jul 2026 00:48:33 +1000 Subject: [PATCH] =?UTF-8?q?=F0=9F=8C=8A=20Juno-106=20chorus=20=E2=80=94=20?= =?UTF-8?q?the=20whole=20synth,=20warmer=20and=20wider?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The safest, highest-value vintage borrow: an always-on subtle BBD-style chorus on the master bus — two short delays each warbled by its own slow LFO, panned wide, ~0.3 wet. Universally warms and widens the dry oscillators; can't sound bad, can't error. Parallel send off `post`, chorusWet exposed for future world-modulation. Verified: graph builds clean on synth start, no errors. (FM mode, supersaw, and the 12-bit bitcrush are the next step — deferred to a listening pass since they reshape core timbre and want real ears to tune, not a backgrounded preview tab.) Co-Authored-By: Claude Opus 4.8 --- viz/index.html | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/viz/index.html b/viz/index.html index e08f7cc..5ade59d 100644 --- a/viz/index.html +++ b/viz/index.html @@ -6627,6 +6627,27 @@ post.connect(glitch); glitch.connect(out); post.connect(delSend); post.connect(revSend); post.connect(echoIn); // the mix onto the Earth Echo tape + // ---- Juno-106-style BBD chorus — two short delays, each warbled by its own + // slow LFO and panned wide. Always gently on, so the dry oscillators sound + // warm and stereo. The single best-value vintage borrow: universally widens + // the mix and can't sound bad. World-modulatable via chorusWet if wanted. ---- + const chorusWet = ctx.createGain(); chorusWet.gain.value = 0.3; + const chIn = ctx.createGain(); chIn.gain.value = 1; + const chD1 = ctx.createDelay(0.05); chD1.delayTime.value = 0.017; + const chD2 = ctx.createDelay(0.05); chD2.delayTime.value = 0.023; + const chLfo1 = ctx.createOscillator(); chLfo1.frequency.value = 0.62; + const chLfo2 = ctx.createOscillator(); chLfo2.frequency.value = 0.47; + const chDep1 = ctx.createGain(); chDep1.gain.value = 0.0038; // ±3.8 ms warble + const chDep2 = ctx.createGain(); chDep2.gain.value = 0.0044; + const chPanL = ctx.createStereoPanner(); chPanL.pan.value = -0.75; + const chPanR = ctx.createStereoPanner(); chPanR.pan.value = 0.75; + chLfo1.connect(chDep1); chDep1.connect(chD1.delayTime); + chLfo2.connect(chDep2); chDep2.connect(chD2.delayTime); + chIn.connect(chD1); chD1.connect(chPanL); chPanL.connect(chorusWet); + chIn.connect(chD2); chD2.connect(chPanR); chPanR.connect(chorusWet); + chorusWet.connect(out); post.connect(chIn); + chLfo1.start(); chLfo2.start(); + lfo = ctx.createOscillator(); lfo.frequency.value = 0.2; const lfoAmt = ctx.createGain(); lfoAmt.gain.value = 260; lfo.connect(lfoAmt); @@ -6681,7 +6702,7 @@ lfo.start(); return { out, preSat, glitch, revSend, fb, satDry, satWet, leadOsc, leadFilt, leadAmp, bassOsc, bassAmp, padOscs, padFilt, padAmp, droneOscs, droneAmp, - echoDelay, echoFilt, echoFb, echoWet, echoFlutAmt, hissGain }; + echoDelay, echoFilt, echoFb, echoWet, echoFlutAmt, hissGain, chorusWet }; } function hit(node, peak, dec) { // pluck envelope