Code: Select all
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: Select all
#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: Select all
# 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
