Consolidate all code into one main script

This commit is contained in:
Cainan 2024-06-25 15:35:15 +01:00
parent 5428c72f38
commit d9f883b8a5
8 changed files with 225 additions and 380 deletions

View File

@ -1,70 +0,0 @@
import argparse
import subprocess
import os
import sys
def convert_audio_to_nus3bank(input_audio, audio_type, game, preview_point, song_id):
# Determine the output filename for the nus3bank
output_filename = f"song_{song_id}.nus3bank"
converted_audio_file = f"{input_audio}.{audio_type}"
# Determine the path to the run.py script within the 'script' folder
templates_folder = os.path.join(os.path.dirname(__file__), 'script')
run_py_path = os.path.join(templates_folder, 'run.py')
# Prepare the command based on the audio type
if audio_type in ["bnsf", "at9", "idsp", "lopus", "wav"]:
# Construct the command to convert input audio to the specified type
conversion_command = ["python", run_py_path, audio_type, input_audio, f"{input_audio}.{audio_type}"]
# Construct the command to create the nus3bank
nus3_command = ["python", run_py_path, "nus3", game, f"{input_audio}.{audio_type}", str(preview_point), output_filename]
try:
# Execute the conversion command
subprocess.run(conversion_command, check=True)
# Execute the nus3 command
subprocess.run(nus3_command, check=True)
print(f"Conversion successful! Created {output_filename}")
# Delete the non-nus3bank file after successful conversion
if os.path.exists(converted_audio_file):
os.remove(converted_audio_file)
print(f"Deleted {converted_audio_file}")
except subprocess.CalledProcessError as e:
print(f"Error: {e}")
else:
print(f"Unsupported audio type: {audio_type}")
def main():
# Create an argument parser
parser = argparse.ArgumentParser(description="Convert audio to nus3bank")
# Define command-line arguments
parser.add_argument("input_audio", type=str, nargs="?", help="Input audio file path.")
parser.add_argument("audio_type", type=str, nargs="?", help="Type of input audio (e.g., wav, bnsf, at9, idsp, lopus).")
parser.add_argument("game", type=str, nargs="?", help="Game type (e.g., nijiiro, ns1, ps4, wiiu3).")
parser.add_argument("preview_point", type=int, nargs="?", help="Audio preview point in ms.")
parser.add_argument("song_id", type=str, nargs="?", help="Song ID for the nus3bank file.")
# Parse the command-line arguments
args = parser.parse_args()
# If no arguments are provided, display usage information
if len(sys.argv) == 1:
parser.print_help()
sys.exit(0)
# Validate input audio file path
if not args.input_audio:
print("Error: Input audio file path is required.")
parser.print_help()
sys.exit(1)
# Call function to convert audio to nus3bank
convert_audio_to_nus3bank(args.input_audio, args.audio_type, args.game, args.preview_point, args.song_id)
if __name__ == "__main__":
main()

View File

