Authors: WindShadowRuins
Put this inside python script inside your soundbank folder where the soundbank.json is located and it will generate a csv file that will tell you what Play_c and Play_s ID plays Wem files.
#!/usr/bin/env python3
import json
import os
import csv
def extract_wem_mappings(json_file):
print("Starting extraction...")
# Load JSON data
try:
with open(json_file, 'r', encoding='utf-8') as f:
data = json.load(f)
except json.JSONDecodeError as e:
print(f"Error loading JSON: {e}")
input("Press Enter to exit...")
return
# Extract all HIRC objects from all sections
hirc_objects = []
for section in data.get("sections", []):
body = section.get("body", {})
hirc = body.get("HIRC", {})
objects = hirc.get("objects", [])
hirc_objects.extend(objects)
print(f"Extracted {len(hirc_objects)} HIRC objects.")
# Build mapping from Sound objects:
# Mapping: direct_parent_id -> list of WEM source_ids
parent_to_wems = {}
sound_count = 0
for obj in hirc_objects:
if not isinstance(obj, dict):
continue
sound = obj.get("body", {}).get("Sound", {})
if not isinstance(sound, dict):
continue
bank_source = sound.get("bank_source_data", {})
if bank_source.get("plugin") == "VORBIS":
source_id = bank_source.get("media_information", {}).get("source_id")
node_params = sound.get("node_base_params", {})
direct_parent_id = node_params.get("direct_parent_id")
if isinstance(source_id, int) and isinstance(direct_parent_id, int):
parent_to_wems.setdefault(direct_parent_id, []).append(source_id)
sound_count += 1
print(f"Found {sound_count} WEM sound entries. Parent-to-WEM mapping has {len(parent_to_wems)} keys.")
# Build mapping for Action objects:
# Mapping: action object's id (Hash) -> external_id
action_id_to_external = {}
action_count = 0
for obj in hirc_objects:
if not isinstance(obj, dict):
continue
action = obj.get("body", {}).get("Action")
if isinstance(action, dict):
act_hash = obj.get("id", {}).get("Hash")
external_id = action.get("external_id")
if isinstance(act_hash, int) and isinstance(external_id, int):
action_id_to_external[act_hash] = external_id
action_count += 1
print(f"Found {action_count} Action objects with external IDs.")
# Extract play events (Play_c and Play_s) and determine their external_id.
play_to_external = {}
play_count = 0
for obj in hirc_objects:
if not isinstance(obj, dict):
continue
play_name = obj.get("id", {}).get("String")
if play_name and (play_name.startswith("Play_c") or play_name.startswith("Play_s")):
event = obj.get("body", {}).get("Event")
if isinstance(event, dict):
actions = event.get("actions", [])
found_external = None
for act in actions:
if isinstance(act, dict):
# If action is a dict, try to get external_id directly.
ext = act.get("external_id")
if isinstance(ext, int):
found_external = ext
break
elif isinstance(act, int):
# If action is an integer, use it as key in our Action mapping.
if act in action_id_to_external:
found_external = action_id_to_external[act]
break
if found_external is not None:
play_to_external[play_name] = found_external
play_count += 1
print(f"Found {play_count} play events with external IDs.")
# Build the final mapping: for each play event, match its external_id with the Sound's direct_parent_id
final_mappings = []
for play, external_id in play_to_external.items():
wem_ids = parent_to_wems.get(external_id, [])
wem_str = ", ".join(map(str, wem_ids)) if wem_ids else "N/A"
final_mappings.append((play, external_id, wem_str))
print(f"Built final mapping for {len(final_mappings)} play events.")
# Write the output to a CSV file
output_file = "wem_mappings.csv"
try:
with open(output_file, "w", encoding="utf-8", newline="") as csvfile:
writer = csv.writer(csvfile)
writer.writerow(["Play Name", "External ID", "WEM Source IDs"])
for row in final_mappings:
writer.writerow(row)
print(f"Extraction complete! Output saved to {output_file}")
except Exception as e:
print(f"Error writing to file: {e}")
input("Press Enter to exit...")
if __name__ == "__main__":
json_file = "soundbank.json"
if os.path.exists(json_file):
extract_wem_mappings(json_file)
else:
print(f"Error: {json_file} not found in the current directory.")
input("Press Enter to exit...")