Here I uploaded a few files with a txt file with all the information I could get from them - For someone willing to take a look
edit: For .abk files they seem to have a different header section but the BNK1 header is "only" a version newer than the one in this script
Code: Select all
Most of sound effects and speech files (and sometimes ASF music files) are
stored in .BNK and .VIV resource files. The .BNK file may contain several
sounds. BNKs of older version have the following header:
struct OldBNKHeader
{
char szID[4];
WORD wVersion;
WORD wNumberOfSounds;
DWORD dwFirstSoundStart;
DWORD dwSoundsArray[wNumberOfSounds];
};
For the newer BNK files the header is:
struct NewBNKHeader
{
char szID[4];
WORD wVersion;
WORD wNumberOfSounds;
DWORD dwFirstSoundStart;
DWORD dwSoundSize; // = total filesize - dwFirstSoundStart
DWORD dwUnknown; // seems to contain small number <20 or -1
DWORD dwSoundsArray[wNumberOfSounds];
};
szID -- string ID, always "BNKl".
wVersion -- for old version this is 0x0002, for new version -- 0x0004.
wNumberOfSounds -- number of sounds stored in .BNK file.
dwFirstSoundStart -- the starting position of the first sound audio data
relative the BNK file beginning. There's no real use of this...
dwSoundsArray -- the array of (wNumberOfSounds) DWORDs. Each of these is the
shift to the PT header describing the separate sound in .BNK relative to the
starting position of this DWORD. That is, if such DWORD (dwShift) starts at
the position (dwShiftPos) (relative to the start of .BNK), the correspondent
PT header starts at the position: dwPTHeaderPos=dwShiftPos+dwShift.
Note that some DWORDs in this array are zeroes that means they correspond to
no sound. Remember that PT header starts with the "PT\0\0" signature.
So, (dwSoundsArray) points to a number of PT headers in .BNK, which follow the
BNK header. Each of these PT headers describe a separate sound in .BNK.
Refer to the .ASF file description for details on dealing with PT headers.
Note that some PT headers do not contain (dwChannels), (dwSampleRate),
(dwCompression) data. I use the default value if it's omitted in the header:
mono, 22050 Hz, unknown compression. In any case, PT header for .BNK sound
should contain values for (dwNumSamples) and (dwDataStart). (dwDataStart) is
the starting position of sound data relative to the start of .BNK file. Sound
data itself has no additional headers and in case of EA ADPCM compression
(dwCompression==0x07) should be decoded just like "SCDl" block data (following
ASFChunkHeader). As to the size of the sound data, just use (dwNumSamples) and
stop playback of the sound when it's exhausted.
As to .VIV files these seem to be multi-data resources. In particular, they
can contain .BNK/.ASF files. So, if you want to play sounds from a .BNK file
contained within .VIV, just search .VIV for "BNKl" string ID and that will
be just the .BNK file described above. Note that all (dwDataShifts) given in
PT headers in .BNK are always positions relative to the start of .BNK file,
that is, if .BNK is in .VIV, they will be relative to the start of "BNKl"
signature you found in .VIV. To play .ASF file from .VIV you may just search
for "SCHl" string ID and that'll mark the beginning of .ASF file, while
the end will be marked by "SCEl" block.
Then this version has small differences between the formats but even then, how to update this script?
EDIT2: It seems like "dwDataStart" is not following the 4 byte/field structure, because my hex editor (hexworkshop) can't display the values however when using the hex calculator it has the proper offset/value. I say this because when we have 00 00 00 01 - 14 15 FF 00, the value is actually starting from last byte of the first field, and the BNK1 section inside the ABK file is big endian, yet the rest of the file is little endian, I never found out this until today...guess it's part of the learning curve