viper
A vim-keyed NES chiptune tracker for the terminal that compiles songs to real NSF files, plays them through an emulated 2A03, and can rip music back out of NSFs and cartridges.

A step sequencer for the five NES sound channels (two pulse, triangle, noise, DPCM) in a single Rust binary. You edit a tracker grid with vim motions, operators and text objects: dd deletes a row, dip deletes a phrase, . repeats, q/@ record and replay macros. Insert mode turns the bottom keyboard row into a chromatic piano.
Songs save as plain-text .vip files that round-trip losslessly, so they can be diffed, grepped, or written by hand.
Beyond the grid
- Real NES output.
viper compilelinks a song against a 6502 sound driver and produces an NSF or NSFe.:engine apuplays the song through an emulated 2A03 instead of the built-in ADSR synth. - Verification.
viper renderwrites a deterministic mix, per-channel stems, trigger MIDI and a register-write log.viper verifydiffs that log against another emulator; the bundled stress song matches FCEUX frame for frame. - Ripping.
viper ripreads music back out of an NSF, a register dump, or a cartridge it boots itself. It recovers the row grid by simulating the driver’s row clock at candidate tempos, infers instruments from the envelopes, and reports which numbers were read and which were guessed. - Generators.
:gencovers Euclidean rhythms, chord progressions, basslines, arpeggios, L-systems and cellular automata, all deterministic per seed.viper gencomposes a whole song from a style directory. - Visualizer. Bars, scope, grid, orbit and sprite renderers in half-blocks. Sprite sheets can be loaded straight from a ROM’s CHR data, and sprite properties bind to audio sources through a small expression language.
- Live mode. Play notes in real time, overdub, launch scenes on bar boundaries, mute channels.
Running it
Needs Rust 1.80+ (and ALSA headers on Linux). It boots with a demo song loaded.
git clone https://github.com/sadovsky/viper.git
cd viper
cargo run --release
A working sound driver ships in tests/fixtures/, so the compile, render and verify commands work out of the box.