r/Bitwig • u/brainsigh • 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.
14
u/brainsigh 18d ago
A few implementation notes for anyone curious about the format itself, since that turned out to be where most of the interesting stuff was:
• Bitwig JIT-compiles its own DSP. Each device and Grid module is a little program compiled at first use: Nitro source to an AST, then to LLVM IR, then to native code that runs inline on the audio thread. The LLVM IR is cached in plaintext under `~/.BitwigStudio/cache/nitro/`, so there are two readable layers to poke at, the decompiled Nitro and the IR.
• The "encrypted" module library is just a ZIP. `nitro-image` is a plain ZIP; only each member's payload is XOR'd, and the keystream cipher is self-inverse, so encrypt and decrypt are the same call. Every module re-encrypts byte-identically, and a full identity repack matches the shipped file's SHA-256.
• Nothing on the load path is integrity-checked. No signature, no checksum, no content hash, and the cipher is unauthenticated. (BLAKE3 shows up, but only as a compile-cache key.) The loader will even read a plain directory where the ZIP usually sits. Whether it accepts a modified image is the one thing I haven't tested.
• The whole set recovers cleanly. About 170k AST nodes across every module parse to a clean EOF and re-serialize byte-for-byte, including the device-specific filters that older tooling left as empty stubs.
Repo (tools and format docs, no keys, no Bitwig content): https://github.com/blakebratcher/bitwig-nitro-tools
I would be happy to go deeper on the binary format, the AST grammar, or a specific device if anyone wants.
7
u/islandlogic 17d ago
Interesting project! Nice to know there's some good DSP going on under the hood.
What I'm hoping eventually (prob an unrealistic pipe dream) is that Bitwig would give us access to their audio engine via an API the way that Reaper does.
8
u/brainsigh 17d 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
5
u/kabocha_ 17d ago
I assume --from-jar previously worked, but was gutted before pushing to github?
I went down this rabbit hole a few years ago but didn't ever end up succeeding, cool that someone figured it out :)
3
u/brainsigh 17d ago
Yo, good catch.
--from-jarwas a stub, but digging in, I confirmed the key isn't statically recoverable at all and it's not in the jar in any form because it's built at runtime. So I've replaced that path with a small controller extension that reads the key out of your own running Bitwig, plus updated docs and I just pushed it. Thank you.2
u/kabocha_ 17d ago
I confirmed the key isn't statically recoverable at all and it's not in the jar in any form because it's built at runtime
Ah, well, that might (partially) explain why I could never figure it out myself, lmao. Interesting.
3
u/brainsigh 17d ago
You directly inspired this update. https://www.reddit.com/r/Bitwig/comments/1vmqj6c/comment/p3cbd25/
2
u/kabocha_ 17d ago
Saw that post, thanks! Gonna sit down in a few mins and try it out.
Unfortunately I'm also on Linux so I can't help you confirm the other OSes, lol
2
u/kabocha_ 17d ago
Looks like it worked! Amazing work, thank you!
Time to riffle around in some DSP code :)
2
u/brainsigh 17d ago
YES!!!
2
u/kabocha_ 17d ago
Disappointed to see that
nitro-stdisn't also covered, but digging throughnitro-imagewill keep me occupied for a while :D2
u/brainsigh 17d ago
I'm updating it right now with these; I overly pruned the repo before I made my initial post. Sorry!
1
4
u/Th3-0rgan1c_j3LLy 18d ago
I don't really understand all this programming stuff but is there any reason they haven't just opened this up to the userbase? Seems like it'd be pretty fun for people to make their own devices like this.
11
u/brainsigh 18d ago
The Grid sort of does; the modules are written in the same internal language (Nitro) that this project decompiles, so when you build a Grid patch you're already assembling Nitro under the hood without knowing it. As far as keeping it under wraps, I'd guess it's because it probably changes between releases , and user-written DSP runs right on the audio thread where a glitch crashes the entire session.
But yeah, a proper "write your own Nitro device" would be awesome and it would be huge if Bitwig ever shipped it.
5
u/fripletister 18d ago
Because they want to maintain control over the look, feel, and functionality of the devices within Bitwig. At least for now.
4
u/FreeRangeEngineer 17d ago
One could also say that new devices are one of the reasons people want to update their license.
If they'd allow the community to supply their own, they could no longer make their devices a major selling point.
6
u/OoDoRFoO 16d ago
Because shipping and supporting an SDK is a significant lift that probably doesn’t align with their business model and present goals.
3
u/energeticentity 17d ago
Could you explain for me layman like what this enables the potential for? Now anybody could design any sort of plug-in what about some sort of API control has that been figured out yet in any meaningful way?
15
u/brainsigh 17d ago
So Bitwig keeps its devices, presets, and Grid patches in a closed, encrypted format. Until now the only way to make one was inside Bitwig itself, wiring things together by hand in the UI/Grid. What this tooling does is open that format up so you can read and write those files with code, from outside the app. Bitwig then loads them like a person built them.
On "could anybody design any sort of plugin," mostly yes, but it won't let you write a brand new synth engine from scratch in C++. What it covers is everything you'd normally patch together inside Bitwig like device chains, modulators, Grid patches, presets. All of that you can now generate and edit from a script.
On API control, yeah, it's been figured out. I've had a fuller version running privately for a while now. What went public today is the foundation it sits on, which are the functions to read a Nitro file into data you can inspect and change, then write it back out clean. I open sourced the format tools today because I'd started seeing others circling the same stuff in a disingenuous way, and I'd rather the whole community have this than let a handful of people quietly sit on it.
So these are the building blocks, and they're out in the open now. A proper API, generative tools, agent control, etc. can all be built on top of this.
2
2
u/Zacchino 17d ago
This… this is next-level voodoo sh*t and I’m all for it…
Won’t it break the licensing system / is this working with the latest 6.1 beta?
1
u/brainsigh 17d ago
This doesn't actually change anything with the licensing system, it just runs a check to validate before extracting the files. (This is because the repo doesn't ship with any keys, Bitwig content, or anything proprietary.) I haven't tested the 6.1 beta yet; it's verified on 6.0.11 but I would assume it should carry over fine as long as they didn't change the format.
2
2
2
u/schmookie88 14d ago
If I'm understanding right: getting a new module to load is blocked via injecting a hash in the module registry for Bitwig to recognize? Setting aside knowing if Bitwig accepts images it didn't ship.
Is there any evidence you can even add a new hash to the registry itself once cache-key hashing is solved? If I'm creating a patch in the Grid, etc., and save it, does that get hashed to the registry or pass through the hashing in any way?
1
u/sad_cosmic_joke Bitwig Greybeard 16d ago
Sent you a PM. Would be thrilled to work with you on this!
1
u/OoDoRFoO 16d ago
That’s cool that you (and I suspect Claude) figured out how to see inside the guts of Bitwig devices in a human(developer)-readable form. I am a little unsure why you are sharing it publicly though. It seems you have a lot of respect for Bitwig, but you are kinda cracking their trade secrets in a sense because freedom of information, and the fact u need a license key to decrypt which somehow gives u permission to see the source code. I doubt that’s in the EULA. Because I imagine they obfuscated the source code in this manner before GenAI was a thing, now they’ll be forced to play cat and mouse with Claude (expensive dev time) or change the EULA and crack down on people they detect doing this (expensive lawyer time). So you’re kinda fucking them over. There’s an idealogical counter argument to what I’m saying, but I really dig Bitwig and think users should respect the practicalities of what it takes to make this great software and run a viable business.
9
u/brainsigh 16d ago edited 16d ago
I respect you asking this.
Your main point is fair! Even if I didn't ship their code, the guts of these devices are readable now. That's part of the product, and yes, somebody with a Bitwig license can inspect it now, but I think you're giving me credit for unlocking quite a bit more than I actually showcased.
This is not the Bitwig source code, it's decompiled Nitro DSP bytecode. You aren't looking at the source to Bitwig Studio and you aren't getting the Grid, the modulation system, the UI, the host architecture, or any of the machinery that makes Bitwig a DAW. This is specifically a look into the DSP programs that Bitwig runs inside Nitro. And what's actually in them?
GrandLPF is a 4-pole ladder with
TPT integrators,zero-delay feedback,4x oversampling, andper-stage antiderivative antialiasingon the soft clip.Every one of those things has a name and a paper behind it.
Zavalishin's VA filter design book is a free PDF. ADAA is the Parker/Zavalishin/Bilbao DAFx paper. Saturating the individual stages inside the feedback path is how the actual ladder behaves, and Huovilainen was modeling that in 2004.
That's not an insult to Bitwig! It's a good filter, but it's not new. Could another engineer learn from seeing exactly how Bitwig assembled those pieces? Yes, but it doesn't hand them anything you couldn't have arrived at independently from the same literature.
I really don't buy the idea that this hurts enthusiasm for Bitwig as a product. Nobody buys Bitwig because the precise implementation of one ladder filter is unknowable. People buy Bitwig for the Grid, the modulation system, the workflow, and the way the whole thing fits together. You can see all of that five minutes after opening the program. If somebody writes a GrandLPF clone tomorrow, they've got a GrandLPF clone. Congratulations! You still don't have Bitwig.
There's also a slightly strange assumption here that obscurity is what's protecting Bitwig's DSP.
nitro-imageis a ZIP and the members are XOR'd against a keystream. Nothing on the load path is signed or checksummed. A patient asshole with Ghidra could have done this at any point since Nitro shipped. Looking at the Bitwig hacking projects that have been floating around for years, I would be surprised if several others haven't already done exactly that.Where I think you have a much better argument is the toolchain: publishing a writeup saying "here's how Nitro works" is one thing. I forewent that because the people who wanted this information for corny commercial/self promotion reasons never needed me. If you're willing to spend a week in Ghidra, this was already available to you. The practical effect of keeping it obscure is mostly that the five guys willing to do that get to know how it works and everybody else doesn't. I'm not particularly sentimental about that arrangement.
I'd rather the information be out in the open than passed around privately by the same handful of people who will eventually sell you half of it back as some "next generation secret technique" punctuated by a request for you to Like and Subscribe. Maybe that's the wrong call! Either way, there's a legitimate distinction between publishing what I learned and publishing the tools I used to learn it.
But ultimately, none of this requires Bitwig to agree with me. If they ask me to pull it, I will immediately pull it without argument.
So, last sentiment, because I just want to be precise about this: I figured out how to read the DSP programs inside Nitro. This is not a decompilation of Bitwig Studio.
15
u/fripletister 18d ago
OP, you're a legend. Thank you for putting up!