Intro
I am writing a EA BNK file format spec in kaitai-struct. The format is more fully described here, but I'll summarize the most relevant parts.
The BNK file is basically an archive that may contain multiple sounds. Each sound entry in the BNK file contains the so-called PT
header containing values somewhat resembling TLVs (I'll keep calling them TLVs just for simplicity). The data for the number of samples in the audio stream, the offset of the audio stream, and other values are each stored in separate TLVs.
Here is the relevant ksy
spec snippet describing the PT header
:
types:
sound_data:
seq:
- id: magic
contents: [PT, 0, 0]
- id: header
type: header(false)
header:
params:
- id: is_subheader
type: bool
seq:
- id: tlvs
type: pt_header_tlv
repeat: until
repeat-until: _.type == tv_type::terminator or (is_subheader and _.type == tv_type::subheader_terminator)
pt_header_tlv:
seq:
- id: type
type: u1
enum: tv_type
- id: value
type:
switch-on: type
cases:
'tv_type::subheader': header(true)
'tv_type::terminator': empty_value
'tv_type::num_samples': num_samples
'tv_type::data_start': data_start
_: unknown_value
unknown_value:
seq:
- id: size
type: u1
- id: no_value
size: size
empty_value:
seq:
- id: no_value
size: 0
data_start:
seq:
- id: size
type: u1
- id: offset
type: u4be
instances:
body:
pos: offset
size: 100 # FIXME: Correct size needed here
num_samples:
seq:
- id: size
type: u1
- id: data_size
type: u2be
enums:
tv_type:
0x80: revision
0x82: channels
0x83: compression_type
0x84: sample_rate
0x85: num_samples
0x86: loop_offset
0x87: loop_length
0x88: data_start
0x8a: subheader_terminator
0x92: bytes_per_sample
0xa0: revision2
0xfd: subheader
0xff: terminator
The problem
I need to take the values for the number of samples and the offset in file (and possibly other values) from separate TLVs and create an instance
for the audio stream with the correct size.
What I tried
I was thinking if it is possible to create a named value
instance for the parent (type header
in my snippet) that could iterate over the TLVs and extract the needed values, but that doesn't seem to be possible. What other approaches could I take to solve this?
The closest example to my problem in the documentation is in the typecasting section, but it assumes that the relevant values are always under the same offset, which is something I cannot assume in my case.