Skip to content

Repository files navigation

wstudio

wstudio: make music the vim way

A keyboard-centric digital audio workstation written in Zig (0.16), for the terminal and as a native GUI.

wstudio borrows vim's modal model instead of a mouse-first workflow: normal mode navigates the project and drives the transport, insert turns the keyboard into a piano, visual selects and yanks ranges, and command mode runs : commands. It ships with grand and upright pianos, a harpsichord, synths, samplers, a drum machine, a sample-chopping slicer, and a full effects rack (gate, compressor, multiband compressor, OTT, limiter, expander, clipper, crossover, transient shaper, EQ, multimode filter, utility, stereo width, auto-pan/tremolo, saturation, bitcrush, chorus, phaser, flanger, tape, frequency shifter, pitch shifter, delay, reverb) built in, so there's no plugin hunting before the first note.

Quickstart

nix develop                     # zig, zls, audio libs
zig build run                   # launch the GUI on a blank project
zig build run -- demo.wsj       # open the curated four-track demo
zig build run -- --tui demo.wsj # open the TUI instead
zig build run -- render demo.wsj demo.wav # render saved project without frontend
zig build run -- render-stems demo.wsj stems # render each track without frontend

On Linux, devShell also supplies Odin 2, Surge XT, sfizz, Chow Tape Model, Uhhyou, and LSP plugins across CLAP and VST3. Both formats scan this stress-test set automatically through CLAP_PATH and VST3_PATH.

Without Nix, install Zig 0.16, libsndfile, speexdsp, Lua 5.4 and, on Linux, the ALSA development libraries, then build the same way; see CONTRIBUTING.md for the full development setup. The Linux release tarball links libsndfile dynamically, so a distribution package of it (libsndfile1 on Debian and Ubuntu) has to be present to run it; Windows x64 and Arm64 archives carry their own DLLs. Once running: enter on a blank track opens the instrument picker, space plays/stops, and :help lists every command. Choosing Acoustic starts on the bundled grand piano. Use :preset <name> or press f to browse the bundled pianos, organ, guitars, basses, winds, strings, harp, and mallets. SoundFont is the separate instrument for your own .sf2 banks: :load picks the file, f browses its presets.

External plugins

wstudio hosts stereo CLAP instruments and effects using the CLAP 1.2 ABI. Discovery follows CLAP_PATH and the platform paths required by the CLAP specification.

On Linux, plugins of both formats load in a separate process by default, so one that crashes or hangs degrades to silence in its own slot rather than taking the session with it. Set wstudio.o.sandbox_plugins = false to host them in-process instead. Other platforms always host in-process.

wstudio clap-scan

List backend-native audio and live MIDI device IDs with wstudio devices. Use those values for wstudio.o.audio_output_device, wstudio.o.audio_input_device, and wstudio.o.midi_input_device. Explicit playback devices fail with backend error instead of silently switching to silent playback.

The instrument and effect pickers divide devices into Internal and External sections. External CLAP plugins are scanned automatically from the platform's canonical directories. Use RESCAN beside the External section, or :plugin-scan, after installing a plugin while wstudio is open. Set wstudio.o.clap_plugin_path = "/path/to/clap" in init.lua to scan only a fixed custom directory instead.

wstudio also hosts VST3 instruments and effects. Discovery checks VST3_PATH before standard Linux, Windows, and macOS VST3 directories. Set wstudio.o.vst3_plugin_path = "/path/to/vst3" to scan one custom directory, or inspect discovery with:

wstudio vst3-scan

VST3 supports one mono or stereo main output for instruments, and one mono or stereo main input and output for effects. Notes, mapped MIDI CC and pitch bend, transport, generic parameter editing, opaque component/controller state, latency queries, restart notifications, and native editor windows are supported. Multiple buses, sidechains, surround, and sample-accurate parameter ramps are not supported.

The scan prints <plugin-id> <name> <path>. In either frontend, select a track and use:

:clap-instrument <plugin-id> <path>
:clap-fx <plugin-id> <path>
:clap-param <1-based-index> [plain-value]

CLAP audio, notes, MIDI, transport, parameters, opaque state, latency, tails, logging, main-thread callbacks, parameter flushes, dirty-state notifications, and native floating or host-windowed GUIs are supported. Use :clap-gui on a CLAP instrument or focused effect to toggle its window. Plugin identity and state are saved in the .wsj project. Surround buses, polyphonic modulation, plugin-requested restarts, and plugin-requested thread pools are not supported yet.

External controller input accepts MIDI 1.0 and MIDI 2.0 Universal MIDI Packets through ALSA sequencer on Linux, CoreMIDI on macOS, and Windows MIDI Services. Note velocity, CC, pitch bend, pressure, and per-note pitch bend retain MIDI 2.0 resolution through built-in synth routing; program and bank changes reach hosted plugins. Windows falls back to MIDI 1.0 WinMM when Windows MIDI Services is unavailable. Profiles, Property Exchange, SysEx, Flex Data, and Stream messages are not advertised as supported. See MIDI 2.0 input.

Status: beta

The first public beta is live and audible. Expect rough edges, and keep project-file backups while the .wsj format continues to evolve. Linux is used daily by the maintainer and is the most exercised platform; Windows has had some manual testing, with TUI, GUI, and audio confirmed working. macOS has no hardware available to test on: it only gets CI compiling and running the test suite, with no human having run it. If you're on a Mac, trying it and reporting back is one of the most useful things you can do right now. See CONTRIBUTING.md to report a bug or send a focused change.

Configuration

wstudio is scripted with Lua: options, keymaps, custom : commands, autocmds, and the project itself, down to notes, drum steps, FX chains, and arrangement clips. On first run it writes a fully documented template to the user configuration directory as init.lua (see examples/init.lua); a broken config never blocks startup. The full API is documented in docs/lua-api.md. Nix users can enable wstudio via nixosModules.default or homeManagerModules.default, configuring it with typed settings or raw Lua:

programs.wstudio = {
  enable = true;
  settings.default_tempo = 128;
};

Learn more

  • docs/ - editing grammar, UI conventions, undo/redo, and GUI color identity
  • CHANGELOG.md - what changed in each release
  • FORMAT.md - the .wsj save format and versioning contract
  • CONTRIBUTING.md - bug reports and development setup

License

GPL-3.0-or-later, Copyright (c) 2026 zexk. See LICENSE. Releases up to and including v1.0.0-beta.9 were published under the MIT License and stay available on those terms.

Bundled assets keep their own licenses: src/assets/fonts/wstudio-icons.ttf is a subset of Symbols Nerd Font Mono (MIT, see src/assets/fonts/LICENSE), DejaVu Sans Mono is Bitstream's (see src/assets/fonts/DEJAVU-LICENSE), and the bundled acoustic sample library is public domain (CC0) from the VCSL, FreePats and VSCO 2 CE projects (see src/assets/library/README.md).

About

A keyboard-centric digital audio workstation written in Zig

Topics

Resources

Contributing

Stars

5 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages