Skip to content
View in the app

A better way to browse. Learn more.

ResHax

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.
Help us keep the site running.

EA XMA multilayer audio files

Featured Replies

  • Author
  • Localization

AlphaTwentyThree, posted Mon Mar 23, 2015 12:39 pm (4033)


Hello there!
I'm currently taking another look at those pesky XMA files from Electronic arts, namely from Battlefield: Hardline. ea_multi_xma.exe from HCS doesn't work on these so I tried to write my own parser but strangely it doesn't work.
So here's my work-in-progress. This is an example file: http://*USE_ANOTHER_FILEHOSTING*/3408d63 ... 78/test.7z
. For testing purposes I've manually split the file into the two streams that are present and began testing with the first one. The structure of these streams is fairly simple:
(big endian)
0x00 - 4800000C long
0x04 - channel count
0x06 - frequency short
0x08 - number of samples
0x0c - END - stream structure:
short: 0x4400 - new block marker, 0x4500 stop marker
short: length of block
longlong: dummy (or something else?)
length_of_block - 0xc: stream data
To parse the blocks you just write the stream data and fill the block up to the next 0x800 multiple with zeros to get a complete XMA2 block. Afterwards it should be parsable with xma_parse. However the parsing stops at around 63kb and this is where it gets interesting: This very block has a wrong size (8 bytes short) so I've coded in a workaround that writes the missing 8 bytes into the block but to no avail: parsing stops at this block, no matter if I leave the additional bytes or discard them.
Here is the in-progress script I wrote:
Code:
idstring \x48\x0\x0\xC
endian big
get UNK short
get FREQ short
get UNK long
callfunction getlayers 1

set LAYERS 1
for k = 1 <= LAYERS
   log MEMORY_FILE 0 0
   set OFFSET 0xc
   for i = 1
      goto OFFSET
      get TEST short
      if   TEST == 0x4500 # end marker
         callfunction wrapup 1
      endif
      get SIZE short
      math SIZE -= 0xc
      get DUMMY longlong
      savepos OFFSET
      set BIAS 0
      set ADJUST OFFSET
      math ADJUST = SIZE
      goto ADJUST
      get TEST short
      if TEST == 0x4400
      elif TEST == 0x4500
      else
         goto ADJUST
         do
            get TEST byte
            get DUMMY2 threebyte
            savepos SIZE2
         while TEST != 0x44
         xmath BIAS "SIZE2 - 4 - OFFSET - SIZE"
      endif
      callfunction write 1
      #set GO i
      #math GO %= LAYERS
      #if GO == k
      #   callfunction write 1
      #elif GO == 0
      #   if k == LAYERS
      #      callfunction write 1   
      #   endif
      #endif
      math OFFSET = SIZE
      math OFFSET = BIAS
   next i
next k

startfunction getlayers
   savepos MYOFF
   get DUMMY long
   set i 0
   do
      math i = 1
      get TEST short
      get DUMMY short
   while TEST == 0
   math i -= 1
   set LAYERS i
   goto MYOFF
endfunction

startfunction write
   goto OFFSET
   append
      log MEMORY_FILE OFFSET SIZE
   append
   get MSIZE asize MEMORY_FILE
   math MSIZE x= 0x800
   math MSIZE -= 1
   putVarChr MEMORY_FILE MSIZE 0 # write 0 at end of block
endfunction

startfunction wrapup
   get SIZE asize MEMORY_FILE
   get NAME basename
   string NAME = ".uxma"
   log NAME 0 SIZE MEMORY_FILE
   cleanexit
endfunction

As you can see, I'm currently treating files as single layer as I don't know how to distinguish between single- and multi-layer files (thus "set LAYERS 1"). Anyway the outcome is the same. The block-commented section ("set GO i" and so on) is for multilayer files and still work-in-progress.
Ok, this is what I got, now I'll need some help. You can parse the res files to uxma but pasing isn't possible.
Anybody has the time and patience to take a look at this? That would be wonderful!
  • Author
  • Localization

ili, posted Sun Aug 23, 2015 2:11 pm (6909)


old method look close to work but sure help is welcome
  • Author
  • Localization

id-daemon, posted Fri Sep 25, 2015 6:39 pm (7730)


AlphaTwentyThree wrote:
0x04 - codec byte / channel number
0x06 - frequency short
0x08 - flags / number of samples
  • Author
  • Localization

AlphaTwentyThree, posted Sun Sep 27, 2015 8:20 am (7749)


id-daemon2 wrote:
AlphaTwentyThree wrote:
0x04 - codec byte / channel number
0x06 - frequency short
0x08 - flags / number of samples

Thanks. Any idea why the files won't parse?
  • Author
  • Localization

id-daemon, posted Sun Sep 27, 2015 10:52 am (7754)


Can you upload the files again? zippyshare or mega

Considering parsing stops at 64k it is most possible that files were extracted wrong from CAS files. What did you use to extract them?
  • Author
  • Localization

id-daemon, posted Sun Sep 27, 2015 11:07 am (7755)


And to be more precise:

0x04 - codec byte
0x05 - channel number (0 = 1ch, 4 = 2ch, C = 4ch, 10 = 5ch, 14 = 6ch)
0x08 - flags
0x09 (3bytes) number of samples
  • Author
  • Localization

AlphaTwentyThree, posted Sun Sep 27, 2015 11:57 am (7757)


