LUG files hold audio data for the game. Geneally, it will be audio used by the game engine in-game for special effects, like villager yells, rock smashing, ambience, and so forth. In contrast, music is generally in ogg format.
Each LUG file is a container holding many audio files, always in the WAV format. Further, it seems the packed files are always uncompressed WAV. The WAV files may be either stereo or mono, usually 22050 or 44100 bitrate. Each file has metadata ssociated with it describing the format and how it is used in the game. ENUM script values are assigned to each packed file. Sounds that are to be randomly selected for a particular actions (like a villager grunt) are grouped together.
The LUG files include several major sections containing different data describing the packed files.
LiOnHeAdLHAudioBankMetaData
Header
string[40]
Section Header name, "LiOnHeAdLHAudioBankMetaData"
dword[1]
Size of this section, minus the header name and this value.
dword[1]
Value of "3" . Unknown purpose, possibly a version number. This seems to be the same across all LUG files. The other random though is that it may be a count of 'sub-arrays' for this section
dword[1]
Value of "4" . Unknown purpose, possibly a version number. This seems to be the same across all LUG files. It may also describe the number of following DWORDS
dword[4]
All have a value of "0" . Unknown purpose. These seem to always have a value of 0, and there always seems to be four of them
Filename Metadata Array
dword[1] - "LiOnHeAdLHAudioBankMetaData_FILE_ENTRY_NUM"
This is the number of entries in the following array
STRUCT: Filename-Metadata-Array
This array desribes each of the WAV files contained in this LUG file. This array is a 1:1 association with the actual array of WAV files; In other words, each entry corresponds to a WAV file in the order that the WAV files appear in their own array firther below. The actual WAV files are packed in an array further in the LUG file. The index of an entry corresponds to the index of a WAV file in that array. For instance, the 3rd entry in this array will describe the 3rd WAV file.
dword[1]
This value assigns an index number to this WAV file
dword[1] - "nameSize"
The number of characters in the filename directly below
char[nameSize]
Appears to be the original filename of the WAV file on the computer that compiled the LUG file.
dword[1]
The value indicates the size in bytes of this WAV file. A value of 23145 means that the file will be 23145 bytes long in the packed WAV file array further in the LUG file.
dword[1]
This value is the offset of the WAV file realtive the entire LUG file. a value of 13392039 means that the WAV file's actual audio data exists beginning at address 13392039 in the LUG file.
Partial WAV header
Note that two of the values are in the reverse order as they would normally appear in an actual WAV file header
word[1]
The number of channels in the wAV file. 1 = mono 2 = stereo
word[1]
Compression Code. This value appears to always be "1" which means uncompressed PCM audio data. The meaning of any other codes can be looked up on the internet.
dword[1]
Bitrate. The value will generally be either 22050 or 44100.
?? dword[1] ??
Unkown. Often just 0xFFFF, but not always. It's possible this isn't a dword
?? dword[1] ??
Unkown. Often just 0xFFFF, but not always. It's possible this isn't a dword
END Struct
Filename-Metadata-Array [ LiOnHeAdLHAudioBankMetaData_FILE_ENTRY_NUM ]
An array describing metadata for each WAV file.
Tag Metadata Array
dword[1] - "LiOnHeAdLHAudioBankMetaData_TAG_ENTRY_NUM"
This is the number of entries in the following array
STRUCT: Tag-Metadata-Array
Tag may be a poor name. Much of this array is currently unknown. I suspect that much of the data is part of whtever WAV tagging scheme the Lionhead people were using.. Lik ID3 tags or some other form of tagging. My current working theory is that much of this can be set to "0" with no technical harm other than the loss of original file tag info.
This array is *NOT* 1:1 with the actual array of WAV files. There may be more or less entries.
dword[1]
This value assigns an index number to this tag entry. The tag entry is unique to this array. It is not directly associated with the index assigned in the "Filename-Metadata-Array" array.
dword[1]
"Association index" - This value seems to asociated this tag entry with a WAV file index given in the "Filename-Metadata-Array" array above.
dword[1] - "nameSize"
The number of characters in the tag name directly below
char[nameSize]
The tag name for this entry. Many entries will have the same tag name. A number of entries will have a BLANK tag name. For whatever purpose this tagname entry is for, not all sounds need this tag, apparently. It is possible that these tag names have no purpose in the game and are only informational for the developer. Like, maybe this is WAV file TAG info?
?? word[1] ??
Unkown format or purpose. May not be a word
?? word[1] ??
Unkown format or purpose. May not be a word. Seems to have a relation to tags/files that are grouped. The entries that are grouped in the next array have the same value indicated in this word. The value the meaning of the value itself is unknown.
?? word[1] ??
Unkown format or purpose. May not be a word
?? word[1] ??
Unkown format or purpose. May not be a word
?? dword[1] ??
Unkown format or purpose. May not be a dword
?? word[1] ??
Unkown format or purpose. May not be a word
?? word[1] ??
Unkown format or purpose. May not be a word
float[1]
Unkown purpose. This is very likely a float, but it's possible it isn't.
float[1]
Unkown purpose. This is very likely a float, but it's possible it isn't.
?? dword[1] ??
Unkown format or purpose. May not be a dword
?? word[1] ??
Unkown format or purpose. May not be a word
?? word[1] ??
Unkown format or purpose. May not be a word
float[1]
First float number copied from the "random modulator" array below. The random-array entry that indicates this entrie's tag index number will have the values copied here.
float[1]
Second float number copied from the "random modulator" array below. The random-array entry that indicates this entrie's tag index number will have the values copied here.
float[1]
Third float number copied from the "random modulator" array below. The random-array entry that indicates this entrie's tag index number will have the values copied here.
END Struct
Tag-Metadata-Array [ LiOnHeAdLHAudioBankMetaData_TAG_ENTRY_NUM ]
An array describing tag metadata for each WAV file.
ENUM Metadata Array
dword[1] - "LiOnHeAdLHAudioBankMetaData_ENUM_ENTRY_NUM"
This is the number of entries in the following array
STRUCT: ENUM-Metadata-Array
This array seems to describe script ENUM names. The format of the name string is imilar to the names listed in various .h files used for creating .chl scripts. I suspect this array is used to tie the particular WAV files to script ENUM values.
This array is *NOT* 1:1 with the actual array of WAV files. There may be more or less entries.
dword[1] - "nameSize"
The number of characters in the ENUM name directly below
char[nameSize]
The ENUM name for this entry. No entry will have the same name, but some names are similar, like "ABODESMELTBELLOWS1" , "ABODESMELTBELLOWS2", "ABODESMELTBELLOWS3" and so forth. Unlike the previous array, all entries have a name.
dword[1]
Unkown Purpose. Seems to always be "1". This might describe the number of following groups.. of which there always seems to be one.
dword[1] - "ENUM_ENTRY_COUNT"
A count of the number of tag index entries for this ENUM value.
dword[ ENUM_ENTRY_COUNT ]
These are a list of TAG index entries (not WAV file index!). These values seem to group the various individual tag entries and their associated WAV files into groups for the purpose of this ENUM name. So, for instance, the "BRUSHFUR" enum name has 6 values here. I assume this means that, when this enum value is used for an action or creating a sound, the actual sound produced in the game will be one of a random selection of these 6 WAV files.
END Struct
ENUM-Metadata-Array [ LiOnHeAdLHAudioBankMetaData_ENUM_ENTRY_NUM ]
An array describing tag metadata for each WAV file.
dword[1]
Seems to be padding. All LUG files tested have a "0" here.
LHFileSegmentBankInfo
string[32]
Section Header name, "LHFileSegmentBankInfo"
dword[1]
Size of this section, minus the header name and this value. For this particular section, this value always seems to be 520.
String[520]
It seems that this section is never used in any LUG file. The section will have some names or info, but it is values like "Default Title" or "***SAMPE". This can probably be made blank or set to one of these preset values with no consequence.
LHAudioWaveData
string[32]
Section Header name, "LHAudioWaveData"
dword[1]
Size of this section, minus the header name and this value.
STRUCT: WAV-Data
This array is really a series of packed WAV files in their raw form. This struct is a loose outline of the usual headers. More description of how WAV files are formatted can be found on the internet.
String[4]
Always "RIFF"
dword[1] - "FileSize"
The size in bytes of the rest of this WAV file. Or, the size of this array entry minus the RIFF string and this value.
String[4]
Generally "WAVE"
WAVE header format
Remember that this whole structure is a loose representation. Some of the WAV files have different orders of the format. Some have list tags, with the various entry tags, some don't. Generally, just read the whole wav file in verbatim.
String[1]
Usually "fmt ". Notice the space at the end.
dword[1]
fmt chunk datasize. Or, the size of the rest of the WAVE fmt header in bytes. Or, the size of the entire WAVE header, minus "fmt " and this value
word[1]
Compression Code. I believe all of the LUG files use uncompressed PCM, so this value will always be "1"
word[1]
Number of channels. I believe all the LUG WAV files are either stereo or mono, so this value will be "1"=mono, or "2"=stereo
dword[1]
Sample Rate. It looks like this is always 22050 or 44100 for these LUG WAV files
dword[1]
Bytes per Second. value depends on the format. This will always be a multiple of 22050 (usually one of 22050, 44100, 88200)
word[1]
Block Align. usually 2
word[1]
Bits per sample. Usually 16. Other possible values are things like 8, 24, 32.
End WAVE header
String[4]
Will usually be "data"
Rest of WAV file data here
And so the rest of the WAV file is here.
END Struct
WAV-Data [ LiOnHeAdLHAudioBankMetaData_FILE_ENTRY_NUM ]
An array containing all of the packed WAV files. The size of each file is widely variable. use the sizes specified in the meta data arrays to read them in correctly.
LHAudioBankSampleTable
string[32]
Section Header name, "LHAudioBankSampleTable"
dword[1]
Size of this section, minus the header name and this value.
word[1]
Number of entries in the following array. Notice this is a WORD, not a DWORD
?? word[1] ??
??? - May not be a word, or may be trash, dunno
STRUCT: Bank-Sample-Table
This array is really a series of packed WAV files in their raw form. This struct is a loose outline of the usual headers. More description of how WAV files are formatted can be found on the internet.
String[256]
Original path and name of the WAV file
dword[1]
Padding. Always 0.
dword[1]
The *Tag* index of this file (as defined in the metadata tag array)
dword[1]
The *file* index of this file as defined in the metadata file array
dword[1]
The size in bytes of the file this entry corresponds to
dword[1]
The offset of the beinning of this file, relative to the FIRST RIFF header of the first packed wave file in the LHAudioWaveData section. This is the the file offset as indicated in the previous offset listing.
dword[1]
This seems to count the number of times this particular WAV file is reused (the number of times this particular WAV file is referenced in the tag array). count starts a 0. If the file is used 10 times (10 different 'tags' use the same WAV file), then this number will be 9.
?? word[1] ??
???
?? word[1] ??
???
dword[1]
Padding? Seems to always be 0.
dword[1]
Padding? Seems to always be 0.
Partial WAV header
word[1]
Compression Code. I believe all of the LUG files use uncompressed PCM, so this value will always be "1"
word[1]
Number of channels. I believe all the LUG WAV files are either stereo or mono, so this value will be "1"=mono, or "2"=stereo
dword[1]
Sample Rate. It looks like this is always 22050 or 44100 for these LUG WAV files
dword[1]
Bytes per Second. value depends on the format. This will always be a multiple of 22050 (usually one of 22050, 44100, 88200)
word[1]
Block Align. usually 2
word[1]
Bits per sample. Usually 16. Other possible values are things like 8, 24, 32.
dword[1]
Padding? Seems to always be 0
dword[1]
Not really known. Current guess is that this is a starting address of a portion of the WAV file that wil be played in a loop. So, 0 = start of the WAV file, other numbers indicate an offset into the WAV file (starting from SAMPLE data, not the header data). BE careful not to be off by a few numbers.. the first few values after 'data' may not actually be samples yet.. read more on headers.
dword[1]
Not really known. Current guess is the ending address of a portion of the WAV file that will be played in a loop.
NOTE: The rest of the values seem to have a relation to the 'tag' metadata array above, but not enitrely. SOme of the values are similar, but not all of them are present and a collection of the numbers here are not present in the tag array.
String[256]
Name of 'tag'
?? dword[1] ??
May not be dword. Unkown purpose.
?? dword[1] ??
May not be dword. Unkown purpose.
?? dword[1] ??
May not be dword. Unkown purpose.
?? dword[1] ??
May not be dword. Unkown purpose.
?? dword[1] ??
May not be dword. Unkown purpose.
?? dword[1] ??
May not be dword. Unkown purpose.
?? dword[1] ??
May not be dword. Unkown purpose.
?? dword[1] ??
May not be dword. Unkown purpose.
?? dword[1] ??
May not be dword. Unkown purpose.
?? dword[1] ??
May not be dword. Unkown purpose.
float[1]
Unkown purpose
float[1]
Unkown purpose
?? dword[1] ??
May not be dword. Unkown purpose.
?? dword[1] ??
May not be dword. Unkown purpose.
?? dword[1] ??
May not be dword. Unkown purpose.
?? dword[1] ??
May not be dword. Unkown purpose.
?? dword[1] ??
May not be dword. Unkown purpose.
?? dword[1] ??
May not be dword. Unkown purpose.
END Struct
Bank-Sample-Table [ HIghest Tag Entry Number ]
An array containing all of the packed WAV files. The size of each file is widely variable. use the sizes specified in the meta data arrays to read them in correctly.
LHAudioBankCriteiaInfo
This is a copy of the ENUM Metadata Array above. It contains basically the same information.
string[32]
Section Header name, "LHAudioBankCriteiaInfo"
dword[1]
Size of this section, minus the header name and this value.
dword[1]
Number of entries in the following array. Notice this is a WORD, not a DWORD
STRUCT: Bank-Criteia-Info
dword[1] - "nameSize"
The number of characters in the ENUM name directly below
char[nameSize]
The ENUM name for this entry. No entry will have the same name, but some names are similar, like "ABODESMELTBELLOWS1" , "ABODESMELTBELLOWS2", "ABODESMELTBELLOWS3" and so forth. Unlike the previous array, all entries have a name.
dword[1] - "ENUM_ENTRY_COUNT"
A count of the number of tag index entries for this ENUM value.
dword[ ENUM_ENTRY_COUNT ]
These are a list of TAG index entries (not WAV file index!). These values seem to group the various individual tag entries and their associated WAV files into groups for the purpose of this ENUM name. So, for instance, the "BRUSHFUR" enum name has 6 values here. I assume this means that, when this enum value is used for an action or creating a sound, the actual sound produced in the game will be one of a random selection of these 6 WAV files.
END Struct
Bank-Criteia-Info [ LiOnHeAdLHAudioBankMetaData_ENUM_ENTRY_NUM ]
Basically, a copy of the ENUM metadata array above.
LHAudioBankGlobalProps
This array seems to be identical for all LUG files. They are all the same size and have the same values. The purpose of the values is unknown, and I decided generally not worth discovering since all files simply have the same values.
string[32]
Section Header name, "LHAudioBankGlobalProps"
dword[1]
Size of this section, minus the header name and this value.
dword[1]
Always "4"
dword[1]
Always "1"
dword[1]
Always "0"
dword[1]
Always "0"
dword[1]
Always "0"
dword[1]
Always "0"
LHAudioBankRandomModulator
string[32]
Section Header name, "LHAudioBankRandomModulator"
dword[1]
Size of this section, minus the header name and this value.
dword[1]
Unkown purpose. Seems to always be "1"
dword[1] - RANDOM_MODULATOR_COUNT
Count of the number of entries in the small structure below
STRUCT: Random_Modulator
dword[1]
Index *tag* number. Seems to indicate a tag index number as assigned in the meta-data tag array above
float[1]
Unknown purpose
float[1]
Unknown purpose
float[1]
Unknown purpose
END Struct
Random_Modulator [ RANDOM_MODULATOR_COUNT ]
Unkown purpose