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,23 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
# Author: Dylan Jones
|
3
|
-
# Date: 2022-04-10
|
4
|
-
|
5
|
-
"""Package logger configuration."""
|
6
|
-
|
7
|
-
import logging
|
8
|
-
|
9
|
-
logger = logging.getLogger("pyrekordbox")
|
10
|
-
|
11
|
-
# Logging format
|
12
|
-
frmt = "[%(asctime)s] %(name)s:%(levelname)-8s - %(message)s"
|
13
|
-
formatter = logging.Formatter(frmt, datefmt="%H:%M:%S")
|
14
|
-
|
15
|
-
# Set up console logger
|
16
|
-
sh = logging.StreamHandler()
|
17
|
-
sh.setLevel(logging.DEBUG)
|
18
|
-
sh.setFormatter(formatter)
|
19
|
-
logger.addHandler(sh)
|
20
|
-
|
21
|
-
# Set logging level
|
22
|
-
logger.setLevel(logging.WARNING)
|
23
|
-
logging.root.setLevel(logging.NOTSET)
|
@@ -1,32 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
# Author: Dylan Jones
|
3
|
-
# Date: 2023-02-01
|
4
|
-
|
5
|
-
import re
|
6
|
-
from pathlib import Path
|
7
|
-
from . import structs
|
8
|
-
from .file import (
|
9
|
-
FILES,
|
10
|
-
SettingsFile,
|
11
|
-
MySettingFile,
|
12
|
-
MySetting2File,
|
13
|
-
DjmMySettingFile,
|
14
|
-
DevSettingFile,
|
15
|
-
)
|
16
|
-
|
17
|
-
RE_MYSETTING = re.compile(".*SETTING[0-9]?.DAT$")
|
18
|
-
|
19
|
-
|
20
|
-
def get_mysetting_paths(root, deep=False):
|
21
|
-
files = list()
|
22
|
-
root = Path(root)
|
23
|
-
iteator = root.rglob("*") if deep else root.iterdir()
|
24
|
-
for path in iteator:
|
25
|
-
if path.is_file() and RE_MYSETTING.match(path.name):
|
26
|
-
files.append(path)
|
27
|
-
return files
|
28
|
-
|
29
|
-
|
30
|
-
def read_mysetting_file(path) -> SettingsFile:
|
31
|
-
obj = FILES[str(Path(path).name)]
|
32
|
-
return obj.parse_file(path)
|
@@ -1,369 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
# Author: Dylan Jones
|
3
|
-
# Date: 2023-02-01
|
4
|
-
|
5
|
-
"""Rekordbox My-Setting file handlers."""
|
6
|
-
|
7
|
-
import re
|
8
|
-
from construct import Struct
|
9
|
-
from collections.abc import MutableMapping
|
10
|
-
from . import structs
|
11
|
-
|
12
|
-
# fmt: off
|
13
|
-
CRC16_XMODEM_TABLE = [
|
14
|
-
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
|
15
|
-
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
|
16
|
-
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
|
17
|
-
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
|
18
|
-
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
|
19
|
-
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
|
20
|
-
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
|
21
|
-
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
|
22
|
-
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
|
23
|
-
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
|
24
|
-
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
|
25
|
-
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
|
26
|
-
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
|
27
|
-
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
|
28
|
-
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
|
29
|
-
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
|
30
|
-
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
|
31
|
-
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
|
32
|
-
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
|
33
|
-
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
|
34
|
-
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
|
35
|
-
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
36
|
-
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
|
37
|
-
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
|
38
|
-
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
|
39
|
-
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
|
40
|
-
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
|
41
|
-
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
|
42
|
-
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
|
43
|
-
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
|
44
|
-
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
|
45
|
-
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
|
46
|
-
]
|
47
|
-
# fmt: on
|
48
|
-
|
49
|
-
RE_INVALID_KEY = re.compile("[_u][0-9]?", flags=re.IGNORECASE)
|
50
|
-
|
51
|
-
|
52
|
-
def compute_checksum(data, struct):
|
53
|
-
"""Computes the CRC16 XModem checksum for My-Setting files.
|
54
|
-
|
55
|
-
The checksum is calculated over the contents of the `data` field,
|
56
|
-
except for `DJMSETTING.DAT` files where the checksum is calculated over all
|
57
|
-
preceding bytes including the length fields.
|
58
|
-
|
59
|
-
Parameters
|
60
|
-
----------
|
61
|
-
data : bytes
|
62
|
-
The binary filey contents of the My-Setting file for which the checksum is
|
63
|
-
computed.
|
64
|
-
struct : Struct
|
65
|
-
The ``Struct`` of the My-Setting file. This is used for deciding which bytes
|
66
|
-
are used for computing the checksum.
|
67
|
-
|
68
|
-
Returns
|
69
|
-
-------
|
70
|
-
crc : int
|
71
|
-
The calculated CRC16-XModem checksum.
|
72
|
-
|
73
|
-
References
|
74
|
-
----------
|
75
|
-
https://reveng.sourceforge.io/crc-catalogue/all.htm#crc.cat.crc-16-xmodem
|
76
|
-
"""
|
77
|
-
start = 0 if struct == structs.DjmMySetting else 104
|
78
|
-
crc = 0
|
79
|
-
for byte in data[start:-4]:
|
80
|
-
crc = ((crc << 8) & 0xFF00) ^ CRC16_XMODEM_TABLE[((crc >> 8) & 0xFF) ^ byte]
|
81
|
-
return crc
|
82
|
-
|
83
|
-
|
84
|
-
def _is_valid_key(k: str):
|
85
|
-
return not RE_INVALID_KEY.match(k)
|
86
|
-
|
87
|
-
|
88
|
-
class SettingsFile(MutableMapping):
|
89
|
-
"""Base class for the Rekordbox My-Setting file handler.
|
90
|
-
|
91
|
-
The base class implements the getters and setter defined by the keys and
|
92
|
-
default values in the ``defaults`` class attribute.
|
93
|
-
The keys of the ``defaults`` dictionary, which has to be defined by the inheriting
|
94
|
-
class, defines the valid attributes of the My-Setting file. The values are used
|
95
|
-
as default values if a new (and empty) My-Setting file is initialized.
|
96
|
-
"""
|
97
|
-
|
98
|
-
struct: Struct
|
99
|
-
defaults: dict
|
100
|
-
version: str = "" # only used by DEVSETTING
|
101
|
-
|
102
|
-
def __init__(self):
|
103
|
-
super().__init__()
|
104
|
-
self.parsed = None
|
105
|
-
self._items = dict()
|
106
|
-
|
107
|
-
@classmethod
|
108
|
-
def parse(cls, data: bytes):
|
109
|
-
"""Parses the in-memory data of a Rekordbox settings binary file.
|
110
|
-
|
111
|
-
Parameters
|
112
|
-
----------
|
113
|
-
data : bytes
|
114
|
-
The in-memory binary contents of a Rekordbox settings file.
|
115
|
-
|
116
|
-
Returns
|
117
|
-
-------
|
118
|
-
self : SettingsFile
|
119
|
-
The new instance with the parsed file content.
|
120
|
-
"""
|
121
|
-
self = cls()
|
122
|
-
self._parse(data)
|
123
|
-
return self
|
124
|
-
|
125
|
-
@classmethod
|
126
|
-
def parse_file(cls, path: str):
|
127
|
-
"""Reads and parses a Rekordbox settings binary file.
|
128
|
-
|
129
|
-
Parameters
|
130
|
-
----------
|
131
|
-
path : str
|
132
|
-
The path of a Rekordbox settings file which is used to read
|
133
|
-
the file contents before parsing the binary data.
|
134
|
-
|
135
|
-
Returns
|
136
|
-
-------
|
137
|
-
self : AnlzFile
|
138
|
-
The new instance with the parsed file content.
|
139
|
-
|
140
|
-
See Also
|
141
|
-
--------
|
142
|
-
SettingsFile.parse: Parses the data of a Rekordbox settings file.
|
143
|
-
"""
|
144
|
-
with open(path, "rb") as fh:
|
145
|
-
data = fh.read()
|
146
|
-
return cls.parse(data)
|
147
|
-
|
148
|
-
def _parse(self, data):
|
149
|
-
parsed = self.struct.parse(data)
|
150
|
-
keys = filter(_is_valid_key, parsed.data.keys())
|
151
|
-
items = dict()
|
152
|
-
for key in keys:
|
153
|
-
items[key] = str(parsed.data[key])
|
154
|
-
|
155
|
-
self.parsed = parsed
|
156
|
-
self._items.update(items)
|
157
|
-
|
158
|
-
def __len__(self):
|
159
|
-
return len(self.defaults.keys())
|
160
|
-
|
161
|
-
def __iter__(self):
|
162
|
-
return iter(self.defaults)
|
163
|
-
|
164
|
-
def __getitem__(self, key):
|
165
|
-
try:
|
166
|
-
return self._items[key]
|
167
|
-
except KeyError:
|
168
|
-
return self.defaults[key]
|
169
|
-
|
170
|
-
def __setitem__(self, key, value):
|
171
|
-
if key not in self.defaults.keys():
|
172
|
-
raise KeyError(f"Key {key} not a valid field of {self.__class__.__name__}")
|
173
|
-
self._items[key] = value
|
174
|
-
|
175
|
-
def __delitem__(self, key):
|
176
|
-
del self._items[key]
|
177
|
-
|
178
|
-
def get(self, key, default=None):
|
179
|
-
"""Returns the value of a setting of the My-Setting file.
|
180
|
-
|
181
|
-
If the key is not found in the My-Setting data, but it is present in the
|
182
|
-
``defaults`` class dictionary, that default value is used. Otherwise, the
|
183
|
-
parameter ``default`` is used as default value.
|
184
|
-
|
185
|
-
Parameters
|
186
|
-
----------
|
187
|
-
key : str
|
188
|
-
The key of the setting.
|
189
|
-
default : Any, optional
|
190
|
-
The default value returned if the setting does not exist in the
|
191
|
-
My-Setting file data or the ``defaults`` dictionary.
|
192
|
-
|
193
|
-
Returns
|
194
|
-
-------
|
195
|
-
value : Any
|
196
|
-
The value of the setting.
|
197
|
-
"""
|
198
|
-
try:
|
199
|
-
return self.__getitem__(key)
|
200
|
-
except KeyError:
|
201
|
-
return default
|
202
|
-
|
203
|
-
def set(self, key, value):
|
204
|
-
"""Sets the value of a setting of the My-Setting file.
|
205
|
-
|
206
|
-
Parameters
|
207
|
-
----------
|
208
|
-
key : str
|
209
|
-
The key of the setting.
|
210
|
-
value : Any
|
211
|
-
The new value for updating the setting.
|
212
|
-
"""
|
213
|
-
self.__setitem__(key, value)
|
214
|
-
|
215
|
-
def build(self):
|
216
|
-
"""Constructs the binary data for saving the My-Setting file.
|
217
|
-
|
218
|
-
Returns
|
219
|
-
-------
|
220
|
-
byte_data : bytes
|
221
|
-
The binary file contents fot eh My-Setting file.
|
222
|
-
"""
|
223
|
-
# Copy defaults and update with cuirrent data
|
224
|
-
items = self.defaults.copy()
|
225
|
-
items.update(self._items)
|
226
|
-
|
227
|
-
# Create file data
|
228
|
-
file_items = {"data": items, "checksum": 0}
|
229
|
-
if self.version:
|
230
|
-
file_items["version"] = self.version
|
231
|
-
|
232
|
-
# Compute and update checksum. For this the data has to be serialized twice:
|
233
|
-
# Once for generating the checksum and another time for writing the data
|
234
|
-
# with the updated checksum
|
235
|
-
data = self.struct.build(file_items)
|
236
|
-
checksum = compute_checksum(data, self.struct)
|
237
|
-
file_items["checksum"] = checksum
|
238
|
-
|
239
|
-
# Write data with updated checksum
|
240
|
-
return self.struct.build(file_items)
|
241
|
-
|
242
|
-
def save(self, path):
|
243
|
-
"""Save the contents of the My-Setting file object.
|
244
|
-
|
245
|
-
Parameters
|
246
|
-
----------
|
247
|
-
path : str
|
248
|
-
The file path used for saving.
|
249
|
-
|
250
|
-
See Also
|
251
|
-
--------
|
252
|
-
build: Constructs the binary data of the file.
|
253
|
-
"""
|
254
|
-
data = self.build()
|
255
|
-
with open(path, "wb") as fh:
|
256
|
-
fh.write(data)
|
257
|
-
|
258
|
-
def __repr__(self):
|
259
|
-
return f"{self.__class__.__name__}()"
|
260
|
-
|
261
|
-
|
262
|
-
class MySettingFile(SettingsFile):
|
263
|
-
"""Rekordbox `MYSETTING.DAT` file handler.
|
264
|
-
|
265
|
-
See Also
|
266
|
-
--------
|
267
|
-
SettingsFile : Base class implementing getters and setter defined by the keys and
|
268
|
-
default values in the ``defaults`` class attribute.
|
269
|
-
"""
|
270
|
-
|
271
|
-
struct = structs.MySetting
|
272
|
-
defaults = {
|
273
|
-
"auto_cue": structs.AutoCue.on,
|
274
|
-
"auto_cue_level": structs.AutoCueLevel.memory,
|
275
|
-
"disc_slot_illumination": structs.DiscSlotIllumination.bright,
|
276
|
-
"eject_lock": structs.EjectLock.unlock,
|
277
|
-
"hotcue_autoload": structs.HotCueAutoLoad.on,
|
278
|
-
"hotcue_color": structs.HotCueColor.off,
|
279
|
-
"jog_mode": structs.JogMode.vinyl,
|
280
|
-
"jog_ring_brightness": structs.JogRingBrightness.bright,
|
281
|
-
"jog_ring_indicator": structs.JogRingIndicator.on,
|
282
|
-
"language": structs.Language.english,
|
283
|
-
"lcd_brightness": structs.LCDBrightness.three,
|
284
|
-
"master_tempo": structs.MasterTempo.off,
|
285
|
-
"needle_lock": structs.NeedleLock.lock,
|
286
|
-
"on_air_display": structs.OnAirDisplay.on,
|
287
|
-
"phase_meter": structs.PhaseMeter.type1,
|
288
|
-
"play_mode": structs.PlayMode.single,
|
289
|
-
"quantize": structs.Quantize.on,
|
290
|
-
"quantize_beat_value": structs.QuantizeBeatValue.one,
|
291
|
-
"slip_flashing": structs.SlipFlashing.on,
|
292
|
-
"sync": structs.Sync.off,
|
293
|
-
"tempo_range": structs.TempoRange.ten,
|
294
|
-
"time_mode": structs.TimeMode.remain,
|
295
|
-
}
|
296
|
-
|
297
|
-
|
298
|
-
class MySetting2File(SettingsFile):
|
299
|
-
"""Rekordbox `MYSETTING2.DAT` file handler.
|
300
|
-
|
301
|
-
See Also
|
302
|
-
--------
|
303
|
-
SettingsFile : Base class implementing getters and setter defined by the keys and
|
304
|
-
default values in the ``defaults`` class attribute.
|
305
|
-
"""
|
306
|
-
|
307
|
-
struct = structs.MySetting2
|
308
|
-
defaults = {
|
309
|
-
"vinyl_speed_adjust": structs.VinylSpeedAdjust.touch,
|
310
|
-
"jog_display_mode": structs.JogDisplayMode.auto,
|
311
|
-
"pad_button_brightness": structs.PadButtonBrightness.three,
|
312
|
-
"jog_lcd_brightness": structs.JogLCDBrightness.three,
|
313
|
-
"waveform_divisions": structs.WaveformDivisions.phrase,
|
314
|
-
"waveform": structs.Waveform.waveform,
|
315
|
-
"beat_jump_beat_value": structs.BeatJumpBeatValue.sixteen,
|
316
|
-
}
|
317
|
-
|
318
|
-
|
319
|
-
class DjmMySettingFile(SettingsFile):
|
320
|
-
"""Rekordbox `DJMMYSETTING.DAT` file handler.
|
321
|
-
|
322
|
-
See Also
|
323
|
-
--------
|
324
|
-
SettingsFile : Base class implementing getters and setter defined by the keys and
|
325
|
-
default values in the ``defaults`` class attribute.
|
326
|
-
"""
|
327
|
-
|
328
|
-
struct = structs.DjmMySetting
|
329
|
-
defaults = {
|
330
|
-
"channel_fader_curve": structs.ChannelFaderCurve.linear,
|
331
|
-
"cross_fader_curve": structs.CrossfaderCurve.fast_cut,
|
332
|
-
"headphones_pre_eq": structs.HeadphonesPreEQ.post_eq,
|
333
|
-
"headphones_mono_split": structs.HeadphonesMonoSplit.stereo,
|
334
|
-
"beat_fx_quantize": structs.BeatFXQuantize.on,
|
335
|
-
"mic_low_cut": structs.MicLowCut.on,
|
336
|
-
"talk_over_mode": structs.TalkOverMode.advanced,
|
337
|
-
"talk_over_level": structs.TalkOverLevel.minus_18db,
|
338
|
-
"midi_channel": structs.MidiChannel.one,
|
339
|
-
"midi_button_type": structs.MidiButtonType.toggle,
|
340
|
-
"display_brightness": structs.MixerDisplayBrightness.five,
|
341
|
-
"indicator_brightness": structs.MixerIndicatorBrightness.three,
|
342
|
-
"channel_fader_curve_long": structs.ChannelFaderCurveLong.exponential,
|
343
|
-
}
|
344
|
-
|
345
|
-
|
346
|
-
class DevSettingFile(SettingsFile):
|
347
|
-
"""Rekordbox `DEVSETTING.DAT` file handler.
|
348
|
-
|
349
|
-
Warnings
|
350
|
-
--------
|
351
|
-
The data of the `DEVSETTING.DAT` file is not supported. Only the header can be
|
352
|
-
parsed and written. This class is implemented for completness only.
|
353
|
-
|
354
|
-
See Also
|
355
|
-
--------
|
356
|
-
SettingsFile : Base class implementing getters and setter defined by the keys and
|
357
|
-
default values in the ``defaults`` class attribute.
|
358
|
-
"""
|
359
|
-
|
360
|
-
struct = structs.DevSetting
|
361
|
-
defaults = dict(entries="")
|
362
|
-
|
363
|
-
|
364
|
-
FILES = {
|
365
|
-
"DEVSETTING.DAT": DevSettingFile,
|
366
|
-
"DJMMYSETTING.DAT": DjmMySettingFile,
|
367
|
-
"MYSETTING.DAT": MySettingFile,
|
368
|
-
"MYSETTING2.DAT": MySetting2File,
|
369
|
-
}
|
@@ -1,282 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
# Author: Dylan Jones
|
3
|
-
# Date: 2023-02-01
|
4
|
-
|
5
|
-
"""Binary structures of Rekordbox MySettings files.
|
6
|
-
|
7
|
-
Files in this format include:
|
8
|
-
|
9
|
-
- `DEVSETTINGS.DAT`
|
10
|
-
- `DJMMYSETTING.DAT`
|
11
|
-
- `MYSETTING.DAT`
|
12
|
-
- `MYSETTING2.DAT`
|
13
|
-
|
14
|
-
References
|
15
|
-
----------
|
16
|
-
.. [1] Jan Holthuis. rekordcrate.
|
17
|
-
https://holzhaus.github.io/rekordcrate/rekordcrate/setting/struct.Setting.html
|
18
|
-
"""
|
19
|
-
|
20
|
-
from construct import Int8ul, Int16ul, Int32ul, PaddedString, Const, Padding
|
21
|
-
from construct import Enum, Bytes, Struct, Default, Select
|
22
|
-
|
23
|
-
|
24
|
-
# -- DjmSettings -----------------------------------------------------------------------
|
25
|
-
|
26
|
-
ChannelFaderCurve = Enum(Int8ul, steep_top=0x80, linear=0x81, steep_bottom=0x82)
|
27
|
-
CrossfaderCurve = Enum(Int8ul, constant=0x80, slow_cut=0x81, fast_cut=0x82)
|
28
|
-
HeadphonesPreEQ = Enum(Int8ul, post_eq=0x80, pre_eq=0x81)
|
29
|
-
HeadphonesMonoSplit = Enum(Int8ul, stereo=0x80, mono_split=0x81)
|
30
|
-
BeatFXQuantize = Enum(Int8ul, off=0x80, on=0x81)
|
31
|
-
MicLowCut = Enum(Int8ul, off=0x80, on=0x81)
|
32
|
-
TalkOverMode = Enum(Int8ul, advanced=0x80, normal=0x81)
|
33
|
-
TalkOverLevel = Enum(
|
34
|
-
Int8ul,
|
35
|
-
minus_24db=0x80,
|
36
|
-
minus_18db=0x81,
|
37
|
-
minus_12db=0x82,
|
38
|
-
minus_6db=0x83
|
39
|
-
)
|
40
|
-
MidiChannel = Enum(
|
41
|
-
Int8ul,
|
42
|
-
one=0x80,
|
43
|
-
two=0x81,
|
44
|
-
three=0x82,
|
45
|
-
four=0x83,
|
46
|
-
five=0x84,
|
47
|
-
six=0x85,
|
48
|
-
seven=0x86,
|
49
|
-
eight=0x87,
|
50
|
-
nine=0x88,
|
51
|
-
ten=0x89,
|
52
|
-
eleven=0x8A,
|
53
|
-
twelve=0x8B,
|
54
|
-
thirteen=0x8C,
|
55
|
-
fourteen=0x8D,
|
56
|
-
fifteen=0x8E,
|
57
|
-
sixteen=0x8F
|
58
|
-
)
|
59
|
-
MidiButtonType = Enum(Int8ul, toggle=0x80, trigger=0x81)
|
60
|
-
MixerDisplayBrightness = Enum(
|
61
|
-
Int8ul,
|
62
|
-
white=0x80,
|
63
|
-
one=0x81,
|
64
|
-
two=0x82,
|
65
|
-
three=0x83,
|
66
|
-
four=0x84,
|
67
|
-
five=0x85)
|
68
|
-
MixerIndicatorBrightness = Enum(Int8ul, one=0x80, two=0x81, three=0x82)
|
69
|
-
ChannelFaderCurveLong = Enum(Int8ul, exponential=0x80, smooth=0x81, linear=0x82)
|
70
|
-
|
71
|
-
|
72
|
-
# 52 bytes
|
73
|
-
DjmMySettingBody = Struct(
|
74
|
-
"u1" / Default(Bytes(12), b"xV4\x12\x01\x00\x00\x00 \x00\x00\x00"),
|
75
|
-
"channel_fader_curve" / ChannelFaderCurve,
|
76
|
-
"cross_fader_curve" / CrossfaderCurve,
|
77
|
-
"headphones_pre_eq" / HeadphonesPreEQ,
|
78
|
-
"headphones_mono_split" / HeadphonesMonoSplit,
|
79
|
-
"beat_fx_quantize" / BeatFXQuantize,
|
80
|
-
"mic_low_cut" / MicLowCut,
|
81
|
-
"talk_over_mode" / TalkOverMode,
|
82
|
-
"talk_over_level" / TalkOverLevel,
|
83
|
-
"midi_channel" / MidiChannel,
|
84
|
-
"midi_button_type" / MidiButtonType,
|
85
|
-
"display_brightness" / MixerDisplayBrightness,
|
86
|
-
"indicator_brightness" / MixerIndicatorBrightness,
|
87
|
-
"channel_fader_curve_long" / ChannelFaderCurveLong,
|
88
|
-
"u2" / Padding(27) # Unknown values, always 0 (27 bytes)
|
89
|
-
)
|
90
|
-
|
91
|
-
# -- MySettings ------------------------------------------------------------------------
|
92
|
-
|
93
|
-
OnAirDisplay = Enum(Int8ul, off=0x80, on=0x81)
|
94
|
-
LCDBrightness = Enum(Int8ul, one=0x81, two=0x82, three=0x83, four=0x84, five=0x85)
|
95
|
-
Quantize = Enum(Int8ul, off=0x80, on=0x81)
|
96
|
-
AutoCueLevel = Enum(
|
97
|
-
Int8ul,
|
98
|
-
minus_36db=0x80,
|
99
|
-
minus_42db=0x81,
|
100
|
-
minus_48db=0x82,
|
101
|
-
minus_54db=0x83,
|
102
|
-
minus_60db=0x84,
|
103
|
-
minus_66db=0x85,
|
104
|
-
minus_72db=0x86,
|
105
|
-
minus_78db=0x87,
|
106
|
-
memory=0x88,
|
107
|
-
)
|
108
|
-
Language = Enum(
|
109
|
-
Int8ul,
|
110
|
-
english=0x81,
|
111
|
-
french=0x82,
|
112
|
-
german=0x83,
|
113
|
-
italian=0x84,
|
114
|
-
dutch=0x85,
|
115
|
-
spanish=0x86,
|
116
|
-
russian=0x87,
|
117
|
-
korean=0x88,
|
118
|
-
chinese_simplified=0x89,
|
119
|
-
chinese_traditional=0x8A,
|
120
|
-
japanese=0x8B,
|
121
|
-
portuguese=0x8C,
|
122
|
-
swedish=0x8D,
|
123
|
-
czech=0x8E,
|
124
|
-
hungarian=0x8F,
|
125
|
-
danish=0x90,
|
126
|
-
greek=0x91,
|
127
|
-
turkish=0x92
|
128
|
-
)
|
129
|
-
JogRingBrightness = Enum(Int8ul, off=0x80, dark=0x81, bright=0x82)
|
130
|
-
JogRingIndicator = Enum(Int8ul, off=0x80, on=0x81)
|
131
|
-
SlipFlashing = Enum(Int8ul, off=0x80, on=0x81)
|
132
|
-
DiscSlotIllumination = Enum(Int8ul, off=0x80, dark=0x81, bright=0x82)
|
133
|
-
EjectLock = Enum(Int8ul, unlock=0x80, lock=0x81)
|
134
|
-
Sync = Enum(Int8ul, off=0x80, on=0x81)
|
135
|
-
PlayMode = Enum(Int8ul, continue_=0x80, single=0x81)
|
136
|
-
QuantizeBeatValue = Enum(Int8ul, one=0x80, half=0x81, quarter=0x82, eighth=0x83)
|
137
|
-
HotCueAutoLoad = Enum(Int8ul, off=0x80, on=0x81, rekordbox=0x82)
|
138
|
-
HotCueColor = Enum(Int8ul, off=0x80, on=0x81)
|
139
|
-
NeedleLock = Enum(Int8ul, unlock=0x80, lock=0x81)
|
140
|
-
TimeMode = Enum(Int8ul, elapsed=0x80, remain=0x81)
|
141
|
-
JogMode = Enum(Int8ul, cdj=0x80, vinyl=0x81)
|
142
|
-
AutoCue = Enum(Int8ul, off=0x80, on=0x81)
|
143
|
-
MasterTempo = Enum(Int8ul, off=0x80, on=0x81)
|
144
|
-
TempoRange = Enum(Int8ul, six=0x80, ten=0x81, sixteen=0x82, wide=0x83)
|
145
|
-
PhaseMeter = Enum(Int8ul, type1=0x80, type2=0x81)
|
146
|
-
|
147
|
-
|
148
|
-
# 40 bytes
|
149
|
-
MySettingBody = Struct(
|
150
|
-
"u1" / Default(Bytes(8), b"xV4\x12\x02\x00\x00\x00"),
|
151
|
-
"on_air_display" / OnAirDisplay,
|
152
|
-
"lcd_brightness" / LCDBrightness,
|
153
|
-
"quantize" / Quantize,
|
154
|
-
"auto_cue_level" / AutoCueLevel,
|
155
|
-
"language" / Language,
|
156
|
-
"u2" / Default(Int8ul, 0x01),
|
157
|
-
"jog_ring_brightness" / JogRingBrightness,
|
158
|
-
"jog_ring_indicator" / JogRingIndicator,
|
159
|
-
"slip_flashing" / SlipFlashing,
|
160
|
-
"u3" / Default(Bytes(3), b"\x01\x01\x01"),
|
161
|
-
"disc_slot_illumination" / DiscSlotIllumination,
|
162
|
-
"eject_lock" / EjectLock,
|
163
|
-
"sync" / Sync,
|
164
|
-
"play_mode" / PlayMode,
|
165
|
-
"quantize_beat_value" / QuantizeBeatValue,
|
166
|
-
"hotcue_autoload" / HotCueAutoLoad,
|
167
|
-
"hotcue_color" / HotCueColor,
|
168
|
-
"u4" / Const(0, Int16ul), # Unknown, always 0
|
169
|
-
"needle_lock" / NeedleLock,
|
170
|
-
"u5" / Const(0, Int16ul), # Unknown, always 0
|
171
|
-
"time_mode" / TimeMode,
|
172
|
-
"jog_mode" / JogMode,
|
173
|
-
"auto_cue" / AutoCue,
|
174
|
-
"master_tempo" / MasterTempo,
|
175
|
-
"tempo_range" / TempoRange,
|
176
|
-
"phase_meter" / PhaseMeter,
|
177
|
-
"u6" / Const(0, Int16ul),
|
178
|
-
)
|
179
|
-
|
180
|
-
|
181
|
-
# -- MySettings2 -----------------------------------------------------------------------
|
182
|
-
|
183
|
-
VinylSpeedAdjust = Enum(Int8ul, touch_release=0x80, touch=0x81, release=0x82)
|
184
|
-
JogDisplayMode = Enum(Int8ul, auto=0x80, info=0x81, simple=0x82, artwork=0x83)
|
185
|
-
PadButtonBrightness = Enum(Int8ul, one=0x81, two=0x82, three=0x83, four=0x84)
|
186
|
-
JogLCDBrightness = Enum(Int8ul, one=0x81, two=0x82, three=0x83, four=0x84, five=0x85)
|
187
|
-
WaveformDivisions = Enum(Int8ul, time_scale=0x80, phrase=0x81)
|
188
|
-
Waveform = Enum(Int8ul, waveform=0x80, phase_meter=0x81)
|
189
|
-
BeatJumpBeatValue = Enum(
|
190
|
-
Int8ul,
|
191
|
-
half=0x80,
|
192
|
-
one=0x81,
|
193
|
-
two=0x82,
|
194
|
-
four=0x83,
|
195
|
-
eight=0x84,
|
196
|
-
sixteen=0x85,
|
197
|
-
thirtytwo=0x86,
|
198
|
-
sixtyfour=0x87
|
199
|
-
)
|
200
|
-
|
201
|
-
|
202
|
-
# 40 bytes
|
203
|
-
MySetting2Body = Struct(
|
204
|
-
"vinyl_speed_adjust" / VinylSpeedAdjust,
|
205
|
-
"jog_display_mode" / JogDisplayMode,
|
206
|
-
"pad_button_brightness" / PadButtonBrightness,
|
207
|
-
"jog_lcd_brightness" / JogLCDBrightness,
|
208
|
-
"waveform_divisions" / WaveformDivisions,
|
209
|
-
"u1" / Padding(5),
|
210
|
-
"waveform" / Waveform,
|
211
|
-
"u2" / Default(Int8ul, 0x81),
|
212
|
-
"beat_jump_beat_value" / BeatJumpBeatValue,
|
213
|
-
"u3" / Padding(27), # Unknown (27 bytes), always 0
|
214
|
-
)
|
215
|
-
|
216
|
-
|
217
|
-
# -- DevSettings -----------------------------------------------------------------------
|
218
|
-
|
219
|
-
# 32 bytes
|
220
|
-
DevSettingBody = Struct(
|
221
|
-
"u1" / Default(Bytes(8), b"xV4\x12\x02\x00\x00\x00"),
|
222
|
-
"entries" / Bytes(24),
|
223
|
-
)
|
224
|
-
|
225
|
-
|
226
|
-
# -- Main Tags -------------------------------------------------------------------------
|
227
|
-
|
228
|
-
|
229
|
-
DjmMySetting = Struct(
|
230
|
-
"len_strings" / Const(0x0060, Int32ul),
|
231
|
-
"brand" / Const("PioneerDJ", PaddedString(32, "ascii")),
|
232
|
-
"software" / Const("rekordbox", PaddedString(32, "ascii")),
|
233
|
-
"version" / Const("1.000", PaddedString(32, "ascii")),
|
234
|
-
"len_data" / Const(52, Int32ul),
|
235
|
-
# Main data
|
236
|
-
"data" / DjmMySettingBody,
|
237
|
-
# Footer
|
238
|
-
"checksum" / Int16ul,
|
239
|
-
"unknown" / Const(0x00, Int16ul),
|
240
|
-
)
|
241
|
-
|
242
|
-
|
243
|
-
MySetting = Struct(
|
244
|
-
"len_strings" / Const(0x0060, Int32ul),
|
245
|
-
"brand" / Const("PIONEER", PaddedString(32, "ascii")),
|
246
|
-
"software" / Const("rekordbox", PaddedString(32, "ascii")),
|
247
|
-
"version" / Const("0.001", PaddedString(32, "ascii")),
|
248
|
-
"len_data" / Const(40, Int32ul),
|
249
|
-
# Main data
|
250
|
-
"data" / MySettingBody,
|
251
|
-
# Footer
|
252
|
-
"checksum" / Int16ul,
|
253
|
-
"unknown" / Const(0x00, Int16ul),
|
254
|
-
)
|
255
|
-
|
256
|
-
|
257
|
-
MySetting2 = Struct(
|
258
|
-
"len_strings" / Const(0x0060, Int32ul),
|
259
|
-
"brand" / Const("PIONEER", PaddedString(32, "ascii")),
|
260
|
-
"software" / Const("rekordbox", PaddedString(32, "ascii")),
|
261
|
-
"version" / Const("0.001", PaddedString(32, "ascii")),
|
262
|
-
"len_data" / Const(40, Int32ul),
|
263
|
-
# Main data
|
264
|
-
"data" / MySetting2Body,
|
265
|
-
# Footer
|
266
|
-
"checksum" / Int16ul,
|
267
|
-
"unknown" / Const(0x00, Int16ul),
|
268
|
-
)
|
269
|
-
|
270
|
-
|
271
|
-
DevSetting = Struct(
|
272
|
-
"len_strings" / Const(0x0060, Int32ul),
|
273
|
-
"brand" / Const("PIONEER DJ", PaddedString(32, "ascii")),
|
274
|
-
"software" / Const("rekordbox", PaddedString(32, "ascii")),
|
275
|
-
"version" / PaddedString(32, "ascii"),
|
276
|
-
"len_data" / Const(32, Int32ul),
|
277
|
-
# Main data
|
278
|
-
"data" / DevSettingBody,
|
279
|
-
# Footer
|
280
|
-
"checksum" / Int16ul,
|
281
|
-
"unknown" / Const(0x00, Int16ul),
|
282
|
-
)
|