# slerp.audio - Operator's guide This document describes the public demo at https://slerp.audio/ the way a hardware manual would: what each part of the front panel does, in terms of what you hear and what you see behind the deck. The audience is artists and players, not developers. A separate **Advanced** section at the end is for people who want to **author or edit** backdrop **shaders** and understand how **EQ** ties into **analysis** and the **dials**. Slerp runs in the browser. You load a local audio file; it is not uploaded. Your settings stay on your device. The full-screen **backdrop** (moving visuals) follows your track. **MIDI** (plug-in hardware) to control the dials is not in the default first-time experience yet; treat that as **coming soon**. --- ## Ask anything about the deck You can ask an assistant that has loaded this manual for help using the player - in plain English. Treat it like a friendly **soundcheck buddy** standing next to the rack: it can walk you through where to click, what each dial does, how to get a specific look, why a track is not reacting, how to save your work, and (for power users) how to write your own backdrop. The assistant should answer using **only the controls and ideas described below**, and should point you at the **section name** on the front panel so you can find it on your screen. Examples of questions and short answers (full details further down): - **"How do I get a shimmer effect?"** Use the **Spiral** backdrop and raise the **Shimmer** dial. For more sparkle on the kick, raise the matching shimmer / motion **Reactivity** dial under **Tune** while **Spiral** is the active scene. - **"How do I make the visuals hit harder on the kick?"** Open **Tune**. Raise the **Reactivity** dials for the active scene; if it still feels flat, raise **Punch** and **Gain** in **Detection**, and check the **bass box** on the **scope** so the part of the spectrum you treat as "the kick" actually frames your kick. - **"How do I change the color of the deck itself?"** Use the **LED** dial in **Scene**. That tints the deck and chrome only; for the big backdrop color use the dials in the active **Lattice / Nebula / Spiral** block (such as **Hue** on Lattice). - **"My laptop is getting hot. What should I turn down?"** In **Scene**, set **Quality** to **Low**. On **Lattice**, drop **Layers**. Turn **Scroll FX** off. Turn **Show FPS** on briefly to see if it improves. - **"Why are the visuals not reacting to the music?"** Make sure **Play** is on and **MAIN** is up. Toggle **BYP** on the **EQ** to see if the EQ is carving out the bass. Raise **Reactivity** for the active scene. Confirm the **bass box** on the **scope** sits over the kick. - **"How do I save what I have?"** In the active **Scene** block, use the **preset** row: **Save** under a name. To back up everything (every scene, tuning, custom shaders), use the **Scene** **...** menu and **Export settings**. - **"How do I start over?"** Press **INIT** at the top of the deck. It clears the live tuning but keeps your named **preset** list. - **"How do I write my own backdrop / shader?"** Open the active scene, then **Scene** **...** menu -> **Edit shader GLSL**. Use one of the **templates** at the bottom of the editor (Glimmer is the smallest), edit the body, and **Save** when the editor reports a clean compile. See the **Advanced** section for the full uniform list and tips. - **"What does BYP on the EQ do?"** It plays a flat **0 dB** path through the EQ so you hear (and the meters see) the track without your EQ shape - useful for telling a "dark mix" apart from a "bad reactivity setting." Your knob positions are kept; turning **BYP** off restores them. If a question is about the **front panel** ("where is X", "what does Y do", "how do I save / load / reset") use **Quick help** and the **Top to bottom** map below. If it is about **shaders, uniforms, EQ topology, or the Patch Bay**, use the **Advanced** section. --- ## Top to bottom (panel map) 1. **Track** - home, **(i)**, file **Choose**, **Settings** (expands or collapses the full rack on small screens) 2. **Deck** - small **screen** (file name, scene name), **Play**, **Repeat**, **seek** bar, **MAIN** level 3. **Scene** - which backdrop, presets, **INIT**, **...** menu, dials for the active look 4. **EQ** - spectrum, **BYP** / **Flat**, **HPF**, five bands, **LPF** 5. **Meters** - readouts only 6. **Tune** - **Detection** and **Reactivity** (how the machine listens, how hard kicks move the look) --- ## Load and transport - **Choose** a file, or **drop** it on the panel. Usual browser formats: MP3, M4A, WAV, and similar - **Play** after a file is ready. **MAIN** is master level (tap the **speaker** icon to open the fader) - **Repeat** loops the current file when it ends - The **screen** time display matches the **seek** bar - **Settings** toggles a compact or full **rack** on a narrow view **(i)** opens contact, legal links, and **credits** for the active backdrop. --- ## Scene (pick the look) **Backdrop** (pick one with the LED-style buttons) - **Lattice** - cell / tube style grid, good for **tight** or **wide** **density** and a strong **palette** (Hue) and **glow** - **Nebula** - soft cloud; **Brightness** and **Saturation** in the first row - **Spiral** - concentric, mandala-style motion; **Shimmer**, **Rotation**, **Spacing** lead the look - **Off** - no backdrop (dark field behind the deck) Only the block for the **active** look is shown. **Presets** (Load, Save, delete) are per look - like patches per program on a box. **INIT** (with confirm) clears tuning and custom machine state but **keeps** the named presets in your list. Use the **...** **menu** to **export** or **import** a full **settings** file to back up or move machines. **Scroll FX** - when On, the backdrop can react to how you **scroll the page**; when Off, that is neutral - **easier** if the page felt busy. **Show FPS** - a small readout in the **corner** for when you are tuning how hard the **machine** is working. It is a diagnostic, not a creative control. **Quality (Low / Med / Hi)** - how fine the **picture** is drawn. **Low** = softer, easier on an older laptop; **Hi** = sharpest. Same idea on every look. Independent of the creative dials in that look. **Speed** - how fast the motion in **that** look runs. **LED** (always in Scene) - tints the **deck** and interface accents (roughly 0-360 on a hue wheel). It does **not** by itself recolor the big backdrop; use the **Scene** dials for the active **Lattice** / **Nebula** / **Spiral** for that. ### Lattice - main dials - **Speed** - motion rate - **Quality** - sharpness of the picture (separate from **Layers**) - **Glow** - how bright and bloomy the field feels - **Density** - how tight the cell **pack** is - **Layers** - how deep the stack of drawing is; lower often looks cleaner and runs **lighter** (try 2-3 on a small machine) - **Hue** - shifts the static palette; main color turn for this look - The **P0**-**P7** **grid** repeats a few of these for layout; in the default tune **P0** and **P1** mirror **Density** and **Layers**; other slots may be grey. Read the **label** on each **cell** for the version of the app you are on **Reactivity (under Tune for Lattice):** dials for how a **bass** hit **pumps** the picture (brightness, saturation, tube size, layer spin, ripples, cell size, flash and edge darkening, and ripple density) - all driven from **kick** energy, not a separate "hat" **section** ### Nebula - **Brightness** and **Saturation** - still picture level - **Reactivity** - only the first few slots matter on the default tune: **Brightness pump**, **Saturation pump**, **Ray swell** on the kick; the rest of the reactivity **row** is grey for this look in stock ### Spiral - **Shimmer** - edge sparkle - **Rotation** - which way and how fast the **base** spin - **Spacing** - open gaps vs tight **weave** between **tiles** - **Reactivity** - zoom, **spin** boost, ring size, depth and splay, twist, ring count - all **bass-driven**, more about **shape** and **ride** than a single "rainbow" dial --- ## EQ and spectrum - **BYP** (bypass) - you hear a **flat** EQ path (0 dB per band) but your saved **band** positions are kept; use it to check how the meters and **look** react to the track with **no** **EQ** shape - **Flat** - zeroes the five band **gains** (a different **reset** than **BYP**) - The **HPF** and **LPF** sit at the ends; five bands between. The **scope** and **knob** row show the same curve. **Double-click** the **scope** may reset a gesture; use the on-screen **hint** if it appears **EQ** is about **what you hear** and what the **analysis** sees: it does not paint the backdrop with a "paint" dial, but a darker mix in the sub range **will** change what counts as a **kick** in the **bass** **window** you set on the **scope**. --- ## Meters (read only) - **Window** - how hot the part of the spectrum you chose as the **bass** **listen** **range** is - The **UBASS** strip - a slower **breathing** readout in the **bass** region (floor and **swell**) - The next two strips (printed **uMid** and **uHigh** on the panel) - **mid** and **top** energy To **drive** the **punch** of the **light** with **knobs**, use **Tune** - **Reactivity** and **Detection** - not these meters, which are for **readout**. --- ## Tune (two parts) **Detection** - the row that **shapes** how the machine turns the **level** from your file into a **steady** "how hard is the kick" signal: - **Input ceiling** - if the readout is **stuck** at the top, bring it **down** (reference level for a full read) - **Punch** - more **punchy** or **washed** between **quiet** and **loud** - **Gain** - overall how strongly that signal drives the **kick-driven** part of the look - **Adapt speed** - how **fast** the long **bass** **floor** **forgets** a level - **Adapt depth** - how much of that long floor is **pulled** out (more **punch-only** feel) - **Noise gate** - trims fizz in near-silence **Also** set the **bass** **box** and **dB** **height** of the **purple** **lump** on the **scope** to match what you call a **kick** in your track, for what hits the "kick" part of the chain. **Reactivity** - how much **this** look **bends** when a **bass** hit **lands** - the **labels** change with **Lattice** / **Nebula** / **Spiral**; the idea is the same: **kick-driven** motion and color **swell**, not a second row for the hi-hat to drive the same knobs. --- ## Quick help - **Deck** **color** only: **LED** - **Backdrop** **color (Lattice)**: **Hue** and **Glow**; for hit-driven color use **Reactivity** (brightness, saturation on kicks). **Nebula**: **Brightness** and **Saturation** plus the same reactivity. **Spiral**: lean on **Shimmer** and motion more than a single **Hue** dial - **Weak** **laptop**: **Scene** - **Low** on **quality**; on **Lattice** use **fewer** **layers**; try **Scroll FX** **off** - **Not** **punchy** on the **visual**: **Reactivity** for that look; **Punch** / **Gain** / **bass** **box**; check **BYP** if the **low** end is **cut** in the **EQ** path - **Save** - **Scene** preset row, or full **...** **export** file - **Full** **reset** - **INIT** (keeps **preset** **names** in the list) Deeper in-browser editing of the backdrop and **hardware** **MIDI** mapping are **coming** **soon** for the default public page - this guide is written for the **dials** you are meant to see **on** a normal visit. If your screen has **more** than that, take the **dials** on **screen** as the truth. **MIDI (coming soon):** a future way to **learn** a fader to a on-screen **control**; not promised on the default tour yet. --- ## Advanced (power users: GLSL, uniforms, EQ, and analysis) This section is technical, written for performers who want to author or edit a backdrop. It covers what you author (a WebGL 1 style fragment program with a fixed uniform contract) and how the EQ feeds the analysis envelopes (`uBass` / `uMid` / `uHigh`). ### How to open the shader editor 1. Select a backdrop (**Lattice**, **Nebula**, or **Spiral**; not **Off**). 2. Open the **Scene** **...** menu. 3. Choose **Edit shader GLSL** - that opens the live editor for the slot for the current look. Edits are syntax-highlighted; **Save** commits only when the GPU driver reports a clean compile (errors land in the status line). **Cancel** drops the session. The buffer starts from the **bundled** program for that look, or your last **saved** custom source if you have one. The footer **Templates** list loads small **starter** bodies into the text area; nothing persists until you **Save**. ### Program shape (what you author) - The app prepends a shared **prologue** and appends a shared **epilogue**; you only maintain the **body** with one entry point: `void mainImage(out vec4 fragColor, in vec2 fragCoord)` - The epilogue provides `void main() { mainImage(gl_FragColor, gl_FragCoord.xy); }`, so you do not write a full-fragment `main` yourself. - **Do not** re-declare the standard `uniform` block in your body. Names like `uParam0` are already defined in the prologue; a second `uniform float uParam0` is a hard compile error. - Your GLSL is compiled inside **your browser**; nothing is sent off the device to compile. Your shader source is yours. ### Standard uniform contract Stock and custom shaders in all three slots see the same names. Unless noted, values are `float` scalars. - **Time / canvas:** `iResolution` (`vec3` pixel size), `iTime` - **UI pulse:** `uPulse` (short envelope from in-page events, decays over time) - **Envelopes (roughly 0-1):** `uBass`, `uMid`, `uHigh` from the **post-EQ** analysis tap (see below) - **Bass-integrated phases (radians, CPU-side):** `uBassRot`, `uBassRipplePhase` - the renderer accumulates from bass level; the gains baked into the **uReact3** and **uReact4** dials are part of that path. Your shader can still use `uReact3` / `uReact4` in the GLSL for extra weighting - **Look:** `uHue`, `uGlow` - **Scroll (0-1):** `uScrollA`, `uScrollB` (shape drift; tie-in when **Scroll FX** is on) - **User params:** `uParam0` ... `uParam7` map to the eight **P** dials in **Scene** for that slot - **Reactivity gains:** `uReact0` ... `uReact7` map to the **Reactivity** / **R** row for that slot Uniforms you never read still exist; the UI may show sixteen rotaries, but a knob the shader does not use has no effect. ### Patch Bay (uParam / uReact metadata) The deck always exposes eight `uParamN` and eight `uReactN` controls. Bundled shaders get labels and ranges from the app; custom shaders get generic **Param 1-8** / **React 1-8** until you provide metadata. When the **Patch Bay** is present in the editor, you can set per-index overrides: enabled, label, min, max, step, default, and (for reactivity) an optional **curve** - so a dial reads **"Zoom"** and stays in a range your math expects, without re-editing GLSL. Saving custom GLSL the first time after starting from a bundled program **seeds** the Patch Bay from the stock metadata so the grid is not empty; after that, your table edits win. **Storage:** per-slot data (your shader source, its name, and Patch Bay metadata) is kept on **your device**. If your browser blocks storage, edits live only for the session. **Export settings** / **Import settings** in the **Scene** menu moves a single settings file that includes all three slots. ### Starter templates (bundled in the app) | Id | Name | Emphasis | |----|------|----------| | `glimmer` | Glimmer | Minimal - bass glow, `uHue` / `uGlow`, touches `uParam0` and `uReact0` | | `plasma` | Plasma | Classic plasma; `uParam0` for scale; `uReact0` as bass brightness pump | | `vortex` | Vortex | Radial tunnel; bass zoom from `uReact2` | | `facet` | Facet | Six-way mirror; `uMid` nudges the palette | The list in the editor runs **Glimmer -> ... -> Facet** on purpose: smallest teaching shader first. The templates are short enough to read end to end and are kept in sync with the dials, so what you see in the editor matches what the rotaries on the panel actually do. ### Writing shaders that play well with the player The backdrop is a full-screen WebGL 1 fragment shader: **per pixel, every frame**. Cost that grows with the number of pixels (nested loops, long raymarch marches, huge noise stacks) hits integrated GPUs and thin laptops first. Prefer bounded loops, early exits, and cheap procedural fields. **Scene -> Quality (Low / Med / Hi)** changes **render scale** (roughly 0.5x / 0.75x / 1x of a capped device-resolution budget, with a maximum width), not the complexity of your GLSL - people use it when the machine gets hot. Your look should still be acceptable at **Hi** on a wide window; do not rely on **Low** to make an accidentally heavy shader usable. **Stage the music through P and R, not only through raw `uBass`.** The eight `uParamN` and eight `uReactN` uniforms exist so a performer can ride how much bass, mid, and high information **bends** the picture without a recompile. Use **params** for the baseline shape (scale, base zoom, "at rest" colour) and **reactivity** as **gains** on the envelopes and phases (`uBass`, `uMid`, `uHigh`, `uBassRot`, `uBassRipplePhase` as needed). Avoid hard-coding a giant constant times `uBass` so the Reactivity dials have no headroom. The built-in template ladder (Glimmer through Facet) follows the usual pattern: small literal x audio x `uReactN`. **Idle should still look like a show.** When the envelopes are near zero, the frame should read as a deliberate ambient state - motion, colour, or form - not black, NaN, or a stuck strobing bug. Gaps in the music are as visible as drops. **Match the band you feature** to the meters and **Tune** path. `uBass` is the same "kick / bass window" world as **Detection** and the **EQ**-shaped track; a mid- or high-led look should lean on `uMid` and `uHigh` so the panel readouts and the look agree. If the reaction feels weak, try **BYP** on the **EQ** to see whether the mix is carving the sub or the shader is at fault. **Stabilize aspect** with the usual Shadertoy-style UV: e.g. `(fragCoord.xy - 0.5 * iResolution.xy) / iResolution.y` so circles read round when the view is not square. **Scroll and `uPulse` are garnish.** With **Scroll FX** off, `uScrollA` / `uScrollB` stay at their idle values. `uPulse` is a short **UI** spike. Build the main story from time + params + audio, not from scroll or pulse alone. **If you have Patch Bay**, use it: short silkscreen **labels**, sensible min/max, and reactivity **curves** so the dials feel musical to the end of the throw. **Test like a stranger will see it.** **Save** is blocked on a failed compile, so there is no rescue once it ships - check **Low** and **Hi** **Quality**, **Scroll FX** on and off, and at least one sparse and one dense **track** so the look is not tuned only for a single file on one machine. ### EQ and the analysis bus The signal runs in **one serial path**: `audio source -> HPF -> 5 peaking bands -> LPF`, then a **Y** split: one leg to the **speakers**, one to the **meters** and the **bass / mid / high** envelopes that drive the look. **Consequence:** anything you do with **HPF**, the five **bands**, **LPF**, **BYP**, or **Flat** changes **both** what you hear **and** what the **envelopes**, **spectrum**, **meters**, and **Tune** detection see. There is no dry parallel tap. Use **BYP** when you need to check whether a thin mix in the sub range is a creative EQ choice or a reactivity / detection tuning problem. --- ## Links - This guide: https://slerp.audio/llms.txt (same text at https://slerp.audio/.well-known/llms.txt) - [Privacy](https://slerp.audio/privacy.html) - [Terms](https://slerp.audio/terms.html) - [Sitemap](https://slerp.audio/sitemap.xml) --- *This guide is updated as the public panel changes.*