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%"