mirror of
https://github.com/zeldaret/oot.git
synced 2024-12-01 15:26:01 +00:00
2d454933f3
* [Audio 9/?] Multiversion samplebank and soundfont extraction xmls, 1.0 and 1.1 audio extraction * Rework multiversion samplebanks to reduce duplicates
135 lines
5.8 KiB
Python
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
|