pyrekordbox 0.2.1__py3-none-any.whl → 0.2.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- docs/source/formats/anlz.md +178 -7
- docs/source/formats/db6.md +1 -1
- docs/source/index.md +2 -6
- docs/source/quickstart.md +68 -45
- docs/source/tutorial/index.md +1 -1
- pyrekordbox/__init__.py +1 -1
- pyrekordbox/_version.py +2 -2
- pyrekordbox/anlz/file.py +39 -0
- pyrekordbox/anlz/structs.py +3 -5
- pyrekordbox/config.py +71 -27
- pyrekordbox/db6/database.py +260 -33
- pyrekordbox/db6/registry.py +22 -0
- pyrekordbox/db6/tables.py +3 -4
- {pyrekordbox-0.2.1.dist-info → pyrekordbox-0.2.2.dist-info}/METADATA +12 -11
- pyrekordbox-0.2.2.dist-info/RECORD +80 -0
- {pyrekordbox-0.2.1.dist-info → pyrekordbox-0.2.2.dist-info}/top_level.txt +0 -2
- tests/test_config.py +175 -0
- tests/test_db6.py +78 -0
- build/lib/build/lib/docs/source/conf.py +0 -178
- build/lib/build/lib/pyrekordbox/__init__.py +0 -22
- build/lib/build/lib/pyrekordbox/__main__.py +0 -204
- build/lib/build/lib/pyrekordbox/_version.py +0 -16
- build/lib/build/lib/pyrekordbox/anlz/__init__.py +0 -127
- build/lib/build/lib/pyrekordbox/anlz/file.py +0 -186
- build/lib/build/lib/pyrekordbox/anlz/structs.py +0 -299
- build/lib/build/lib/pyrekordbox/anlz/tags.py +0 -508
- build/lib/build/lib/pyrekordbox/config.py +0 -596
- build/lib/build/lib/pyrekordbox/db6/__init__.py +0 -45
- build/lib/build/lib/pyrekordbox/db6/aux_files.py +0 -213
- build/lib/build/lib/pyrekordbox/db6/database.py +0 -1808
- build/lib/build/lib/pyrekordbox/db6/registry.py +0 -304
- build/lib/build/lib/pyrekordbox/db6/tables.py +0 -1618
- build/lib/build/lib/pyrekordbox/logger.py +0 -23
- build/lib/build/lib/pyrekordbox/mysettings/__init__.py +0 -32
- build/lib/build/lib/pyrekordbox/mysettings/file.py +0 -369
- build/lib/build/lib/pyrekordbox/mysettings/structs.py +0 -282
- build/lib/build/lib/pyrekordbox/utils.py +0 -162
- build/lib/build/lib/pyrekordbox/xml.py +0 -1294
- build/lib/build/lib/tests/__init__.py +0 -3
- build/lib/build/lib/tests/test_anlz.py +0 -206
- build/lib/build/lib/tests/test_db6.py +0 -1039
- build/lib/build/lib/tests/test_mysetting.py +0 -203
- build/lib/build/lib/tests/test_xml.py +0 -629
- build/lib/docs/source/conf.py +0 -178
- build/lib/pyrekordbox/__init__.py +0 -22
- build/lib/pyrekordbox/__main__.py +0 -204
- build/lib/pyrekordbox/_version.py +0 -16
- build/lib/pyrekordbox/anlz/__init__.py +0 -127
- build/lib/pyrekordbox/anlz/file.py +0 -186
- build/lib/pyrekordbox/anlz/structs.py +0 -299
- build/lib/pyrekordbox/anlz/tags.py +0 -508
- build/lib/pyrekordbox/config.py +0 -596
- build/lib/pyrekordbox/db6/__init__.py +0 -45
- build/lib/pyrekordbox/db6/aux_files.py +0 -213
- build/lib/pyrekordbox/db6/database.py +0 -1808
- build/lib/pyrekordbox/db6/registry.py +0 -304
- build/lib/pyrekordbox/db6/tables.py +0 -1618
- build/lib/pyrekordbox/logger.py +0 -23
- build/lib/pyrekordbox/mysettings/__init__.py +0 -32
- build/lib/pyrekordbox/mysettings/file.py +0 -369
- build/lib/pyrekordbox/mysettings/structs.py +0 -282
- build/lib/pyrekordbox/utils.py +0 -162
- build/lib/pyrekordbox/xml.py +0 -1294
- build/lib/tests/__init__.py +0 -3
- build/lib/tests/test_anlz.py +0 -206
- build/lib/tests/test_db6.py +0 -1039
- build/lib/tests/test_mysetting.py +0 -203
- build/lib/tests/test_xml.py +0 -629
- pyrekordbox-0.2.1.dist-info/RECORD +0 -129
- {pyrekordbox-0.2.1.dist-info → pyrekordbox-0.2.2.dist-info}/LICENSE +0 -0
- {pyrekordbox-0.2.1.dist-info → pyrekordbox-0.2.2.dist-info}/WHEEL +0 -0
@@ -1,186 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
# Author: Dylan Jones
|
3
|
-
# Date: 2023-02-01
|
4
|
-
|
5
|
-
import logging
|
6
|
-
from collections import abc
|
7
|
-
from pathlib import Path
|
8
|
-
from typing import Union
|
9
|
-
from .tags import TAGS
|
10
|
-
from . import structs
|
11
|
-
|
12
|
-
logger = logging.getLogger(__name__)
|
13
|
-
|
14
|
-
|
15
|
-
class BuildFileLengthError(Exception):
|
16
|
-
def __init__(self, struct, len_data):
|
17
|
-
super().__init__(
|
18
|
-
f"`len_file` ({struct.len_file}) of '{struct.type}' does not "
|
19
|
-
f"match the data-length ({len_data})!"
|
20
|
-
)
|
21
|
-
|
22
|
-
|
23
|
-
class AnlzFile(abc.Mapping):
|
24
|
-
"""Rekordbox `ANLZnnnn.xxx` binary file handler."""
|
25
|
-
|
26
|
-
def __init__(self):
|
27
|
-
self._path = ""
|
28
|
-
self.file_header = None
|
29
|
-
self.tags = list()
|
30
|
-
|
31
|
-
@property
|
32
|
-
def num_tags(self):
|
33
|
-
return len(self.tags)
|
34
|
-
|
35
|
-
@property
|
36
|
-
def tag_types(self):
|
37
|
-
return [tag.type for tag in self.tags]
|
38
|
-
|
39
|
-
@property
|
40
|
-
def path(self):
|
41
|
-
return self._path
|
42
|
-
|
43
|
-
@classmethod
|
44
|
-
def parse(cls, data: bytes):
|
45
|
-
"""Parses the in-memory data of a Rekordbox analysis binary file.
|
46
|
-
|
47
|
-
Parameters
|
48
|
-
----------
|
49
|
-
data : bytes
|
50
|
-
The in-memory binary contents of a Rekordbox analysis file.
|
51
|
-
|
52
|
-
Returns
|
53
|
-
-------
|
54
|
-
self : AnlzFile
|
55
|
-
The new instance with the parsed file content.
|
56
|
-
"""
|
57
|
-
self = cls()
|
58
|
-
self._parse(data)
|
59
|
-
return self
|
60
|
-
|
61
|
-
@classmethod
|
62
|
-
def parse_file(cls, path: Union[str, Path]):
|
63
|
-
"""Reads and parses a Rekordbox analysis binary file.
|
64
|
-
|
65
|
-
Parameters
|
66
|
-
----------
|
67
|
-
path : str or Path
|
68
|
-
The path of a Rekordbox analysis file which is used to read
|
69
|
-
the file contents before parsing the binary data.
|
70
|
-
|
71
|
-
Returns
|
72
|
-
-------
|
73
|
-
self : AnlzFile
|
74
|
-
The new instance with the parsed file content.
|
75
|
-
|
76
|
-
See Also
|
77
|
-
--------
|
78
|
-
AnlzFile.parse: Parses the data of a Rekordbox analysis file.
|
79
|
-
"""
|
80
|
-
path = Path(path)
|
81
|
-
ext = path.suffix.upper()
|
82
|
-
if ext not in (".DAT", ".EXT", ".2EX"):
|
83
|
-
raise ValueError(f"File type '{ext}' not supported!")
|
84
|
-
|
85
|
-
logger.debug(f"Reading file {path.name}")
|
86
|
-
with open(path, "rb") as fh:
|
87
|
-
data = fh.read()
|
88
|
-
|
89
|
-
self = cls.parse(data)
|
90
|
-
self._path = path
|
91
|
-
return self
|
92
|
-
|
93
|
-
def _parse(self, data: bytes):
|
94
|
-
file_header = structs.AnlzFileHeader.parse(data)
|
95
|
-
tag_type = file_header.type
|
96
|
-
assert tag_type == "PMAI"
|
97
|
-
|
98
|
-
tags = list()
|
99
|
-
i = file_header.len_header
|
100
|
-
while i < file_header.len_file:
|
101
|
-
# Get data starting from struct
|
102
|
-
tag_data = data[i:]
|
103
|
-
# Get the four byte struct type
|
104
|
-
tag_type = tag_data[:4].decode("ascii")
|
105
|
-
|
106
|
-
try:
|
107
|
-
# Parse the struct
|
108
|
-
tag = TAGS[tag_type](tag_data)
|
109
|
-
tags.append(tag)
|
110
|
-
len_header = tag.struct.len_header
|
111
|
-
len_tag = tag.struct.len_tag
|
112
|
-
logger.debug(
|
113
|
-
"Parsed struct '%s' (len_header=%s, len_tag=%s)",
|
114
|
-
tag_type,
|
115
|
-
len_header,
|
116
|
-
len_tag,
|
117
|
-
)
|
118
|
-
except KeyError:
|
119
|
-
logger.warning("Tag '%s' not supported!", tag_type)
|
120
|
-
tag = structs.AnlzTag.parse(tag_data)
|
121
|
-
len_tag = tag.len_tag
|
122
|
-
i += len_tag
|
123
|
-
|
124
|
-
self.file_header = file_header
|
125
|
-
self.tags = tags
|
126
|
-
|
127
|
-
def update_len(self):
|
128
|
-
# Update struct lengths
|
129
|
-
tags_len = 0
|
130
|
-
for tag in self.tags:
|
131
|
-
tag.update_len()
|
132
|
-
tags_len += tag.struct.len_tag
|
133
|
-
# Update file length
|
134
|
-
len_file = self.file_header.len_header + tags_len
|
135
|
-
self.file_header.len_file = len_file
|
136
|
-
|
137
|
-
def build(self):
|
138
|
-
self.update_len()
|
139
|
-
header_data = structs.AnlzFileHeader.build(self.file_header)
|
140
|
-
section_data = b"".join(tag.build() for tag in self.tags)
|
141
|
-
data = header_data + section_data
|
142
|
-
# Check `len_file`
|
143
|
-
len_file = self.file_header.len_file
|
144
|
-
len_data = len(data)
|
145
|
-
if len_file != len_data:
|
146
|
-
raise BuildFileLengthError(self.file_header, len_file)
|
147
|
-
|
148
|
-
return data
|
149
|
-
|
150
|
-
def save(self, path=""):
|
151
|
-
path = path or self._path
|
152
|
-
|
153
|
-
data = self.build()
|
154
|
-
with open(path, "wb") as fh:
|
155
|
-
fh.write(data)
|
156
|
-
|
157
|
-
def get_tag(self, key):
|
158
|
-
return self.__getitem__(key)[0]
|
159
|
-
|
160
|
-
def getall_tags(self, key):
|
161
|
-
return self.__getitem__(key)
|
162
|
-
|
163
|
-
def get(self, key):
|
164
|
-
return self.__getitem__(key)[0].get()
|
165
|
-
|
166
|
-
def getall(self, key):
|
167
|
-
return [tag.get() for tag in self.__getitem__(key)]
|
168
|
-
|
169
|
-
def __len__(self):
|
170
|
-
return len(self.keys())
|
171
|
-
|
172
|
-
def __iter__(self):
|
173
|
-
return iter(set(tag.type for tag in self.tags))
|
174
|
-
|
175
|
-
def __getitem__(self, item):
|
176
|
-
if item.isupper() and len(item) == 4:
|
177
|
-
return [tag for tag in self.tags if tag.type == item]
|
178
|
-
else:
|
179
|
-
return [tag for tag in self.tags if tag.name == item]
|
180
|
-
|
181
|
-
def __repr__(self):
|
182
|
-
return f"{self.__class__.__name__}({self.tag_types})"
|
183
|
-
|
184
|
-
def set_path(self, path):
|
185
|
-
tag = self.get_tag("PPTH")
|
186
|
-
tag.set(path)
|
@@ -1,299 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
# Author: Dylan Jones
|
3
|
-
# Date: 2022-10-24
|
4
|
-
|
5
|
-
"""Binary structures of Rekordbox ANLZ-files.
|
6
|
-
|
7
|
-
References
|
8
|
-
----------
|
9
|
-
.. [1] Rekordbox Export Structure Analysis: Analysis Files,
|
10
|
-
https://djl-analysis.deepsymmetry.org/rekordbox-export-analysis/anlz.html
|
11
|
-
"""
|
12
|
-
|
13
|
-
from construct import Int8ub, Int16ub, Int32ub, PaddedString, Int32sb, StopIf
|
14
|
-
from construct import Const, Array, Padding, Bytes
|
15
|
-
from construct import Default, Enum, GreedyRange, Struct, Switch, this
|
16
|
-
|
17
|
-
|
18
|
-
# -- Beat Grid Tag (PQTZ) --------------------------------------------------------------
|
19
|
-
|
20
|
-
AnlzQuantizeTick = Struct(
|
21
|
-
"beat" / Int16ub,
|
22
|
-
"tempo" / Int16ub,
|
23
|
-
"time" / Int32ub # in ms from start
|
24
|
-
)
|
25
|
-
|
26
|
-
# len_header: 24
|
27
|
-
PQTZ = Struct(
|
28
|
-
"u1" / Padding(4),
|
29
|
-
"u2" / Const(0x80000, Int32ub),
|
30
|
-
"entry_count" / Int32ub,
|
31
|
-
"entries" / Array(this.entry_count, AnlzQuantizeTick),
|
32
|
-
)
|
33
|
-
|
34
|
-
|
35
|
-
# Extended Beat Grid Tag (PQT2)
|
36
|
-
|
37
|
-
AnlzQuantizeTick2 = Struct(
|
38
|
-
"beat" / Int8ub, # 1 byte
|
39
|
-
"unkown" / Int8ub, # 1 byte
|
40
|
-
)
|
41
|
-
|
42
|
-
# len_header: 56
|
43
|
-
PQT2 = Struct(
|
44
|
-
Padding(4), # -> 16
|
45
|
-
"u1" / Const(0x01000002, Int32ub), # -> 20, count of "bpm" objects?
|
46
|
-
Padding(4), # -> 24
|
47
|
-
"bpm" / Array(2, AnlzQuantizeTick), # -> 40 (2 * 8 bytes = 16 bytes)
|
48
|
-
"entry_count" / Int32ub, # -> 44 number of entries of 2 bytes
|
49
|
-
"u3" / Int32ub, # -> 48
|
50
|
-
"u4" / Int32ub, # -> 52
|
51
|
-
"u5" / Int32ub, # -> 56
|
52
|
-
# End header
|
53
|
-
StopIf(this.entry_count == 0),
|
54
|
-
# "entries" / Array(this.entry_count, Bytes(2)),
|
55
|
-
"entries" / Array(this.entry_count, AnlzQuantizeTick2),
|
56
|
-
)
|
57
|
-
|
58
|
-
|
59
|
-
# -- Cue List Tag (PCOB) ---------------------------------------------------------------
|
60
|
-
|
61
|
-
AnlzCuePointType = Enum(Int8ub, single=1, loop=2)
|
62
|
-
|
63
|
-
AnlzCuePointStatus = Enum(Int32ub, disabled=0, enabled=4)
|
64
|
-
|
65
|
-
AnlzTagCueObjectType = Enum(Int32ub, memory=0, hotcue=1)
|
66
|
-
|
67
|
-
AnlzCuePoint = Struct(
|
68
|
-
"type" / Const("PCPT", PaddedString(4, encoding="ascii")),
|
69
|
-
"len_header" / Int32ub,
|
70
|
-
"len_entry" / Int32ub,
|
71
|
-
"hot_cue" / Int32ub, # 0 for memory
|
72
|
-
"status" / AnlzCuePointStatus,
|
73
|
-
"u1" / Const(0x10000, Int32ub),
|
74
|
-
"order_first" / Int16ub, # 0xffff for first cue, 0,1,3 for next
|
75
|
-
"order_last" / Int16ub, # 1,2,3 for first, second, third cue, 0xffff for last
|
76
|
-
"type" / AnlzCuePointType,
|
77
|
-
Padding(1),
|
78
|
-
"u2" / Const(1000, Int16ub),
|
79
|
-
"time" / Int32ub,
|
80
|
-
"loop_time" / Default(Int32ub, -1),
|
81
|
-
Padding(16),
|
82
|
-
)
|
83
|
-
|
84
|
-
# len_header: 24
|
85
|
-
PCOB = Struct(
|
86
|
-
"cue_type" / AnlzTagCueObjectType,
|
87
|
-
"unk" / Int16ub,
|
88
|
-
"count" / Int16ub,
|
89
|
-
"memory_count" / Int32sb,
|
90
|
-
"entries" / Array(this.count, AnlzCuePoint),
|
91
|
-
)
|
92
|
-
|
93
|
-
|
94
|
-
# Extended (nxs2) Cue List Tag (PCO2)
|
95
|
-
|
96
|
-
AnlzCuePoint2 = Struct(
|
97
|
-
"type" / Const("PCP2", PaddedString(4, encoding="ascii")),
|
98
|
-
"len_header" / Int32ub,
|
99
|
-
"len_entry" / Int32ub,
|
100
|
-
"hot_cue" / Int32ub, # 0 for memory
|
101
|
-
"type" / Int8ub, # spotted: 0x010003e8 0x020003e8
|
102
|
-
Padding(3),
|
103
|
-
"time" / Int32ub,
|
104
|
-
"loop_time" / Default(Int32ub, -1),
|
105
|
-
"color_id" / Int8ub,
|
106
|
-
Padding(7),
|
107
|
-
"loop_enumerator" / Int16ub,
|
108
|
-
"loop_denominator" / Int16ub,
|
109
|
-
"len_comment" / Int32ub,
|
110
|
-
"comment" / PaddedString(this.len_comment, encoding="utf-16-be"),
|
111
|
-
"color_code" / Int8ub,
|
112
|
-
"color_red" / Int8ub,
|
113
|
-
"color_green" / Int8ub,
|
114
|
-
"color_blue" / Int8ub,
|
115
|
-
Padding(this.len_entry - 48 - this.len_comment),
|
116
|
-
)
|
117
|
-
|
118
|
-
# len_header: 20
|
119
|
-
PCO2 = Struct(
|
120
|
-
"type" / AnlzTagCueObjectType,
|
121
|
-
"count" / Int16ub,
|
122
|
-
"unknown" / Int16ub,
|
123
|
-
"entries" / Array(this.count, AnlzCuePoint2),
|
124
|
-
)
|
125
|
-
|
126
|
-
|
127
|
-
# -- Path Tag (PPTH) -------------------------------------------------------------------
|
128
|
-
|
129
|
-
# len_header: 16
|
130
|
-
PPTH = Struct(
|
131
|
-
"len_path" / Int32ub, # is 0 for some tag types
|
132
|
-
"path" / PaddedString(this.len_path - 2, encoding="utf-16-be"),
|
133
|
-
Padding(2),
|
134
|
-
)
|
135
|
-
|
136
|
-
|
137
|
-
# -- VBR Tag (PVBR) --------------------------------------------------------------------
|
138
|
-
|
139
|
-
# len_header: 16
|
140
|
-
PVBR = Struct(
|
141
|
-
"u1" / Int32ub,
|
142
|
-
"idx" / Array(400, Int32ub),
|
143
|
-
"u2" / Int32ub
|
144
|
-
)
|
145
|
-
|
146
|
-
|
147
|
-
# -- (Tiny) Waveform Preview Tag (PWAV / PWV2) -----------------------------------------
|
148
|
-
|
149
|
-
# len_header: 20
|
150
|
-
PWAV = Struct(
|
151
|
-
"len_preview" / Int32ub, # is 0 for some tag types
|
152
|
-
"unknown" / Const(0x10000, Int32ub),
|
153
|
-
"entries" / Array(this.len_preview, Int8ub),
|
154
|
-
)
|
155
|
-
|
156
|
-
# len_header: 20
|
157
|
-
PWV2 = Struct(
|
158
|
-
"len_preview" / Int32ub, # is 0 for some tag types
|
159
|
-
"unknown" / Const(0x10000, Int32ub),
|
160
|
-
"entries" / Array(this.len_preview, Int8ub),
|
161
|
-
)
|
162
|
-
|
163
|
-
|
164
|
-
# -- Waveform Detail Tag (PWV3) --------------------------------------------------------
|
165
|
-
|
166
|
-
# len_header: 24
|
167
|
-
PWV3 = Struct(
|
168
|
-
"len_entry_bytes" / Const(1, Int32ub),
|
169
|
-
"len_entries" / Int32ub,
|
170
|
-
"u1" / Const(0x00960000, Int32ub),
|
171
|
-
"entries" / Array(this.len_entries, Int8ub),
|
172
|
-
)
|
173
|
-
|
174
|
-
|
175
|
-
# -- Waveform Color Preview Tag (PWV4) -------------------------------------------------
|
176
|
-
|
177
|
-
# len_header: 24
|
178
|
-
PWV4 = Struct(
|
179
|
-
"len_entry_bytes" / Const(0x00000006, Int32ub),
|
180
|
-
"len_entries" / Int32ub,
|
181
|
-
"unknown" / Int32ub,
|
182
|
-
"entries" / Bytes(this.len_entry_bytes * this.len_entries),
|
183
|
-
)
|
184
|
-
|
185
|
-
|
186
|
-
# -- Waveform Color Detail Tag (PWV5) --------------------------------------------------
|
187
|
-
|
188
|
-
# len_header: 24
|
189
|
-
PWV5 = Struct(
|
190
|
-
"len_entry_bytes" / Const(0x00000002, Int32ub),
|
191
|
-
"len_entries" / Int32ub,
|
192
|
-
"unknown" / Int32ub,
|
193
|
-
"entries" / Array(this.len_entries, Int16ub),
|
194
|
-
)
|
195
|
-
|
196
|
-
# -- Song Structure Tag (PSSI) ---------------------------------------------------------
|
197
|
-
|
198
|
-
# FixMe: Implement reverse XOR mask to descramble values
|
199
|
-
|
200
|
-
SongStructureEntry = Struct(
|
201
|
-
"index" / Int16ub,
|
202
|
-
"beat" / Int16ub,
|
203
|
-
"kind" / Int16ub,
|
204
|
-
"u1" / Int8ub,
|
205
|
-
"k1" / Int8ub,
|
206
|
-
"u2" / Int8ub,
|
207
|
-
"k2" / Int8ub,
|
208
|
-
"u3" / Int8ub,
|
209
|
-
"b" / Int8ub,
|
210
|
-
"beat_2" / Int16ub,
|
211
|
-
"beat_3" / Int16ub,
|
212
|
-
"beat_4" / Int16ub,
|
213
|
-
"u4" / Int8ub,
|
214
|
-
"k3" / Int8ub,
|
215
|
-
"u5" / Int8ub,
|
216
|
-
"fill" / Int8ub,
|
217
|
-
"beat_fill" / Int16ub,
|
218
|
-
)
|
219
|
-
|
220
|
-
# len_header: 32
|
221
|
-
PSSI = Struct(
|
222
|
-
"len_entry_bytes" / Const(24, Int32ub),
|
223
|
-
"len_entries" / Int16ub,
|
224
|
-
"mood" / Bytes(2),
|
225
|
-
"u1" / Bytes(6),
|
226
|
-
"end_beat" / Bytes(2),
|
227
|
-
"u2" / Bytes(2),
|
228
|
-
"bank" / Bytes(1),
|
229
|
-
"u3" / Bytes(1),
|
230
|
-
"entries" / Array(this.len_entries, SongStructureEntry),
|
231
|
-
)
|
232
|
-
|
233
|
-
# -- PWV6 ------------------------------------------------------------------------------
|
234
|
-
|
235
|
-
# len_header: 20
|
236
|
-
PWV6 = Struct(
|
237
|
-
"len_entry_bytes" / Const(0x00000003, Int32ub),
|
238
|
-
"len_entries" / Int32ub,
|
239
|
-
"entries" / Bytes(this.len_entry_bytes * this.len_entries),
|
240
|
-
)
|
241
|
-
|
242
|
-
# -- PWV7 ------------------------------------------------------------------------------
|
243
|
-
|
244
|
-
# len_header: 24
|
245
|
-
PWV7 = Struct(
|
246
|
-
"len_entry_bytes" / Const(0x00000003, Int32ub),
|
247
|
-
"len_entries" / Int32ub,
|
248
|
-
"unknown" / Const(0x00960000, Int32ub),
|
249
|
-
"entries" / Bytes(this.len_entry_bytes * this.len_entries),
|
250
|
-
)
|
251
|
-
|
252
|
-
# -- PWVC ------------------------------------------------------------------------------
|
253
|
-
|
254
|
-
# len_header: 14
|
255
|
-
PWVC = Struct(
|
256
|
-
"unknown" / Int16ub,
|
257
|
-
"data" / Array(3, Int16ub)
|
258
|
-
)
|
259
|
-
|
260
|
-
|
261
|
-
# -- Main Items ------------------------------------------------------------------------
|
262
|
-
|
263
|
-
AnlzFileHeader = Struct(
|
264
|
-
"type" / PaddedString(4, encoding="ascii"),
|
265
|
-
"len_header" / Int32ub,
|
266
|
-
"len_file" / Int32ub,
|
267
|
-
"u1" / Int32ub,
|
268
|
-
"u2" / Int32ub,
|
269
|
-
"u3" / Int32ub,
|
270
|
-
"u4" / Int32ub,
|
271
|
-
)
|
272
|
-
|
273
|
-
|
274
|
-
AnlzTag = Struct(
|
275
|
-
"type" / PaddedString(4, encoding="ascii"),
|
276
|
-
"len_header" / Int32ub,
|
277
|
-
"len_tag" / Int32ub,
|
278
|
-
"content" / Switch(
|
279
|
-
this.type,
|
280
|
-
{
|
281
|
-
"PQTZ": PQTZ,
|
282
|
-
"PQT2": PQT2,
|
283
|
-
"PCOB": PCOB, # seen in both DAT and EXT files
|
284
|
-
"PCO2": PCO2, # seen in EXT files
|
285
|
-
"PPTH": PPTH,
|
286
|
-
"PVBR": PVBR,
|
287
|
-
"PSSI": PSSI, # seen in EXT files
|
288
|
-
"PWAV": PWAV,
|
289
|
-
"PWV2": PWV2,
|
290
|
-
"PWV3": PWV3, # seen in EXT files
|
291
|
-
"PWV4": PWV4, # seen in EXT files
|
292
|
-
"PWV5": PWV5, # seen in EXT files
|
293
|
-
"PWV6": PWV6, # seen in 2EX files
|
294
|
-
"PWV7": PWV7, # seen in 2EX files
|
295
|
-
"PWVC": PWVC, # seen in 2EX files
|
296
|
-
},
|
297
|
-
default=Bytes(this.len_tag - 12),
|
298
|
-
),
|
299
|
-
)
|