id-daemon2 wrote:
Can you upload the files again? zippyshare or mega

Considering parsing stops at 64k it is most possible that files were extracted wrong from CAS files. What did you use to extract them?

I've re-uploaded the sample above.
The files are from the Xbox 360 version inside the sb/toc pairs. They were extracted with Luigi's frostbyte script. Here's an example: http://*USE_ANOTHER_FILEHOSTING*/68bbd96 ... ksaudio.7z
  • Author
  • Localization

id-daemon, posted Sun Sep 27, 2015 12:36 pm (7758)


Ok all works perfectly fine. The problem is that Frostbyte engine packs all its chunks and Luigi's script just cuts them off, without unpacking and removing segment headers.

So, first you unpack it all with Luigi's script.

Then use my tool to rebuild the data from chunks (or delete 8 bytes at each 0x10000 manually)

Then use ea_multi_xma.

Note that some files have additional info at the beginning (starting like 01100180), for these you have to manually cut it until 4800000C before using ea_multi_xma

Frostbyte_chunk.rar

  • Author
  • Localization

aluigi, posted Sun Sep 27, 2015 12:58 pm (7759)


Do you think it's a bug of the script or they are just saved in this chunked way on purpose?
As far as I know all the other files are extracted correctly.
  • Author
  • Localization

id-daemon, posted Sun Sep 27, 2015 1:01 pm (7760)


I know that all frostbyte chunks are "chunked" on purpose. Some of them may also be compressed. I don't know how its possible that other files extracted correctly, they all must have these chunk headers every 0x10000 bytes.
  • Author
  • Localization

id-daemon, posted Mon Sep 28, 2015 6:43 pm (7790)


By the way, why do you call these "multi-layer" ? What do you mean by layers?
  • Author
  • Localization

AlphaTwentyThree, posted Mon Sep 28, 2015 7:42 pm (7792)


In this specific case they are single layer. There are EA XMA streams that contain two streams (interleaved). In most cases these are "layers" of the same track, e.g. one orchestral track and one percussion track that only kicks in at a certain trigger inside the game. So I guess the engine buffers both layers and when the trigger is activated, fades in the second layer to mix into the first one. I'm a bit surprised you haven't heard of that mechanic.
  • Author
  • Localization

id-daemon, posted Mon Sep 28, 2015 8:01 pm (7794)


Yes I've heard about that type of layers, but I was surprised by thread name "EA XMA multilayer audio files" when all the files in this case seem to be single layer.
  • Author
  • Localization

AlphaTwentyThree, posted Mon Sep 28, 2015 8:37 pm (7797)


If you look at the script you can see that I've already implemented multilayered files. :)
I'll get around to check this in the next few days I think.
  • Author
  • Localization

id-daemon, posted Tue Sep 29, 2015 4:24 pm (7824)


Ok if you will need any more help with these blocks, chunks, or other EA structures, feel free to ask me.
  • Author
  • Localization

AlphaTwentyThree, posted Fri Nov 20, 2015 12:04 pm (9935)


Ok, I have another question here. I'm currently implementing the above code into my big xma transform script. I'm taking a look at the files from Need for Speed: Hot Pursuit (2010, Xbox 360) and I have to admit I have no idea how to distinguish between single and multilayer files. I thought that the block header determines the layer count but obviously I'm wrong.
Here are three multilayer/multichannel files to look at: http://www33.zippyshare.com/v/t8YtSsoM/file.html
Where can I see how many layers/channel pairs there are to process?
  • Author
  • Localization

id-daemon, posted Sun Nov 22, 2015 8:37 pm (9998)


Ok, I'm rarely working with XMA, so I completely forgot everything about those files you uploaded before.

Anyway, these you uploaded now are 6 channel files, that's stated in the header. So because XMA files can only be mono or stereo, these must contain 3 stereo streams.
  • Author
  • Localization

id-daemon, posted Mon Nov 23, 2015 4:47 pm (10014)


I took a closer look at the files. Now I know all the fields meaning and I'm sure there's no layer number there.

Also, I mostly work with PC, and layered files are never interlaced there, but included as separate files. It seems on consoles its otherwise. Based on 3 console games that I researched, I can say that layer number is usually not in the audio file, but in a separate srtucture, or even hardcoded in the .EXE.

Just out of interest, I'm now downloading PC version of Need for Speed: Hot Pursuit 2010 to look at the files.
  • Author
  • Localization

AlphaTwentyThree, posted Mon Nov 23, 2015 6:11 pm (10022)


id-daemon2 wrote:
Anyway, these you uploaded now are 6 channel files, that's stated in the header.
Where exactly? I don't see any field that depicts that...
  • Author
  • Localization

id-daemon, posted Mon Nov 23, 2015 7:26 pm (10037)


id-daemon2 wrote:
And to be more precise:

0x04 - codec byte
0x05 - channel number (0 = 1ch, 4 = 2ch, C = 4ch, 10 = 5ch, 14 = 6ch)
0x08 - flags
0x09 (3bytes) number of samples
  • Author
  • Localization

id-daemon, posted Mon Nov 23, 2015 8:20 pm (10039)


I have the files on PC now. And these are not layered. These are normal 6-channel files (front, back, center, LFE).

If you could find some multilayer sounds, then maybe we can figure out where layer numbers are.
Guest
This topic is now closed to further replies.

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.