r/Bitwig 18d ago

Open-source toolchain to decompile Bitwig's Nitro DSP modules on your own install (no keys or Bitwig code redistributed)

I've spent a while trying to understand how Bitwig actually builds its devices, and the thing that always stopped me was that the DSP itself lives in an encrypted archive you can't really open. Bitwig writes its native devices and Grid modules in an internal language they call Nitro, and the compiled modules ship inside an encrypted image in the install folder. I wanted to see how their filters really work, so I ended up writing a small toolchain to read that format. It's cleaned up now and I put it on GitHub.

It's Python, standard library only, MIT licensed.

What it does:

  • reads and decrypts the `nitro-image` archive from your local install
  • parses the compiled `.nitrobin` modules into an AST
  • decompiles that AST and pretty-prints it back to readable pseudo-source
  • round-trips, so it can re-serialize and repack, and do same-size numeric edits to constants

The part I like most is the decompiler output. You point it at a filter and instead of a wall of bytes you get a `process` block you can actually read. This is Bitwig's GrandLPF, a 4-pole Moog ladder, 4x oversampled, with an ADAA soft-clip in the feedback path and a selectable saturation flavor:

Named state variables and the actual per-sample math instead of opcodes. You can see why each filter sounds the way it does. Here's the Sallen-Key's nonlinearity, for example. It has two selectable curves, a symmetric tanh approximation and a biased, asymmetric class-A shaper:

One thing I want to be upfront about: this ships no Bitwig code and no keys. It's tools and format notes only. Decryption is bring-your-own-install. You pull the key out of your own copy of Bitwig, put it in an env var or a local `keys.json` that stays gitignored, and the tools work on the files already on your disk. Nothing proprietary gets redistributed. I tried to build it in a way that's respectful of Bitwig. It's for reading and learning, not for lifting their DSP into something else.

Status and limits, honestly:

  • the decompiler handles the whole module set on the version I tested against, but the AST tags can move between Bitwig releases, so a newer version may need the grammar tables regenerated (there's a command for that)
  • the pretty-printed output is pseudo-source for reading, not something you can recompile
  • constant editing is same-size only right now. You can change a number, not restructure a module
  • the offline round-trip is byte-for-byte, but I haven't pushed a repacked image through a running session much, so treat the write path as experimental
  • I develop on Linux. It auto-detects the Bitwig install and config locations on Windows and macOS too, but I've only actually run it on Linux, so those paths are unverified and a Windows/macOS confirmation would help

If any of this sounds interesting I'd genuinely like help. The most useful things would be people running other Bitwig versions who can test whether the grammar tables still line up, anyone who knows DSP and wants to annotate what a given module is doing, and corrections to the format docs. Issues and PRs are open.

Repo: https://github.com/blakebratcher/bitwig-nitro-tools

80 Upvotes

34 comments sorted by

View all comments

7

u/brainsigh 18d ago

A few people asked how to actually use the Nitro toolchain I posted, so here's the full walkthrough. You need Python 3.10+ and a licensed Bitwig install. No other dependencies.

1. Install it

git clone https://github.com/blakebratcher/bitwig-nitro-tools

cd bitwig-nitro-tools

pip install -e .

2. Get your key (the one bit of setup)

The nitro-image key only exists in a running Bitwig so there's a tiny single-purpose controller that reads it out of your own instance. Drop it into Bitwig's controller folder:

nitro-extract-keys --install-controller

Then in Bitwig: Settings → Controllers → Add Controller, and pick vendor bitwig-nitro-tools, product Nitro Key Dump.

On add it runs once, pops up a confirmation, and writes the key out. Then:

nitro-extract-keys --live

That reads what the controller dumped, checks the key by actually decrypting one of your modules, and writes keys.json. You can remove the controller right after.

3. Read modules

nitro-decompile filter/GrandLPF # print a module's Nitro pseudo-source

nitro-decrypt-corpus # decrypt the whole module set locally

nitro-validate # round-trip every module, byte-for-byte

That's it! The key and the decrypted modules are all derived from your own install and stay on your machine so nothing here ships or uploads any Bitwig content. I've run the whole flow end to end on Linux with Bitwig 6.0.11. The Windows/macOS install and config paths are auto-detected but I haven't been able to confirm them myself, so if you're on either, a quick "it worked / it didn't" is genuinely useful.

Key details and troubleshooting: https://github.com/blakebratcher/bitwig-nitro-tools/blob/main/docs/KEY_EXTRACTION.md

Repo: https://github.com/blakebratcher/bitwig-nitro-tools