lug files editing

ejonesss

New member
Joined
Apr 30, 2012
Messages
49
i read in a couple places about and even tried the program dragon unpacker witch is able to extract or unpack lug files.

repacking shouldnt be too difficult.

all one needs to do is get the source code for an unpacker and look at the unpacking algorithm and  reverse engineer the unpacking algorithm and make a packer based on it.

lug files cant be that proprietary or it would be a violation of copyrights to unpack them for example you need to be dolby sound licensed to read or play ac3 files used by dvds so to be legal (that's why you only find dvd ac3 to aiff or wav converters on pirate sites and never in legal software sites) and dragon unpacker is fairly out in the open

and what are lug files ?

they seem to act like they are wav files concated  into 1 big file since some of the sounds are extracted by the mac program file juicer

unfortunately file juicer does not extract all the files but because it can extract some suggests lug files are not that proprietary of a format.

when i looked at a lug file in a hex editor or even in a text editor i saw some references to suggest that lug files may be a virtual hard drive because for example

K:\WORK\B+W\B+W 2\sfx\Ingame\Atmos\22\Sacrifice.wav

k: is a pc drive root level sign.

i also see reference to sound forge in the files so does anyone know if sound forge has a file packer in it (it is a $300+ program so i am not getting it anytime soon)
 
  I've not been here for awhile nor working on mods (much). I have been doing a bit though and hope to get back to working on them before too long.

  The actual sounds are stored as raw PCM wave files, uncompressed. They can be extracted very easily by any program that can do something like a search-extract on the WAV file headers. One can also write a script very easily to do it by just looking for the string "RIFF", reading up to the next instance of RIFF, and saving the result as a WAV file (this'll miss the last file but is really easy.. more correct way is to get the file size from the WAV header). RE-packing the file is much more difficult. There are proprietary data entries in the files such as the file size and offset descriptions, the random-selection-groups, ENUM tagging for use in scripts, and so forth.
  To truly be able to edit the files, these need to be understood so that they can be modified. However, an easier thing to do would be to just keep most of this data intact and only allow for modifying already existing sounds. This will still require changing the size/offset entries in the file but this should be pretty easy. The only problem with this may be what appear to be loop entries.. I think part of the data includes a description of a portion of a WAV file that will loop, like a fire burning sound will loop *part* of the whole WAV file, as given by a start-end offset number in one of the sections. If the WAV files are replaced, some of the loops may sound odd if the new sound isn't made correctly.

   Here is the current state of my LUG analysis. It's a bit rough and may not be clearly explaining some entries. I've also attached it as an RTF file. The extension has been changed to .DOC so that it can be uploaded but should still open without trouble:

EDIT: As I'm skimming the file, I noticed a few places where I copy-pasted format but accidently left sentances in place that dont belong, like under the "STRUCT:  Bank-Sample-Table" line.. oops. Like I said, may be rough.





Code:
   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




  -ego533

 
is there any way to add custom sounds like the be a star feature of leisure suit larry 7 did?
 
Back
Top