#!/usr/bin/env python3 # SPDX-FileCopyrightText: © 2024 ZeldaRET # SPDX-License-Identifier: CC0-1.0 # # Configures and runs baserom audio extraction # import argparse from audio.extraction.audio_extract import extract_audio_for_version, GameVersionInfo from audio.extraction.disassemble_sequence import MMLVersion, SequenceTableSpec, SqSection if __name__ == '__main__': parser = argparse.ArgumentParser(description="baserom audio asset extractor") parser.add_argument("-o", "--extracted-dir", required=True, help="path to extracted directory") parser.add_argument("-v", "--version", required=True, help="version name") parser.add_argument("--read-xml", required=False, action="store_true", help="Read extraction xml files") parser.add_argument("--write-xml", required=False, action="store_true", help="Write extraction xml files") args = parser.parse_args() version = args.version # TODO move these to config yaml soundfont_table_code_offset, seq_font_table_code_offset, seq_table_code_offset, sample_bank_table_code_offset = { "n64-jp-1.0" : (0xC97130-0xB5F000, 0xC973C0-0xB5F000, 0xC975D0-0xB5F000, 0xC97DE0-0xB5F000), "n64-us" : (0xC776C0-0xB3C000, 0xC77960-0xB3C000, 0xC77B70-0xB3C000, 0xC78380-0xB3C000), "n64-eu-1.1-dbg" : (0xE0F7E0-0xC95000, 0xE0FA80-0xC95000, 0xE0FC90-0xC95000, 0xE104A0-0xC95000), }[version] # List any sequences that are "handwritten", we don't extract these by # default as we want these checked in for documentation. handwritten_sequences = (0, 1) # Sequence enum names for extraction purposes. seq_enum_names = ( "NA_BGM_GENERAL_SFX", "NA_BGM_AMBIENCE", "NA_BGM_TERMINA_FIELD", "NA_BGM_CHASE", "NA_BGM_MAJORAS_THEME", "NA_BGM_CLOCK_TOWER", "NA_BGM_STONE_TOWER_TEMPLE", "NA_BGM_INV_STONE_TOWER_TEMPLE", "NA_BGM_FAILURE_0", "NA_BGM_FAILURE_1", "NA_BGM_HAPPY_MASK_SALESMAN", "NA_BGM_SONG_OF_HEALING", "NA_BGM_SWAMP_REGION", "NA_BGM_ALIEN_INVASION", "NA_BGM_SWAMP_CRUISE", "NA_BGM_SHARPS_CURSE", "NA_BGM_GREAT_BAY_REGION", "NA_BGM_IKANA_REGION", "NA_BGM_DEKU_PALACE", "NA_BGM_MOUNTAIN_REGION", "NA_BGM_PIRATES_FORTRESS", "NA_BGM_CLOCK_TOWN_DAY_1", "NA_BGM_CLOCK_TOWN_DAY_2", "NA_BGM_CLOCK_TOWN_DAY_3", "NA_BGM_FILE_SELECT", "NA_BGM_CLEAR_EVENT", "NA_BGM_ENEMY", "NA_BGM_BOSS", "NA_BGM_WOODFALL_TEMPLE", "NA_BGM_CLOCK_TOWN_MAIN_SEQUENCE", "NA_BGM_OPENING", "NA_BGM_INSIDE_A_HOUSE", "NA_BGM_GAME_OVER", "NA_BGM_CLEAR_BOSS", "NA_BGM_GET_ITEM", "NA_BGM_CLOCK_TOWN_DAY_2_PTR", "NA_BGM_GET_HEART", "NA_BGM_TIMED_MINI_GAME", "NA_BGM_GORON_RACE", "NA_BGM_MUSIC_BOX_HOUSE", "NA_BGM_FAIRY_FOUNTAIN", "NA_BGM_ZELDAS_LULLABY", "NA_BGM_ROSA_SISTERS", "NA_BGM_OPEN_CHEST", "NA_BGM_MARINE_RESEARCH_LAB", "NA_BGM_GIANTS_THEME", "NA_BGM_SONG_OF_STORMS", "NA_BGM_ROMANI_RANCH", "NA_BGM_GORON_VILLAGE", "NA_BGM_MAYORS_OFFICE", "NA_BGM_OCARINA_EPONA", "NA_BGM_OCARINA_SUNS", "NA_BGM_OCARINA_TIME", "NA_BGM_OCARINA_STORM", "NA_BGM_ZORA_HALL", "NA_BGM_GET_NEW_MASK", "NA_BGM_MINI_BOSS", "NA_BGM_GET_SMALL_ITEM", "NA_BGM_ASTRAL_OBSERVATORY", "NA_BGM_CAVERN", "NA_BGM_MILK_BAR", "NA_BGM_ZELDA_APPEAR", "NA_BGM_SARIAS_SONG", "NA_BGM_GORON_GOAL", "NA_BGM_HORSE", "NA_BGM_HORSE_GOAL", "NA_BGM_INGO", "NA_BGM_KOTAKE_POTION_SHOP", "NA_BGM_SHOP", "NA_BGM_OWL", "NA_BGM_SHOOTING_GALLERY", "NA_BGM_OCARINA_SOARING", "NA_BGM_OCARINA_HEALING", "NA_BGM_INVERTED_SONG_OF_TIME", "NA_BGM_SONG_OF_DOUBLE_TIME", "NA_BGM_SONATA_OF_AWAKENING", "NA_BGM_GORON_LULLABY", "NA_BGM_NEW_WAVE_BOSSA_NOVA", "NA_BGM_ELEGY_OF_EMPTINESS", "NA_BGM_OATH_TO_ORDER", "NA_BGM_SWORD_TRAINING_HALL", "NA_BGM_OCARINA_LULLABY_INTRO", "NA_BGM_LEARNED_NEW_SONG", "NA_BGM_BREMEN_MARCH", "NA_BGM_BALLAD_OF_THE_WIND_FISH", "NA_BGM_SONG_OF_SOARING", "NA_BGM_MILK_BAR_DUPLICATE", "NA_BGM_FINAL_HOURS", "NA_BGM_MIKAU_RIFF", "NA_BGM_MIKAU_FINALE", "NA_BGM_FROG_SONG", "NA_BGM_OCARINA_SONATA", "NA_BGM_OCARINA_LULLABY", "NA_BGM_OCARINA_NEW_WAVE", "NA_BGM_OCARINA_ELEGY", "NA_BGM_OCARINA_OATH", "NA_BGM_MAJORAS_LAIR", "NA_BGM_OCARINA_LULLABY_INTRO_PTR", "NA_BGM_OCARINA_GUITAR_BASS_SESSION", "NA_BGM_PIANO_SESSION", "NA_BGM_INDIGO_GO_SESSION", "NA_BGM_SNOWHEAD_TEMPLE", "NA_BGM_GREAT_BAY_TEMPLE", "NA_BGM_NEW_WAVE_SAXOPHONE", "NA_BGM_NEW_WAVE_VOCAL", "NA_BGM_MAJORAS_WRATH", "NA_BGM_MAJORAS_INCARNATION", "NA_BGM_MAJORAS_MASK", "NA_BGM_BASS_PLAY", "NA_BGM_DRUMS_PLAY", "NA_BGM_PIANO_PLAY", "NA_BGM_IKANA_CASTLE", "NA_BGM_GATHERING_GIANTS", "NA_BGM_KAMARO_DANCE", "NA_BGM_CREMIA_CARRIAGE", "NA_BGM_KEATON_QUIZ", "NA_BGM_END_CREDITS", "NA_BGM_OPENING_LOOP", "NA_BGM_TITLE_THEME", "NA_BGM_DUNGEON_APPEAR", "NA_BGM_WOODFALL_CLEAR", "NA_BGM_SNOWHEAD_CLEAR", "NA_BGM_SEQ_122", "NA_BGM_INTO_THE_MOON", "NA_BGM_GOODBYE_GIANT", "NA_BGM_TATL_AND_TAEL", "NA_BGM_MOONS_DESTRUCTION", "NA_BGM_END_CREDITS_SECOND_HALF", ) # Some bugged soundfonts report the wrong samplebank. Map them to the correct samplebank for proper sample discovery. fake_banks = { "n64-jp-1.0" : { 37 : 2 }, }.get(version, { 40 : 2 }) # Some audiotable banks have a buffer clearing bug. Indicate which banks suffer from this. audiotable_buffer_bugs = () # Tables have no clear start and end in a sequence. Mark the locations of all tables that appear in sequences. seq_disas_tables = { # sequence number : (spec, ...) 0 : ( SequenceTableSpec(0x011E, 8, 0, SqSection.TABLE), SequenceTableSpec(0x012E, 464, 0, SqSection.CHAN), SequenceTableSpec(0x18B2, 48, 0, SqSection.LAYER), SequenceTableSpec(0x1990, 112, 0, SqSection.CHAN), SequenceTableSpec(0x23D8, 8, 0, SqSection.TABLE), SequenceTableSpec(0x23E8, 464, 0, SqSection.CHAN), SequenceTableSpec(0x566E, 8, 0, SqSection.TABLE), SequenceTableSpec(0x567E, 733, 0, SqSection.CHAN), SequenceTableSpec(0xA4C1, 96, 0, SqSection.CHAN), SequenceTableSpec(0xB163, 16, 0, SqSection.CHAN), SequenceTableSpec(0xB2FE, 8, 0, SqSection.TABLE), SequenceTableSpec(0xB30E, 390, 0, SqSection.CHAN), ), 1 : ( SequenceTableSpec(0x018A, 20, 0, SqSection.LAYER), SequenceTableSpec(0x01B2, 20, 0, SqSection.LAYER), SequenceTableSpec(0x01DA, 20, 0, SqSection.LAYER), SequenceTableSpec(0x0202, 20, 0, SqSection.LAYER), SequenceTableSpec(0x022A, 20, 1, SqSection.LAYER), SequenceTableSpec(0x0252, 20, 1, SqSection.LAYER), SequenceTableSpec(0x027A, 20, 1, SqSection.LAYER), ), } version_info = GameVersionInfo(MMLVersion.MM, soundfont_table_code_offset, seq_font_table_code_offset, seq_table_code_offset, sample_bank_table_code_offset, seq_enum_names, handwritten_sequences, fake_banks, audiotable_buffer_bugs, seq_disas_tables) extract_audio_for_version(version_info, args.extracted_dir, args.read_xml, args.write_xml)