1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2024-12-01 15:26:01 +00:00
oot/tools/audio/extraction/extraction_xml.py
Tharo 2d454933f3
[Audio 9/?] Multiversion samplebank and soundfont extraction xmls, 1.0 and 1.1 audio extraction (#2291)
* [Audio 9/?] Multiversion samplebank and soundfont extraction xmls, 1.0 and 1.1 audio extraction

* Rework multiversion samplebanks to reduce duplicates
2024-11-12 08:47:34 -05:00

135 lines
5.8 KiB
Python

# 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.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