› Foros › Xbox 360 › Exploits y homebrew
ber18 escribió:hey amigos se podra con COD MW3 colocar en español ? como podria buscar esos archivos.. xq he intentado en google y nada jajaja saludos
Corrected. Actually just a tiny little mistake.
BTW, XWV files don't hold any frequency information in the header, so you need to adjust the frequency manually (change the FREQ_DEFAULT variable or edit the XMA files manually at offset 0x24). toWAV doesn't make a difference between 44.1kHz and 48kHz so it's a guessing game, but some of the samples are 22050Hz and the xma files won't decode correctly with other frequencies. Best method would be to use 44kHz/48kHz (maybe you can get the frequency from elsewhere?) on all files and try to decode them. Move the correctly decoded files together with the xma and xwv to another directory, change the FREQ_DEFAULT and run the script on the remaining xwv files and try to decode again.
Regards, Timo
set TESTMODE 0
set TESTXMA1 0
set TEST_ADVANCED_BLOCKSIZES 0
set FREQ_DEFAULT 48000 # for files without given freq info
set COMMENTS 0
set BLOCKSIZE 0x10000
set XMAVERSION 2
set PARSE 1
# XMA_transform (rev 2012-10-03)
# ==============================
# (c) by AlphaTwentyThree of XeNTaX
#
# Usage: tansform various XMA source formats to XMA files that are decodable by toWAV
# xma_parse.exe needs to be located either in the directory of this script or included in whe Windows PATH variable
#
#
# supported XMA types:
# - wave header (RIFF/RIFX), big-endian & little-endian with any number of channels
# - wave header with additional "xma." at the start (e.g. Fable II)
# - *.SoundNodeWave files from the UT3 engine (two types)
# - *.psb files from several XBLA games *needs some correction*
# - xma files with magic sign \x0\x0\x0\x0\x0\x0\x2\x0 (Are You Smarter Than A 5th Grader? series)
# - *.res files from Electronic Arts fbrb archives with possibly deflated XMA stream (e.g. Battlefield series)
# - xma files with "XWV " identifier (e.g. Bloody Good Time XBLA)
# - Microsoft XNA framework *.xnb files (e.g. Boulder Dash XL XBLA)
# - headerless XMA stream
# - header-reversed RIFF (e.g. Resident Evil 6)
#
# to do (not sorted by proprity):
# - try to determine working frequency (will need toWAV execution call)
# - transform SoundNodeWave markers to standard cue markers
# - add support for the Ubisoft XMA variant (includes multilayered files, Forge engine included)
# - for certain variants: disable TESTMODE and set specs automatically
# - auto-detection for SoundNodeWave and EA XMA (no file extension needed)
#
#
# Contents:
# ==================
# 1. Set user variables
# 2. Get/set some standards
# 3. identify XMA file type and link to according process lists
# 4. process different file types
# 4.1 RIFF/RIFX header ~ processRIFF
# 4.1a get stream start and stream size from "data" section ~ getDatastartRIFF
# 4.1b. RIFF header with codec ascii sign at offset INFO ~ getSpecsRIFF
# 4.1c Extract RIFF cue markers ~ getCueRIFF
# 4.2 UT3 Engine *.SoundNodeWave (two types) ~ processSNW
# 4.2a Get INFO variable for RIFF header or determine variant ~ getInfoSNW
# 4.2b Get specs from variant type ~ SNWVariant
# 4.2c Write SNW header to disk ~ getCueSNW
# 4.3 PSB header (various XBLA games) ~ processPSB
# 4.4 Variant from Are You Smarter Than A 5th Grader? (XBLA) ~ process5thGraderXMA
# 4.5 Electronic Arts XMA variant (e.g. Battlefield series) ~ processEAXMA
# 4.5a Inflate EA XMA ~ parse_ea_xma
# 4.6 XWV header variant (e.g. Bloody Good Time XBLA) ~ processXWV
# 4.7 Microsoft XNA Framework *.xnb ~ processXNB
# 4.8 FFIR header (RE6) ~ processFFIR
# 4.9 others ~ processScan
# 4.Xa determmine XMA stream start ~ getXMAstart
# 4.Xb determine chanel count ~ getXMACH
# 5. Standard functions
# 5.1 Use OFFSET and SIZE to write the raw data to memory ~ write_raw_to_mem
# 5.2 Process the raw data from MEMORY_FILE ~ process_raw_data
# 5.3 Add header to MEMORY_FILE (raw data) and write to disk ~ write_raw_xma
# 5.4 Parse call (from MEMORY_FILE to MEMORY_FILE2) ~ parse
# 5.5 Add header in MEMORY_FILE3 and write to disk as NAME ~ XMA
# ==================================================================================================================\\
# 1. Set user variables ||
# --------------------- ||
# ||
# TESTMODE ||
# Toggles between a test run (to be applied on one file only) and the final run (with user-defined settings) ||
# The test run writes the following data to disk (each file is named accordingly): ||
# - unparsed (only adjusted header) - one file ||
# - parsed: five different block sizes, XMA1 and XMA2 - 10 files ||
# - headerless unparsed raw data (for manual testing with xma_parse) ||
# Note: if the file is multichannel, only the first channel pair is tested. ||
# ||
# TESTXMA1 - (de-)activates testing for XMA1 in TESTMODE ||
# ||
# TEST_ADVANCED_BLOCKSIZES - 0 only tests for 0x8000 and 0x10000 (most common) ||
# 1 additionally tests for 0x2000, 0x4000 and 0x3000 (only rare cases) ||
# ||
# COMMENTS - set to 1 to print information what the script is currently doing ||
# (for debugging) ||
# ||
# FREQ_DEFAULT - take this frequency if none is found/given ||
# (might need adjusting if the resulting files from TESTMODE are undecodable ||
# ||
# user-defined settings (if TESTMODE is activated, these ignored): ||
# BLOCKSIZE - corresponds to the xma_parse -b option ||
# XMAVERSION - 2 or 1 possible (corresponds to the xma_parse -1/2 option) ||
# PARSE - decide whether to parse or just manipulate the header to standard ||
# note: PARSE 0, CH > 2 => TESTMODE activated! ||
# that means you should sheck your settings and parse all input files ||
# ||
# ==================================================================================================================//
# ==========================\
# 2. Get/set some standards | ---------------------------------------------------------------------------------------------------------------------------
# ==========================/
get BNAME basename
get FSIZE asize
set WRITEUXMA 0 # debug mode
set RNAME "" # initialize retrieved name
# ==============================================================\
# 3. identify XMA file type and link to according process lists | ----------------------------------------------------------------------------------------
# ==============================================================/
getDstring IDENT 4
if IDENT == "RIFF"
callfunction processRIFF 1
elif IDENT == "RIFX"
# endianness is determined in getSpecsRIFF
callfunction processRIFF 1
elif IDENT == "xma" # e.g. Fable II for Xbox 360
set INFO 0x18
callfunction processRIFF 1
elif IDENT == "PSB" # some XBLA games
callfunction processPSB 1
elif IDENT == "XWV " # some XBLA games
callfunction processXWV 1
elif IDENT == "XNBx" # Microsoft XNA Framework
callfunction processXNB 1
elif IDENT == "FFIR" # reversed XMA (e.g. Resident Evil 6)
set TESTMODE 0
set PARSE 0
callfunction processFFIR 1
else
get IDENT extension
if IDENT == "SoundNodeWave" # * needs auto-detection! *
set TESTMODE 0
set BLOCKSIZE 0x8000
set PARSE 1
callfunction processSNW 1
elif IDENT == "res" # * needs auto-detection! *
callfunction processEAXMA 1
else
goto 0
get IDENT longlong
if IDENT == 0x20000
callfunction process5thGraderXMA 1
else
goto 6
get TEST byte
if TEST == 0xfc
callfunction processXMAheaderless 1
else
callfunction processScan 1
endif
endif
endif
endif
# ================================\
# 4. process different file types | ------------------------------------------------------------------------------------------------------------------------
# ================================/
# ======================\
# 4.0 headerless XMA |
# ======================/
startfunction processXMAheaderless 1
if COMMENTS == 1
print "processing headerless XMA"
endif
set OFFSET 0
get SIZE asize
set FREQ FREQ_DEFAULT
callfunction write_raw_to_mem 1
callfunction getXMACH 1
callfunction process_raw_data 1
endfunction
# ======================\
# 4.1 RIFF/RIFX header |
# ======================/
startfunction processRIFF
if COMMENTS == 1
print "processing wave header XMA"
endif
callfunction getDatastartRIFF 1
if OFFSET == 0x14
set XMA2OFF OFFSET
math XMA2OFF += SIZE
goto XMA2OFF
getDstring XMA2IDENT 4
reverseLong SIZE # because it's reversed inif XMA2IDENT == "XMA2"
set INFO XMA2OFF
math INFO += 0x8
set TESTXMA1 0
set XMAVERSION 2
callfunction getSpecsRIFF 1
callfunction getCueRIFF 1
elif OFFSET == 0x800 # multichannel XMA2
set TESTMODE 0
set BLOCKSIZE 0x10000 # always?
set XMAVERSION 2
set PARSE 1
goto 0x20
get FREQ long
reverselong FREQ
set CH 6
else # no XMA2 info at end
set INFO 0x14
callfunction getSpecsRIFF 1
callfunction getCueRIFF 1
endif
endian little
callfunction write_raw_to_mem 1
callfunction process_raw_data 1
endfunction
# ==============================================================\
# 4.1a get stream start and stream size from "data" section |
# ==============================================================/
startfunction getDatastartRIFF
do
findLoc OFFSET string "data" 0 ""
goto OFFSET
idstring "data"
get SIZE long
while SIZE == 0 # skip marker section to find stream size
math OFFSET += 0x8
#print "data start found at %OFFSET%"
endfunction
# ==========================================================\
# 4.1b. RIFF header with codec ascii sign at offset INFO |
# ==========================================================/
startfunction getSpecsRIFF
if COMMENTS == 1
print "getting stream specs"
endif
goto INFO
get CODE short
if CODE == 0x165
math INFO += 0x10
goto INFO
get FREQ long
math INFO += 0xd
goto INFO
get CH byte
elif CODE == 0x166
get CH short
get FREQ long
elif CODE == 0x6601 # RIFX header or big endian SNW
endian big
reverseLong SIZE
get CH short
get FREQ long
endian little
elif CODE == 0x104 # e.g. XMA2 with spesc at end
endian big
reverseLong SIZE
math INFO += 0xc
goto INFO
get FREQ long
math INFO += 0x1c
goto INFO
get CH byte
elif CODE == 0x401
endian big
reverseLong SIZE
math INFO += 0xc
goto INFO
get FREQ long
math INFO += 0x1c
goto INFO
get CH byte
else
print "Error: No XMA code found at designated offset (%INFO%). Aborting all operations."
cleanexit
endif
endfunction
# ==============================\
# 4.1c Extract RIFF cue markers |
# ==============================/
startfunction getCueRIFF
if COMMENTS == 1
print "extracting marker section"
endif
goto 0
if CODE == 0x6601
endian big
endif
findLoc MARKERS string "cue " 0 ""
if MARKERS != ""
if MARKERS < OFFSET # in header
goto MARKERS
idstring "cue "
get CSIZE long
math CSIZE += 8
append
log MEMORY_FILE MARKERS CSIZE
append
math MARKERS += CSIZE
goto MARKERS
getDstring IDENT 4
if IDENT == "LIST"
get CSIZE long
math CSIZE += 8
append
log MEMORY_FILE MARKERS CSIZE
append
endif
math MARKERS += 0x18
goto MARKERS
get RNAME string
if RNAME != ""
string BNAME += "~"
string BNAME += RNAME
endif
get CSIZE asize MEMORY_FILE
set CNAME BNAME
string CNAME += ".XMAcue"
log CNAME 0 CSIZE MEMORY_FILE
endif
endif
endian little
endfunction
# ==============================================\
# 4.2 UT3 Engine *.SoundNodeWave (two types) |
# ==============================================/
startfunction processSNW
if COMMENTS == 1
print "processing UT3 XMA"
endif
callfunction getInfoSNW 1 # get INFO variable
if SNWVARIANT == 0 # get stream specs, extract cue section
set OFFSET INFO
math OFFSET += 0x34
callfunction getSpecsRIFF 1
get SIZE asize
math SIZE -= 0x10
goto SIZE
get TEST long
if TEST != 0
math SIZE += 0x10
endif
math SIZE -= OFFSET
callfunction getCueSNW 1
elif SNWVARIANT == 1
callfunction SNWvariant 1
endif
callfunction write_raw_to_mem 1
callfunction process_raw_data 1
endfunction
# ==============================================================\
# 4.2a Get INFO variable for RIFF header or determine variant |
# ==============================================================/
startfunction getInfoSNW
set SNWVARIANT 0
get FSIZE asize
goto 0x10
callfunction getXMAstart 1
math XOFFSET -= 0x34
if XOFFSET <= 0
math XOFFSET += 0x3f
goto XOFFSET
callfunction getXMAstart 1
math XOFFSET -= 0x34
endif
goto XOFFSET
savepos INFO
get CODE short
if CODE == 0x165
elif CODE == 0x166
elif CODE == 0x6601
elif CODE == 0x6601
elif CODE == 0x104
elif CODE == 0x401
else
set SNWVARIANT 1
endif
endfunction
# ==================================\
# 4.2b Get specs from variant type |
# ==================================/
startfunction SNWVariant
endian big
goto 0xa0
get STREAMSIZE long
get FSIZE asize
math FSIZE -= 8
goto FSIZE
get TEST long
if TEST == 0
math FSIZE -= 8 # last 0x10 are dummy bytes
else
math FSIZE += 8
endif
set DATASTART FSIZE
math DATASTART -= STREAMSIZE
goto DATASTART
get IDENT long
if IDENT != 0x2c
print "ERROR: No XMA stream found in SoundNodeWave. Aborting all operations."
cleanexit
endif
get SEEKSIZE long
math DATASTART += 0x18
goto DATASTART
get FREQ long
math DATASTART += 0x1c
goto DATASTART
get CH byte
get DUMMY threebyte
savepos OFFSET
math OFFSET += SEEKSIZE
set SIZE FSIZE
math SIZE -= OFFSET
endian little
endfunction
# ==================================\
# 4.2c Write SNW header to disk | * needs to be converted to standard cue or smpl section *
# ==================================/
startfunction getCueSNW
goto 0
FindLoc TEST string "Loop_Start" 0 ""
if TEST != ""
set CSIZE OFFSET
math CSIZE -= 0x5c
set NAME BNAME
string NAME += ".SNW_head"
log NAME 0 CSIZE
endif
endfunction
# ======================================\
# 4.3 PSB header (various XBLA games) | * needs some correction *
# ======================================/
startfunction processPSB
if COMMENTS == 1
print "processing PSB"
endif
goto 0x14
get INFO long
math INFO += 0x1e
goto INFO
get SIZE threebyte
savepos INFO
callfunction getSpecsRIFF 1 # see 4.1a
savepos OFFSET
math OFFSET += 0x2c
callfunction write_raw_to_mem 1
callfunction process_raw_data 1
endfunction
# ==============================================================\
# 4.4 Variant from Are You Smarter Than A 5th Grader? (XBLA) |
# ==============================================================/
startfunction process5thGraderXMA
endian big
goto 0x30 # specs are easily accessible
get UNK short
get CH short
get FREQ long
endian little
set OFFSET 0x800
get SIZE asize
math SIZE -= OFFSET
set BLOCKSIZE 0x8000
callfunction write_raw_to_mem 1
callfunction process_raw_data 1
endfunction
# ==========================================================\
# 4.5 Electronic Arts XMA variant (e.g. Battlefield series) |
# ==========================================================/
startfunction processEAXMA
if COMMENTS == 1
print "processing EA XMA"
endif
callfunction getXMAstart 1
set OFFSET XOFFSET
if OFFSET > 0xc # single layer with specs and full blocks, no inflating needed (?)
set FREQ OFFSET
math FREQ -= 0x12
goto FREQ
get FREQ short
reverseShort FREQ
#set XMAVERSION 1
get SIZE asize
math SIZE -= OFFSET
callfunction write_raw_to_mem 1
callfunction getXMACH 1
callfunction process_raw_data 1
else
callfunction parse_ea_xma 1 # inflate to unparsed XMA (in MEMORY_FILE)
set FREQ FREQ_DEFAULT
callfunction getXMACH 1
callfunction process_raw_data 1
endif
endfunction
# ==============================================\
# 4.5a Inflate EA XMA |
# note: xma_parse doesn't need FF blocks |
# ==============================================/
startfunction parse_ea_xma
if COMMENTS == 1
print "inflating EA XMA"
endif
endian big
for p = 0 <= 1 # first run: pre-allicartion, second run: inflation
get FSIZE asize
set OFFSET 0
set i 0
do
goto OFFSET
get DUMMY short
get SIZE short
math SIZE -= 0xc
get DUMMY long
get DUMMY long
savepos OFFSET
if p == 0
math OFFSET += SIZE
math i += 1
else
append
log MEMORY_FILE OFFSET SIZE
append
get FILL asize MEMORY_FILE
set TEST FILL
math TEST %= 0x800
if TEST != 0
math FILL /= 0x800
math FILL += 1
math FILL *= 0x800
math FILL -= 1
putVarChr MEMORY_FILE FILL 0 byte
endif
math OFFSET += SIZE
endif
while OFFSET < FSIZE
if p == 0 # pre-allocate memory for inflated file
set PSIZE i
math PSIZE *= 0x800
putVarChr MEMORY_FILE PSIZE 0
log MEMORY_FILE 0 0
endif
next p
endfunction
# ====================================================\
# 4.6 XWV header variant (e.g. Bloody Good Time XBLA) |
# ====================================================/
startfunction processXWV
if COMMENTS == 1
print "processing XWV XMA"
endif
endian big
goto 0x10
get OFFSET long
get SIZE long
goto 0x2b
get CH byte
set FREQ FREQ_DEFAULT
callfunction write_raw_to_mem 1
callfunction process_raw_data 1
endfunction
# ==================================\
# 4.7 Microsoft XNA Framework *.xnb |
# ==================================/
startfunction processXNB
if COMMENTS == 1
print "process XNA Framework XMA"
endif
callfunction getXMAstart 1
set OFFSET XOFFSET
set INFO 0x47
callfunction getSpecsRIFF 1
get SIZE asize
math SIZE -= 0xc
math SIZE -= OFFSET
callfunction write_raw_to_mem 1
callfunction process_raw_data 1
endfunction
# ======================\
# 4.8 FFIR header (RE6) | * no parsing needed
# ======================/
startfunction processFFIR 1
if COMMENTS == 1
print "processing reversed header XMA"
endif
endian big
goto 0x16
get CH short
get FREQ long
findLoc OFFSET string atad 0 ""
math OFFSET += 4
goto OFFSET
get SIZE long
savepos OFFSET
endian little
callfunction write_raw_to_mem 1
callfunction process_raw_data 1
endfunction
# ==================\
# 4.9 Others | * scan for possible XMA start
# ==================/
startfunction processScan
print "scanning for possible XMA stream starts..."
get BNAME basename
string BNAME += "_"
set SCAN 1
set SOFF 0 # search offset
get FSIZE asize
for s = 0
set QUIT 0
if SOFF < FSIZE
goto SOFF
callfunction getXMAstart 1
if XOFFSET != ""
#print "-> possible XMA start found at %XOFFSET%"
set NAME BNAME
set p s
math p += 1
string NAME += p
string WOFF p= "_0x%08x" XOFFSET
string NAME += WOFF
string NAME += ".uxma"
get SIZE asize
math SIZE -= XOFFSET
log NAME XOFFSET SIZE
math SOFF += XOFFSET
math SOFF += 0x10
else
set QUIT 1
endif
else
set QUIT 1
endif
if QUIT == 1
break # quits function
endif
next s
endfunction
# ==================================\
# 4.Xa determmine XMA stream start |
# ==================================/
startfunction getXMAstart
if COMMENTS == 1
print "determining XMA stream start"
endif
for
set CONT 1 # continue?
FindLoc XOFFSET string \xfc 0 ""
if XOFFSET == ""
if SCAN == 1
set CONT 0
else
print "Error: No XMA stream start found. Aborting all operations."
cleanexit
endif
endif
if CONT == 1
#print "0xfc found at %XOFFSET%"
goto XOFFSET
get DUMMY byte
get TEST byte
if TEST == 0
elif TEST == 1
elif TEST == 3
else
set CONT 0
endif
endif
if CONT == 1
math XOFFSET -= 6
goto XOFFSET
get TEST short
if TEST != 0 # continue testing heuristics
else
set CONT 0
endif
endif
if CONT == 1
get TEST2 short
if TEST2 == 0
elif TEST2 == 1
elif TEST2 == 0x101
else
set CONT 0
endif
endif
if CONT == 1 # all test came back positive, so...
break # ... XOFFSET stays (break -> quit function)
else
math XOFFSET += 8 # jump after non-XMA 0xfc
endif
if XOFFSET >= FSIZE
if SCAN == 1 # in case of source file scan -> just return not-found identifier
set XOFFSET ""
break
else
print "Error: No XMA stream start found. Aborting all operations."
cleanexit
endif
else
goto XOFFSET # continue search from after last found 0xfc that was no XMA start
endif
next
endfunction
# ==================================\
# 4.Xb determine chanel count |
# ==================================/
startfunction getXMACH # inside MEMORY_FILE!
if COMMENTS == 1
print "detecting channel count"
endif
set CHOFF 7
goto CHOFF MEMORY_FILE
get IDENT byte MEMORY_FILE
if IDENT == 1
set CH 2
elif IDENT == 3
set CH 1
elif IDENT == 0 # e.g. from multichannel stream
set CH 2
else
print "ERROR: Not able to auto-determine channel count! Aborting all operations."
cleanexit
endif
endfunction
# ======================\
# 5. Standard functions | ----------------------------------------------------------------------------------------------------------------------------------------------
# ======================/
# ==========================================================\
# 5.1 Use OFFSET and SIZE to write the raw data to memory |
# (not needed for EA XMA without filler blocks) |
# ==========================================================/
startfunction write_raw_to_mem
putVarChr MEMORY_FILE SIZE 0 long
log MEMORY_FILE 0 0
log MEMORY_FILE2 0 0
append
log MEMORY_FILE OFFSET SIZE
append
endfunction
# ==========================================\
# 5.2 Process the raw data from MEMORY_FILE |
# ==========================================/
startfunction process_raw_data
if COMMENTS == 1
print "processing raw stream"
endif
if CH > 2
if PARSE == 0 # that combination doesn't happen -> run in test mode instead
set TESTMODE 1
endif
endif
get SIZE asize MEMORY_FILE
if TESTMODE == 1 # write all possible combinations
get NAME basename
string NAME += " -unparsed.uxma" # raw data without header
log NAME 0 SIZE MEMORY_FILE
callfunction write_raw_xma 1 # raw data with header (determined specs)
callfunction parse 1
elif TESTMODE == 0
if WRITEUXMA == 1
get NAME basename
string NAME += " -unparsed.uxma" # raw data without header
log NAME 0 SIZE MEMORY_FILE
endif
if PARSE == 1
callfunction parse 1
elif PARSE == 0 # add header to raw data
callfunction write_raw_xma 1
endif
endif
endfunction
# ===========================================================\
# 5.3 Add header to MEMORY_FILE (raw data) and write to disk |
# ===========================================================/
startfunction write_raw_xma
get MSIZE asize MEMORY_FILE # write to MEMORY_FILE2 for XMA header call
log MEMORY_FILE2 0 SIZE MEMORY_FILE
get NAME basename
if TESTMODE == 1
string NAME += " -unparsed"
endif
string NAME += ".xma"
callfunction XMA 1 # add header and write to disk
endfunction
# ==================================================\
# 5.4 Parse call (from MEMORY_FILE to MEMORY_FILE2) |
# ==================================================/
startfunction parse
if COMMENTS == 1
print "parsing"
endif
endian little # just to be sure
if TESTMODE == 1 # test different block sizes
putArray 0 0 0x8000 long # TESTRUN 1
putArray 1 0 0x10000 long # TESTRUN 2
if TEST_ADVANCED_BLOCKSIZES == 0
set TESTRUNS 2
elif TEST_ADVANCED_BLOCKSIZES == 1
putArray 2 0 0x20000 long # TESTRUN 3 (rare)
putArray 3 0 0x40000 long # TESTRUN 4 (very rare)
putArray 4 0 0x3000 long # TESTRUN 5 (extremely rare)
set TESTRUNS 5
endif
set LOOPS 1 # only one run, no matter how many actual channels
if TESTXMA1 == 1
set XMATESTS 2 # test both XMA1 and XMA2
elif TESTXMA1 == 0
set XMATESTS 1 # only test XMA2
endif
elif TESTMODE == 0 # only parse all channels when TESTRUN is deactivated
set TESTRUNS 1 # don't try blocksizes
if CH > 2
set LOOPS CH
math LOOPS /= 2
set CH 2
else
set LOOPS 1
endif
set XMATESTS 1 # use only the given XMA version
endif
for i = 0 < TESTRUNS # loop changes blocksize if TESTMODE is activated
if TESTRUNS > 1 # otherwise use the user-defined blocksize
getArray BLOCKSIZE i 0
endif
string BLOCKSIZE p= "%08x" BLOCKSIZE
for l = 1 <= LOOPS # loop for channel pairs
for x = 1 <= XMATESTS # note that this is 1 when TESTMODE or TESTXMA1 is deactivated
set FUNCCALL string "xma_parse.exe #INPUT# -b 0x"
string FUNCCALL += BLOCKSIZE
string FUNCCALL += " -"
if TESTMODE == 1
if TESTXMA1 == 1
string FUNCCALL += x # changes between 1 and 2
elif TESTXMA1 == 0
string FUNCCALL += 2 # only test XMA2
endif
elif TESTMODE == 0
string FUNCCALL += XMAVERSION
endif
string FUNCCALL += " -o "
set OFF l # changes with channel loops
math OFF -= 1
math OFF *= 0x800
string OFF p= "0x%08x" OFF
string FUNCCALL += OFF
string FUNCCALL += " -r #OUTPUT#"
comtype EXECUTE FUNCCALL
clog MEMORY_FILE2 0 SIZE SIZE MEMORY_FILE # from mem to temp to mem2 (mem stays)
encryption "" ""
set NAME BNAME
if TESTMODE == 1 # then TESTRUNS == 5
string NAME += " -b 0x"
string NAME += BLOCKSIZE
string NAME += " -"
if TESTXMA1 == 1
string NAME += x
elif TESTXMA1 == 0
string NAME += 2
endif
endif
if LOOPS != 1 # only when TESTMODE is deactivated!
set NUM l
string NAME += "_"
string NAME += NUM
endif
string NAME += ".xma"
get MSIZE asize MEMORY_FILE2
if MSIZE != 0
callfunction XMA 1 # add header and write to disk
endif
next x # xma version loop
next l # channel loop
next i # blocksize loop
endfunction
# ==========================================================\
# 5.5 Add header in MEMORY_FILE3 and write to disk as NAME |
# ==========================================================/
startfunction XMA # variant of standard function (mem2 to mem3)
if COMMENTS == 1
print "adding header"
endif
get MSIZE asize MEMORY_FILE2
set RIFFSIZE MSIZE
math RIFFSIZE += 0x34
set PRESIZE RIFFSIZE # pre-alloc
math PRESIZE += 0x38
putVarChr MEMORY_FILE3 PRESIZE 0
log MEMORY_FILE3 0 0
set MEMORY_FILE3 binary "\x52\x49\x46\x46\xb8\x59\xa7\x00\x57\x41\x56\x45\x66\x6d\x74\x20\x20\x00\x00\x00\x65\x01\x10\x00\xd6\x10\x00\x00\x01\x00\x00\x03\xe3\x9a\x00\x00\x80\xbb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x02\x00\x64\x61\x74\x61\x00\x58\xa7\x00"
putVarChr MEMORY_FILE3 0x04 RIFFSIZE long
putVarChr MEMORY_FILE3 0x24 FREQ long
putVarChr MEMORY_FILE3 0x31 CH byte
putVarChr MEMORY_FILE3 0x38 MSIZE long
get MSIZE asize MEMORY_FILE2
append
log MEMORY_FILE3 0 MSIZE MEMORY_FILE2
append
if NAME == ""
get NAME basename
string NAME += ".xma"
endif
log NAME 0 MSIZE MEMORY_FILE3
endfunction
# ==================================================================================================================================================================
# E-N-D O-F S-C-R-I-P-T
# ==================================================================================================================================================================
Gromber escribió:Buenas
Aunque últimamente el foro esta más dedicado a algunos negocios en cuanto rgh etc, vuelvo a comentar este gran tema (que grandes recuerdos tendran los jtageros), que nos ha tenido un poco en ascuas, el averiguar que tipo de archivo es el 360.wav de Valve.
Bien, ese archivo no es más que XWV, un XMA con un "identificador" especial (una variante del header)
Pues bien, este tema ni lo he tocado hace tela, pero navegando por inet este finde, encontré por casualidad el XMA transform de AlphaTwentyThree, un script bms que se encarga (junto a xmaparse) con unos pequeños retoques, hacer compatibles algunos xma con el programa conversor towav.
Lo probé por curiosidad con resultado negativo y envié unas muestras de audio del half life 2 con la esperanza de que me hiciera caso y así fue, a sacado una update con soporte para el audio del orange box. El problema es que en los XWV no es posible determinar la frecuencia de serie, y claro el script por defecto trabaja a una determinada, por lo que toca ir trasteando, quizás sea la misma que los .wav de la versión PC. Me imagino que casi todas las voces funcionarán a 48000.Corrected. Actually just a tiny little mistake.
BTW, XWV files don't hold any frequency information in the header, so you need to adjust the frequency manually (change the FREQ_DEFAULT variable or edit the XMA files manually at offset 0x24). toWAV doesn't make a difference between 44.1kHz and 48kHz so it's a guessing game, but some of the samples are 22050Hz and the xma files won't decode correctly with other frequencies. Best method would be to use 44kHz/48kHz (maybe you can get the frequency from elsewhere?) on all files and try to decode them. Move the correctly decoded files together with the xma and xwv to another directory, change the FREQ_DEFAULT and run the script on the remaining xwv files and try to decode again.
Regards, Timo
Los que tengan el Half Life 2 original en Steam, pueden sacar el audio fácilmente de C:\Program Files (x86)\Steam\SteamApps\half-life 2_spanish.gcf Con la herramienta GCFScape, se puede extraer sin problemas y están en .wav normal
El Script (con pequeña guía) :añadir contenido a archivo texto y renombrar a XMA_transform.bms y en la misma ubicación renombrar el xma_test.exe a xma_parse.exe
Podéis usar el quickbms para probarlo con un audio de la 360, lo convertirá a un xma compatible.set TESTMODE 0
set TESTXMA1 0
set TEST_ADVANCED_BLOCKSIZES 0
set FREQ_DEFAULT 48000 # for files without given freq info
set COMMENTS 0
set BLOCKSIZE 0x10000
set XMAVERSION 2
set PARSE 1
# XMA_transform (rev 2012-10-03)
# ==============================
# (c) by AlphaTwentyThree of XeNTaX
#
# Usage: tansform various XMA source formats to XMA files that are decodable by toWAV
# xma_parse.exe needs to be located either in the directory of this script or included in whe Windows PATH variable
#
#
# supported XMA types:
# - wave header (RIFF/RIFX), big-endian & little-endian with any number of channels
# - wave header with additional "xma." at the start (e.g. Fable II)
# - *.SoundNodeWave files from the UT3 engine (two types)
# - *.psb files from several XBLA games *needs some correction*
# - xma files with magic sign \x0\x0\x0\x0\x0\x0\x2\x0 (Are You Smarter Than A 5th Grader? series)
# - *.res files from Electronic Arts fbrb archives with possibly deflated XMA stream (e.g. Battlefield series)
# - xma files with "XWV " identifier (e.g. Bloody Good Time XBLA)
# - Microsoft XNA framework *.xnb files (e.g. Boulder Dash XL XBLA)
# - headerless XMA stream
# - header-reversed RIFF (e.g. Resident Evil 6)
#
# to do (not sorted by proprity):
# - try to determine working frequency (will need toWAV execution call)
# - transform SoundNodeWave markers to standard cue markers
# - add support for the Ubisoft XMA variant (includes multilayered files, Forge engine included)
# - for certain variants: disable TESTMODE and set specs automatically
# - auto-detection for SoundNodeWave and EA XMA (no file extension needed)
#
#
# Contents:
# ==================
# 1. Set user variables
# 2. Get/set some standards
# 3. identify XMA file type and link to according process lists
# 4. process different file types
# 4.1 RIFF/RIFX header ~ processRIFF
# 4.1a get stream start and stream size from "data" section ~ getDatastartRIFF
# 4.1b. RIFF header with codec ascii sign at offset INFO ~ getSpecsRIFF
# 4.1c Extract RIFF cue markers ~ getCueRIFF
# 4.2 UT3 Engine *.SoundNodeWave (two types) ~ processSNW
# 4.2a Get INFO variable for RIFF header or determine variant ~ getInfoSNW
# 4.2b Get specs from variant type ~ SNWVariant
# 4.2c Write SNW header to disk ~ getCueSNW
# 4.3 PSB header (various XBLA games) ~ processPSB
# 4.4 Variant from Are You Smarter Than A 5th Grader? (XBLA) ~ process5thGraderXMA
# 4.5 Electronic Arts XMA variant (e.g. Battlefield series) ~ processEAXMA
# 4.5a Inflate EA XMA ~ parse_ea_xma
# 4.6 XWV header variant (e.g. Bloody Good Time XBLA) ~ processXWV
# 4.7 Microsoft XNA Framework *.xnb ~ processXNB
# 4.8 FFIR header (RE6) ~ processFFIR
# 4.9 others ~ processScan
# 4.Xa determmine XMA stream start ~ getXMAstart
# 4.Xb determine chanel count ~ getXMACH
# 5. Standard functions
# 5.1 Use OFFSET and SIZE to write the raw data to memory ~ write_raw_to_mem
# 5.2 Process the raw data from MEMORY_FILE ~ process_raw_data
# 5.3 Add header to MEMORY_FILE (raw data) and write to disk ~ write_raw_xma
# 5.4 Parse call (from MEMORY_FILE to MEMORY_FILE2) ~ parse
# 5.5 Add header in MEMORY_FILE3 and write to disk as NAME ~ XMA
# ==================================================================================================================\\
# 1. Set user variables ||
# --------------------- ||
# ||
# TESTMODE ||
# Toggles between a test run (to be applied on one file only) and the final run (with user-defined settings) ||
# The test run writes the following data to disk (each file is named accordingly): ||
# - unparsed (only adjusted header) - one file ||
# - parsed: five different block sizes, XMA1 and XMA2 - 10 files ||
# - headerless unparsed raw data (for manual testing with xma_parse) ||
# Note: if the file is multichannel, only the first channel pair is tested. ||
# ||
# TESTXMA1 - (de-)activates testing for XMA1 in TESTMODE ||
# ||
# TEST_ADVANCED_BLOCKSIZES - 0 only tests for 0x8000 and 0x10000 (most common) ||
# 1 additionally tests for 0x2000, 0x4000 and 0x3000 (only rare cases) ||
# ||
# COMMENTS - set to 1 to print information what the script is currently doing ||
# (for debugging) ||
# ||
# FREQ_DEFAULT - take this frequency if none is found/given ||
# (might need adjusting if the resulting files from TESTMODE are undecodable ||
# ||
# user-defined settings (if TESTMODE is activated, these ignored): ||
# BLOCKSIZE - corresponds to the xma_parse -b option ||
# XMAVERSION - 2 or 1 possible (corresponds to the xma_parse -1/2 option) ||
# PARSE - decide whether to parse or just manipulate the header to standard ||
# note: PARSE 0, CH > 2 => TESTMODE activated! ||
# that means you should sheck your settings and parse all input files ||
# ||
# ==================================================================================================================//
# ==========================\
# 2. Get/set some standards | ---------------------------------------------------------------------------------------------------------------------------
# ==========================/
get BNAME basename
get FSIZE asize
set WRITEUXMA 0 # debug mode
set RNAME "" # initialize retrieved name
# ==============================================================\
# 3. identify XMA file type and link to according process lists | ----------------------------------------------------------------------------------------
# ==============================================================/
getDstring IDENT 4
if IDENT == "RIFF"
callfunction processRIFF 1
elif IDENT == "RIFX"
# endianness is determined in getSpecsRIFF
callfunction processRIFF 1
elif IDENT == "xma" # e.g. Fable II for Xbox 360
set INFO 0x18
callfunction processRIFF 1
elif IDENT == "PSB" # some XBLA games
callfunction processPSB 1
elif IDENT == "XWV " # some XBLA games
callfunction processXWV 1
elif IDENT == "XNBx" # Microsoft XNA Framework
callfunction processXNB 1
elif IDENT == "FFIR" # reversed XMA (e.g. Resident Evil 6)
set TESTMODE 0
set PARSE 0
callfunction processFFIR 1
else
get IDENT extension
if IDENT == "SoundNodeWave" # * needs auto-detection! *
set TESTMODE 0
set BLOCKSIZE 0x8000
set PARSE 1
callfunction processSNW 1
elif IDENT == "res" # * needs auto-detection! *
callfunction processEAXMA 1
else
goto 0
get IDENT longlong
if IDENT == 0x20000
callfunction process5thGraderXMA 1
else
goto 6
get TEST byte
if TEST == 0xfc
callfunction processXMAheaderless 1
else
callfunction processScan 1
endif
endif
endif
endif
# ================================\
# 4. process different file types | ------------------------------------------------------------------------------------------------------------------------
# ================================/
# ======================\
# 4.0 headerless XMA |
# ======================/
startfunction processXMAheaderless 1
if COMMENTS == 1
print "processing headerless XMA"
endif
set OFFSET 0
get SIZE asize
set FREQ FREQ_DEFAULT
callfunction write_raw_to_mem 1
callfunction getXMACH 1
callfunction process_raw_data 1
endfunction
# ======================\
# 4.1 RIFF/RIFX header |
# ======================/
startfunction processRIFF
if COMMENTS == 1
print "processing wave header XMA"
endif
callfunction getDatastartRIFF 1
if OFFSET == 0x14
set XMA2OFF OFFSET
math XMA2OFF += SIZE
goto XMA2OFF
getDstring XMA2IDENT 4
reverseLong SIZE # because it's reversed inif XMA2IDENT == "XMA2"
set INFO XMA2OFF
math INFO += 0x8
set TESTXMA1 0
set XMAVERSION 2
callfunction getSpecsRIFF 1
callfunction getCueRIFF 1
elif OFFSET == 0x800 # multichannel XMA2
set TESTMODE 0
set BLOCKSIZE 0x10000 # always?
set XMAVERSION 2
set PARSE 1
goto 0x20
get FREQ long
reverselong FREQ
set CH 6
else # no XMA2 info at end
set INFO 0x14
callfunction getSpecsRIFF 1
callfunction getCueRIFF 1
endif
endian little
callfunction write_raw_to_mem 1
callfunction process_raw_data 1
endfunction
# ==============================================================\
# 4.1a get stream start and stream size from "data" section |
# ==============================================================/
startfunction getDatastartRIFF
do
findLoc OFFSET string "data" 0 ""
goto OFFSET
idstring "data"
get SIZE long
while SIZE == 0 # skip marker section to find stream size
math OFFSET += 0x8
#print "data start found at %OFFSET%"
endfunction
# ==========================================================\
# 4.1b. RIFF header with codec ascii sign at offset INFO |
# ==========================================================/
startfunction getSpecsRIFF
if COMMENTS == 1
print "getting stream specs"
endif
goto INFO
get CODE short
if CODE == 0x165
math INFO += 0x10
goto INFO
get FREQ long
math INFO += 0xd
goto INFO
get CH byte
elif CODE == 0x166
get CH short
get FREQ long
elif CODE == 0x6601 # RIFX header or big endian SNW
endian big
reverseLong SIZE
get CH short
get FREQ long
endian little
elif CODE == 0x104 # e.g. XMA2 with spesc at end
endian big
reverseLong SIZE
math INFO += 0xc
goto INFO
get FREQ long
math INFO += 0x1c
goto INFO
get CH byte
elif CODE == 0x401
endian big
reverseLong SIZE
math INFO += 0xc
goto INFO
get FREQ long
math INFO += 0x1c
goto INFO
get CH byte
else
print "Error: No XMA code found at designated offset (%INFO%). Aborting all operations."
cleanexit
endif
endfunction
# ==============================\
# 4.1c Extract RIFF cue markers |
# ==============================/
startfunction getCueRIFF
if COMMENTS == 1
print "extracting marker section"
endif
goto 0
if CODE == 0x6601
endian big
endif
findLoc MARKERS string "cue " 0 ""
if MARKERS != ""
if MARKERS < OFFSET # in header
goto MARKERS
idstring "cue "
get CSIZE long
math CSIZE += 8
append
log MEMORY_FILE MARKERS CSIZE
append
math MARKERS += CSIZE
goto MARKERS
getDstring IDENT 4
if IDENT == "LIST"
get CSIZE long
math CSIZE += 8
append
log MEMORY_FILE MARKERS CSIZE
append
endif
math MARKERS += 0x18
goto MARKERS
get RNAME string
if RNAME != ""
string BNAME += "~"
string BNAME += RNAME
endif
get CSIZE asize MEMORY_FILE
set CNAME BNAME
string CNAME += ".XMAcue"
log CNAME 0 CSIZE MEMORY_FILE
endif
endif
endian little
endfunction
# ==============================================\
# 4.2 UT3 Engine *.SoundNodeWave (two types) |
# ==============================================/
startfunction processSNW
if COMMENTS == 1
print "processing UT3 XMA"
endif
callfunction getInfoSNW 1 # get INFO variable
if SNWVARIANT == 0 # get stream specs, extract cue section
set OFFSET INFO
math OFFSET += 0x34
callfunction getSpecsRIFF 1
get SIZE asize
math SIZE -= 0x10
goto SIZE
get TEST long
if TEST != 0
math SIZE += 0x10
endif
math SIZE -= OFFSET
callfunction getCueSNW 1
elif SNWVARIANT == 1
callfunction SNWvariant 1
endif
callfunction write_raw_to_mem 1
callfunction process_raw_data 1
endfunction
# ==============================================================\
# 4.2a Get INFO variable for RIFF header or determine variant |
# ==============================================================/
startfunction getInfoSNW
set SNWVARIANT 0
get FSIZE asize
goto 0x10
callfunction getXMAstart 1
math XOFFSET -= 0x34
if XOFFSET <= 0
math XOFFSET += 0x3f
goto XOFFSET
callfunction getXMAstart 1
math XOFFSET -= 0x34
endif
goto XOFFSET
savepos INFO
get CODE short
if CODE == 0x165
elif CODE == 0x166
elif CODE == 0x6601
elif CODE == 0x6601
elif CODE == 0x104
elif CODE == 0x401
else
set SNWVARIANT 1
endif
endfunction
# ==================================\
# 4.2b Get specs from variant type |
# ==================================/
startfunction SNWVariant
endian big
goto 0xa0
get STREAMSIZE long
get FSIZE asize
math FSIZE -= 8
goto FSIZE
get TEST long
if TEST == 0
math FSIZE -= 8 # last 0x10 are dummy bytes
else
math FSIZE += 8
endif
set DATASTART FSIZE
math DATASTART -= STREAMSIZE
goto DATASTART
get IDENT long
if IDENT != 0x2c
print "ERROR: No XMA stream found in SoundNodeWave. Aborting all operations."
cleanexit
endif
get SEEKSIZE long
math DATASTART += 0x18
goto DATASTART
get FREQ long
math DATASTART += 0x1c
goto DATASTART
get CH byte
get DUMMY threebyte
savepos OFFSET
math OFFSET += SEEKSIZE
set SIZE FSIZE
math SIZE -= OFFSET
endian little
endfunction
# ==================================\
# 4.2c Write SNW header to disk | * needs to be converted to standard cue or smpl section *
# ==================================/
startfunction getCueSNW
goto 0
FindLoc TEST string "Loop_Start" 0 ""
if TEST != ""
set CSIZE OFFSET
math CSIZE -= 0x5c
set NAME BNAME
string NAME += ".SNW_head"
log NAME 0 CSIZE
endif
endfunction
# ======================================\
# 4.3 PSB header (various XBLA games) | * needs some correction *
# ======================================/
startfunction processPSB
if COMMENTS == 1
print "processing PSB"
endif
goto 0x14
get INFO long
math INFO += 0x1e
goto INFO
get SIZE threebyte
savepos INFO
callfunction getSpecsRIFF 1 # see 4.1a
savepos OFFSET
math OFFSET += 0x2c
callfunction write_raw_to_mem 1
callfunction process_raw_data 1
endfunction
# ==============================================================\
# 4.4 Variant from Are You Smarter Than A 5th Grader? (XBLA) |
# ==============================================================/
startfunction process5thGraderXMA
endian big
goto 0x30 # specs are easily accessible
get UNK short
get CH short
get FREQ long
endian little
set OFFSET 0x800
get SIZE asize
math SIZE -= OFFSET
set BLOCKSIZE 0x8000
callfunction write_raw_to_mem 1
callfunction process_raw_data 1
endfunction
# ==========================================================\
# 4.5 Electronic Arts XMA variant (e.g. Battlefield series) |
# ==========================================================/
startfunction processEAXMA
if COMMENTS == 1
print "processing EA XMA"
endif
callfunction getXMAstart 1
set OFFSET XOFFSET
if OFFSET > 0xc # single layer with specs and full blocks, no inflating needed (?)
set FREQ OFFSET
math FREQ -= 0x12
goto FREQ
get FREQ short
reverseShort FREQ
#set XMAVERSION 1
get SIZE asize
math SIZE -= OFFSET
callfunction write_raw_to_mem 1
callfunction getXMACH 1
callfunction process_raw_data 1
else
callfunction parse_ea_xma 1 # inflate to unparsed XMA (in MEMORY_FILE)
set FREQ FREQ_DEFAULT
callfunction getXMACH 1
callfunction process_raw_data 1
endif
endfunction
# ==============================================\
# 4.5a Inflate EA XMA |
# note: xma_parse doesn't need FF blocks |
# ==============================================/
startfunction parse_ea_xma
if COMMENTS == 1
print "inflating EA XMA"
endif
endian big
for p = 0 <= 1 # first run: pre-allicartion, second run: inflation
get FSIZE asize
set OFFSET 0
set i 0
do
goto OFFSET
get DUMMY short
get SIZE short
math SIZE -= 0xc
get DUMMY long
get DUMMY long
savepos OFFSET
if p == 0
math OFFSET += SIZE
math i += 1
else
append
log MEMORY_FILE OFFSET SIZE
append
get FILL asize MEMORY_FILE
set TEST FILL
math TEST %= 0x800
if TEST != 0
math FILL /= 0x800
math FILL += 1
math FILL *= 0x800
math FILL -= 1
putVarChr MEMORY_FILE FILL 0 byte
endif
math OFFSET += SIZE
endif
while OFFSET < FSIZE
if p == 0 # pre-allocate memory for inflated file
set PSIZE i
math PSIZE *= 0x800
putVarChr MEMORY_FILE PSIZE 0
log MEMORY_FILE 0 0
endif
next p
endfunction
# ====================================================\
# 4.6 XWV header variant (e.g. Bloody Good Time XBLA) |
# ====================================================/
startfunction processXWV
if COMMENTS == 1
print "processing XWV XMA"
endif
endian big
goto 0x10
get OFFSET long
get SIZE long
goto 0x2b
get CH byte
set FREQ FREQ_DEFAULT
callfunction write_raw_to_mem 1
callfunction process_raw_data 1
endfunction
# ==================================\
# 4.7 Microsoft XNA Framework *.xnb |
# ==================================/
startfunction processXNB
if COMMENTS == 1
print "process XNA Framework XMA"
endif
callfunction getXMAstart 1
set OFFSET XOFFSET
set INFO 0x47
callfunction getSpecsRIFF 1
get SIZE asize
math SIZE -= 0xc
math SIZE -= OFFSET
callfunction write_raw_to_mem 1
callfunction process_raw_data 1
endfunction
# ======================\
# 4.8 FFIR header (RE6) | * no parsing needed
# ======================/
startfunction processFFIR 1
if COMMENTS == 1
print "processing reversed header XMA"
endif
endian big
goto 0x16
get CH short
get FREQ long
findLoc OFFSET string atad 0 ""
math OFFSET += 4
goto OFFSET
get SIZE long
savepos OFFSET
endian little
callfunction write_raw_to_mem 1
callfunction process_raw_data 1
endfunction
# ==================\
# 4.9 Others | * scan for possible XMA start
# ==================/
startfunction processScan
print "scanning for possible XMA stream starts..."
get BNAME basename
string BNAME += "_"
set SCAN 1
set SOFF 0 # search offset
get FSIZE asize
for s = 0
set QUIT 0
if SOFF < FSIZE
goto SOFF
callfunction getXMAstart 1
if XOFFSET != ""
#print "-> possible XMA start found at %XOFFSET%"
set NAME BNAME
set p s
math p += 1
string NAME += p
string WOFF p= "_0x%08x" XOFFSET
string NAME += WOFF
string NAME += ".uxma"
get SIZE asize
math SIZE -= XOFFSET
log NAME XOFFSET SIZE
math SOFF += XOFFSET
math SOFF += 0x10
else
set QUIT 1
endif
else
set QUIT 1
endif
if QUIT == 1
break # quits function
endif
next s
endfunction
# ==================================\
# 4.Xa determmine XMA stream start |
# ==================================/
startfunction getXMAstart
if COMMENTS == 1
print "determining XMA stream start"
endif
for
set CONT 1 # continue?
FindLoc XOFFSET string \xfc 0 ""
if XOFFSET == ""
if SCAN == 1
set CONT 0
else
print "Error: No XMA stream start found. Aborting all operations."
cleanexit
endif
endif
if CONT == 1
#print "0xfc found at %XOFFSET%"
goto XOFFSET
get DUMMY byte
get TEST byte
if TEST == 0
elif TEST == 1
elif TEST == 3
else
set CONT 0
endif
endif
if CONT == 1
math XOFFSET -= 6
goto XOFFSET
get TEST short
if TEST != 0 # continue testing heuristics
else
set CONT 0
endif
endif
if CONT == 1
get TEST2 short
if TEST2 == 0
elif TEST2 == 1
elif TEST2 == 0x101
else
set CONT 0
endif
endif
if CONT == 1 # all test came back positive, so...
break # ... XOFFSET stays (break -> quit function)
else
math XOFFSET += 8 # jump after non-XMA 0xfc
endif
if XOFFSET >= FSIZE
if SCAN == 1 # in case of source file scan -> just return not-found identifier
set XOFFSET ""
break
else
print "Error: No XMA stream start found. Aborting all operations."
cleanexit
endif
else
goto XOFFSET # continue search from after last found 0xfc that was no XMA start
endif
next
endfunction
# ==================================\
# 4.Xb determine chanel count |
# ==================================/
startfunction getXMACH # inside MEMORY_FILE!
if COMMENTS == 1
print "detecting channel count"
endif
set CHOFF 7
goto CHOFF MEMORY_FILE
get IDENT byte MEMORY_FILE
if IDENT == 1
set CH 2
elif IDENT == 3
set CH 1
elif IDENT == 0 # e.g. from multichannel stream
set CH 2
else
print "ERROR: Not able to auto-determine channel count! Aborting all operations."
cleanexit
endif
endfunction
# ======================\
# 5. Standard functions | ----------------------------------------------------------------------------------------------------------------------------------------------
# ======================/
# ==========================================================\
# 5.1 Use OFFSET and SIZE to write the raw data to memory |
# (not needed for EA XMA without filler blocks) |
# ==========================================================/
startfunction write_raw_to_mem
putVarChr MEMORY_FILE SIZE 0 long
log MEMORY_FILE 0 0
log MEMORY_FILE2 0 0
append
log MEMORY_FILE OFFSET SIZE
append
endfunction
# ==========================================\
# 5.2 Process the raw data from MEMORY_FILE |
# ==========================================/
startfunction process_raw_data
if COMMENTS == 1
print "processing raw stream"
endif
if CH > 2
if PARSE == 0 # that combination doesn't happen -> run in test mode instead
set TESTMODE 1
endif
endif
get SIZE asize MEMORY_FILE
if TESTMODE == 1 # write all possible combinations
get NAME basename
string NAME += " -unparsed.uxma" # raw data without header
log NAME 0 SIZE MEMORY_FILE
callfunction write_raw_xma 1 # raw data with header (determined specs)
callfunction parse 1
elif TESTMODE == 0
if WRITEUXMA == 1
get NAME basename
string NAME += " -unparsed.uxma" # raw data without header
log NAME 0 SIZE MEMORY_FILE
endif
if PARSE == 1
callfunction parse 1
elif PARSE == 0 # add header to raw data
callfunction write_raw_xma 1
endif
endif
endfunction
# ===========================================================\
# 5.3 Add header to MEMORY_FILE (raw data) and write to disk |
# ===========================================================/
startfunction write_raw_xma
get MSIZE asize MEMORY_FILE # write to MEMORY_FILE2 for XMA header call
log MEMORY_FILE2 0 SIZE MEMORY_FILE
get NAME basename
if TESTMODE == 1
string NAME += " -unparsed"
endif
string NAME += ".xma"
callfunction XMA 1 # add header and write to disk
endfunction
# ==================================================\
# 5.4 Parse call (from MEMORY_FILE to MEMORY_FILE2) |
# ==================================================/
startfunction parse
if COMMENTS == 1
print "parsing"
endif
endian little # just to be sure
if TESTMODE == 1 # test different block sizes
putArray 0 0 0x8000 long # TESTRUN 1
putArray 1 0 0x10000 long # TESTRUN 2
if TEST_ADVANCED_BLOCKSIZES == 0
set TESTRUNS 2
elif TEST_ADVANCED_BLOCKSIZES == 1
putArray 2 0 0x20000 long # TESTRUN 3 (rare)
putArray 3 0 0x40000 long # TESTRUN 4 (very rare)
putArray 4 0 0x3000 long # TESTRUN 5 (extremely rare)
set TESTRUNS 5
endif
set LOOPS 1 # only one run, no matter how many actual channels
if TESTXMA1 == 1
set XMATESTS 2 # test both XMA1 and XMA2
elif TESTXMA1 == 0
set XMATESTS 1 # only test XMA2
endif
elif TESTMODE == 0 # only parse all channels when TESTRUN is deactivated
set TESTRUNS 1 # don't try blocksizes
if CH > 2
set LOOPS CH
math LOOPS /= 2
set CH 2
else
set LOOPS 1
endif
set XMATESTS 1 # use only the given XMA version
endif
for i = 0 < TESTRUNS # loop changes blocksize if TESTMODE is activated
if TESTRUNS > 1 # otherwise use the user-defined blocksize
getArray BLOCKSIZE i 0
endif
string BLOCKSIZE p= "%08x" BLOCKSIZE
for l = 1 <= LOOPS # loop for channel pairs
for x = 1 <= XMATESTS # note that this is 1 when TESTMODE or TESTXMA1 is deactivated
set FUNCCALL string "xma_parse.exe #INPUT# -b 0x"
string FUNCCALL += BLOCKSIZE
string FUNCCALL += " -"
if TESTMODE == 1
if TESTXMA1 == 1
string FUNCCALL += x # changes between 1 and 2
elif TESTXMA1 == 0
string FUNCCALL += 2 # only test XMA2
endif
elif TESTMODE == 0
string FUNCCALL += XMAVERSION
endif
string FUNCCALL += " -o "
set OFF l # changes with channel loops
math OFF -= 1
math OFF *= 0x800
string OFF p= "0x%08x" OFF
string FUNCCALL += OFF
string FUNCCALL += " -r #OUTPUT#"
comtype EXECUTE FUNCCALL
clog MEMORY_FILE2 0 SIZE SIZE MEMORY_FILE # from mem to temp to mem2 (mem stays)
encryption "" ""
set NAME BNAME
if TESTMODE == 1 # then TESTRUNS == 5
string NAME += " -b 0x"
string NAME += BLOCKSIZE
string NAME += " -"
if TESTXMA1 == 1
string NAME += x
elif TESTXMA1 == 0
string NAME += 2
endif
endif
if LOOPS != 1 # only when TESTMODE is deactivated!
set NUM l
string NAME += "_"
string NAME += NUM
endif
string NAME += ".xma"
get MSIZE asize MEMORY_FILE2
if MSIZE != 0
callfunction XMA 1 # add header and write to disk
endif
next x # xma version loop
next l # channel loop
next i # blocksize loop
endfunction
# ==========================================================\
# 5.5 Add header in MEMORY_FILE3 and write to disk as NAME |
# ==========================================================/
startfunction XMA # variant of standard function (mem2 to mem3)
if COMMENTS == 1
print "adding header"
endif
get MSIZE asize MEMORY_FILE2
set RIFFSIZE MSIZE
math RIFFSIZE += 0x34
set PRESIZE RIFFSIZE # pre-alloc
math PRESIZE += 0x38
putVarChr MEMORY_FILE3 PRESIZE 0
log MEMORY_FILE3 0 0
set MEMORY_FILE3 binary "\x52\x49\x46\x46\xb8\x59\xa7\x00\x57\x41\x56\x45\x66\x6d\x74\x20\x20\x00\x00\x00\x65\x01\x10\x00\xd6\x10\x00\x00\x01\x00\x00\x03\xe3\x9a\x00\x00\x80\xbb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x02\x00\x64\x61\x74\x61\x00\x58\xa7\x00"
putVarChr MEMORY_FILE3 0x04 RIFFSIZE long
putVarChr MEMORY_FILE3 0x24 FREQ long
putVarChr MEMORY_FILE3 0x31 CH byte
putVarChr MEMORY_FILE3 0x38 MSIZE long
get MSIZE asize MEMORY_FILE2
append
log MEMORY_FILE3 0 MSIZE MEMORY_FILE2
append
if NAME == ""
get NAME basename
string NAME += ".xma"
endif
log NAME 0 MSIZE MEMORY_FILE3
endfunction
# ==================================================================================================================================================================
# E-N-D O-F S-C-R-I-P-T
# ==================================================================================================================================================================XMA_transform_2012-10-07.zip
La herramienta "ToWav Music Converter" se puede encontrar aquí.
xmaparse
Con esto se pueden pasar a wav sin muchos problemas, luego la cuestión es pasar los audios de pc a xma (¿XDK?) y modificarles el header (editor hexadecimal) para que sean XWV y usar el quickbms con script zip.bms para pasarlo al zip especial y trastear... suena facil, pero es todo un trabajo y tocaría catarlo... son muchos archivos y seguro que salen nuevos problemas...
Quien quiera probar esta invitado a comentar resultados.
EJEMPLO AUDIO CONVERTIDO
FUENTE: Xentax.com
¿Alguien se ha puesto en todo este tiempo en este tema?
Gromber escribió:Creo que no se me entendio el ultimo post...
c0d3m4st4 escribió:Si alguno tiene la versión de steam, puede extraer el audio y postear el listado de los ficheros (o que me contacte por privado directamente ) ? Yo tengo la versión de PC por aquí y quiero comprobar si coinciden... porque es una versión rara, con la IA tuneada, expansiones y no se qué, así que lo mismo hay alguan cosa cambiada, no tengo 100% claro qué audios son del HL2 y cuales no.
Si me posteais los headers que hay que añadir, me curro en estos días una herramienta para intentar automatizar todo o gran parte del proceso, que voy a estar de vacas y aunque tengo varios proyectos seguro que algún ratejo me sobra por ahí
metalex escribió:EDITADO
funciona quieren que suba el archivo zip0.360.zip?