A terminal-based step sequencer, drum machine, and synthesizer built entirely in Rust.
βͺ All DSP from scratch β no samples, no external audio libraries. Just your terminal and your speakers. β«
- π₯ 8 Drum Tracks β Kick, Snare, Closed HiHat, Open HiHat, Ride, Clap, Cowbell, Tom β each fully synthesized with 8 tweakable sound parameters
- πΉ Dual Polyphonic Synths β Synth A + Synth B with DJ-style crossfader, each with 2 oscillators (4-voice supersaw) + selectable sub, portamento, osc sync, 2 ADSR envelopes, resonant filter with key follow, dual LFOs with 6 waveforms, independent patterns and kits
- π² 32-Step Sequencer β 10 patterns and 8 kit slots with per-pattern BPM and swing
- π¬ 16 Scene Slots β snapshot and recall full instrument states (all patterns, kits, BPM, swing) with queued or immediate switching
- π Pro Audio Engine β FDN reverb (8-line stereo), tempo-synced delay, 2Γ-oversampled tube saturator, SSL-style glue compressor, lookahead limiter, sidechain compression (kick ducks synths)
- π€ Live Performance β drum pads, real-time recording, pattern queuing, scene-based arrangement
- π±οΈ Mouse Support β click the grid, drag parameters Ableton-style, audition sounds from the activity bar
- πΎ Project System β save/load
.tspfiles, standalone kit export, preset browser - π Collapsible Panels β minimize/expand synth, drum knobs, and waveform sections; auto-adapts to small terminals
- π Spectrum Analyzer β real-time FFT spectrum display and VU meter with 90s Hi-Fi LED aesthetic
- π Ableton Link β sync tempo, start/stop, and beat position with other TextStep instances or any Link-enabled DAW on the network. Press
F3to toggle. Link-as-master: when enabled, the network's shared timeline drives this instance's clock continuously, eliminating drift.
Ships with 10 demo scenes ready to play: π΅ Acid Techno, Classic House, Deep House, Driving Techno, Lo-Fi Hip Hop, Trance, Drum & Bass, Electro Funk, Dub Techno, and Ambient β each with matched drum patterns, synth patterns, and kits.
- Rust 1.70 or later
- macOS with CoreAudio (primary target)
Requires Rust (1.70+). macOS with CoreAudio is the primary target; Linux with ALSA is also supported.
# Clone the repository
git clone https://github.com/illobo/textStep.git
cd textStep
# Build and run (release mode recommended for audio performance)
cargo build --release
cargo run --release
# Build without Ableton Link (skips link / tokio dependencies)
cargo build --release --no-default-featuresOn Linux, install ALSA development headers first:
sudo apt-get install libasound2-dev # Debian/UbuntuRun the tests:
cargo test # 55 tests, runs in <1sPre-built binaries for macOS (ARM, x86_64, universal) and Linux (x86_64) are available from GitHub Actions artifacts.
macOS note: Downloaded binaries will be blocked by Gatekeeper. Remove the quarantine flag before running:
xattr -d com.apple.quarantine ./textstep| Key | Action |
|---|---|
Space |
Play / Pause |
Esc |
Stop (reset to step 0) |
- / = |
BPM -1 / +1 |
_ / + |
BPM -10 / +10 |
` |
Toggle record mode |
l |
Toggle loop on/off |
L |
Cycle loop length: 8 / 16 / 24 / 32 |
Shift+C |
Cycle compressor: Off / Light / Medium / Heavy / Max |
Shift+T |
Cycle tube saturator: Off / Light / Medium / Heavy / Max |
Shift+D |
Cycle sidechain duck: Off / Light / Medium / Heavy / Max |
Shift+V |
Adjust master volume |
< / > |
Swing Β±5% |
( / ) |
Crossfader toward A / B |
Click A / B |
Mute/unmute Synth A / B |
Click C |
Reset crossfader to center |
| Key | Action |
|---|---|
Tab / Shift+Tab |
Cycle focus: Grid β Controls β Transport |
| Arrow keys | Move cursor in grid or controls |
Enter |
Toggle step (and advance β hold to fill) |
; |
Cycle parameter page: SYN β AMP β FX |
F2 |
Collapse/expand all synth panels (A + B) |
F3 |
Toggle Ableton Link sync |
~ |
Toggle spectrum analyzer / VU meter |
? |
Help overlay |
Each drum track has 8 parameters across three pages:
| Page | Parameters | Controls |
|---|---|---|
| SYN | Tune, Sweep, Color, Snap | Pitch, timbre, transient character |
| AMP | Filter, Drive, Decay, Volume | Tone shaping, saturation, envelope |
| FX | Reverb Send, Delay Send | Per-track effect routing |
Tweak with Shift+Up/Down (adjust value) or Alt+Up/Down (adjust and audition simultaneously). With the mouse, click-drag any gauge vertically. Alt+R randomizes the current page across all tracks.
Mute (Shift+M) and Solo (Shift+S) are always accessible on any page.
The bottom keyboard row triggers sounds live:
z |
x |
c |
v |
b |
n |
m |
, |
|---|---|---|---|---|---|---|---|
| Kick | Snare | CHH | OHH | Ride | Clap | Cowbell | Tom |
With record enabled and playback running, pad hits write steps at the playhead.
Patterns β 10 slots per section (Synth A, Synth B, Drums), each with its own step data:
| Key | Action |
|---|---|
q w e r t y u i o p |
Queue pattern 1β10 (switches at loop end) |
Shift+ above |
Switch pattern immediately |
[ / ] |
Queue prev / next |
{ / } |
Immediate prev / next |
Kits β 8 slots of sound parameters, shared across patterns:
| Key | Action |
|---|---|
1 through 8 |
Switch to kit slot |
TextStep features two independent polyphonic synthesizers (Synth A and Synth B), each with its own patterns, kits, 2 oscillators + sub, noise, 2 ADSR envelopes, 24dB resonant filter, and LFO with 6 waveforms. Toggle all synth panels with F2. Each synth has its own pattern/kit selectors shown in the transport bar.
Synth notes are triggered with z x c v when a synth grid is focused, with Up/Down for pitch and ( ) for octave shifts.
Scenes are snapshots of the full instrument state: which pattern and kit is selected for drums, Synth A, and Synth B, plus BPM and swing. Use them to arrange your track.
| Key | Action |
|---|---|
Ctrl+E |
Open scene browser |
Return |
Queue scene (switches at drum loop end) |
! |
Immediate scene switch |
S |
Save current state to selected slot |
R |
Rename scene |
D |
Delete scene |
Esc |
Close browser |
| Key | Action |
|---|---|
Ctrl+S |
Save project |
Ctrl+O |
Load project |
Ctrl+E |
Scene browser |
Ctrl+N |
Rename current pattern |
Ctrl+K |
Save kit as standalone .tsk file |
Ctrl+J |
Load kit into active slot |
Ctrl+P |
Preset browser |
Ctrl+L |
Pattern browser |
Ctrl+C / Ctrl+Q |
Quit |
Projects are stored as JSON in ~/Library/Application Support/textstep/projects/.
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β UI Thread β
β ββββββββββββββ ββββββββββββ ββββββββββββββββ β
β β ratatui β β crosstermβ β App State β β
β β renderer β β events β β (app.rs) β β
β ββββββββββββββ ββββββββββββ ββββββββββββββββ β
β β
β crossbeam channels (lock-free, bounded) β
β βΌ UiToAudio β² AudioToUi β
β β
β Audio Thread β
β ββββββββββββββ ββββββββββββ ββββββββββββββββ β
β β Sequencer β β Voices β Effects β β
β β Clock β βDrum+SynABβ β Rev/Dly/Comp β β
β ββββββββββββββ ββββββββββββ ββββββββββββββββ β
β β β
β cpal/CoreAudio β
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
Two-thread model:
- UI thread β ratatui + crossterm for rendering and input at ~60fps
- Audio thread β cpal/CoreAudio callback running all DSP per-sample
Communication is lock-free via bounded crossbeam channels. The audio thread never blocks.
Every sound is synthesized in real-time with no external DSP dependencies:
- Drum voices β TR-808/909-inspired kicks (dual-stage pitch envelope, bridged-T BP/LP click blend, subharmonic at octave below, asymmetric drive saturation), noise-blended snares with comb filter, 6-oscillator metallic banks for hats and rides (Mutable Instruments Plaits-style inharmonic ratios), ring-modulated open hats, bandpass claps, detuned pulse cowbells, FM toms
- Synth voice β dual PolyBLEP anti-aliased oscillators (4-voice supersaw), selectable sub waveform (square/sine/saw), noise, two ADSR envelopes, resonant SVF filter with key follow, portamento/glide, oscillator hard sync, dual 6-waveform tempo-synced LFOs
- Effects β 8-line FDN reverb with Householder feedback matrix (native stereo), tempo-synced filtered delay, 2Γ-oversampled asymmetric tube saturator, feedforward RMS glue compressor with soft knee, true-peak lookahead limiter, sidechain envelope follower
- Primitives β 1-pole HP/LP filters, state-variable filter, xorshift32 noise, stereo decorrelation
| Directory | Purpose |
|---|---|
src/ |
Core: entry point, app state, input handling, messages |
src/ui/ |
Rendering: layout, theme, grids, knobs, transport, spectrum |
src/audio/ |
DSP: engine, clock, drum/synth voices, effects, mixer, FFT |
src/sequencer/ |
Data: patterns, transport, project serialization |
src/presets/ |
Preset browser: drum/synth sounds and patterns by genre |
Hardware/synthwave aesthetic β all rendered with UTF-8 block characters on a dark background.
| Color | Hex | Usage |
|---|---|---|
| Amber | #e8a838 |
Active steps, gauge fills, primary data |
| Cyan | #61dafb |
Transport state, beat LEDs, playhead, focused borders |
| Pink | #ff6b9d |
Focus/selection, current track, record |
| Gold | #ffd700 |
Queued patterns, warnings |
| Crate | Version | Purpose |
|---|---|---|
ratatui |
0.29 | TUI rendering framework |
crossterm |
0.28 | Terminal backend (events, raw mode) |
cpal |
0.15 | Cross-platform audio I/O (CoreAudio) |
crossbeam-channel |
0.5 | Lock-free bounded MPSC channels |
serde + serde_json |
1 | Project serialization (JSON) |
No other runtime dependencies.
textStep/
βββ src/
β βββ main.rs # Entry point, thread spawning, event loop
β βββ app.rs # Application state, focus, modals
β βββ keys.rs # Keyboard input handler
β βββ mouse.rs # Mouse input handler (mirrors UI layout)
β βββ messages.rs # Cross-thread message enums
β βββ params.rs # Shared effect parameters
β βββ ui/
β β βββ mod.rs # Top-level render dispatch
β β βββ layout.rs # Layout constants (single source of truth)
β β βββ theme.rs # Color palette and styling
β β βββ transport_bar.rs # Transport controls rendering
β β βββ drum_grid.rs # 8Γ32 drum step grid
β β βββ synth_grid.rs # Synth step grid with note display
β β βββ knobs.rs # Drum parameter sliders
β β βββ synth_knobs.rs # Synth parameter groups
β β βββ waveform.rs # Spectrum analyzer / VU meter
β β βββ splash.rs # Boot animation
β β βββ help_overlay.rs # Keyboard shortcut reference
β βββ audio/
β β βββ engine.rs # Audio callback and voice management
β β βββ clock.rs # Beat/step timing with swing
β β βββ drum_voice.rs # 8 drum synth voices (all DSP)
β β βββ synth_voice.rs # Polyphonic synth DSP
β β βββ effects.rs # Reverb, delay, compressor, saturator
β β βββ mixer.rs # Channel mixing, mute/solo
β β βββ display_buffer.rs # Lock-free audioβUI waveform buffer
β β βββ fft.rs # FFT for spectrum analyzer
β βββ sequencer/
β β βββ drum_pattern.rs # Drum pattern data (8 tracks Γ 32 steps)
β β βββ synth_pattern.rs # Synth pattern data and parameters
β β βββ transport.rs # Transport state (BPM, play, swing)
β β βββ project.rs # Project serialization (.tsp JSON)
β βββ presets/
β βββ mod.rs # Preset browser state machine
β βββ drum_presets.rs # Drum sound presets
β βββ synth_presets.rs # Synth sound presets
β βββ pattern_presets.rs # Drum pattern presets by genre
β βββ synth_pattern_presets.rs # Synth pattern presets
βββ assets/
β βββ demo.gif # Demo recording
βββ Cargo.toml
βββ BLUEPRINT.md # Full technical documentation
βββ LICENSE # GPL v2
Kick Voice Realism
- Dual-stage pitch envelope (2.5ms fast attack + color-controlled slow stage)
- Bridged-T network: bandpass/lowpass click blend replacing simple LP impulse
- Subharmonic at octave below (0.5Γ) instead of 0.75Γ β eliminates phase cancellation
- Asymmetric tanh saturation for drive-dependent even harmonics
- All 16 kick presets retuned for the new synthesis architecture
Synth Engine Features
- Portamento/glide with exponential pitch smoothing
- Oscillator hard sync (osc2 β osc1)
- Selectable sub waveform (square / sine / saw)
- Filter key follow
- Wider 4-voice supersaw with PolyBLEP anti-aliasing
CPU Optimizations
- Cached SVF filter coefficients (skip per-sample
tan()when cutoff unchanged) fast_exp2polynomial approximation replacingpowf()in pitch calculations- Incremental O(1) peak tracking in lookahead limiter (full scan only on peak exit)
- Inactive oscillator skip (zero-cost when osc2/sub level is 0)
Contributions are welcome! Please ensure:
- All tests pass:
cargo test - Code compiles without warnings:
cargo build --release - Follow the existing code style and comment conventions
See BLUEPRINT.md for full technical documentation and architecture details.
This project is licensed under the GNU General Public License v2.0.
π¦ Built with Rust Β· π All DSP from scratch Β· π΅ Zero audio dependencies
"Any sufficiently advanced terminal is indistinguishable from a drum machine."
