- Overview
- Serum 1 Preset File Format (
.fxp
) - Serum 2 Preset File Format (
.SerumPreset
) - Tweets
- See Also
The following files are also included in this gist:
serum-params-from-pedalboard.txt
serum-params-in-code.txt
serum-params-SYParameters-1-demo.txt
serum-params-SYParameters-1.334.txt
vst_fxp.ksy
vst_fxp_extractor.py
And you can see my overview/thoughts/notes about some of them in this comment on the other gist:
This is just a bit of a scratch pad for extra files/notes that are too big to include in my main notes.. but for most things, what you probably actually want to be looking at is this gist:
Specifically sections like:
- Interacting with VSTs from code
- Reverse engineering Serum patch format
- Parsing preset files from code (.fxp/.fxb/.vstpreset)
- etc
As well as the comments on that gist, as there are also some useful/insightful additions/discussion there too:
The notes/links in the Overview section above are a good starting point for my older notes/etc; and then the additional files 'included in this gist' section of the above Table of Contents also generally relate to my work on exploring the Serum v1 .fxp
preset file format.
I also gave a bit of a high level overview on my Twitter / BlueSky thread included below ("2025-04-21 – Revisiting and Expanding on Reverse Engineering the Serum VST Preset Format"), and also gave a bit of a high level overview of my notes/tools/etc in this issue:
- KennethWussmann/serum-preset-packager#1
-
Support for legacy Serum v1.x
.fxp
preset format
-
As part of uploading my old notes/tools, I made a bit of an overview/context dump from what I could remember of it all, which I am also including here for reference:
Also created a new gist for supplementary notes/files in case I do find anything useful in those notes that I can put up that's too big to make sense to include directly on this gist
Just had a quick skim through the files I had in my old notes and added some to that gist. You can see an overview of them in the Table of Contents:
But as a quick reference, here are the files I just added:
The following files are also included in this gist:
I don't remember exactly which version of the binary / which section/function within it
serum-params-in-code.txt
were extracted from.
vst_fxp.ksy
was my initial attempt at creating a Katai Struct definition for FXP files (and eventually for the Serum preset format itself), but from memory I was finding that it was a bit too painful to try and do exploratory parsing within the limitations of that format (or at least, in my knowledge of how to use it).So then I think I moved mostly iterating on
vst_fxp_extractor.py
as a way to explore and map out the preset format more programmatically.I haven't deeply reviewed the code there recently, but from a quick skim + what I remember, in
data_segments
you can see where I identified a large section of the parameters that corresponded with the params inSYParameters.txt
. I believe the..snip..
comment was just me being lazy in not wanting to write out all the intermediary values/offsets manually, as I think my plan was to do that in a more programmatic/loop sort of way. The values inserum-params-SYParameters-1-demo.txt
only go up to288
(LFO8 Delay
), whereasserum-params-SYParameters-1.334.txt
goes up to298
(FX Hyper Level
); so that's probably why I included the second..snip..
comment indata_segments
to signify the end of where that data mapping seemed to get to.Then the next part of
data_segments
seems to be parameters/offsets I identified more manually via diffing the values. I think for the diffs, I probably wasn't using Serum's built in 'save preset' functionality; I think I was more likely to have been using Spotify Pedalboard to dump the plugin state/similar, and then diffing based on that. So there is probably some crossover with the code in mypoc-audio-pedalboard
repo here:Then from memory, I think I was noticing a seemingly large section of data in the binary that I was trying to figure out what it was for, and I believe my running theory was that it might have been an area reserved for the wavetable/similar; since I think I was noticing changes within that when I was diffing. I can't remember what offset that was unfortunately. But from memory, the changes I was making within the wavetable editor never ended up creating as much data change in the diff as I was expecting. I think one of the theories I wanted to test (but never got around to), was going to be adding/creating a new wavetable from an actual audio file, rather than editing the wavetable within Serum's editor; with the idea being that maybe the editor wavetables weren't storing the full data, if they could be represented by formulae/etc (which might have explained the smaller amount of change I was seeing in the diffs), whereas by creating a new wavetable from audio, I would expect it to fill up the full space available, and therefore show a bigger diff change.
In my test patches/etc folder I can see
HackyCrazy.wav
andHackyCrazy-notes.txt
, which skimming through them, sounds like it relates to my attempts to figure out where the wavetables were stored within the preset data. These are the notes I had there:The
HackyCrazy.wav
wavetable seems to have 136bytes of headerThen the first 'slice' of the wavetable appears to be 16384/4 = 4096 little endian floats (4-bytes each)
⇒ python -c "import struct; print(struct.unpack('<f', bytes.fromhex('0000 80bf')))" (-1.0,)
⇒ python -c "import struct; print(struct.unpack('<f', bytes.fromhex('0000 803f')))" (1.0,)
This was created using an 8x8 grid within serum's wavetable editor; but that can be sliced into smaller chunks.. which I assume would give a maximum slices number that would divide nicely into the above.
It seems that the grid can go up to 64x64: which gives the 4096 we saw above.
From the manual:
Page 11:
The wavetables in Serum consist of up to 256 sub-tables, or single-cycle waves (referred to hereafter as 'frames'). This is probably best thought of as (up to) 256 discrete waveforms, which are joined together end-to- end in the parent file on disk.
Technically speaking, when Serum loads a wavetable it is using 2048 samples for a sub-table of the wavetable set. This means the maximum file size would be 2048(samples) x 256(sub-tables) x 32(bits) (which is exactly 2 megabytes).
Page 13:
NOTE: Serum will always save the changes you have made to a wavetable data inside a preset (your song) unless it is a Factory wavetable. While this uses hard disk space (how much size depends on how many frames you use in the Wavetables, from 8k to 4 Megabytes) the beneft is that you can exchange presets with others, or open your song in the future, without having to worry about table file management. so there is no need to save wavetables unless you want your wavetable to appear in the Wavetable Menu. This increases the size of both the presets and the projects containing them. There is a setting in
Serum.cfg
that you can change in order to disable saving the tables as parts of the presets, but that is not advisable.And then, from memory, all of this offset stuff I was figuring out was on the binary data extracted from Spotify Pedalboard; but then my theory (that I might have briefly tested/checked for a few parameters? Can't remember) was that the same 'binary layout' would almost certainly be used in the preset files themselves (even if the base of the offsets might be slightly different/similar)
Hopefully there is some useful stuff in that to help you out; or if not, at least when future me gets back to looking at this more deeply I'll at least have a better starting point to refresh my memory on what I had already done 😅
There had been some recent (as of 2025-04-22) discussion in the comments on my gist of notes related to figuring out the Serum preset file format; with a lot of the comments relating to the Serum 2 .SerumPreset
file format.
When I shared some podcast notes of Steve Duda talking about how he eventually wants to open the preset format, it inspired KennethWussmann to dive deeper into figuring out the v2 preset format; which as of 2025-04-22, they have basically figured out completely, and created a tool that can pack/unpack v2 presets:
- https://github.com/KennethWussmann/serum-preset-packager
-
CLI tool to unpack and pack Serum 2 preset files
-
That tool doesn't have support for Serum v1 .fxp
preset files (though Serum 2 can convert the legacy presets.. so you could technically access them that way); but this discussion did inspire me to find/share my old notes/tools from when I was digging into the .fxp
format previously. While it's not fully figured out, it's definitely a good starting point for anyone interested in looking deeper; and I also made this issue on the v2 tool to summarise the relevant context/resources for the .fxp
format:
- KennethWussmann/serum-preset-packager#1
-
Support for legacy Serum v1.x
.fxp
preset format
-
- https://x.com/_devalias/status/1914174697149006092
- Also crossposted to BlueSky: https://bsky.app/profile/devalias.net/post/3lncdkufods2a
-
@0xdevalias (April 21, 2025)
Speaking of old projects of mine; there's been some interesting discussion recently on one of my old gists that in part is about reverse engineering / figuring out the Serum VST preset file format.
- https://x.com/_devalias/status/1914174699367743988
-
@0xdevalias (April 21, 2025)
The main gist is here:
- https://gist.github.com/0xdevalias/5a06349b376d01b2a76ad27a86b08c1b#generating-synth-patches-with-ai
But check the comments for recent discussions and insights, for both Serum v1 and v2 preset file formats:
-
- https://x.com/_devalias/status/1914174702328910075
-
@0xdevalias (April 21, 2025)
This also inspired me to dig out some of my old notes and code (that I had forgotten where they were it had been that long.. 😅), and made a new gist to upload those to:
-
- https://x.com/_devalias/status/1914174704363184195
-
@0xdevalias (April 21, 2025)
Which I then summarised/mused over to fill in the context as best I could remember it in this comment back on the main gist:
-
- https://x.com/_devalias/status/1914174706485452998
-
@0xdevalias (April 21, 2025)
If reverse engineering / figuring out the Serum VST preset format is something you have any interest / insight in, I'd love to collaborate on it with anyone who's interested.
(I find it hard to find the time to push forward all of my projects as quickly as I would like to)
-
- https://x.com/_devalias/status/1914484589135061452
-
@0xdevalias (April 22, 2025)
Speaking of the discussions in the comments on my gist, KennethWussmann was making good progress on the Serum 2 preset file format: https://gist.github.com/0xdevalias/5a06349b376d01b2a76ad27a86b08c1b?permalink_comment_id=5548632#gistcomment-5548632
And has since figured it out: https://gist.github.com/0xdevalias/5a06349b376d01b2a76ad27a86b08c1b?permalink_comment_id=5549354#gistcomment-5549354
And published a tool to decode it to JSON: https://github.com/KennethWussmann/serum-preset-packager
-
- https://x.com/_devalias/status/1914484591836193276
-
@0xdevalias (April 22, 2025)
The Serum v1
.fxp
file format hasn't been fully figured out yet, but I summarised links to my old notes/tools/progress on this in the following issue, in case it helps anyone else make further progress on it:
-
- https://bsky.app/profile/devalias.net/post/3lnel5dtoo22u
-
@0xdevalias (April 22, 2025)
I also added 2 new sections to my new gist, summarising the Serum 1 preset (
.fxp
) file format notes:And the Serum 2 preset (
.SerumPreset
) file format notes:
-
-
-
@0xdevalias (April 22, 2025)
And similar to my original gist, to better direct people to the appropriate details in a slightly less scattered/chaotic way than in the past:
Serum 1 Preset File Format (
.fxp
):Serum 2 Preset File Format (
.SerumPreset
):
-
While I don't think there are any older tweet threads about this project (at least based on the following search), in case there are any future ones that I forget to document here, this might help you find them:
- https://gist.github.com/0xdevalias/5a06349b376d01b2a76ad27a86b08c1b#generating-synth-patches-with-ai
- This is where most of my main notes and references on this subject live
- https://gist.github.com/KennethWussmann/5b58e4de728680a0bf8906a8b113103d#file-serum-2-vst3-parameters-json
-
VST3 Parameters of a freshly loaded Serum 2
- Fork: https://gist.github.com/0xdevalias/1b85af59724b79c6484f660ab6982744#file-serum-2-vst3-parameters-json
-