Merges two mono Xbox ADPCM files of the same length to one stereo file. Encountered this when splitting and re-merging multichannel Xbox ADPCM files in "Disney's Cars 2: The Video Game". Each multichannel stream contains eight channels and has interleave 0x2. So deinterleaving will result in 8 mono files. As the streams actually consist of four layers, I needed to join two channels each layer. This is the script I used.
Note 1: Each file already needs to have an Xbox ADPCM header and the extension ".xadp" for the script to work
Note 2: The script will take very long to run, so don't wonder. :-\
Note 3: Resulting files may be decoded with toWAV or renamed to *.wav and played in vgmstream (I found out that toWAV decodes the stream with higher quality - don't know why)
Note 4: The PC and PS3 version of Driver: San Francisco uses an Xbox ADPCM variant that hides behind a 0x02 code identifier (a quick look at the character distribution reveals the true codec ). The files are 0x24-byte-interleaved mono Xbox ADPCM files and need to be transformed to xadp. So they just need deinterleaving, adding headers and joining the channels with the below script.
Code: Select all
get NAME basename
string NAME -= 1
set NAME1 NAME
string NAME1 += "L.xadp"
set NAME2 NAME
string NAME2 += "R.xadp"
open FDSE NAME1 0
open FDSE NAME2 1
idstring "RIFF" 0
idstring "RIFF" 1
callfunction compare 1
goto 0x18 0
get FREQ long 0
get FSIZE asize 0
set OFFSET 0x30
do
append
log MEMORY_FILE OFFSET 0x4 0
log MEMORY_FILE OFFSET 0x4 1
append
math OFFSET += 0x4
while OFFSET < FSIZE
get SIZE asize MEMORY_FILE
set CH 2
callfunction XADP 1
string NAME += ".xadp"
get SIZE asize MEMORY_FILE2
log NAME 0 SIZE MEMORY_FILE2
startfunction compare
get SIZE1 asize 0
get SIZE2 asize 1
if SIZE1 != SIZE2
print "ERROR: sizes are different!"
cleanexit
endif
goto 0x14 0
get CODE1 short 0
goto 0x14 1
get CODE2 short 1
if CODE1 != CODE2
print "ERROR: different codecs!"
cleanexit
endif
endfunction
startfunction XADP
set MEMORY_FILE2 binary "\x52\x49\x46\x46\x18\x51\xa3\x0\x57\x41\x56\x45\x66\x6d\x74\x20\x14\x0\x0\x0\x69\x0\x2\x0\x44\xac\x0\x0\xcc\xc1\x0\x0\x48\x0\x4\x0\x2\x0\x40\x0\x64\x61\x74\x61\xf0\x50\xa3\x0"
set RIFFSIZE SIZE # streamsize
math RIFFSIZE += 0x28
putVarChr MEMORY_FILE2 0x04 RIFFSIZE long
putVarChr MEMORY_FILE2 0x16 CH byte
putVarChr MEMORY_FILE2 0x18 FREQ long
set VAR1 0x3073
math VAR1 *= CH
if FREQ == 48000
math VAR1 *= 44100
else
math VAR1 *= FREQ
endif
math VAR1 /= 22050
putVarChr MEMORY_FILE2 0x1c VAR1 long
set VAR2 0x24
math VAR2 *= CH
putVarChr MEMORY_FILE2 0x20 VAR2 short
putVarChr MEMORY_FILE2 0x2c SIZE long
get SIZE asize MEMORY_FILE
append
log MEMORY_FILE2 0 SIZE MEMORY_FILE
append
endfunction
Code: Select all
for %%i in (*L.xadp) do quickbms merge_mono_xadp.bms "%%i" "%CD%"