ZenHAX

Free Game Research Forum | Official QuickBMS support | twitter @zenhax | SSL HTTPS://zenhax.com
It is currently Thu Apr 15, 2021 8:13 am

All times are UTC




Post new topic  Reply to topic  [ 4 posts ] 
Author Message
 Post subject: X-Com Alliance imus
PostPosted: Tue Mar 16, 2021 4:10 pm 

Joined: Thu Apr 23, 2020 5:57 pm
Posts: 5
Here is what I have discovered after examining the X-Com Alliance imus .int format:

Code:
Offset 0x00 has the track count

Offset 0x264 is the start of the track info header block
0x266 is the channel count for track 1
0x268 is the sample rate for track 1
0x270 is the interleave for track 1

Each track block is 54 bytes, so track 2 offset would be at 0x29A, etc.

Then the audio data begins. 4 byte header which is the data size of the chunk. Each chunk is interleaved, so the first chunk is for track 1, the next chunk is for track 2, etc.

I tried to make a bms script, which works but is not optimal, because I haven't played with bms recently. I found that each chunk needs to be decoded to wav with Foobar2000, because if I binary copy the data to 1 file, the audio is distorted.

With the script, you can dechunk the files and then use a txth with foobar2000 to encode to 1 wav for each subsong, with the converter set to output merge.

If a spike in audio is seen at the end, then remove the last vgmstream file.

I recommend listening to the audio in Audacity because the music is often really quiet, and then spikes to max amplitude.

Code:
#X-Com Alliance BMS
get TRACKS byte
goto 0x264
for i = 1 <= TRACKS
   get DUMMY1 short
   get CHANNELS byte
   get DUMMY2 byte
   get FREQUENCY short
   get DUMMY3 long
   get DUMMY4 short
   get INTERLEAVE short

   for x = 0 < 10
      get DUMMY4 long
   next x

   print "Track %i%, Channels %CHANNELS%, Frequency %FREQUENCY%, Interleave %INTERLEAVE|hex%"
next i

# Uncomment next line if you want to see the track info but not extract
# cleanexit

get FSIZE ASIZE
math counter = 1

for i = 1
   get SIZE long
   savePos OFFSET
   
   if counter > TRACKS
      math counter = 1
   endif
   
   get NAME BASENAME
   string NAME += "-"
   string NAME += counter
   string NAME += "_"
   if i < 10
      string NAME += 0
      string NAME += 0
      string NAME += i
   elif i >= 10 && i < 100
      string NAME += 0
      string NAME += i
   else
      string NAME += i
   endif
   
   string NAME += ".vgmstream"
   
   log NAME OFFSET SIZE
   
   math counter += 1
   
   math OFFSET += SIZE
   if OFFSET == FSIZE
      cleanexit
   else
      goto OFFSET
   endif
next i


Code:
# X-Com Alliance PC TXTH
# vgmstream files extracted from imusX.int

codec = MSADPCM

interleave = 0x400
#interleave = 0x200

channels = 2
#channels = 1

sample_rate = 22050
#sample_rate = 11025

num_samples = data_size


Top
   
 Post subject: Re: X-Com Alliance imus
PostPosted: Wed Mar 17, 2021 7:05 am 
Site Admin
User avatar

Joined: Wed Jul 30, 2014 9:32 pm
Posts: 12088
Little off-topic from me: you can build the filename just by using the following command :)
Code:
get NAME basename
string NAME p "%s-%d_%03d.vgmstream" NAME counter i


Top
   
 Post subject: Re: X-Com Alliance imus
PostPosted: Wed Mar 17, 2021 2:59 pm 

Joined: Thu Apr 23, 2020 5:57 pm
Posts: 5
Thank you aluigi, that code is much more elegant.


Top
   
 Post subject: Re: X-Com Alliance imus
PostPosted: Sat Mar 20, 2021 3:32 pm 

Joined: Thu Apr 23, 2020 5:57 pm
Posts: 5
I improved the bms script by concatenating the chunks and generating txth files for use with vgmstream.

Code:
# X-Com Alliance BMS to deinterleave the imus int files
# and create txth files needed to play the concatenated
# chunks with vgmstream

# Decrease the value of subsong_count in the generated txth files
# if you hear pops at the end of the music

goto 0x00
get TRACKS byte

goto 0x04
get CHUNKS byte

goto 0x264
for i = 0 < TRACKS
   get DUMMY1 short
   get CHANNELS byte
   get DUMMY2 byte
   get FREQUENCY short
   get DUMMY3 long
   get DUMMY4 short
   get INTERLEAVE short

   for x = 0 < 10
      get DUMMY4 long
   next x

   print "Track %i%, Interleave %INTERLEAVE|hex%, Channels %CHANNELS%, Frequency %FREQUENCY%, Chunks %CHUNKS%"
   putarray 0 i INTERLEAVE
   putarray 1 i CHANNELS
   putarray 2 i FREQUENCY
   putarray 3 i CHUNKS
next i

# Uncomment next line if you want to see the track info but not extract
# cleanexit

math COUNTER = 0
set TOTALCHUNKS CHUNKS
math TOTALCHUNKS *= TRACKS

for i = 0 < TOTALCHUNKS
   get DUMMY long

   if COUNTER == TRACKS
      math COUNTER = 0
   endif
   getarray INTERLEAVE 0 COUNTER
   getarray CHANNELS 1 COUNTER
   getarray FREQUENCY 2 COUNTER
   getarray CHUNKS 3 COUNTER

   if INTERLEAVE == 0x400
      set SIZE == 0x2B94
   elif INTERLEAVE == 0x200
      set SIZE == 0x15CA
   elif INTERLEAVE == 0x100
      set SIZE == 0x0B0C
   else
      cleanexit
   endif

   savePos OFFSET

   math COUNTER += 1

   get NAME basename
   string VGMSTREAM p "%s-%d.vgmstream" NAME COUNTER

   if i < TRACKS
      string TXTH p "%s-%d.vgmstream.txth" NAME COUNTER

      log MEMORY_FILE 0 0

      put "codec = MSADPCM" line MEMORY_FILE
      string txthval p "interleave = 0x%x" INTERLEAVE
      put txthval line MEMORY_FILE
      string txthval p "channels = %d" CHANNELS
      put txthval line MEMORY_FILE
      string txthval p "sample_rate = %d" FREQUENCY
      put txthval line MEMORY_FILE
      put "" line MEMORY_FILE
      string txthval p "subsong_count = %d" CHUNKS
      put txthval line MEMORY_FILE
      put "chunk_start = 0" line MEMORY_FILE
      string txthval p "chunk_size = 0x%x" SIZE
      put txthval line MEMORY_FILE
      string txthval p "chunk_count = %d" CHUNKS
      put txthval line MEMORY_FILE
      put "" line MEMORY_FILE
      put "start_offset = 0x00" line MEMORY_FILE
      put "num_samples = data_size" line MEMORY_FILE

      get MEM_SIZE asize MEMORY_FILE

      log TXTH 0 MEM_SIZE MEMORY_FILE
   endif

   if i == TRACKS
      append
   endif
   log VGMSTREAM OFFSET SIZE

   math OFFSET += SIZE
   goto OFFSET
next i


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 4 posts ] 

All times are UTC


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Limited