chroma
🌈 Shader-based audio visualizer for the terminal
git clone https://github.com/yuri-xyz/chroma.gityuri-xyz/chroma
🌈 A Rust-based, ASCII art shader audio visualizer for your terminal!
⭐ Features
- 🎨 GPU-accelerated shaders using wgpu (compute shaders)
- 🖼️ ASCII art rendering with ANSI color support
- ⚙️ Highly configurable parameters via config file
- 💾 Save and load configurations with automatic deduplication via hashing
- 🔄 Live config reloading for real-time parameter adjustment
- 🎵 Audio visualization driven by system audio input
- 📊 FFT-based audio analysis for reactive visual effects
✨ Demos & screenshots
🔊 Make sure sound is enabled for the videos.
demo-short.webm
chroma-demo-long.webm
🔗 Install
Nix
# Run Chroma nix run github:yuri-xyz/chroma # Install the CLI into your profile nix profile install github:yuri-xyz/chroma # Develop locally with Rust, Vulkan, and audio dependencies nix develop
Chroma always builds with audio support. Vulkan still requires a working host GPU driver/ICD. See NIX.md for the flake outputs, pinned Rust toolchains, and validation checks.
Cargo
git clone https://github.com/yuri-xyz/chroma.git cd chroma # Make sure you have ALSA, libpulse, and PipeWire/PulseAudio packages installed, # the exact package names may vary depending on your distro. cargo install --path .
ℹ️ Usage
# Run with default settings chroma # Load a saved configuration chroma --config config_a3f8c2d9e1b5.toml # Or using the short form chroma -c config_a3f8c2d9e1b5.toml # View help for all arguments and settings chroma --help # Emit output for embedding in other terminal apps chroma --stream 80x24
Stream mode skips terminal setup, the status bar, and interactive input. By default it emits the legacy ANSI stream with a blank line after each frame for compatibility with existing embedders. Use --stream-format ansi for length-prefixed ANSI frames, or --stream-format cells for length-prefixed tab-separated cell records.
🕹️ Controls
QorEsc- Quit applicationR- Randomize parameters ⭐ (Discover new effects!)S- Save configuration 💾 (Createsconfig_<hash>.tomlin current directory)P/O- Cycle palettes 🎨 (16 different character sets!)↑/↓- Adjust frequency→/←- Adjust speed+/-- Adjust amplitude[/]- Adjust scale
See CONTROLS.md and PALETTES.md for more details.
🎨 Configuration & Ricing
Chroma is designed to be highly configurable and CLI-friendly, so it feels natural alongside your other terminal tools. There are multiple ways to configure the effects and visuals:
Config files: Load preset configurations from TOML files. You can find example preset configs in the examples directory:
chroma -c examples/0.toml
Live reloading: Edit your config file while Chroma is running and see changes applied instantly. This makes it easy to tweak parameters and visualize your adjustments in real time.
CLI parameters: Most parameters can be set via command-line arguments. Run chroma --help to see all available options.
Tip
You can combine config files with CLI parameters—CLI args take precedence. This is perfect when you have a favorite base config but want to tweak specific values on the fly or in a script.
Tip
Use --random or -r to randomize any parameters that haven't been explicitly set by your config file or CLI args. Great for adding variety to each run!
You can also create custom shader patterns and load them with chroma --custom-shader my_shader.wgsl. See examples/custom_shader.wgsl for a beginner template.
📦 Dependencies
- Runtime
- vulkan-icd-loader
- A Vulkan driver: one of
vulkan-intel,vulkan-radeon, ornvidia-utils - Terminal with ANSI color support
- PipeWire/PulseAudio with libpulse for Linux system-audio capture
- alsa-lib for CPAL fallback capture
- Build
- rust, cargo, git
🏗️ Contributing
Contributions are welcome. If you have ideas, find bugs, or want to improve the project, feel free to create an issue and a corresponding PR.
How it works:
- Shader files are compiled by
wgpuand rendered as ASCII output with ANSI colors in the terminal. - Chroma connects to system audio with PulseAudio/PipeWire on Linux, falling back to
cpalwhere needed. - It uses fast Fourier transforms from the
rustfftcrate to make the visuals react to what is playing, extracting bass (20-250 Hz), mid (250-2000 Hz), and treble (2000-8000 Hz) bands.
See CONTRIBUTING for a more in-depth guide.
more like this
TachiSnap
TachiSnap — Pixel Snapper for animation pixel artists. Rust + WebAssembly client-side tool for cleaning up AI-generated…
bit_gossip
Pathfinding library for calculating all node pairs' shortest paths in an unweighted undirected graph.