@ -1,19 +1,143 @@
import sys import argparse
import subprocess
import os import os
import struct import sys
import shutil
import tempfile
import random import random
from pydub import AudioSegment
from pydub.exceptions import CouldntDecodeError
#from idsp.py
def convert_audio_to_idsp(input_file, output_file):
temp_folder = tempfile.mkdtemp()
try:
if not input_file.lower().endswith('.wav'):
temp_wav_file = os.path.join(temp_folder, "temp.wav")
audio = AudioSegment.from_file(input_file)
audio.export(temp_wav_file, format="wav")
input_file = temp_wav_file
vgaudio_cli_path = os.path.join("bin", "VGAudioCli.exe")
subprocess.run([vgaudio_cli_path, "-i", input_file, "-o", output_file], check=True)
finally:
shutil.rmtree(temp_folder, ignore_errors=True)
#from lopus.py
def convert_audio_to_opus(input_file, output_file):
# Create a unique temporary folder to store intermediate files
temp_folder = tempfile.mkdtemp()
try:
# Check if the input file is already in WAV format
if not input_file.lower().endswith('.wav'):
# Load the input audio file using pydub and convert to WAV
temp_wav_file = os.path.join(temp_folder, "temp.wav")
audio = AudioSegment.from_file(input_file)
audio = audio.set_frame_rate(48000) # Set frame rate to 48000 Hz
audio.export(temp_wav_file, format="wav")
input_file = temp_wav_file
# Path to VGAudioCli executable
vgaudio_cli_path = os.path.join("bin", "VGAudioCli.exe")
# Run VGAudioCli to convert WAV to Switch OPUS
subprocess.run([vgaudio_cli_path, "-i", input_file, "-o", output_file, "--opusheader", "namco"], check=True)
finally:
# Clean up temporary folder
shutil.rmtree(temp_folder, ignore_errors=True)
#from wav.py
def convert_audio_to_wav(input_file, output_file):
try:
# Load the input audio file using pydub
audio = AudioSegment.from_file(input_file)
# Ensure the output file has a .wav extension
if not output_file.lower().endswith('.wav'):
output_file += '.wav'
# Export the audio to WAV format
audio.export(output_file, format="wav")
except Exception as e:
raise RuntimeError(f"Error during WAV conversion: {e}")
#from at9.py
def convert_audio_to_at9(input_file, output_file):
# Create a unique temporary folder to store intermediate files
temp_folder = tempfile.mkdtemp()
try:
# Check if the input file is already in WAV format
if not input_file.lower().endswith('.wav'):
# Load the input audio file using pydub and convert to WAV
temp_wav_file = os.path.join(temp_folder, "temp.wav")
audio = AudioSegment.from_file(input_file)
audio.export(temp_wav_file, format="wav")
input_file = temp_wav_file
# Path to AT9Tool executable
at9tool_cli_path = os.path.join("bin", "at9tool.exe")
# Run VGAudioCli to convert WAV to AT9
subprocess.run([at9tool_cli_path, "-e", "-br", "192", input_file, output_file], check=True)
finally:
# Clean up temporary folder
shutil.rmtree(temp_folder, ignore_errors=True)
# from bnsf.py
def convert_to_mono_48k(input_file, output_file):
"""Convert input audio file to 16-bit mono WAV with 48000 Hz sample rate."""
try:
audio = AudioSegment.from_file(input_file)
audio = audio.set_channels(1) # Convert to mono
audio = audio.set_frame_rate(48000) # Set frame rate to 48000 Hz
audio = audio.set_sample_width(2) # Set sample width to 16-bit (2 bytes)
audio.export(output_file, format='wav')
except CouldntDecodeError:
print(f"Error: Unable to decode {input_file}. Please provide a valid audio file.")
sys.exit(1)
def run_encode_tool(input_wav, output_bs):
"""Run external encode tool with specified arguments."""
subprocess.run(['bin/encode.exe', '0', input_wav, output_bs, '48000', '14000'])
def modify_bnsf_template(output_bs, output_bnsf, header_size, total_samples):
"""Modify the BNSF template file with calculated values and combine with output.bs."""
# Calculate the file size of output.bs
bs_file_size = os.path.getsize(output_bs)
# Create modified BNSF data
new_file_size = bs_file_size + header_size - 0x8
total_samples_bytes = total_samples.to_bytes(4, 'big')
bs_file_size_bytes = bs_file_size.to_bytes(4, 'big')
# Read BNSF template data
with open('templates/header.bnsf', 'rb') as template_file:
bnsf_template_data = bytearray(template_file.read())
# Modify BNSF template with calculated values
bnsf_template_data[0x4:0x8] = new_file_size.to_bytes(4, 'big') # File size
bnsf_template_data[0x1C:0x20] = total_samples_bytes # Total sample count
bnsf_template_data[0x2C:0x30] = bs_file_size_bytes # Size of output.bs
# Append output.bs data to modified BNSF template
with open(output_bs, 'rb') as bs_file:
bs_data = bs_file.read()
final_bnsf_data = bnsf_template_data + bs_data
# Write final BNSF file
with open(output_bnsf, 'wb') as output_file:
output_file.write(final_bnsf_data)
#from nus3.py
def generate_random_uint16_hex(): def generate_random_uint16_hex():
return format(random.randint(0, 65535), '04X') return format(random.randint(0, 65535), '04X')
def load_template_config():
# Load template configurations from config.toml (if needed in the future)
# This function can be expanded to load more template configurations if necessary
# For now, we don't need to use this function directly for selecting templates
return {}
def select_template_name(game, output_file): def select_template_name(game, output_file):
# Determine the appropriate template name based on the game and the length of the output file name
base_filename = os.path.splitext(output_file)[0] base_filename = os.path.splitext(output_file)[0]
length = len(base_filename) length = len(base_filename)
@ -48,7 +172,6 @@ def select_template_name(game, output_file):
return "song_ABCDE" return "song_ABCDE"
elif length == 11: elif length == 11:
return "song_ABCDEF" return "song_ABCDEF"
pass
elif game == "wiiu3": elif game == "wiiu3":
if length == 8: if length == 8:
return "song_ABC" return "song_ABC"
@ -58,12 +181,10 @@ def select_template_name(game, output_file):
return "song_ABCDE" return "song_ABCDE"
elif length == 11: elif length == 11:
return "song_ABCDEF" return "song_ABCDEF"
pass
raise ValueError("Unsupported game or output file name length.") raise ValueError("Unsupported game or output file name length.")
def modify_nus3bank_template(game, template_name, audio_file, preview_point, output_file): def modify_nus3bank_template(game, template_name, audio_file, preview_point, output_file):
# Define game-specific template configurations
game_templates = { game_templates = {
"nijiiro": { "nijiiro": {
"template_folder": "nijiiro", "template_folder": "nijiiro",
@ -164,7 +285,7 @@ def modify_nus3bank_template(game, template_name, audio_file, preview_point, out
}, },
"song_ABCDEF": { "song_ABCDEF": {
"audio_size_offsets": [76, 3228, 3452], "audio_size_offsets": [76, 3228, 3452],
"preview_point_offset": 3360, "preview_point_offset": 3352,
"song_placeholder": "SONG_ABCDEF", "song_placeholder": "SONG_ABCDEF",
"template_file": "SONG_ABCDEF.nus3bank" "template_file": "SONG_ABCDEF.nus3bank"
} }
@ -253,20 +374,95 @@ def modify_nus3bank_template(game, template_name, audio_file, preview_point, out
with open(output_file, 'wb') as out: with open(output_file, 'wb') as out:
out.write(template_data) out.write(template_data)
if __name__ == "__main__": print(f"Created {output_file} successfully.")
if len(sys.argv) != 5:
print("Usage: nus3.py <game> <audio_file> <preview_point> <output_file>")
sys.exit(1)
game = sys.argv[1] # from script.py
audio_file = sys.argv[2] def run_script(script_name, script_args):
preview_point = sys.argv[3] if script_name == "idsp":
output_file = sys.argv[4] input_file, output_file = script_args
convert_audio_to_idsp(input_file, output_file)
elif script_name == "lopus":
input_file, output_file = script_args
convert_audio_to_opus(input_file, output_file)
elif script_name == "at9":
input_file, output_file = script_args
convert_audio_to_at9(input_file, output_file)
elif script_name == "wav":
input_file, output_file = script_args
convert_audio_to_wav(input_file, output_file)
elif script_name == "bnsf":
input_audio, output_bnsf = script_args
temp_folder = 'temp'
os.makedirs(temp_folder, exist_ok=True)
output_wav = os.path.join(temp_folder, 'output_mono.wav')
output_bs = os.path.join(temp_folder, 'output.bs')
header_size = 0x30
try: try:
convert_to_mono_48k(input_audio, output_wav)
run_encode_tool(output_wav, output_bs)
mono_wav = AudioSegment.from_wav(output_wav)
total_samples = len(mono_wav.get_array_of_samples())
modify_bnsf_template(output_bs, output_bnsf, header_size, total_samples)
print("BNSF file created:", output_bnsf)
finally:
if os.path.exists(temp_folder):
shutil.rmtree(temp_folder)
elif script_name == "nus3":
game, audio_file, preview_point, output_file = script_args
template_name = select_template_name(game, output_file) template_name = select_template_name(game, output_file)
modify_nus3bank_template(game, template_name, audio_file, preview_point, output_file) modify_nus3bank_template(game, template_name, audio_file, preview_point, output_file)
print(f"Created {output_file} successfully.") else:
except ValueError as e: print(f"Unsupported script: {script_name}")
print(f"Error: {e}")
sys.exit(1) sys.exit(1)
#from conv.py
def convert_audio_to_nus3bank(input_audio, audio_type, game, preview_point, song_id):
output_filename = f"song_{song_id}.nus3bank"
converted_audio_file = f"{input_audio}.{audio_type}"
if audio_type in ["bnsf", "at9", "idsp", "lopus", "wav"]:
conversion_command = ["python", __file__, audio_type, input_audio, converted_audio_file]
nus3_command = ["python", __file__, "nus3", game, converted_audio_file, str(preview_point), output_filename]
try:
subprocess.run(conversion_command, check=True)
subprocess.run(nus3_command, check=True)
print(f"Conversion successful! Created {output_filename}")
if os.path.exists(converted_audio_file):
os.remove(converted_audio_file)
print(f"Deleted {converted_audio_file}")
except subprocess.CalledProcessError as e:
print(f"Error: {e}")
else:
print(f"Unsupported audio type: {audio_type}")
def main():
parser = argparse.ArgumentParser(description="Convert audio to nus3bank")
parser.add_argument("input_audio", type=str, nargs="?", help="Input audio file path.")
parser.add_argument("audio_type", type=str, nargs="?", help="Type of input audio (e.g., wav, bnsf, at9, idsp, lopus).")
parser.add_argument("game", type=str, nargs="?", help="Game type (e.g., nijiiro, ns1, ps4, wiiu3).")
parser.add_argument("preview_point", type=int, nargs="?", help="Audio preview point in ms.")
parser.add_argument("song_id", type=str, nargs="?", help="Song ID for the nus3bank file.")
args = parser.parse_args()
if len(sys.argv) == 1:
parser.print_help()
sys.exit(0)
if not args.input_audio:
print("Error: Input audio file path is required.")
parser.print_help()
sys.exit(1)
if args.audio_type in ["bnsf", "at9", "idsp", "lopus", "wav"] and args.game and args.preview_point and args.song_id:
convert_audio_to_nus3bank(args.input_audio, args.audio_type, args.game, args.preview_point, args.song_id)
else:
script_name = sys.argv[1]
script_args = sys.argv[2:]
run_script(script_name, script_args)
if __name__ == "__main__":
main()

View File

@ -1,44 +0,0 @@
import subprocess
import os
import sys
import shutil
from pydub import AudioSegment
def convert_audio_to_at9(input_file, output_file):
# Create a temporary folder to store intermediate files
temp_folder = "temp"
os.makedirs(temp_folder, exist_ok=True)
try:
# Check if the input file is already in WAV format
if not input_file.lower().endswith('.wav'):
# Load the input audio file using pydub and convert to WAV
temp_wav_file = os.path.join(temp_folder, "temp.wav")
audio = AudioSegment.from_file(input_file)
audio.export(temp_wav_file, format="wav")
input_file = temp_wav_file
# Path to AT9Tool executable
at9tool_cli_path = os.path.join("bin", "at9tool.exe")
# Run VGAudioCli to convert WAV to AT9
subprocess.run([at9tool_cli_path, "-e", "-br", "192", input_file, output_file], check=True)
finally:
# Clean up temporary folder
shutil.rmtree(temp_folder, ignore_errors=True)
if __name__ == "__main__":
# Check command-line arguments
if len(sys.argv) != 3:
print("Usage: python at9.py <input_file> <output_file>")
sys.exit(1)
input_audio_file = sys.argv[1]
output_audio_file = sys.argv[2]
try:
convert_audio_to_at9(input_audio_file, output_audio_file)
print(f"Conversion successful. Output file: {output_audio_file}")
except Exception as e:
print(f"Error during conversion: {e}")

View File

@ -1,93 +0,0 @@
import subprocess
import os
import sys
import shutil
from pydub import AudioSegment
from pydub.exceptions import CouldntDecodeError
def convert_to_mono_48k(input_file, output_file):
"""Convert input audio file to 16-bit mono WAV with 48000 Hz sample rate."""
try:
audio = AudioSegment.from_file(input_file)
audio = audio.set_channels(1) # Convert to mono
audio = audio.set_frame_rate(48000) # Set frame rate to 48000 Hz
audio = audio.set_sample_width(2) # Set sample width to 16-bit (2 bytes)
audio.export(output_file, format='wav')
except CouldntDecodeError:
print(f"Error: Unable to decode {input_file}. Please provide a valid audio file.")
sys.exit(1)
def run_encode_tool(input_wav, output_bs):
"""Run external encode tool with specified arguments."""
subprocess.run(['bin/encode.exe', '0', input_wav, output_bs, '48000', '14000'])
def modify_bnsf_template(output_bs, output_bnsf, header_size, total_samples):
"""Modify the BNSF template file with calculated values and combine with output.bs."""
# Calculate the file size of output.bs
bs_file_size = os.path.getsize(output_bs)
# Create modified BNSF data
new_file_size = bs_file_size + header_size - 0x8
total_samples_bytes = total_samples.to_bytes(4, 'big')
bs_file_size_bytes = bs_file_size.to_bytes(4, 'big')
# Read BNSF template data
with open('templates/header.bnsf', 'rb') as template_file:
bnsf_template_data = bytearray(template_file.read())
# Modify BNSF template with calculated values
bnsf_template_data[0x4:0x8] = new_file_size.to_bytes(4, 'big') # File size
bnsf_template_data[0x1C:0x20] = total_samples_bytes # Total sample count
bnsf_template_data[0x2C:0x30] = bs_file_size_bytes # Size of output.bs
# Append output.bs data to modified BNSF template
with open(output_bs, 'rb') as bs_file:
bs_data = bs_file.read()
final_bnsf_data = bnsf_template_data + bs_data
# Write final BNSF file
with open(output_bnsf, 'wb') as output_file:
output_file.write(final_bnsf_data)
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: bnsf.py <input_audio> [<output_bnsf>]")
sys.exit(1)
input_audio = sys.argv[1]
output_bnsf = sys.argv[2] if len(sys.argv) > 2 else 'output.bnsf'
# Create temp folder if it doesn't exist
temp_folder = 'temp'
os.makedirs(temp_folder, exist_ok=True)
# Temporary file paths
output_wav = os.path.join(temp_folder, 'output_mono.wav')
output_bs = os.path.join(temp_folder, 'output.bs')
# Header size (assuming fixed size)
header_size = 0x30
try:
# Step 1: Convert input audio to required format (WAV)
convert_to_mono_48k(input_audio, output_wav)
# Step 2: Run external encoding tool
run_encode_tool(output_wav, output_bs)
# Step 3: Get sample count from the converted mono WAV
mono_wav = AudioSegment.from_wav(output_wav)
total_samples = len(mono_wav.get_array_of_samples())
# Step 4: Modify BNSF template with calculated values and combine with output.bs
modify_bnsf_template(output_bs, output_bnsf, header_size, total_samples)
print("BNSF file created:", output_bnsf)
finally:
# Cleanup: Delete temporary files and temp folder
if os.path.exists(temp_folder):
shutil.rmtree(temp_folder)

View File

@ -1,44 +0,0 @@
import subprocess
import os
import sys
import shutil
from pydub import AudioSegment
def convert_audio_to_idsp(input_file, output_file):
# Create a temporary folder to store intermediate files
temp_folder = "temp"
os.makedirs(temp_folder, exist_ok=True)
try:
# Check if the input file is already in WAV format
if not input_file.lower().endswith('.wav'):
# Load the input audio file using pydub and convert to WAV
temp_wav_file = os.path.join(temp_folder, "temp.wav")
audio = AudioSegment.from_file(input_file)
audio.export(temp_wav_file, format="wav")
input_file = temp_wav_file
# Path to VGAudioCli executable
vgaudio_cli_path = os.path.join("bin", "VGAudioCli.exe")
# Run VGAudioCli to convert WAV to IDSP
subprocess.run([vgaudio_cli_path, "-i", input_file, "-o", output_file], check=True)
finally:
# Clean up temporary folder
shutil.rmtree(temp_folder, ignore_errors=True)
if __name__ == "__main__":
# Check command-line arguments
if len(sys.argv) != 3:
print("Usage: python idsp.py <input_file> <output_file>")
sys.exit(1)
input_audio_file = sys.argv[1]
output_audio_file = sys.argv[2]
try:
convert_audio_to_idsp(input_audio_file, output_audio_file)
print(f"Conversion successful. Output file: {output_audio_file}")
except Exception as e:
print(f"Error during conversion: {e}")

View File

@ -1,45 +0,0 @@
import subprocess
import os
import sys
import shutil
from pydub import AudioSegment
def convert_audio_to_opus(input_file, output_file):
# Create a temporary folder to store intermediate files
temp_folder = "temp"
os.makedirs(temp_folder, exist_ok=True)
try:
# Check if the input file is already in WAV format
if not input_file.lower().endswith('.wav'):
# Load the input audio file using pydub and convert to WAV
temp_wav_file = os.path.join(temp_folder, "temp.wav")
audio = AudioSegment.from_file(input_file)
audio = audio.set_frame_rate(48000) # Set frame rate to 48000 Hz
audio.export(temp_wav_file, format="wav")
input_file = temp_wav_file
# Path to VGAudioCli executable
vgaudio_cli_path = os.path.join("bin", "VGAudioCli.exe")
# Run VGAudioCli to convert WAV to Switch OPUS
subprocess.run([vgaudio_cli_path, "-i", input_file, "-o", output_file, "--opusheader", "namco"], check=True)
finally:
# Clean up temporary folder
shutil.rmtree(temp_folder, ignore_errors=True)
if __name__ == "__main__":
# Check command-line arguments
if len(sys.argv) != 3:
print("Usage: python opus.py <input_file> <output_file>")
sys.exit(1)
input_audio_file = sys.argv[1]
output_audio_file = sys.argv[2]
try:
convert_audio_to_opus(input_audio_file, output_audio_file)
print(f"Conversion successful. Output file: {output_audio_file}")
except Exception as e:
print(f"Error during conversion: {e}")

View File

@ -1,22 +0,0 @@
import os
import sys
import subprocess
def run_script(script_name, script_args):
script_path = os.path.join('script', script_name, f'{script_name}.py')
if os.path.exists(script_path):
command = ['python', script_path] + script_args
subprocess.run(command)
else:
print(f"Script '{script_name}' not found.")
sys.exit(1)
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python launcher.py <script_name> [<script_args>]")
sys.exit(1)
script_name = sys.argv[1]
script_args = sys.argv[2:] # Capture all arguments after script_name
run_script(script_name, script_args)

View File

@ -1,33 +0,0 @@
import os
import sys
from pydub import AudioSegment
def convert_audio_to_wav(input_file, output_file):
try:
# Load the input audio file using pydub
audio = AudioSegment.from_file(input_file)
# Ensure the output file has a .wav extension
if not output_file.lower().endswith('.wav'):
output_file += '.wav'
# Export the audio to WAV format
audio.export(output_file, format="wav")
except Exception as e:
raise RuntimeError(f"Error during WAV conversion: {e}")
if __name__ == "__main__":
# Check command-line arguments
if len(sys.argv) != 3:
print("Usage: python audio_converter.py <input_file> <output_file>")
sys.exit(1)
input_audio_file = sys.argv[1]
output_audio_file = sys.argv[2]
try:
convert_audio_to_wav(input_audio_file, output_audio_file)
print(f"Conversion successful. Output file: {output_audio_file}")
except Exception as e:
print(f"Error during conversion: {e}")