desc:GFX Aureus // gfx-aureus - Golden Ratio & Decadic 4-Band EQ / Drive / Compressor //tags: multiband eq saturation compressor mastering //author: JGWizrad / Garden FX (GFX) // // DECADIC BANDS: LR4 crossovers at F1 / F1 x 10 / F1 x 100, with the top split kept between // 5 and 10 kHz so the top band is always presence/air. F1 is picked from the Fibonacci // numbers 34, 55, 89, 144 Hz (each step ~ x PHI) or the classic 70 Hz (70 / 700 / 7k). // An LR4 low/high pair sums to ONE 2nd-order all-pass (Q 0.7071) at its corner, so every band // (and the dry path used by MIX) passes through exactly one all-pass per crossover it did not // go through. The four bands therefore sum back to a flat, phase-coherent signal. // // PER BAND: EQ (P / S / D) -> DRIVE (T / S / X) -> COMP (O / V / R) -> band GAIN, plus SOLO / MUTE. // // GOLDEN RATIO (PHI = 1.618034) sets everything the knobs don't: // EQ corners Band 1 shelf F1/PHI, Band 4 shelf F3*PHI, // Bands 2/3 bells at the geometric band centres // P (program) broad Q = 1/PHI; boosting a shelf adds a classic program-EQ dip of gain/PHI^2 // exactly at the band edge (F1, F3) // S (console) resonant shelves (Q = PHI); bells with proportional Q = PHI * (1 + |gain|/12) // D (dynamic) S shape whose gain follows band energy above -30 dB over a 12*PHI dB range // Attack 30 ms / PHI^band (30, 18.5, 11.5, 7.1 ms) // Release attack * PHI^5 (x 11.09) // Ratios PHI^k: Opto PHI^(2a), VCA PHI^(3a), Gentle PHI^(3a) over three stages // Knees Opto 12*PHI dB, VCA 6/PHI dB, Gentle 6*PHI dB per stage // Drift phi-breathing: each band's threshold wanders slowly (period 3 s * PHI^band) // // R (Gentle, after the GENTLE mode in GFX RND): three gentle compressors in series at // thresholds 6 dB apart, each carrying a third of the ratio, with program-dependent release. // // MASTER: INPUT, DRIFT, MIX (phase-aligned dry vs bands), OUTPUT, safety limiter (-0.3 dBFS). slider1:0<0,7,1{Init,Golden Glue,Tape Polish,Opto Smooth,Air Lift,Iron Low End,VCA Punch,Dynamic Tame}>-Preset slider2:25<0,100,1>-Drift (%) slider3:0<-24,12,0.1>-Output (dB) slider4:0<-24,24,0.1>-Input (dB) slider5:100<0,100,1>-Mix (%) slider6:2<0,4,1{34 Hz,55 Hz,70 Hz,89 Hz,144 Hz}>-Crossover F1 slider10:0<0,2,1{P Program,S Console,D Dynamic}>-B1 EQ Type slider11:0<-12,12,0.1>-B1 EQ (dB) slider12:1<0,2,1{T Transistor,S Tape,X Transformer}>-B1 Drive Type slider13:0<0,100,1>-B1 Drive (%) slider14:0<0,2,1{O Opto,V VCA,R Gentle}>-B1 Comp Type slider15:0<0,100,1>-B1 Comp (%) slider16:0<-12,12,0.1>-B1 Gain (dB) slider17:0<0,1,1{Off,On}>-B1 Solo slider18:0<0,1,1{Off,On}>-B1 Mute slider20:0<0,2,1{P Program,S Console,D Dynamic}>-B2 EQ Type slider21:0<-12,12,0.1>-B2 EQ (dB) slider22:1<0,2,1{T Transistor,S Tape,X Transformer}>-B2 Drive Type slider23:0<0,100,1>-B2 Drive (%) slider24:0<0,2,1{O Opto,V VCA,R Gentle}>-B2 Comp Type slider25:0<0,100,1>-B2 Comp (%) slider26:0<-12,12,0.1>-B2 Gain (dB) slider27:0<0,1,1{Off,On}>-B2 Solo slider28:0<0,1,1{Off,On}>-B2 Mute slider30:0<0,2,1{P Program,S Console,D Dynamic}>-B3 EQ Type slider31:0<-12,12,0.1>-B3 EQ (dB) slider32:1<0,2,1{T Transistor,S Tape,X Transformer}>-B3 Drive Type slider33:0<0,100,1>-B3 Drive (%) slider34:0<0,2,1{O Opto,V VCA,R Gentle}>-B3 Comp Type slider35:0<0,100,1>-B3 Comp (%) slider36:0<-12,12,0.1>-B3 Gain (dB) slider37:0<0,1,1{Off,On}>-B3 Solo slider38:0<0,1,1{Off,On}>-B3 Mute slider40:0<0,2,1{P Program,S Console,D Dynamic}>-B4 EQ Type slider41:0<-12,12,0.1>-B4 EQ (dB) slider42:1<0,2,1{T Transistor,S Tape,X Transformer}>-B4 Drive Type slider43:0<0,100,1>-B4 Drive (%) slider44:0<0,2,1{O Opto,V VCA,R Gentle}>-B4 Comp Type slider45:0<0,100,1>-B4 Comp (%) slider46:0<-12,12,0.1>-B4 Gain (dB) slider47:0<0,1,1{Off,On}>-B4 Solo slider48:0<0,1,1{Off,On}>-B4 Mute @init // ===================================================================== // Constants & helpers // ===================================================================== nextmem = 0; function alloc(n) local(ptr) ( ptr = nextmem; nextmem += n; ptr; ); PHI = (1 + sqrt(5))/2; // 1.6180339... IPHI = 1/PHI; // 0.6180339... TWO_PI = 2*$pi; QBW = 0.70710678; // Butterworth Q (LR4 = two cascaded) function tanh(v) ( v = max(-20, min(20, v)); 1 - 2/(exp(2*v) + 1); ); function db2g(d) ( 10^(d/20); ); function cms(t) ( 1 - exp(-1/(max(0.00001, t)*srate)); ); // one-pole coefficient from seconds function softk(o, w) ( o <= -w*0.5 ? 0 : o >= w*0.5 ? o : (o + w*0.5)*(o + w*0.5)/(2*w); ); // ---- biquad: coefficients p[0..4], state p[5..8] (one block of 9 per channel) ---- function bq(x, p) local(y) ( y = p[0]*x + p[1]*p[5] + p[2]*p[6] - p[3]*p[7] - p[4]*p[8]; p[6] = p[5]; p[5] = x; p[8] = p[7]; p[7] = y; y; ); // coefficient setters (state untouched, so parameter moves never click) function sLP(p, f) local(w, c, al, a0) ( w = TWO_PI*f/srate; c = cos(w); al = sin(w)/(2*QBW); a0 = 1 + al; p[0] = (1 - c)*0.5/a0; p[1] = (1 - c)/a0; p[2] = (1 - c)*0.5/a0; p[3] = -2*c/a0; p[4] = (1 - al)/a0; ); function sHP(p, f) local(w, c, al, a0) ( w = TWO_PI*f/srate; c = cos(w); al = sin(w)/(2*QBW); a0 = 1 + al; p[0] = (1 + c)*0.5/a0; p[1] = -(1 + c)/a0; p[2] = (1 + c)*0.5/a0; p[3] = -2*c/a0; p[4] = (1 - al)/a0; ); function sAP(p, f) local(w, c, al, a0) ( w = TWO_PI*f/srate; c = cos(w); al = sin(w)/(2*QBW); a0 = 1 + al; p[0] = (1 - al)/a0; p[1] = -2*c/a0; p[2] = 1; p[3] = -2*c/a0; p[4] = (1 - al)/a0; ); function sBell(p, f, g, q) local(A, w, c, al, a0) ( A = 10^(g/40); w = TWO_PI*min(f, srate*0.45)/srate; c = cos(w); al = sin(w)/(2*q); a0 = 1 + al/A; p[0] = (1 + al*A)/a0; p[1] = -2*c/a0; p[2] = (1 - al*A)/a0; p[3] = -2*c/a0; p[4] = (1 - al/A)/a0; ); function sLS(p, f, g, q) local(A, w, c, al, sa, a0) ( A = 10^(g/40); w = TWO_PI*min(f, srate*0.45)/srate; c = cos(w); al = sin(w)/(2*q); sa = 2*sqrt(A)*al; a0 = (A + 1) + (A - 1)*c + sa; p[0] = A*((A + 1) - (A - 1)*c + sa)/a0; p[1] = 2*A*((A - 1) - (A + 1)*c)/a0; p[2] = A*((A + 1) - (A - 1)*c - sa)/a0; p[3] = -2*((A - 1) + (A + 1)*c)/a0; p[4] = ((A + 1) + (A - 1)*c - sa)/a0; ); function sHS(p, f, g, q) local(A, w, c, al, sa, a0) ( A = 10^(g/40); w = TWO_PI*min(f, srate*0.45)/srate; c = cos(w); al = sin(w)/(2*q); sa = 2*sqrt(A)*al; a0 = (A + 1) - (A - 1)*c + sa; p[0] = A*((A + 1) + (A - 1)*c + sa)/a0; p[1] = -2*A*((A - 1) + (A + 1)*c)/a0; p[2] = A*((A + 1) + (A - 1)*c - sa)/a0; p[3] = 2*((A - 1) - (A + 1)*c)/a0; p[4] = ((A + 1) - (A - 1)*c - sa)/a0; ); function sUnity(p) ( p[0] = 1; p[1] = 0; p[2] = 0; p[3] = 0; p[4] = 0; ); function cpy(p) ( p[9] = p[0]; p[10] = p[1]; p[11] = p[2]; p[12] = p[3]; p[13] = p[4]; ); // L coeffs -> R // ===================================================================== // Crossover (decadic) - 18 slots per filter: L = 0..8, R = 9..17 // ===================================================================== function xf1(i) ( i == 0 ? 34 : i == 1 ? 55 : i == 2 ? 70 : i == 3 ? 89 : 144; ); function xf3(f1) ( max(5000, min(10000, f1*100)); ); // top split: decadic, held to 5 - 10 kHz F1 = xf1(slider6); F2 = F1*10; F3 = xf3(F1); xo = alloc(18*17); memset(xo, 0, 18*17); lp1a = xo; lp1b = xo + 18; hp1a = xo + 36; hp1b = xo + 54; lp2a = xo + 72; lp2b = xo + 90; hp2a = xo + 108; hp2b = xo + 126; lp3a = xo + 144; lp3b = xo + 162; hp3a = xo + 180; hp3b = xo + 198; ap1_2 = xo + 216; ap1_3 = xo + 234; ap2_3 = xo + 252; // band alignment all-passes apd1 = xo + 270; apd2 = xo + 288; // dry path (+ apd3 below) apd3 = alloc(18); memset(apd3, 0, 18); function xset(p, kind, f) ( kind == 0 ? sLP(p, f) : kind == 1 ? sHP(p, f) : sAP(p, f); cpy(p); ); // (Re)build the crossover for the current F1 / F2 / F3 (filter states are kept) function xbuild() ( xset(lp1a, 0, F1); xset(lp1b, 0, F1); xset(hp1a, 1, F1); xset(hp1b, 1, F1); xset(lp2a, 0, F2); xset(lp2b, 0, F2); xset(hp2a, 1, F2); xset(hp2b, 1, F2); xset(lp3a, 0, F3); xset(lp3b, 0, F3); xset(hp3a, 1, F3); xset(hp3b, 1, F3); xset(ap1_2, 2, F2); xset(ap1_3, 2, F3); xset(ap2_3, 2, F3); xset(apd1, 2, F1); xset(apd2, 2, F2); xset(apd3, 2, F3); ); xbuild(); // Split x (channel offset co = 0 or 9) into globals xb1..xb4 and xdry function split(x, co) local(lo, hi, m2, h2) ( lo = bq(bq(x, lp1a + co), lp1b + co); hi = bq(bq(x, hp1a + co), hp1b + co); m2 = bq(bq(hi, lp2a + co), lp2b + co); h2 = bq(bq(hi, hp2a + co), hp2b + co); xb3 = bq(bq(h2, lp3a + co), lp3b + co); xb4 = bq(bq(h2, hp3a + co), hp3b + co); xb1 = bq(bq(lo, ap1_2 + co), ap1_3 + co); // through the 700 Hz and 7 kHz all-passes xb2 = bq(m2, ap2_3 + co); // through the 7 kHz all-pass xdry = bq(bq(bq(x, apd1 + co), apd2 + co), apd3 + co); ); // ===================================================================== // Per-band state // ===================================================================== // bp: 40 slots per band // 0 eqT 1 eqG 2 drT 3 drive d 4 cmT 5 cmp a 6 gain(lin) 7 active // 9 tape LP coef 10 thr 11 slope (1-1/ratio) 12 knee 13 atk 14 rel 15 makeup // 16 det coef 17 up slope 18 up cap 19 up thr 20 det ms 21 GR (dB, smoothed) // 22/23 VCA feedback L/R 24 D-EQ env 25 D-EQ counter 26 last eqG 27 last eqT // 28 thr base 29 drift wander 30 band out meter 31 drive base 32 eq centre freq bp = alloc(160); memset(bp, 0, 160); eqA = alloc(72); eqB = alloc(72); memset(eqA, 0, 72); memset(eqB, 0, 72); ds = alloc(64); memset(ds, 0, 64); // drive state: 8 per band per channel rgs = alloc(12); memset(rgs, 0, 12); // drift random generators (3 per band) // Band EQ centres (decadic + phi) - recomputed when the crossover changes function eqcentres() ( bp[32] = F1*IPHI; bp[72] = sqrt(F1*F2); bp[112] = sqrt(F2*F3); bp[152] = F3*PHI; ); eqcentres(); lastX = slider6; // EQ coefficients for band b (type t, gain g) on both channels function eqset(b, t, g) local(pa, pq, fc) ( pa = eqA + b*18; pq = eqB + b*18; fc = bp[b*40 + 32]; sUnity(pq); t == 0 ? ( // P: program / passive-style b == 0 ? ( sLS(pa, fc, g, QBW); g > 0 ? sBell(pq, fc*PHI, -g/(PHI*PHI), IPHI); ) : b == 3 ? ( sHS(pa, fc, g, QBW); g > 0 ? sBell(pq, fc*IPHI, -g/(PHI*PHI), IPHI); ) : ( sBell(pa, fc, g, IPHI); ); ) : ( // S / D: console shape b == 0 ? sLS(pa, fc, g, PHI) : b == 3 ? sHS(pa, fc, g, PHI) : sBell(pa, fc, g, PHI*(1 + abs(g)/12)); ); cpy(pa); cpy(pq); ); b = 0; loop(4, eqset(b, 0, 0); b += 1; ); // Smoothed random (drift): p[0] countdown, p[1] target, p[2] value function rgen(p, period) ( p[0] -= 1; p[0] <= 0 ? ( p[0] = period*srate; p[1] = rand(2) - 1; ); p[2] += cms(period)*(p[1] - p[2]); p[2]; ); // ---- Drive: t 0 Transistor, 1 Tape, 2 Transformer; d = drive multiplier; st = 8-slot state ---- function drive(x, t, d, st, lpc) local(u, y, lo, ul, dir) ( t == 0 ? ( u = x*d; y = u/((1 + u*u*u*u)^0.25); // hard-ish, odd-order ) : t == 1 ? ( dir = x >= st[0] ? 1 : -1; st[0] = x; // hysteresis: rising saturates earlier u = x*d*(1 + 0.05*dir*(d - 1)/9); y = tanh(u + 0.15*u*u); // asymmetric soft saturation st[2] = y - st[1] + 0.9995*st[2]; st[1] = y; y = st[2]; // DC block st[3] += lpc*(y - st[3]); y = st[3]; // HF roll-off with drive ) : ( st[4] += xfLp*(x - st[4]); lo = st[4]; // iron: lows saturate hardest ul = max(-1.5, min(1.5, lo*d*PHI)); y = (ul - ul*ul*ul/6.75)*IPHI + tanh((x - lo)*d); ); y/(1 + 0.6*(d - 1)); ); // ===================================================================== // Presets // ===================================================================== function pb(b, eqt, eqg, drt, dra, cmt, cma, gn) local(i) ( i = 10 + b*10; slider(i) = eqt; slider(i + 1) = eqg; slider(i + 2) = drt; slider(i + 3) = dra; slider(i + 4) = cmt; slider(i + 5) = cma; slider(i + 6) = gn; slider(i + 7) = 0; slider(i + 8) = 0; ); // eq: 0 P 1 S 2 D | drive: 0 T 1 S 2 X | comp: 0 O 1 V 2 R function apply_preset(n) ( slider2 = 25; slider3 = 0; slider4 = 0; slider5 = 100; pb(0, 0, 0, 1, 0, 0, 0, 0); pb(1, 0, 0, 1, 0, 0, 0, 0); pb(2, 0, 0, 1, 0, 0, 0, 0); pb(3, 0, 0, 1, 0, 0, 0, 0); n == 1 ? ( // Golden Glue pb(0, 0, 0, 1, 15, 2, 30, 0); pb(1, 0, 0, 1, 15, 2, 30, 0); pb(2, 0, 0, 1, 15, 2, 30, 0); pb(3, 0, 0, 1, 10, 2, 30, 0); ) : n == 2 ? ( // Tape Polish pb(0, 0, 1.5, 1, 20, 0, 15, 0); pb(1, 0, 0, 1, 25, 0, 15, 0); pb(2, 0, 0, 1, 20, 0, 15, 0); pb(3, 0, 1.5, 1, 10, 0, 15, 0); ) : n == 3 ? ( // Opto Smooth pb(0, 0, 0, 1, 0, 0, 40, 0); pb(1, 0, 0, 1, 0, 0, 40, 0); pb(2, 0, 0, 1, 0, 0, 40, 0); pb(3, 0, 0, 1, 0, 0, 40, 0); ) : n == 4 ? ( // Air Lift pb(2, 1, 1.0, 1, 0, 0, 0, 0); pb(3, 0, 4.0, 1, 15, 2, 25, 0); ) : n == 5 ? ( // Iron Low End pb(0, 0, 2.5, 2, 45, 0, 30, 0); pb(1, 1, -1.5, 2, 20, 0, 0, 0); ) : n == 6 ? ( // VCA Punch pb(0, 0, 0, 1, 0, 1, 35, 0); pb(1, 0, 0, 0, 10, 1, 45, 0); pb(2, 0, 0, 1, 0, 1, 35, 0); ) : n == 7 ? ( // Dynamic Tame pb(1, 2, -2, 1, 0, 0, 15, 0); pb(2, 2, -5, 1, 0, 0, 15, 0); pb(3, 2, -4, 1, 0, 0, 15, 0); ); ); // Meters / GUI state vuL = 0; vuR = 0; mOut = 0; mLim = 0; limEnv = 0; limRel = exp(-1/(0.15*srate)); vuC = cms(0.3); xfLp = 1 - exp(-TWO_PI*F1*PHI/srate); // transformer low split: F1 * PHI vnd = alloc(2); memset(vnd, 0, 2); // VU needle positions (GUI) drag_id = -1; pcap = 0; lastS = 0; gfx_ext_retina = 1; q_init == 0 ? ( lastPreset = slider1; ui_sz = 2; ui_szinit = 1; q_init = 1; ); @serialize file_var(0, ui_sz); file_var(0, ui_szinit); file_var(0, lastPreset); // added later: older projects end here, so they keep the defaults (yellow, flat) file_avail(0) != 0 ? ( file_var(0, ui_hw); file_var(0, au_thm); ); @slider slider1 != lastPreset ? ( apply_preset(slider1); lastPreset = slider1; ); @block dr = slider2/100; outG = db2g(slider3); inG = db2g(slider4); // Crossover picker: rebuild filters, EQ centres and transformer split when F1 changes slider6 != lastX ? ( lastX = slider6; F1 = xf1(slider6); F2 = F1*10; F3 = xf3(F1); xbuild(); eqcentres(); xfLp = 1 - exp(-TWO_PI*F1*PHI/srate); b = 0; loop(4, bp[b*40 + 26] = -999; b += 1; ); // force EQ recalculation ); mixW = slider5/100; anySolo = slider17 || slider27 || slider37 || slider47; b = 0; loop(4, i = 10 + b*10; p = bp + b*40; p[0] = floor(slider(i) + 0.5); p[1] = slider(i + 1); p[2] = floor(slider(i + 2) + 0.5); p[3] = 1 + 0.09*slider(i + 3); // drive multiplier 1..10 p[4] = floor(slider(i + 4) + 0.5); p[5] = slider(i + 5)/100; p[6] = db2g(slider(i + 6)); p[7] = slider(i + 8) > 0.5 ? 0 : (anySolo && slider(i + 7) < 0.5) ? 0 : 1; // mute / solo p[9] = 1 - exp(-TWO_PI*min(srate*0.45, 20000/(1 + 0.12*(p[3] - 1)))/srate); // tape HF roll-off // EQ (D type is refreshed in @sample) (p[0] != 2 && (p[1] != p[26] || p[0] != p[27])) ? ( eqset(b, p[0], p[1]); p[26] = p[1]; p[27] = p[0]; ); p[0] == 2 && p[27] != 2 ? ( p[27] = 2; p[26] = -999; ); // Compressor: thresholds, ratios, knees and phi timings a = p[5]; p[28] = -6 - 30*a; atk = 0.030/(PHI^b); rel = atk*(PHI^5); p[4] == 0 ? ( // Opto: smooth, RMS, slower p[11] = 1 - 1/(PHI^(2*a)); p[12] = 12*PHI; atk *= PHI; rel *= PHI; p[16] = cms(0.010*PHI); ) : p[4] == 1 ? ( // VCA: feedback, fast, firm knee p[11] = 1 - 1/(PHI^(3*a)); p[12] = 6*IPHI; atk *= IPHI*IPHI; rel *= IPHI; p[16] = cms(0.0005); ) : ( // Gentle: three gentle stages, RMS, program-dependent release p[11] = 1 - 1/(PHI^(3*a)); p[12] = 6*PHI; p[16] = cms(0.005*PHI); ); p[13] = cms(atk); p[14] = cms(rel); p[15] = 0.5*p[11]*max(0, -18 - p[28]); // half auto-makeup (all types) b += 1; ); @sample spl0 != spl0 ? spl0 = 0; spl1 != spl1 ? spl1 = 0; inL = spl0*inG; inR = spl1*inG; outL = 0; outR = 0; split(inL, 0); aL1 = xb1; aL2 = xb2; aL3 = xb3; aL4 = xb4; dryL = xdry; split(inR, 9); aR1 = xb1; aR2 = xb2; aR3 = xb3; aR4 = xb4; dryR = xdry; b = 0; loop(4, p = bp + b*40; yl = b == 0 ? aL1 : b == 1 ? aL2 : b == 2 ? aL3 : aL4; yr = b == 0 ? aR1 : b == 1 ? aR2 : b == 2 ? aR3 : aR4; // ---- EQ ---- p[0] == 2 ? ( // D: gain follows band energy above -30 dB over a 12*PHI dB range (refreshed every 16 samples) p[24] += (max(abs(yl), abs(yr)) > sqrt(p[24]) ? p[13] : p[14])*(yl*yl + yr*yr - p[24]); (p[25] -= 1) <= 0 ? ( p[25] = 16; ed = p[24] > 0.00000001 ? 10*log10(p[24]) : -160; eqset(b, 2, p[1]*max(0, min(1, (ed + 30)/(12*PHI)))); ); ); yl = bq(bq(yl, eqA + b*18), eqB + b*18); yr = bq(bq(yr, eqA + b*18 + 9), eqB + b*18 + 9); // ---- DRIVE ---- p[3] > 1.0001 ? ( yl = drive(yl, p[2], p[3], ds + b*16, p[9]); yr = drive(yr, p[2], p[3], ds + b*16 + 8, p[9]); ); // ---- COMP ---- p[5] > 0 ? ( det = p[4] == 1 ? max(abs(p[22]), abs(p[23])) : max(abs(yl), abs(yr)); // VCA = feedback p[20] += p[16]*(det*det - p[20]); ldb = p[20] > 0.00000000001 ? 10*log10(p[20]) : -140; thr = p[28] + 3*dr*p[29]; // phi-breathing threshold p[4] == 2 ? ( // Gentle: three stages 6 dB apart, each a third of the slope gr = -(p[11]/3)*(softk(ldb - (thr + 6), p[12]) + softk(ldb - thr, p[12]) + softk(ldb - (thr - 6), p[12])); ) : ( gr = -p[11]*softk(ldb - thr, p[12]); ); // release: Opto slows as reduction deepens; Gentle adapts more gently; VCA fixed c = gr < p[21] ? p[13] : p[4] == 0 ? p[14]/(1 + PHI*abs(p[21])/6) : p[4] == 2 ? p[14]/(1 + abs(p[21])/(6*PHI)) : p[14]; p[21] += c*(gr - p[21]); g = db2g(p[21] + p[15]); yl *= g; yr *= g; p[22] = yl; p[23] = yr; ) : ( p[21] = 0; ); // ---- band gain, solo / mute ---- yl *= p[6]*p[7]; yr *= p[6]*p[7]; p[30] = max(p[30]*0.9995, max(abs(yl), abs(yr))); outL += yl; outR += yr; b += 1; ); // phi-breathing: each band wanders on its own period, 3 s * PHI^band bp[29] = rgen(rgs, 3); bp[69] = rgen(rgs + 3, 3*PHI); bp[109] = rgen(rgs + 6, 3*PHI*PHI); bp[149] = rgen(rgs + 9, 3*PHI*PHI*PHI); // ---- master ---- oL = (dryL*(1 - mixW) + outL*mixW)*outG; oR = (dryR*(1 - mixW) + outR*mixW)*outG; pk = max(abs(oL), abs(oR)); limEnv = pk > limEnv ? pk : limEnv*limRel; lg = limEnv > 0.966 ? 0.966/limEnv : 1; oL *= lg; oR *= lg; spl0 = max(-1, min(1, oL)); spl1 = max(-1, min(1, oR)); vuL += vuC*(spl0*spl0 - vuL); vuR += vuC*(spl1*spl1 - vuR); mLim = lg < 0.98 ? 1 : mLim*0.9995; @gfx 1680 504 // ===================================================================== // GUI - yellow rack faceplate, 1600 x 480 design space. // Size picker: S 75% / M 90% / L 105% (shrinks further if the window is smaller). // Knobs: drag vertically (Shift = fine), double-click or Ctrl-click = reset. // The LCD shows the preset, or the parameter you are touching. // ===================================================================== szf = ui_sz == 1 ? 0.75 : ui_sz == 2 ? 1.05 : 0.9; S = min(szf, min(gfx_w/1600, gfx_h/480)); ox = floor((gfx_w - 1600*S)*0.5); oy = floor((gfx_h - 480*S)*0.5); mx = (mouse_x - ox)/S; my = (mouse_y - oy)/S; // the ? pop-up is modal: while it is open the panel underneath takes no clicks hlp ? ( (mouse_cap & 1) && !(pcap & 1) && !hlp_new ? hlp = 0; pcap = mouse_cap; ); hlp_new = 0; S != lastS ? ( gfx_setfont(1, "Arial Black", max(10, 44*S)); // AUREUS gfx_setfont(2, "Arial Bold", max(9, 18*S)); // band titles gfx_setfont(3, "Arial Bold", max(7, 13*S)); // labels gfx_setfont(4, "Arial Bold", max(7, 12*S)); // values gfx_setfont(5, "Arial Bold", max(7, 12*S)); // small print gfx_setfont(6, "Arial Bold", max(8, 15*S)); // selector letters / buttons gfx_setfont(7, "Courier New", max(9, 24*S), 'b'); // LCD line 2 gfx_setfont(8, "Courier New", max(7, 13*S), 'b'); // LCD line 1 gfx_setfont(9, "Arial Bold", max(6, 9*S)); // VU scale lastS = S; ); // ---- palette: YELLOW (black print) or PETROL TEAL (cream print); HW adds the hardware finish ---- hw = ui_hw; !au_thm ? ( Y_R = 0.98; Y_G = 0.80; Y_B = 0.10; // faceplate yellow K_R = 0.07; K_G = 0.07; K_B = 0.07; // black ink A_R = 0.62; A_G = 0.42; A_B = 0.02; // knob value arc ) : ( Y_R = 0.184; Y_G = 0.369; Y_B = 0.353; // faceplate petrol teal K_R = 0.910; K_G = 0.878; K_B = 0.796; // lime white ink (#E8E0CB) A_R = 0.98; A_G = 0.72; A_B = 0.24; // knob value arc (amber) ); // ---- helpers (design-space coordinates) ---- function col(r, g, b) ( gfx_r = r; gfx_g = g; gfx_b = b; ); function cyel() ( col(Y_R, Y_G, Y_B); ); function cblk() ( col(K_R, K_G, K_B); ); function R(x, y, w, h) ( gfx_rect(ox + x*S, oy + y*S, max(1, w*S), max(1, h*S)); ); function RO(x, y, w, h) local(t, k) ( t = max(1, floor(2*S + 0.5)); k = 0; loop(t, gfx_rect(ox + x*S + k, oy + y*S + k, max(1, w*S - 2*k), max(1, h*S - 2*k), 0); k += 1; ); ); function LN(x1, y1, x2, y2) ( gfx_line(ox + x1*S, oy + y1*S, ox + x2*S, oy + y2*S, 1); ); function TX(x, y, txt) ( gfx_x = ox + x*S; gfx_y = oy + y*S; gfx_drawstr(txt); ); function TC(cx, y, txt) local(w, h) ( gfx_measurestr(txt, w, h); gfx_x = ox + cx*S - w*0.5; gfx_y = oy + y*S; gfx_drawstr(txt); ); function TR(rx, y, txt) local(w, h) ( gfx_measurestr(txt, w, h); gfx_x = ox + rx*S - w; gfx_y = oy + y*S; gfx_drawstr(txt); ); function CIRC(x, y, rr, fill) ( gfx_circle(ox + x*S, oy + y*S, rr*S, fill, 1); ); function clicked(x, y, w, h) ( (mouse_cap & 1) && !(pcap & 1) && mx >= x && mx <= x+w && my >= y && my <= y+h; ); function cnear() ( col(0.07, 0.07, 0.07); ); // stays black in every theme (meters, wells) function setk(idx, v) ( slider(idx) != v ? ( slider(idx) = v; slider_automate(2^(idx - 1)); ); ); // HW: a raised bevel (light top-left, dark bottom-right); inset = 1 for a recess function bev(x, y, w, h, inset) ( gfx_a = au_thm ? 0.18 : 0.30; inset ? col(0, 0, 0) : col(1, 1, 1); R(x, y, w, 1.5); R(x, y, 1.5, h); inset ? col(1, 1, 1) : col(0, 0, 0); R(x, y + h - 1.5, w, 1.5); R(x + w - 1.5, y, 1.5, h); gfx_a = 1; ); function screw(x, y) ( col(0.55, 0.55, 0.57); CIRC(x, y, 7, 1); col(0.25, 0.25, 0.27); CIRC(x, y, 7, 0); LN(x - 4, y + 4, x + 4, y - 4); ); // Button: on = black with yellow text; off = yellow with black outline. red = 1 for MUTE (on = red) function btn(x, y, w, h, lbl, on, fnt, red) local(sw, sh) ( hw ? ( gfx_a = 0.35; col(0, 0, 0); R(x + 1, y + 2.5, w, h); gfx_a = 1; ); on ? ( red ? col(0.86, 0.14, 0.10) : cblk(); ) : cyel(); R(x, y, w, h); hw ? ( gfx_a = (on ? 0.10 : 0.22)*(au_thm ? 0.4 : 1); col(1, 1, 1); R(x + 2, y + 2, w - 4, h*0.42); gfx_a = 1; bev(x, y, w, h, on); ); cblk(); RO(x, y, w, h); on ? ( red ? col(1, 1, 1) : cyel(); ) : cblk(); gfx_setfont(fnt); gfx_measurestr(lbl, sw, sh); gfx_x = ox + (x + w*0.5)*S - sw*0.5; gfx_y = oy + (y + h*0.5)*S - sh*0.5; gfx_drawstr(lbl); clicked(x, y, w, h); ); // Section frame with a black title tab function frame(x, y, w, h, title) ( cblk(); RO(x, y, w, h); title != 0 ? ( gfx_setfont(5); gfx_measurestr(title, fw_, fh_); R(x + 10, y - 7, fw_/S + 14, 14); cyel(); TX(x + 17, y - 6, title); ); ); // Black knob with printed scale. bip = bipolar (centre tick), def = reset value. function knob(id, cx, cy, rad, v, vmin, vmax, bip, def) local(dx, dy, fr, nf, ang, sx, sy, sr, k, t, ca, sa, ta) ( fr = (v - vmin)/(vmax - vmin); dx = mx - cx; dy = my - cy; kn_hot = drag_id == id || (dx*dx + dy*dy) < (rad*rad*1.6); // house style: values show on hover / drag only (mouse_cap & 1) && !(pcap & 1) && drag_id == -1 && (dx*dx + dy*dy) < (rad*rad*1.6) ? ( ((mouse_cap & 4) || (kc_id == id && time_precise() - kc_t < 0.35)) ? ( v = def; kc_t = 0; k_rst = id; ) : ( drag_id = id; drag_sy = my; drag_sf = fr; kc_id = id; kc_t = time_precise(); ); ); drag_id == id ? ( (mouse_cap & 1) ? ( nf = max(0, min(1, drag_sf + (drag_sy - my)/((mouse_cap & 8) ? 720 : 180))); v = vmin + nf*(vmax - vmin); ) : drag_id = -1; ); fr = (v - vmin)/(vmax - vmin); ang = (-0.75 + 1.5*fr)*$pi; sx = ox + cx*S; sy = oy + cy*S; sr = rad*S; // printed scale: 11 ticks, longer at the ends (and centre for bipolar) cblk(); k = 0; loop(11, ta = (-0.75 + 1.5*k/10)*$pi; t = (k == 0 || k == 10 || (bip && k == 5)) ? 9 : 5; gfx_line(sx + sin(ta)*(sr + 4*S), sy - cos(ta)*(sr + 4*S), sx + sin(ta)*(sr + (4 + t)*S), sy - cos(ta)*(sr + (4 + t)*S), 1); k += 1; ); // value marker: small yellow-on-black dot track of the travelled arc col(A_R, A_G, A_B); k = 0; loop(max(2, floor(3*S + 0.5)), gfx_arc(sx, sy, sr + 2*S + k, bip ? min(0, ang) : -0.75*$pi, bip ? max(0, ang) : ang, 1); k += 1; ); // body: skirt, knurled edge, cap, highlight (HW: a drop shadow and a domed cap) hw ? ( gfx_a = 0.45; col(0, 0, 0); gfx_circle(sx + 2*S, sy + 4*S, sr, 1, 1); gfx_a = 1; ); col(0.03, 0.03, 0.03); gfx_circle(sx, sy, sr, 1, 1); col(0.20, 0.20, 0.21); k = 0; loop(28, ta = k*2*$pi/28; gfx_line(sx + sin(ta)*sr*0.82, sy - cos(ta)*sr*0.82, sx + sin(ta)*(sr - 1), sy - cos(ta)*(sr - 1), 1); k += 1; ); kc_r >= 0 ? ( col(kc_r*0.7, kc_g*0.7, kc_b*0.7); gfx_circle(sx, sy, sr*0.76, 1, 1); col(kc_r, kc_g, kc_b); gfx_circle(sx, sy, sr*0.72, 1, 1); col(min(1, kc_r + 0.22), min(1, kc_g + 0.22), min(1, kc_b + 0.22)); gfx_circle(sx - sr*0.2, sy - sr*0.24, sr*0.2, 1, 1); ) : ( col(0.11, 0.11, 0.12); gfx_circle(sx, sy, sr*0.74, 1, 1); col(0.22, 0.22, 0.24); gfx_circle(sx - sr*0.2, sy - sr*0.24, sr*0.2, 1, 1); ); // white pointer col(0.97, 0.97, 0.95); sa = sin(ang); ca = cos(ang); t = max(2, floor(4*S + 0.5)); k = 0; loop(t, gfx_line(sx + sa*sr*0.2 + ca*(k - t*0.5), sy - ca*sr*0.2 + sa*(k - t*0.5), sx + sa*sr*0.95 + ca*(k - t*0.5), sy - ca*sr*0.95 + sa*(k - t*0.5), 1); k += 1; ); v; ); function touch(id, name, val) ( (drag_id == id || k_rst == id) ? ( strcpy(#lcdn, name); strcpy(#lcdv, val); lcd_t = time_precise(); k_rst == id ? k_rst = -1; ); ); function fpct(v) ( sprintf(#vt, "%d%%", floor(v + 0.5)); #vt; ); function fdb(v) local(q) ( q = floor(v*10 + 0.5)/10; q > 0 ? sprintf(#vt, "+%.1f dB", q) : q < 0 ? sprintf(#vt, "%.1f dB", q) : strcpy(#vt, "0.0 dB"); #vt; ); // Frequency as "34", "340", "3.4k", "14.4k" into the given string function fq(f, dst) ( f >= 1000 ? sprintf(dst, "%.3gk", f/1000) : sprintf(dst, "%d", f); dst; ); function pname(n) ( n == 0 ? "INIT" : n == 1 ? "GOLDEN GLUE" : n == 2 ? "TAPE POLISH" : n == 3 ? "OPTO SMOOTH" : n == 4 ? "AIR LIFT" : n == 5 ? "IRON LOW END" : n == 6 ? "VCA PUNCH" : "DYNAMIC TAME"; ); function step_preset(dir) ( slider1 = (slider1 + dir + 8) % 8; apply_preset(slider1); lastPreset = slider1; lcd_t = 0; slider_automate(281474976710655); // sliders 1-48 ); // VU meter: face at (x, y), 230 x 112; v = mean-square level; nd = needle state slot function vu(x, y, v, lbl, np) local(db, pos, a, px_, py_, k, tv, tp, rr, cxv, cyv) ( // bezel + face cnear(); R(x - 4, y - 4, 238, 120); col(0.99, 0.93, 0.62); R(x, y, 230, 112); col(1.0, 0.97, 0.78); R(x + 6, y + 6, 218, 40); cxv = x + 115; cyv = y + 150; rr = 122; // scale: VU values placed on a voltage scale k = 0; loop(10, tv = k == 0 ? -20 : k == 1 ? -10 : k == 2 ? -7 : k == 3 ? -5 : k == 4 ? -3 : k == 5 ? -1 : k == 6 ? 0 : k == 7 ? 1 : k == 8 ? 2 : 3; tp = (10^(tv/20) - 0.1)/(10^(3/20) - 0.1); a = (-48 + 96*tp)*$pi/180; tv >= 0 ? col(0.80, 0.10, 0.08) : cnear(); gfx_line(ox + (cxv + sin(a)*rr)*S, oy + (cyv - cos(a)*rr)*S, ox + (cxv + sin(a)*(rr - 9))*S, oy + (cyv - cos(a)*(rr - 9))*S, 1); gfx_setfont(9); sprintf(#vut, tv > 0 ? "+%d" : "%d", tv); TC(cxv + sin(a)*(rr + 9), cyv - cos(a)*(rr + 9) - 6, #vut); k += 1; ); // red zone arc col(0.80, 0.10, 0.08); k = 0; loop(max(2, floor(3*S + 0.5)), gfx_arc(ox + cxv*S, oy + cyv*S, (rr - 4)*S + k, (-48 + 96*(1 - 0.1)/(10^(3/20) - 0.1))*$pi/180, 48*$pi/180, 1); k += 1; ); cnear(); gfx_setfont(3); TC(cxv, y + 76, "VU"); gfx_setfont(5); TX(x + 8, y + 94, lbl); // needle (0 VU = -18 dBFS RMS), simple ballistics per frame db = v > 0.000000001 ? 10*log10(v) + 18 : -40; pos = max(-0.04, min(1.06, (10^(max(-30, db)/20) - 0.1)/(10^(3/20) - 0.1))); np[0] += 0.35*(pos - np[0]); a = (-48 + 96*np[0])*$pi/180; cnear(); gfx_line(ox + cxv*S, oy + (y + 110)*S, ox + (cxv + sin(a)*(rr - 2))*S, oy + (cyv - cos(a)*(rr - 2))*S, 1); gfx_line(ox + cxv*S + 1, oy + (y + 110)*S, ox + (cxv + sin(a)*(rr - 2))*S + 1, oy + (cyv - cos(a)*(rr - 2))*S, 1); // pivot cover, then (HW) glass cnear(); R(x, y + 104, 230, 8); hw ? ( gfx_a = 0.10; col(1, 1, 1); gfx_triangle(ox + x*S, oy + y*S, ox + (x + 150)*S, oy + y*S, ox + x*S, oy + (y + 80)*S); gfx_a = 1; ); ); // ===================================================================== // Draw // ===================================================================== col(0.10, 0.10, 0.10); gfx_rect(0, 0, gfx_w, gfx_h); // chassis around the faceplate kc_r = -1; cyel(); R(0, 0, 1600, 480); hw ? ( // brushed enamel: fine streaks and a soft top light k = 0; loop(240, hv = sin(k*12.9898)*43758.5453; hv -= floor(hv); gfx_a = 0.025 + 0.035*hv; hv > 0.5 ? col(1, 1, 1) : col(0, 0, 0); R(44, k*2, 1512, 1); k += 1; ); gfx_a = 1; gfx_gradrect(ox, oy, 1600*S, 200*S, 1, 1, 1, 0.10, 0, 0, 0, 0, 0, 0, 0, -0.10/(200*S)); gfx_gradrect(ox, oy + 330*S, 1600*S, 150*S, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.16/(150*S)); bev(0, 0, 1600, 480, 0); ); // rack ears: yellow with black border, slots and a tube icon ex = 0; loop(2, exx = ex == 0 ? 0 : 1556; cblk(); RO(exx, 0, 44, 480); ey = 0; loop(2, eyy = ey == 0 ? 60 : 420; cblk(); CIRC(exx + 16, eyy, 7, 1); CIRC(exx + 28, eyy, 7, 1); R(exx + 16, eyy - 7, 12, 14); ey += 1; ); // tube icon cblk(); RO(exx + 12, 200, 20, 80); RO(exx + 16, 212, 12, 46); LN(exx + 18, 264, exx + 18, 276); LN(exx + 26, 264, exx + 26, 276); ex += 1; ); cblk(); R(44, 0, 1512, 3); R(44, 477, 1512, 3); // ---- Left: brand, LCD, presets, size ---- cblk(); gfx_setfont(1); TX(60, 18, "AUREUS"); gfx_setfont(5); TX(64, 76, "MULTIBAND PROCESSOR"); cnear(); R(60, 104, 266, 92); col(0.07, 0.05, 0.02); R(64, 108, 258, 84); hw ? ( bev(58, 102, 270, 96, 1); gfx_a = 0.07; col(1, 1, 1); R(64, 108, 258, 30); gfx_a = 1; ); col(1.0, 0.68, 0.15); time_precise() - lcd_t < 1.5 ? ( gfx_setfont(8); TX(76, 118, #lcdn); gfx_setfont(7); TX(76, 146, #lcdv); ) : ( gfx_setfont(8); sprintf(#lcd1, "PRESET %02d/08", slider1 + 1); TX(76, 118, #lcd1); gfx_setfont(7); TX(76, 146, pname(slider1)); ); // PRESETS key or a click on the LCD: drop-down menu of all presets (current one ticked) pm_ = btn(60, 210, 130, 36, "PRESETS", 0, 6, 0); clicked(60, 104, 266, 92) || pm_ ? ( strcpy(#pmenu, ""); k = 0; loop(8, k == slider1 ? strcat(#pmenu, "!"); strcat(#pmenu, pname(k)); k < 7 ? strcat(#pmenu, "|"); k += 1; ); gfx_x = mouse_x; gfx_y = mouse_y; psel = gfx_showmenu(#pmenu); psel > 0 ? ( slider1 = psel - 1; apply_preset(slider1); lastPreset = slider1; lcd_t = 0; slider_automate(281474976710655); ); ); btn(198, 210, 60, 36, "◄", 0, 6, 0) ? step_preset(-1); btn(266, 210, 60, 36, "►", 0, 6, 0) ? step_preset(1); cblk(); gfx_setfont(5); TX(60, 270, "SIZE"); btn(60, 286, 48, 30, "S", ui_sz == 1, 6, 0) ? ui_sz = 1; btn(114, 286, 48, 30, "M", ui_sz == 0, 6, 0) ? ui_sz = 0; btn(168, 286, 48, 30, "L", ui_sz == 2, 6, 0) ? ui_sz = 2; btn(222, 286, 30, 30, "?", hlp, 6, 0) ? ( hlp = 1; hlp_new = 1; ); // INPUT trim beside the size picker setk(4, knob(94, 284, 300, 16, slider4, -24, 24, 1, 0)); cblk(); gfx_setfont(5); TC(284, 258, "INPUT"); gfx_setfont(4); kn_hot ? TC(284, 330, fdb(slider4)); touch(94, "INPUT", fdb(slider4)); // Crossover picker: F1 (x10, x100). Fibonacci 34 / 55 / 89 / 144 (steps ~ x phi) + classic 70 cblk(); gfx_setfont(5); TX(60, 352, "CROSSOVER F1 x10 x100"); k = 0; loop(5, btn(60 + k*54, 368, 48, 30, k == 0 ? "34" : k == 1 ? "55" : k == 2 ? "70" : k == 3 ? "89" : "144", slider6 == k, 4, 0) ? ( setk(6, k); strcpy(#lcdn, "CROSSOVERS"); xv = k == 0 ? 34 : k == 1 ? 55 : k == 2 ? 70 : k == 3 ? 89 : 144; sprintf(#lcdv, "%s/%s/%s", fq(xv, #fa), fq(xv*10, #fb), fq(xf3(xv), #fc)); lcd_t = time_precise(); ); k += 1; ); cblk(); gfx_setfont(3); TX(60, 404, "φ = 1.618034"); gfx_setfont(5); TX(60, 422, "FIBONACCI SPLITS LR4"); screw(312, 452); btn(60, 440, 48, 26, "HW", hw, 4, 0) ? ui_hw = !ui_hw; btn(114, 440, 74, 26, au_thm ? "TEAL" : "GOLD", 0, 4, 0) ? au_thm = !au_thm; // ---- Four bands ---- bb = 0; loop(4, bx = 345 + bb*240; base = 10 + bb*10; bq_ = bp + bb*40; // frame + header tab hw ? ( gfx_a = 0.12; col(0, 0, 0); R(bx, 20, 230, 440); gfx_a = 1; bev(bx - 2, 18, 234, 444, 1); ); cblk(); RO(bx, 20, 230, 440); R(bx, 20, 230, 34); cyel(); gfx_setfont(2); TX(bx + 12, 27, bb == 0 ? "SUB" : bb == 1 ? "LOW-MID" : bb == 2 ? "HIGH-MID" : F3 < 6500 ? "PRESENCE" : "AIR"); gfx_setfont(5); bb == 0 ? sprintf(#rng, "< %s Hz", fq(F1, #fa)) : bb == 1 ? sprintf(#rng, "%s - %s Hz", fq(F1, #fa), fq(F2, #fb)) : bb == 2 ? sprintf(#rng, "%s - %s Hz", fq(F2, #fa), fq(F3, #fb)) : sprintf(#rng, "> %s Hz", fq(F3, #fa)); TR(bx + 200, 32, #rng); // activity LED: off / green / red near clip lvl = bq_[30]; lvl > 0.89 ? col(1.0, 0.18, 0.10) : lvl > 0.01 ? col(0.25, 0.95, 0.30) : col(0.12, 0.25, 0.12); CIRC(bx + 216, 37, 6, 1); // three rows: EQ / DRIVE / COMP (HW: band-coloured caps - SUB brown, LOW-MID blue, HIGH-MID green, AIR red) hw ? ( bb == 0 ? ( kc_r = 0.55; kc_g = 0.35; kc_b = 0.17; ) : bb == 1 ? ( kc_r = 0.24; kc_g = 0.44; kc_b = 0.80; ) : bb == 2 ? ( kc_r = 0.20; kc_g = 0.63; kc_b = 0.32; ) : ( kc_r = 0.82; kc_g = 0.18; kc_b = 0.16; ); ); rw = 0; loop(3, y0 = 60 + rw*92; rw > 0 ? ( cblk(); R(bx + 10, y0 - 2, 196, 2); ); ti = base + rw*2; // type slider index vi = ti + 1; // amount slider index tsel = floor(slider(ti) + 0.5); cblk(); gfx_setfont(3); TX(bx + 12, y0 + 6, rw == 0 ? "EQ" : rw == 1 ? "DRIVE" : "COMP"); // one key per row: click to step through the three types; it shows the one in use btn(bx + 12, y0 + 26, 112, 28, rw == 0 ? (tsel == 0 ? "PROGRAM" : tsel == 1 ? "CONSOLE" : "DYNAMIC") : rw == 1 ? (tsel == 0 ? "TRANSISTOR" : tsel == 1 ? "TAPE" : "TRANSFORMER") : (tsel == 0 ? "OPTO" : tsel == 1 ? "VCA" : "GENTLE"), 1, 3, 0) ? ( k = (tsel + 1) % 3; setk(ti, k); strcpy(#lcdn, rw == 0 ? "EQ TYPE" : rw == 1 ? "DRIVE TYPE" : "COMP TYPE"); strcpy(#lcdv, rw == 0 ? (k == 0 ? "PROGRAM" : k == 1 ? "CONSOLE" : "DYNAMIC") : rw == 1 ? (k == 0 ? "TRANSISTOR" : k == 1 ? "TAPE" : "TRANSFORMER") : (k == 0 ? "OPTO" : k == 1 ? "VCA" : "GENTLE")); lcd_t = time_precise(); ); // knob rw == 0 ? ( setk(vi, knob(bb*10 + 1, bx + 162, y0 + 40, 25, slider(vi), -12, 12, 1, 0)); cblk(); gfx_setfont(4); kn_hot ? TC(bx + 162, y0 + 70, fdb(slider(vi))); touch(bb*10 + 1, bb == 0 ? "SUB EQ" : bb == 1 ? "LOW-MID EQ" : bb == 2 ? "HIGH-MID EQ" : "AIR EQ", fdb(slider(vi))); ) : ( setk(vi, knob(bb*10 + 1 + rw, bx + 162, y0 + 40, 25, slider(vi), 0, 100, 0, 0)); cblk(); gfx_setfont(4); kn_hot ? TC(bx + 162, y0 + 70, fpct(slider(vi))); touch(bb*10 + 1 + rw, rw == 1 ? (bb == 0 ? "SUB DRIVE" : bb == 1 ? "LOW-MID DRIVE" : bb == 2 ? "HIGH-MID DRIVE" : "AIR DRIVE") : (bb == 0 ? "SUB COMP" : bb == 1 ? "LOW-MID COMP" : bb == 2 ? "HIGH-MID COMP" : "AIR COMP"), fpct(slider(vi))); ); rw += 1; ); kc_r = -1; // GR ladder (0 .. -20 dB, top to bottom) grv = bq_[21]; cnear(); R(bx + 208, 62, 14, 266); k = 0; loop(14, ly = 66 + k*18.6; (-grv) >= (k + 0.5)*20/14 ? (k > 9 ? col(1.0, 0.18, 0.10) : col(1.0, 0.62, 0.08)) : col(0.25, 0.15, 0.04); R(bx + 211, ly, 8, 14); k += 1; ); cblk(); gfx_setfont(5); TC(bx + 215, 332, "GR"); // bottom row: band GAIN, SOLO, MUTE cblk(); R(bx + 10, 336, 196, 2); setk(base + 6, knob(bb*10 + 4, bx + 54, 386, 24, slider(base + 6), -12, 12, 1, 0)); cblk(); gfx_setfont(3); TC(bx + 54, 420, "GAIN"); gfx_setfont(4); kn_hot ? TC(bx + 54, 438, fdb(slider(base + 6))); touch(bb*10 + 4, bb == 0 ? "SUB GAIN" : bb == 1 ? "LOW-MID GAIN" : bb == 2 ? "HIGH-MID GAIN" : "AIR GAIN", fdb(slider(base + 6))); so = slider(base + 7) > 0.5; mu = slider(base + 8) > 0.5; btn(bx + 106, 366, 52, 34, "SOLO", so, 4, 0) ? setk(base + 7, !so); btn(bx + 164, 366, 52, 34, "MUTE", mu, 4, 1) ? setk(base + 8, !mu); bb += 1; ); // ---- Right: twin VUs + master ---- frame(1305, 20, 245, 262, "OUTPUT"); vu(1312, 34, vuL, "LEFT", vnd); vu(1312, 160, vuR, "RIGHT", vnd + 1); frame(1305, 300, 245, 160, "MASTER"); setk(2, knob(91, 1352, 352, 24, slider2, 0, 100, 0, 25)); cblk(); gfx_setfont(3); TC(1352, 386, "DRIFT"); gfx_setfont(4); kn_hot ? TC(1352, 404, fpct(slider2)); touch(91, "DRIFT (PHI)", fpct(slider2)); setk(5, knob(92, 1428, 352, 24, slider5, 0, 100, 0, 100)); cblk(); gfx_setfont(3); TC(1428, 386, "MIX"); gfx_setfont(4); kn_hot ? TC(1428, 404, fpct(slider5)); touch(92, "MIX", fpct(slider5)); setk(3, knob(93, 1504, 352, 24, slider3, -24, 12, 1, 0)); cblk(); gfx_setfont(3); TC(1504, 386, "OUTPUT"); gfx_setfont(4); kn_hot ? TC(1504, 404, fdb(slider3)); touch(93, "OUTPUT", fdb(slider3)); mLim > 0.5 ? col(1.0, 0.18, 0.10) : col(0.35, 0.08, 0.05); CIRC(1328, 438, 6, 1); cblk(); gfx_setfont(5); TX(1340, 432, "LIMIT"); screw(1530, 440); // ? pop-up: design credit and the manual hlp ? ( gfx_a = 0.62; col(0, 0, 0); gfx_rect(0, 0, gfx_w, gfx_h); gfx_a = 1; col(0.11, 0.11, 0.13); R(560, 150, 480, 170); col(0.88, 0.38, 0.23); R(580, 194, 440, 1); gfx_setfont(2); col(0.95, 0.95, 0.93); TX(580, 166, "Design by JGWizrad. © John Garden 2026"); gfx_setfont(3); col(0.91, 0.70, 0.23); TX(580, 210, "https://www.gardenfx.uk/"); col(0.85, 0.84, 0.82); TX(580, 236, "Manual - https://www.gardenfx.uk/manual/gfx-aureus.pdf"); col(0.52, 0.51, 0.49); TX(580, 284, "Click anywhere to close."); ); pcap = mouse_cap;