Reverse Engineering Serum Preset Format - Supplementary Notes This article provides supplementary notes and files related to reverse engineering the preset file formats for Xfer Records' Serum synthesizer, covering both the legacy Serum 1 (.fxp) and newer Serum 2 (.SerumPreset) formats. The author shares a collection of text files, a Kaitai Struct definition, and a Python extractor script used to map and parse the binary parameter data within Serum presets. The notes also reference additional resources, including Twitter threads and GitHub repositories, that document the process of interacting with VSTs programmatically and analyzing the preset structure. Reverse Engineering Serum Preset Format - Supplementary Notes Table of Contents < -- TOC start generated with https://bitdowntoc.derlin.ch/ -- - Overview overview - Serum 1 Preset File Format .fxp serum-1-preset-file-format-fxp - Serum 2 Preset File Format .SerumPreset serum-2-preset-file-format-serumpreset - Tweets tweets - 2025-04-21 – Revisiting and Expanding on Reverse Engineering the Serum VST Preset Format 2025-04-21--revisiting-and-expanding-on-reverse-engineering-the-serum-vst-preset-format - Older / Other Tweets / Threads? older--other-tweets--threads - See Also see-also < -- TOC end -- The following files are also included in this gist: - serum-params-from-pedalboard.txt file-serum-params-from-pedalboard-txt - serum-params-in-code.txt file-serum-params-in-code-txt - serum-params-SYParameters-1-demo.txt file-serum-params-syparameters-1-demo-txt - serum-params-SYParameters-1.334.txt file-serum-params-syparameters-1-334-txt - vst fxp.ksy file-vst fxp-ksy - vst fxp extractor.py file-vst fxp extractor-py And you can see my overview/thoughts/notes about some of them in this comment on the other gist: - https://gist.github.com/0xdevalias/5a06349b376d01b2a76ad27a86b08c1b?permalink comment id=5548789 gistcomment-5548789 Overview 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: - Generating Synth Patches with AI 0xdevalias' gist https://gist.github.com/0xdevalias/5a06349b376d01b2a76ad27a86b08c1b generating-synth-patches-with-ai Specifically sections like: - Interacting with VSTs from code https://gist.github.com/0xdevalias/5a06349b376d01b2a76ad27a86b08c1b interacting-with-vsts-from-code - Reverse engineering Serum patch format https://gist.github.com/0xdevalias/5a06349b376d01b2a76ad27a86b08c1b reverse-engineering-serum-patch-format - Parsing preset files from code .fxp/.fxb/.vstpreset https://gist.github.com/0xdevalias/5a06349b376d01b2a76ad27a86b08c1b parsing-preset-files-from-code-fxpfxbvstpreset - etc As well as the comments on that gist, as there are also some useful/insightful additions/discussion there too: - https://gist.github.com/0xdevalias/5a06349b376d01b2a76ad27a86b08c1b comments Serum 1 Preset File Format .fxp The notes/links in the Overview 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 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" 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: - https://github.com/KennethWussmann/serum-preset-packager/issues/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 https://gist.github.com/0xdevalias/5a06349b376d01b2a76ad27a86b08c1b?permalink comment id=5548789 gistcomment-5548789 , 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: - https://gist.github.com/0xdevalias/135a18e979ac8e302ebbc700a50a8d74 table-of-contents But as a quick reference, here are the files I just added: The following files are also included in this gist: - serum-params-from-pedalboard.txt https://gist.github.com/0xdevalias/135a18e979ac8e302ebbc700a50a8d74 file-serum-params-from-pedalboard-txt - serum-params-in-code.txt https://gist.github.com/0xdevalias/135a18e979ac8e302ebbc700a50a8d74 file-serum-params-in-code-txt - serum-params-SYParameters-1-demo.txt https://gist.github.com/0xdevalias/135a18e979ac8e302ebbc700a50a8d74 file-serum-params-syparameters-1-demo-txt - serum-params-SYParameters-1.334.txt https://gist.github.com/0xdevalias/135a18e979ac8e302ebbc700a50a8d74 file-serum-params-syparameters-1-334-txt - vst fxp.ksy https://gist.github.com/0xdevalias/135a18e979ac8e302ebbc700a50a8d74 file-vst fxp-ksy - vst fxp extractor.py https://gist.github.com/0xdevalias/135a18e979ac8e302ebbc700a50a8d74 file-vst fxp extractor-py 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 in SYParameters.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 in serum-params-SYParameters-1-demo.txt only go up to 288 LFO8 Delay , whereas serum-params-SYParameters-1.334.txt goes up to 298 FX Hyper Level ; so that's probably why I included the second ..snip.. comment in data 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 my poc-audio-pedalboard repo here: - https://github.com/0xdevalias/poc-audio-pedalboard 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 and HackyCrazy-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 header Then 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 '