Skip to content

File Format: CDS

SalsaGal edited this page Oct 6, 2024 · 4 revisions

A proprietary format developed by Crystal Dynamics. Its structure is almost identical to a standard MIDI file of "Type 0" (SMF0). It can be used in conjunction with soundbanks of multiple formats to play sequences with custom sounds. These files can't be found directly, and have to be extracted first by using utilities (desnd or msqsplit).

Header

The magic number should be "QESa".

Name Type Endianness
Magic number ASCII character x4 N/A
Quarter note time Unsigned 32 bit integer Little
Pulses per quarter note Unsigned 16 bit integer Little
Version number Unsigned 16 bit integer Little

Body

The body of a cds file is comprised of a set commands that highly resemble the command set of standard MIDI files. In fact, most of them look identical.

The body continues all the way to the end of the file, and should typically terminate with FF4400. Some extra zeroes may be present due to 4-byte alignment padding.

Crystal Dynamics, however, implemented their own flavor of the MIDI standard and used non-standard undefined commands that trigger specific functions within the sound engines of their games. Most of the custom commands are meta events and most of their uses are currently undocumented.

A loop begins with 0xFF2E01XX and terminates with 0xFF2F00. Sometimes these loops can be unbalanced, meaning that either a "loop begin" marker or a "loop end" marker is missing. The number of "loop begin" markers should always be equal to the number of "loop end" markers. Loops can be recursively nested, so to expand them you need a recursive function that can parse them and unroll them. If a loop is infinite, or its count is equal to 1, then it does not need unrolling.

Value Custom event
FF0001XX Sequence number(?)
FF0101XX
FF0201XX
FF0300
FF0400
FF0503XXXXXX Set tempo (XXXXXX is the quarter note time in Big Endian), it is the equivalent of FF5103XXXXXX in standard MIDI, which is the command for changing the quarter note time/tempo
FF0601XX
FF0701XX
FF0800
FF0900
FF0A00
FF0B00
FF0E01XX
FF1001XX
FF1200
FF1300
FF1402XXXX
FF1502XXXX
FF1802XXXX
FF1A01XX
FF1C01XX
FF2401XX
FF2501XX
FF2902XXXX
FF2E01XX Loop begin (XX is the number of times the loop has to be read. If XX = 0 then the loop gets read infinitely many times)
FF2F00 Loop end, but in standard MIDI makes the whole track stop (Crystal Dynamics used FF4400 for this)
FF3101XX Loop begin(?). Seen used in more complex 'Type 0' sequences. XX appears to be just a label
FF3201XX Loop end(?). Seen used in more complex 'Type 0' sequences. XX appears to be just a label
FF3302XXXX
FF3402XXXX
FF3502XXXX
FF3602XXXX
FF3802XXXX
FF3903XXXXXX Beginning of 'Type 0' sequence(?). Probably incorrect guess
FF3A03XXXXXX
FF3B03XXXXXX
FF3C03XXXXXX
FF3D03XXXXXX
FF3E03XXXXXX
FF3F03XXXXXX
FF4100
FF4200
FF4300
FF4400 Stop/End
FF4506XXXXXXXXXXXX
FF4801XX
FF4900
FF4B02XXXX
FF4C02XXXX
FF4D02XXXX
FF5002XXXX
FFF0nnXXXXXXXXXX... ASCII Text. Probably used for manufacturer's ID, but here it can output any text. "nn" is the number of how many "XX" bytes are gonna be found.
FFF104XXXXXXXX
Clone this wiki locally