mirror of
https://github.com/Escartem/AnimeWwise.git
synced 2026-06-04 23:40:25 +08:00
switch from bms to wavescan script
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -2,4 +2,5 @@ output/
|
||||
temp/
|
||||
*.pck
|
||||
*.hdiff
|
||||
tools.zip
|
||||
tools.zip
|
||||
__pycache__/
|
||||
25
extract.py
25
extract.py
@@ -2,6 +2,7 @@ import os
|
||||
import shutil
|
||||
import zipfile
|
||||
import filecmp
|
||||
import wavescan
|
||||
import subprocess
|
||||
from halo import Halo
|
||||
from progress.bar import PixelBar
|
||||
@@ -60,20 +61,10 @@ def main():
|
||||
if alone:
|
||||
output_path = "wem"
|
||||
|
||||
# prepare args
|
||||
args = [
|
||||
path("tools/quickbms/quickbms.exe"),
|
||||
"-o",
|
||||
"-Y",
|
||||
path("tools/quickbms/wavescan.bms"),
|
||||
path(f"temp/{file}"),
|
||||
path(f"temp/{output_path}")
|
||||
]
|
||||
|
||||
# update spinner and call program
|
||||
spinner.text = f"[{curr}/{steps}] Extracting"
|
||||
spinner.start()
|
||||
call(args)
|
||||
wavescan.extract(path(f"temp/{file}"), path(f"temp/{output_path}"))
|
||||
spinner.stop()
|
||||
print(f"[{curr}/{steps}] Extracting")
|
||||
|
||||
@@ -114,20 +105,10 @@ def main():
|
||||
if not alone:
|
||||
curr += 1
|
||||
|
||||
# prepare args
|
||||
args = [
|
||||
path("tools/quickbms/quickbms.exe"),
|
||||
"-o",
|
||||
"-Y",
|
||||
path("tools/quickbms/wavescan.bms"),
|
||||
path(f"temp/{file}"),
|
||||
path(f"temp/patched_decoded")
|
||||
]
|
||||
|
||||
# update spinner and call program
|
||||
spinner.text = f"[{curr}/{steps}] Extracting patch"
|
||||
spinner.start()
|
||||
call(args)
|
||||
wavescan.extract(path(f"temp/{file}"), path(f"temp/patched_decoded"))
|
||||
spinner.stop()
|
||||
print(f"[{curr}/{steps}] Extracting patch")
|
||||
|
||||
|
||||
@@ -3,16 +3,15 @@ import struct
|
||||
|
||||
class FileReader:
|
||||
"""
|
||||
Simplified byte file reader with buffer
|
||||
Not particularly optimised, contains repetitive functions
|
||||
In the scope of this project, not everything will be used either
|
||||
|
||||
Simplified byte file reader with buffer, it's not particularly optimised but good enough
|
||||
In the scope of this project, not everything will be used in here
|
||||
"""
|
||||
def __init__(self, file, endianness: str):
|
||||
|
||||
def __init__(self, file, endianness:str):
|
||||
self.stream = file
|
||||
self.endianness = endianness
|
||||
|
||||
def _read(self, mode:str, bufferLength:int, endianness=None) -> bytes:
|
||||
def _read(self, mode:str, bufferLength:int, endianness:str=None) -> bytes:
|
||||
# endianness override
|
||||
if endianness is None:
|
||||
endianness = self.endianness
|
||||
@@ -22,31 +21,31 @@ class FileReader:
|
||||
return struct.unpack(f"{endianness}{mode}", bytearray(self.stream.read(bufferLength)))[0]
|
||||
|
||||
# read methods
|
||||
def ReadInt16(self, endianness=None) -> int:
|
||||
def ReadInt16(self, endianness:str=None) -> int:
|
||||
return self._read("h", 2, endianness)
|
||||
|
||||
def ReadUInt16(self, endianness=None) -> int:
|
||||
def ReadUInt16(self, endianness:str=None) -> int:
|
||||
return self._read("H", 2, endianness)
|
||||
|
||||
def ReadInt32(self, endianness=None) -> int:
|
||||
def ReadInt32(self, endianness:str=None) -> int:
|
||||
return self._read("i", 4, endianness)
|
||||
|
||||
def ReadUInt32(self, endianness=None) -> int:
|
||||
def ReadUInt32(self, endianness:str=None) -> int:
|
||||
return self._read("I", 4, endianness)
|
||||
|
||||
def ReadLong(self, endianness=None) -> int:
|
||||
def ReadLong(self, endianness:str=None) -> int:
|
||||
return self._read("l", 4, endianness)
|
||||
|
||||
def ReadULong(self, endianness=None) -> int:
|
||||
def ReadULong(self, endianness:str=None) -> int:
|
||||
return self._read("L", 4, endianness)
|
||||
|
||||
def ReadLongLong(self, endianness=None) -> int:
|
||||
def ReadLongLong(self, endianness:str=None) -> int:
|
||||
return self._read("q", 8, endianness)
|
||||
|
||||
def ReadULongLong(self, endianness=None) -> int:
|
||||
def ReadULongLong(self, endianness:str=None) -> int:
|
||||
return self._read("Q", 8, endianness)
|
||||
|
||||
def ReadBytes(self, length:int, endianness=None) -> bytes:
|
||||
def ReadBytes(self, length:int, endianness:str=None) -> bytes:
|
||||
return self._read(f"{str(length)}s", int(length), endianness)
|
||||
|
||||
# buffer utils
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -1,67 +0,0 @@
|
||||
# modified version to ignore filenames (and wav)
|
||||
#
|
||||
# scan data for wave files
|
||||
# RIFF and RIFX header supported
|
||||
# note: There are wave files with a wrong file size after RIFF/RIFX
|
||||
# This script takes the stream size, adds the header size and writes the correct size after RIFF/RIFX
|
||||
# (c) 2012-06-26 by AlphaTwentyThree
|
||||
#
|
||||
# future update plans:
|
||||
# - option to also write data between found wave files to disk
|
||||
# - option to automatically transform the file to a playable or at least decodable format
|
||||
|
||||
for i = 1 # run through loop with count variable i
|
||||
FindLoc OFFSET string "WAVE" 0 "" # search for "WAVE", save position as variable OFFSET
|
||||
if OFFSET == "" # when nothing is found
|
||||
cleanexit # the script exits (e.g. at end of file)
|
||||
endif
|
||||
math OFFSET -= 8 # jump to possible
|
||||
goto OFFSET # RIFF/RIFX file start
|
||||
getDstring IDENT 4 # read string of 4 bytes, save variable as IDENT
|
||||
if IDENT == "RIFX" # differentiate between header possibilities
|
||||
endian big # set endianness to big, if file has RIFX identifier
|
||||
callfunction write 1 # see function section below
|
||||
elif IDENT == "RIFF" # endianness stays little
|
||||
callfunction write 1 # also run function
|
||||
else # string "WAVE" found, but doesn't belong to wave file
|
||||
set SIZE 0xc # do as if something with 0xc bytes was found to continue search from the right position
|
||||
endif
|
||||
set SEARCH OFFSET # set marker to position from where to search next
|
||||
math SEARCH += SIZE # (that would be after the file that was found)
|
||||
if SEARCH == FSIZE # in case the last found file ends with the main file, we exit
|
||||
cleanexit
|
||||
endif
|
||||
goto SEARCH # if we haven't exited the script above, we set out cursor to after the last found file
|
||||
next i
|
||||
|
||||
startfunction write # function "write" starts here, is called when a wave file is found above
|
||||
get NAME basename # save name without extension under variable NAME
|
||||
string NAME += "_" # add underscore to the name
|
||||
string NAME += i # add the loop variable to the name
|
||||
goto OFFSET # set cursor to the beginning of the found file
|
||||
get DUMMY long # RIFF/RIFX identifier, not needed
|
||||
get DUMMY long # riff size, not needed
|
||||
get DUMMY long # "WAVE", not needed, we arrive at the "fmt " section
|
||||
for # loop search for the "data" section at the start of the stream (get the stream size from there)
|
||||
getDstring AREA_NAME 4 # name of area in header
|
||||
get AREA_SIZE long # size of area in header
|
||||
savepos MYOFF # save position we are at
|
||||
if AREA_NAME == "data" # when we arrive at the needed "data" area:
|
||||
break # we exit the loop
|
||||
else # otherwise:
|
||||
math MYOFF += AREA_SIZE # not reached "data" area -> adjust cursor position...
|
||||
goto MYOFF # ... and go there
|
||||
endif
|
||||
next # remember: the cursor is now directly at the stream start
|
||||
set STREAMSIZE AREA_SIZE # the last AREA_SIZE is the size we need (size of the audio stream)
|
||||
set HEADERSIZE MYOFF #
|
||||
math HEADERSIZE -= OFFSET # calculate the size of the stream header (offset - offset = size)
|
||||
set SIZE HEADERSIZE #
|
||||
math SIZE += STREAMSIZE # calculate complete file size (header + stream = file)
|
||||
log MEMORY_FILE OFFSET SIZE # write file to memory
|
||||
math SIZE -= 8 # subtract 8 bytes to get the riff size
|
||||
putVarChr MEMORY_FILE 4 SIZE long # write the correct riff size to the header inside the memory
|
||||
string NAME += ".wem" # add extension to the name (the name could contain the name of the first marker if the file has markers)
|
||||
math SIZE += 8 # add the subtracted 8 bytes again
|
||||
log NAME 0 SIZE MEMORY_FILE # write file in memory to disk
|
||||
endfunction # remember that we continue with our next i now!
|
||||
26
wavescan.py
26
wavescan.py
@@ -1,16 +1,18 @@
|
||||
# Custom rewrite of the Wwise AKPK packages extractor, original by Nicknine and bnnm
|
||||
# TODO: use extracted files id with the mapping table to restore file names
|
||||
# TODO: make this script callable by the main one
|
||||
from filereader import FileReader
|
||||
import os
|
||||
|
||||
filename = "External0.pck"
|
||||
cwd = os.getcwd()
|
||||
reader = FileReader(open(filename, "rb"), "little") # defaults to little endian
|
||||
|
||||
reader = None
|
||||
bank_version = 0
|
||||
|
||||
def main():
|
||||
|
||||
def extract(input_file, output_folder):
|
||||
global bank_version
|
||||
global reader
|
||||
|
||||
reader = FileReader(open(input_file, "rb"), "little") # defaults to little endian
|
||||
|
||||
# check file
|
||||
if reader.ReadBytes(4) != b"AKPK":
|
||||
@@ -50,7 +52,7 @@ def main():
|
||||
|
||||
# extract each sector
|
||||
for sector in sectors:
|
||||
extract_sector(*sector[1:], endianness, lang_array, bank_version)
|
||||
extract_sector(*sector[1:], endianness, lang_array, bank_version, output_folder)
|
||||
|
||||
if sector[0] and bank_version == 0:
|
||||
if externals_sector_size == 0:
|
||||
@@ -109,7 +111,7 @@ def detect_bank_version(offset):
|
||||
|
||||
reader.SetBufferPos(current)
|
||||
|
||||
def extract_sector(section_size, is_sounds, is_externals, ext, endianness, lang_array, bank_version, filter_bnk_only=0, filter_wem_only=0):
|
||||
def extract_sector(section_size, is_sounds, is_externals, ext, endianness, lang_array, bank_version, output_folder, filter_bnk_only=0, filter_wem_only=0):
|
||||
# check sector validity
|
||||
if section_size == 0:
|
||||
return
|
||||
@@ -193,20 +195,18 @@ def extract_sector(section_size, is_sounds, is_externals, ext, endianness, lang_
|
||||
if filter_wem_only == 1 and ext != "wem":
|
||||
continue
|
||||
|
||||
print(f"NAME - {name} | OFFSET - {offset} | SIZE - {size}")
|
||||
# file infos
|
||||
# print(f"NAME - {name} | OFFSET - {offset} | SIZE - {size}")
|
||||
|
||||
# save file into disk
|
||||
current = reader.GetBufferPos()
|
||||
reader.SetBufferPos(offset)
|
||||
file_data = reader.ReadBytes(size)
|
||||
|
||||
os.makedirs(os.path.join(cwd, os.path.dirname(name)), exist_ok=True)
|
||||
os.makedirs(output_folder, exist_ok=True)
|
||||
|
||||
with open(os.path.join(cwd, name), "wb+") as f:
|
||||
with open(os.path.join(output_folder, os.path.basename(name)), "wb+") as f:
|
||||
f.write(file_data)
|
||||
f.close()
|
||||
|
||||
reader.SetBufferPos(current)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user