Benny Posted May 23, 2005 Share Posted May 23, 2005 To go with my Psychonauts Audio Ripper here are the specs and ripping instructions for the various audio files. Pc Version: .isb files: ----------------------- The .isb files contain the audio data. Structure of file: ------------------ 4 bytes: Header 'RIFF' 4 bytes: File Size (-8) 8 bytes: 'isbftitl' 4 bytes: Size of Text Block X bytes: Text Block Repeated throughout file for each entry: ***** 4 bytes: Block Name 4 bytes: Block Size (not including 8 bytes for block name and size) X Bytes: Block Data ***** Some of these blocks are special: LIST BLOCK: 4 bytes: 'LIST' 4 bytes: Block Size (including all sub-blocks) 8 bytes: Dummy title? Usually 'samptitl' 4 bytes: Size of filename X Bytes: Filename (each letter is seperated by a 0 byte) The filename sometimes has the incorrect file extension so you'll want to remote this and replace it with the correct one. However sometimes the file extension has '-loop' tagged on the end eg 'AsylumExt.aif-Loop' - if you remove the file extension then this file would become 'AsylumExt' - but there is already a file with this name so you'd need to add 'loop' back to the filename somehow to make it a unique name eg 'AsylumExt-Loop'. SINF BLOCK: 4 bytes: 'SINF' 4 bytes: Block Size 8 bytes: ? 4 bytes: Samplerate 8 bytes: ? CHNK BLOCK: 4 bytes: 'CHNK' 4 bytes: Block Size 4 bytes: Number of Channels CMPI BLOCK: 4 bytes: 'CMPI' 4 bytes: Block Size 20 bytes: ? 4 bytes: if = 1053609165 then its a normal pcm wav otherwise its xbox adpcm. DATA BLOCK: 4 bytes: 'DATA' 4 bytes: Block Size Blocksize sometimes has 1 byte padding so: if blocksize mod 2 <> 0 then blocksize:=blocksize + 1 X bytes: Rest of block is the file data. Dump the file data then continue on to next LIST block. Repeat until you reach end of file. Any other block: Just skip the block. Read the block name and block size then seek 'blocksize' bytes. Dumping Files: -------------- If first 4 bytes of file data='OggS' then its an ogg file. Otherwise its always an xbox or normal pcm wave. If its an ogg file then just copy out 'blocksize' bytes. If its a wav file though you need to write the .wav header first: You need to write the following: 4 bytes: 'RIFF' (1179011410) 4 bytes: Blocksize + 40 4 bytes: 'WAVE' (1163280727) 4 bytes: 'fmt ' (544501094) 4 bytes: Size of fmt block (20) 2 bytes: PCM Code: if its normal pcm then = 1 if its xbox adpcm then = 105 2 bytes: Number of channels 4 bytes: Samplerate 4 bytes: Byterate: if its normal pcm then = (SampleRate * No Channels * 16) div 8 if its xbox adpcm then = No Channels * 24806; 2 bytes: Block align if its normal pcm then = (No Channels * 16) div 8 if its xbox adpcm then = No Channels * 36 2 bytes: Bits per sample if its normal pcm then = 16 if its xbox adpcm then = 4 4 bytes: Extra data if its normal pcm then = 16 if its xbox adpcm then = 4194306 4 bytes: 'DATA' (1635017060) 4 bytes: Size of data block (blocksize bytes) Extra Checks: Sometimes the Number of Channels=0 so change this to 1 (I think its always 1) psychonauts_audio_file_formats.txt Link to comment Share on other sites More sharing options...
Benny Posted May 23, 2005 Author Share Posted May 23, 2005 Xbox Version: .xwb files: ------------------------- .xwb files are Xbox Wavebank files and contain the audio data. Structure of file: ------------------ 4 bytes: 'WBND' 4 bytes: Version 32 bytes: Bank header Strictly speaking you can seek straight past this. It (always?) refers to 4 sections: Section 1 4 bytes: Offset 4 bytes: Length Section 2 4 bytes: Offset 4 bytes: Length Section 3 4 bytes: Offset 4 bytes: Length Section 4 4 bytes: Offset 4 bytes: Length Sections: --------- The sections are: Section 1: Wave bank info Section 2: File records Section 3: Always empty? Section 4: File data Section 1: Wave bank info 4 bytes: Flags 4 bytes: Number of files 16 bytes: WaveBank name (padded with 0's) 4 bytes: Size of each file record (in section 2) 4 bytes: Size of each entry name block 4 bytes: Offset of file data (offset of section 3) 4 bytes: Always empty? Section 2: File records Repeat for (Number of files) 2 bytes: Number of channels 2 bytes: Format tag (0=normal pcm) (1=xbox adpcm) 4 bytes: Magic Value 4 bytes: File Offset (in section 3) 4 bytes: File size 4 bytes: Loop region offset (not sure what this does) 4 bytes: Loop region length (not sure what this does) Section 3: Always empty? Section 4: File data Dumping files: -------------- Read the file records then seek to 'Offset of file data'(section 3) + File Offset. The files are wav's so you need to write a .wav header first: 4 bytes: 'RIFF' (1179011410 4 bytes: Blocksize + 40 4 bytes: 'WAVE' (1163280727) 4 bytes: 'fmt ' (544501094) 4 bytes: Size of fmt block (20) 2 bytes: PCM Code: if its xbox adpcm then = 105 if its normal pcm then = 1 2 bytes: Number of channels (NoChannels) 4 bytes: Samplerate: if its xbox adpcm then = (MagicValue - (1 + (NoChannels * 4))) div 32 if its normal pcm then: I havent been able to work out a formula for getting the samplerate from the MagicValue for a normal pcm wav. The best I can do for now is hardcoded values: If MagicValue=2148894856 then SampleRate=44100 There are other MagicValues for other SampleRates but I havent determined these yet. 4 bytes: Byterate: if its normal pcm then = (SampleRate * NoChannels * 16) div 8 if its xbox adpcm then: the following values were obtained from the xbox codec itself if SampleRate=48000 then ByteRate=NoChannels * 27000 if SampleRate=44100 then ByteRate=NoChannels * 24806 if SampleRate=32000 then ByteRate=NoChannels * 18000 if SampleRate=22050 then ByteRate=NoChannels * 12403 if SampleRate=16000 then ByteRate=NoChannels * 9000 if SampleRate=11025 then (its different for some reason) if NoChannels=1 then ByteRate=6201 else ByteRate=12403 if SampleRate=8000 then ByteRate=NoChannels * 4500 2 bytes: Block align if its normal pcm then = (No Channels * 16) div 8 if its xbox adpcm then = No Channels * 36 2 bytes: Bits per sample if its normal pcm then = 16 if its xbox adpcm then = 4 4 bytes: Extra data if its normal pcm then = 16 if its xbox adpcm then = 4194306 4 bytes: 'DATA' (1635017060) 4 bytes: Size of data block (FileSize bytes) Extra Checks: Sometimes the Number of Channels=0 so change this to 1 Sometimes the Number of Channels is > 2 so correct it: See if there is a remainder, if there is, its 2 channels, if not its 1: if its xbox adpcm then CheckValue:=(MagicValue - 5) mod 32; if its normal pcm then CheckValue:=(MagicValue - 4) mod 32; if CheckValue=0 then NoChannels:=1 else NoChannels:=2; These methods of checking the number of channels work in all cases. Since the number of channels can be incorrectly reported its probably best to run these checks on every file. File Names: ----------- .xsb files You will notice that the Wavebank doesnt contain any file names. This is because these are stored in a seperate file - the SoundBank file (.xsb). The name of the SoundBank corresponds to the WaveBank usually, eg ASMusic.xwb and ASMusic.xsb. If in doubt though, the SoundBank referrs to its WaveBank internally, so you can check. Some WaveBanks do not have a corresponding SoundBank. Offsets are relative to the beginning of the file unless otherwise stated. 4 bytes: 'SDBK' 4 bytes: ? 4 bytes: Offfset of wavebank name (Name is 16 bytes long) 18 bytes: ? 2 bytes: Number of files (File names) 28 bytes: Soundbank name? File records: Repeat for 'Number of files' 4 bytes: Offset of filename 4 bytes: ? 4 bytes: ? 4 bytes: ? 4 bytes: ? Seek to 'Offset of filename' and read the filename (it is null terminated) I assume that the order of the filenames in the SoundBank corresponds to the order of the files in the WaveBank, but I dont know for sure. Be aware that sometimes there are more entries in a WaveBank than there are file names in a SoundBank, so some files have no name. Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.