1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
# SPDX-FileCopyrightText: © 2024 ZeldaRET
# SPDX-License-Identifier: CC0-1.0
#
#
#
from xml.etree import ElementTree
from xml.etree.ElementTree import Element
from .util import error
class ExtractionDescription:
def __init__(self, file_path : str, file_name : str, version_name : str) -> None:
self.type_name = type(self).__name__.replace("ExtractionDescription", "")
self.file_name = file_name.replace(".xml", "")
self.file_path = file_path
xml_root = ElementTree.parse(file_path).getroot()
if xml_root.tag != self.type_name or "Name" not in xml_root.attrib or "Index" not in xml_root.attrib:
error(f"Malformed {self.type_name} extraction xml: \"{file_path}\"")
self.name = xml_root.attrib["Name"]
self.index = int(xml_root.attrib["Index"])
self.post_init(xml_root, version_name)
def post_init(self, xml_root : Element, version_name : str):
raise NotImplementedError() # Implement in subclass
def in_version(self, version_include, version_exclude, version_name : str):
if version_include == "":
version_include = "All"
if version_exclude == "":
version_exclude = "None"
# Determine if this layout is the one we need
if version_include != "All":
version_include = version_include.split(",")
if version_exclude != "None":
version_exclude = version_exclude.split(",")
included = version_include == "All" or version_name in version_include
excluded = version_exclude != "None" and version_name in version_exclude
return included and not excluded
class SampleBankExtractionDescription(ExtractionDescription):
def post_init(self, xml_root : Element, version_name : str):
self.included_version = None
self.sample_info = []
self.sample_info_versions = []
self.blob_info = []
for item in xml_root:
if item.tag == "Sample":
version_include = item.attrib.get("VersionInclude", "")
version_exclude = item.attrib.get("VersionExclude", "")
in_version = self.in_version(version_include, version_exclude, version_name)
if in_version:
self.sample_info.append(item.attrib)
self.sample_info_versions.append((item.tag, item.attrib, in_version))
elif item.tag == "Blob":
version_include = item.attrib.get("VersionInclude", "")
version_exclude = item.attrib.get("VersionExclude", "")
in_version = self.in_version(version_include, version_exclude, version_name)
if in_version:
self.blob_info.append(item.attrib)
self.sample_info_versions.append((item.tag, item.attrib, in_version))
else:
print(xml_root.attrib)
assert False, item.tag
class SoundFontExtractionDescription(ExtractionDescription):
def post_init(self, xml_root : Element, version_name : str):
self.envelopes_info = []
self.instruments_info = {}
self.drums_info = []
self.effects_info = []
self.envelopes_info_versions = []
self.instruments_info_versions = []
self.drums_info_versions = []
self.effects_info_versions = []
for item in xml_root:
if item.tag == "Envelopes":
for env in item:
assert env.tag == "Envelope"
version_include = env.attrib.get("VersionInclude", "")
version_exclude = env.attrib.get("VersionExclude", "")
in_version = self.in_version(version_include, version_exclude, version_name)
if in_version:
self.envelopes_info.append(env.attrib["Name"])
self.envelopes_info_versions.append((env.attrib, in_version))
elif item.tag == "Instruments":
for instr in item:
assert instr.tag == "Instrument"
prg_num = int(instr.attrib["ProgramNumber"])
version_include = instr.attrib.get("VersionInclude", "")
version_exclude = instr.attrib.get("VersionExclude", "")
in_version = self.in_version(version_include, version_exclude, version_name)
if in_version:
self.instruments_info[prg_num] = instr.attrib["Name"]
self.instruments_info_versions.append((instr.attrib, in_version))
elif item.tag == "Drums":
for drum in item:
assert drum.tag == "Drum"
version_include = drum.attrib.get("VersionInclude", "")
version_exclude = drum.attrib.get("VersionExclude", "")
in_version = self.in_version(version_include, version_exclude, version_name)
if in_version:
self.drums_info.append(drum.attrib["Name"])
self.drums_info_versions.append((drum.attrib, in_version))
elif item.tag == "Effects":
for effect in item:
assert effect.tag == "Effect"
version_include = effect.attrib.get("VersionInclude", "")
version_exclude = effect.attrib.get("VersionExclude", "")
in_version = self.in_version(version_include, version_exclude, version_name)
if in_version:
self.effects_info.append(effect.attrib["Name"])
self.effects_info_versions.append((effect.attrib, in_version))
else:
assert False, item.tag
class SequenceExtractionDescription(ExtractionDescription):
def post_init(self, xml_root : Element, version_name : str):
pass
|