+==========================================================================================+ |Commander Keen 4-6 Audio format: | +==========================================================================================+ This is the sound and music file formats for Keen 4-6, Keen Dreams and a number of other ID Software and Apogee games. There are three basic files to consider, the audio huffman dictionary (AUDIODCT) the audio header (AUDIOHED) and the audio data group file (AUDIO). as well as four types of subfile cotained in the AUDIO. These will be considered in turn. +------------------------------------------------------------------------------------------+ |Audio Hufmman Dictionary (AUDIODCT.CKX): | +------------------------------------------------------------------------------------------+ If the AUDIO.CKX file is compressed (And fo Keen it always is.), then there will be a DCT file to decompress it. The DCT is ALWAYS stored in the executable and can be located by the string $FD $01 $00 $00 $00 $00 (This is part of the root node and thus MUST occur in each DCT) In some cases (Biomenace et al), the AUDIO is uncompressed and this file is absent. A quick scan of the executable can confirm this. The DCT, also known as the binary tree (To which it can quickly be rearranged) is described more fully under the file 'Keen 4-6 DICT' which explains the Huffman compression used. However a brief summary of the file's structure is given here: ------------------------------------------------------------------------------- FILE STRUCTURE: NODES ... .. . PADDING ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- STRUCTURE: 0 1020 Node Huffman nodes, 255 4-byte entries 1020 4 Padding Blank ------------------------------------------------------------------------------- ------------------------------------------------ NODE STRUCTURE: ? 1 Left val Left branch character or node value +1 1 Val type Left branch type; $00 = character, $01 = node +2 1 Right val Right branch character or node value +3 1 Val type Right branch type; $00 = character, $01 = node ------------------------------------------------ +------------------------------------------------------------------------------------------+ |Audio Header (AUDIOHED.CKX): | +------------------------------------------------------------------------------------------+ This is the header file for audio data and consists of a number of 4-byte entries pointing to locations in the AUDIO file where sub files start. In essence, using this you can 'unpack' all the (Usually hundreds!) audio files Keen uses. Notice that not all 'entries' may contain a file; if an entry is blank then the next entry will be exactly the same (File is 0 bytes long, x + 0 = x) This is called a 'dummy value' and you can tell what it is because it will occur more than once. It is simpler to just extract an 0-byte file in my opinion. The last entry points to the end of the AUDIO file, and this can be used to find the HED IF it is stored in the exe (Keen 4-6) SO if your audio file is 1025 bytes long ($1001) then look for the string $01 $00 $01 $00 ------------------------------------------------------------------------------- FILE STRUCTURE: POINTERS ... .. . ------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------+ |Audio Group File (AUDIO.CKX): | +------------------------------------------------------------------------------------------+ This is where all the actual audio data is stored. It is ALWAyS external. It consists of each individual file linked together and needs the AUDIOHED to be unpacked. The subfiles can be compressed (AUDIODCT) or uncompressed with the difference being that compressed subfiles have a 4-byte entry at their start saying how long they are when uncompressed. Note that when compression IS used, it is not the AUDIO file that is compressed, but EACH AND EVERY subfile. Subfiles come in four typres, three types of sound and IMF. ------------------------------------------------------------------------------- FILE STRUCTURE: SUBFILE 1 SUBFILE 2... ... .. . ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- SUBFILE STRUCTURE: COMPRESSED ? 4 Dec length Decompressed file length in bytes +4 ? Data Compressed data ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- SUBFILE STRUCTURE: UNCOMPRESSED ? ? Data File data ------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------+ |PC Sounds: | +------------------------------------------------------------------------------------------+ The first type of subfile, and the simplest is the PC sound. Each file controls one PC sound effect used in-game ------------------------------------------------------------------------------- FILE STRUCTURE: 0 4 Length Length of sound data in bytes +4 2 Priority Sounds of a high priority interrupt those with equal or lesser priority (So the 'Got a life' sound will be long, loud and interrupt all other sounds, while the 'walking' sound will get interrupted all the time.) +6 x Data Sound data. Each byte is an inverse-frequency datum lasting about 0.07s, much like the Keen 1-3 sounds but using 1-byte entires instead of 2 (Since PC sounds are less important here.) +x 1 Terminator $00, ends the sound ------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------+ |Digital Sounds: | +------------------------------------------------------------------------------------------+ The second type of subfile. Each file controls one digital sound effect used in-game. Keen does not use digital sounds, but some games do. ------------------------------------------------------------------------------- FILE STRUCTURE: 0 4 Length Length of sound data in bytes +4 2 Priority Sounds of a high priority interrupt those with equal or lesser priority (So the 'Got a life' sound will be long, loud and interrupt all other sounds, while the 'walking' sound will get interrupted all the time.) +6 x Data Sound data. I do not know how this works, but it may be similar to the PC sounds format. +x 1 Terminator $00, ends the sound ------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------+ |Adlib-Soundblaster Sounds: | +------------------------------------------------------------------------------------------+ The third type of subfile. Each file controls one adlib\soundblaster sound effect used in-game. ------------------------------------------------------------------------------- FILE STRUCTURE: 0 4 Length Length of sound data in bytes +4 2 Priority Sounds of a high priority interrupt those with equal or lesser priority (So the 'Got a life' sound will be long, loud and interrupt all other sounds, while the 'walking' sound will get interrupted all the time.) +6 17 Params Adlib parameters, 8x2 + 1 +23 x Data Sound data. I do not know how this works, but it may be similar to the PC sounds format. +x 1 Terminator $00, ends the sound ------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------+ |Id Music Files (IMF): | +------------------------------------------------------------------------------------------+ The fourth type of subfile, and the largest. Anything over 1-byte in length is going to be a music file 9Which cannot exceed 64Kb decompressed.) These are usually the last subfiles in the AUDIO. The id Software Music Format (IMF) is a raw music format that stores the actual bytes sent to the Adlib's OPL2 chip. For this reason it is a very simple format to process. Note that the 'extra data' format given here isn't used by games per se, the extra data that games add to IMF files doesn't have this structure at all and appears to ahve an unknown use. The format IS used by most IMF players though. ------------------------------------------------------------------------------- FILE STRUCTURE: 0 2 Length Length of data (Excluding these bytes) to play. If this is 0 then the whole file is played. This is somtimes referred to as type-1 and type-0 respectively, notable that arbitary data can be stored at the end of type-1 files. 2 1 Ad length Adlib data length APPARENTLY, though how this fits into a single byte confuses ME. Zero for type-0 files 3 1 Ex length Extra data length, once again, makes no sense 6 4x Data Sound data. I do not know how this works, but it may be similar to the PC sounds format. ? ? Extra data For type-1 files only, extra stuff like song title. Some games have data stored here for unknown purposes ------------------------------------------------------------------------------- ------------------------------------------------ DATA STRUCTURE: ? 1 Adlib reg Adlib register. No I don't know what that means +1 1 Adlib dat Adlib data. I don't know what this means either +2 2 Delay Delay. Kinda the 'pause' between data, the less this is, the faster the file plays. There are three speeds, 280, 560 and 700Hz. Wolfenstein 3D (.WLF) uses 700hz, Duke Nukum 2 280 and the rest are 560. It is simple enough to switch speeds by altering (E.g doubbling) the delay values ------------------------------------------------ ------------------------------------------------ EXTRA DATA STRUCTURE: ? 1 Sig Signature, $1A, indicates extra data start +1 x Title Song title, variable length string, max size 255 bytes +? 1 Term terminator byte for title, $00 +? x Comp Song composer, variable length string, max size 255 bytes +? 1 Term terminator byte for composer, $00 +? x Notes Notes on song, variable length string, max size 255 bytes +? 1 Term terminator byte for notes, $00 +? 9 Prog Program that added this data, fixed length padded with nuls ------------------------------------------------