I'm trying to decode the file formats for Massive, FM8 and absynth VST synths. The file format is binary with several sections. Reason for this endeavour is to convert the above formats to general vst .fxp format for automated loading and rendering of presets through the vst api.
From experimenting with saving the files when changing synth parameters I've found out following facts about the format:
- File starts out with length field
- File contains some fixed length sections introduced by "DSIN", "hsin" markers
- The vst binary chunk returned by effGetChunk vst sdk api calls are 99% similar to the .nmsv, .nabs, .nfm8 preset file content
- changing a single parameter in the synth changes some bytes at several places (3-4) in the file
- The main section of the preset file seems to be compressed, while synth parameters should be float values between 0 and 1 they don't seem to be written as floating points into the file - apart from unrecognizable binary values there are plaintext strings e.g. for user defined macros there seems to be some sort of compression applied to the raw data. Compression seems to reference previously encountered strings and reference these strings in later portions of the stream: If "THIS_IS_A_MACRO_NAME_ABC" is preceding "THIS_IS_A_MACRO_NAME_XYZ" in the stream the second string will be compressed to "[short sequence of bytes]_XYZ".
- The files do not seem to contain any dictionary for compression which makes me think the dictionary must be stored somewhere else or there might not be a dictionary at all.
Could anyone help out here:
- What compression scheme could be applied here?
- Does anyone know about a similar format that has been successfully decoded?
Added an example file:
http://s000.tinyupload.com/index.php?file_id=08960658549599455274 contains a sample file. The string "TESTSTRING1" and "PREFIXTESTSTRING1SUFFIX" are contained in the uncompressed stream.
Shannon entropy is 5.84154 for the data chunk which is somewhere in the middle between english text and encrypted.
Here is an example which should demonstrate how the lenght field is computed: The string "TESTSTRING123" precedes the string "PREFIX...SUFFIX".
P R E F I X L1 L2 D S U F L1 D
----------------------------------------------------------------------------------------
PREFIXTESTSTRING123SUFFIX 05 50 52 45 46 49 58 E0 04 16 02 53 55 46 20 12 40 42 00
PREFIXTESTSTRING12SUFFIX 05 50 52 45 46 49 58 E0 03 16 02 53 55 46 20 11 40 41 00
PREFIXTESTSTRING1SUFFIX 05 50 52 45 46 49 58 E0 02 16 02 53 55 46 20 10 40 40 00 33 40
PREFIXTESTSTRINGSUFFIX 05 50 52 45 46 49 58 E0 01 16 02 53 55 46 20 0F 40 3F 00 33 40
PREFIXTESTSTRINSUFFIX 05 50 52 45 46 49 58 E0 00 16 02 53 55 46 20 0E 40 3E 00 33 40
PREFIXTESTSTRISUFFIX 05 50 52 45 46 49 58 C0 16 02 53 55 46 20 0D 40 3D 00 33 40
PREFIXTESTSTRSUFFIX 05 50 52 45 46 49 58 A0 16 02 53 55 46 20 0C 40 3C 00 33 40
PREFIXTESTSTSUFFIX 05 50 52 45 46 49 58 80 16 02 53 55 46 20 0B 40 3B 00 33 40
PREFIXTESTSSUFFIX 05 50 52 45 46 49 58 60 16 02 53 55 46 20 0A 40 3A 00 33 40
PREFIXTESTSUFFIX 05 50 52 45 46 49 58 60 16 01 55 46 20 09 40 39 00 33 40
PREFIXTESSUFFIX 05 50 52 45 46 49 58 20 16 02 53 55 46 20 08 40 38 00 33 40
PREFIXTESUFFIX 05 50 52 45 46 49 58 20 16 01 55 46 20 07 40 37 00 33 40
PREFIXTSUFFIX 09 50 52 45 46 49 58 54 53 55 46 20 06 40 36 00 33 40
DSIN
andhsin
markers are used and connecting stuff via RTTI names, I found zlib usage. According to the RTTI data they have some custom compressed stream class that appears to use zlib. Although the code also seems to check for 'zlib' or 'none' 4 byte markers which aren't in your sample preset.