Skip to content

williamhallpreston/lith

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

LITH — Tonal Gravity Instrument

v2.0 · NYC Graffiti Edition

Where other instruments give you notes, LITH gives you tension.

LITH is a browser-based polyphonic instrument built around a single idea: harmonic gravity. Notes aren't on/off events — they are masses in a tonal field, each exerting measurable dissonance on every other. The Gravity Field makes that force visible and playable. Resolution is the instrument.

Visual identity: 1980s NYC subway car graffiti — wildstyle lettering, Keith Haring lines, Basquiat mark-making, Krylon/Rustoleum palette. White base. Black outlines. Maximum colour.


Screenshot

┌─────────────────────────────────────────────────────────────────┐
│ ▓▓▓ RED ▓▓▓ YELLOW ▓▓▓ CYAN ▓▓▓ MAGENTA ▓▓▓ GREEN ▓▓▓ ORANGE ▓ │  ← drip bar
│ ♦  ▲  ●  ★  ■  ♦  ▲  ●  (animated Haring icons)               │
├──────────────────────────────────────────────────────────────────┤
│ LITH  Tonal Gravity Instrument · v2.0    ◂ Hollow Dusk ▸  ●●○○○ │  ← header
├────────────────────────────────────┬─────────────────────────────┤
│                                    │  TENSION   ██████░░  0.72  │
│   G R A V I T Y   F I E L D       │  RESOLVE   ███░░░░░  0.28  │
│                                    ├─────────────────────────────┤
│   (interactive canvas — voice      │  Interval  Tritone         │
│    nodes, arc connections,         │  Voices    3               │
│    particle physics)               │  Root      C4              │
│                                    ├─────────────────────────────┤
│                                    │  [Gravity] [Decay]  [Body]  │
│  SAMO©              ★ NYC ★       │  [Drift]   [Space]  [Spread]│
├────────────────────────────────────┤                             │
│ ████████████████ WAVEFORM │ FREQ ██│  C  C# D  D# …  scale/root │
├────────────────────────────────────┴─────────────────────────────┤
│  [C][C#][D][D#][E][F][F#][G][G#][A][A#][B][C][C#][D]   Oct 4   │  ← keyboard
├──────────────────────────────────────────────────────────────────┤
│ [About]     ★ LITH NYC ★      [Silence]   [Resolve All · Space] │
└──────────────────────────────────────────────────────────────────┘

Features

Synthesis engine

  • Per-voice oscillator bank: sawtooth (primary) + 2nd/3rd harmonic sines + sub-octave sine
  • Drift LFO with randomised rate per voice — organic beating between simultaneous notes
  • Lowpass filter (body param) with resonance that increases with warmth
  • ADSR envelope with 15 ms attack and configurable release
  • Stereo panning distributed across keyboard range (spread param)
  • Synthetic convolution reverb — IR generated locally, no audio file fetched

Harmonic intelligence

  • Real-time tension calculation from psychoacoustic consonance model (Helmholtz / Plomp–Levelt)
  • Tension and Resolution meters updated at 60 fps
  • Auto-resolve engine — when tension exceeds threshold for ~2 s, the most dissonant voice fades out
  • Resolve All gesture releases voices in dissonance order — the release arc is the resolution

Gravity Field

  • Click top half to trigger notes at horizontal pitch position
  • Drag anywhere to modulate drift in real time (Y axis = pitch instability)
  • Quadratic arc connections between active voices — line weight and colour reflect dissonance
  • Interval name labels float at arc peaks
  • Haring-style concentric ripple rings on click/drag
  • Paint-splatter particle physics — circles and rectangles with gravity and air resistance

Controls

  • 6 knobs: Gravity, Decay, Body, Drift, Space, Spread — all with SVG arc tracks, drag/scroll/touch/keyboard
  • 8 presets: Hollow Dusk, Iron Choir, Glass Lattice, Amber Field, Deep Locrian, Open Fifth, Fog Dorian, Mercury Veil
  • 10 scales, 12 root notes, octave range 1–8
  • 4 mode toggles: Auto-Resolve, Harmonics, Hold Mode, Particles
  • Keyboard shortcuts for all primary actions

Tech Stack

Layer Technology
Runtime Vanilla HTML/CSS/JS — no framework
Audio Web Audio API (native browser API)
Visuals Canvas 2D API
Fonts Google Fonts (Black Ops One, Permanent Marker, Share Tech Mono)
Build None — single-file delivery
Dependencies Zero at runtime

Browser support: Chrome 90+, Firefox 90+, Safari 15+, Edge 90+. Requires Web Audio API support.


Setup & Installation

Quickstart (zero setup)

# Clone the repository
git clone https://github.com/your-org/lith.git
cd lith

# Open directly in browser — works with file:// protocol
open src/lith.html

Local development server (recommended)

A local server avoids occasional browser quirks with file:// and prepares you for testing the CSP headers in a realistic environment:

# Using Python (no install required)
python3 -m http.server 3000 --directory src/

# Using Node.js npx (no install required)
npx serve src/

# Using Caddy (full header support)
caddy file-server --root src/ --listen :3000

Then open http://localhost:3000 in your browser.

Environment configuration

# Copy the example environment file
cp .env.example .env

# Edit .env with your local values
# (Currently LITH needs no environment variables to run)

Usage

Playing

Input Action
A S D F G H J K L White keys (C–D, second octave)
W E T Y U Black keys (C#, D#, F#, G#, A#)
Space Resolve All — releases voices in dissonance order
Click top of Gravity Field Trigger note at horizontal pitch position
Drag Gravity Field Modulate drift in real time (Y = instability)
Drag/scroll knob Adjust parameter
Arrow keys on focused knob Increment/decrement by 1
◂ ▸ Cycle through 8 presets
−/+ Octave down/up

Understanding the display

  • Voice nodes — bright coloured bubbles in the Gravity Field; one per active note
  • Arc connections — drawn between every pair of active voices; thicker/red = more dissonant; thinner/cyan = consonant
  • Tension meter — mean dissonance across all active pairs; 0.00 = pure consonance, 1.00 = maximum tension
  • Resolution meter — inverse of tension; rises as voices settle toward consonance
  • Interval label — identifies the most dissonant interval currently sounding

Presets

Preset Character
Hollow Dusk Dark minor, medium decay, organic drift
Iron Choir Dense Phrygian, heavy body, no auto-resolve
Glass Lattice Airy whole-tone, heavy drift, wide stereo
Amber Field Warm Lydian, long decay, lush reverb
Deep Locrian Maximum tension, Locrian, no auto-resolve
Open Fifth Clean major, short decay, wide spread
Fog Dorian Slow Dorian, very long decay, maximum reverb
Mercury Veil Diminished, extreme drift, extreme reverb

Security Considerations

LITH is a client-side only instrument with no server, no database, and no user data processing. The security surface is narrow by design.

Key properties

  • No runtime network calls. CSP connect-src 'none' blocks all fetch() and XHR. The only external load is Google Fonts at page init.
  • No persistence. Nothing is written to localStorage, sessionStorage, IndexedDB, or cookies.
  • No user input reaches canvas or HTML. All rendered text comes from internal constant arrays.
  • innerHTML used only as = ''. No dynamic HTML construction.
  • AudioContext gated by user gesture. Cannot produce audio without a real pointer or key event.

Deployment

When serving LITH from a web server, add these HTTP response headers. The meta CSP is a defence-in-depth measure; server-sent headers take precedence and are the authoritative control:

X-Frame-Options: DENY
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
X-Content-Type-Options: nosniff
Referrer-Policy: no-referrer
Permissions-Policy: camera=(), microphone=(), geolocation=()

See docs/SECURITY-NOTES.md for full technical security architecture documentation, including CSP justification, audio graph analysis, and a deployment hardening reference for Nginx.

Reporting vulnerabilities

See SECURITY.md for the responsible disclosure policy and contact channels. Please do not report security issues in public GitHub Issues.


Project Structure

lith/
├── src/
│   └── lith.html           # Complete instrument — HTML + CSS + JS in one file
├── docs/
│   └── SECURITY-NOTES.md   # Technical security architecture reference
├── .env.example             # Environment variable template (no real secrets)
├── .gitignore               # Excludes secrets, build artefacts, OS files
├── CHANGELOG.md             # Version history
├── CONTRIBUTING.md          # Development guide and style requirements
├── LICENSE                  # MIT
├── README.md                # This file
└── SECURITY.md              # Vulnerability disclosure policy

Why single-file? LITH is a standalone instrument. Single-file delivery means zero build steps, zero dependency installation, and trivial deployment to any static host — including Itch.io, GitHub Pages, or a USB drive. The architecture is a deliberate constraint, not a limitation.


Contributing

Read CONTRIBUTING.md before opening a PR. The short version:

  • Open an issue before coding
  • No new dependencies without discussion
  • Follow the code style guide
  • Zero secrets in any commit

Licence

MIT — see LICENSE.

Copyright © 2025 LITH Project Contributors.

About

Browser-based tonal gravity instrument. Play harmonic tension, not just notes. 1980s NYC graffiti edition — Web Audio API, zero dependencies.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages