<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="https://www.simswiki.info/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://simswiki.info/index.php?action=history&amp;feed=atom&amp;title=Movie</id>
		<title>Movie - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://simswiki.info/index.php?action=history&amp;feed=atom&amp;title=Movie"/>
		<link rel="alternate" type="text/html" href="http://simswiki.info/index.php?title=Movie&amp;action=history"/>
		<updated>2026-10-07T09:17:49Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.20.2</generator>

	<entry>
		<id>http://simswiki.info/index.php?title=Movie&amp;diff=59675&amp;oldid=prev</id>
		<title>Kiwi tea at 17:01, 17 September 2012</title>
		<link rel="alternate" type="text/html" href="http://simswiki.info/index.php?title=Movie&amp;diff=59675&amp;oldid=prev"/>
				<updated>2012-09-17T17:01:17Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
			&lt;tr style='vertical-align: top;'&gt;
			&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;← Older revision&lt;/td&gt;
			&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 17:01, 17 September 2012&lt;/td&gt;
			&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 496:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 496:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&amp;#160; 0xFFFFFFFD,&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&amp;#160; 0xFFFFFFFD,&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&amp;#160; 0xFFFFFFFC&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&amp;#160; 0xFFFFFFFC&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;};&amp;lt;/pre&amp;gt; [[Category:Modding]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;};&amp;lt;/pre&amp;gt; &amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Category:&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;Sims 2 &lt;/ins&gt;Modding]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Kiwi tea</name></author>	</entry>

	<entry>
		<id>http://simswiki.info/index.php?title=Movie&amp;diff=4107&amp;oldid=prev</id>
		<title>Delphy: Auto-inserted from WakkaWikki</title>
		<link rel="alternate" type="text/html" href="http://simswiki.info/index.php?title=Movie&amp;diff=4107&amp;oldid=prev"/>
				<updated>2005-12-31T23:04:18Z</updated>
		
		<summary type="html">&lt;p&gt;Auto-inserted from WakkaWikki&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{OldWikiEntry}} From Simcity 4&lt;br /&gt;
--------------&lt;br /&gt;
&lt;br /&gt;
MAD video is the format of Simcity4's videos. Not really anything else to say about it. Its taken us a long time to really get started on this though, but here we are&lt;br /&gt;
&lt;br /&gt;
There are video and audio blocks&lt;br /&gt;
The video is EA specific type&lt;br /&gt;
The audio is EA ASF STR Audio&lt;br /&gt;
The whole format is really a one block video one block audio repeat.&lt;br /&gt;
&lt;br /&gt;
It has the following structure&lt;br /&gt;
&lt;br /&gt;
------------------------------&lt;br /&gt;
Video blocks - Hayly,Darkmatter,Karybdis&lt;br /&gt;
------------------------------&lt;br /&gt;
Header:&lt;br /&gt;
&lt;br /&gt;
DWORD - MAD* - Identifier of chunk where * is a unique chunk type identifier : &lt;br /&gt;
DWORD - Size of the frame chunk&lt;br /&gt;
DWORD - Unknown (0)&lt;br /&gt;
WORD - Max Data rate per Sec. (ABAA normally. Max bytes needed to present the video properly per sec)&lt;br /&gt;
WORD - Delay MicroSec Per Frame (standard is 66ms or 15 frames a second.) (indicates file timing)&lt;br /&gt;
WORD - Pixel width of the frame chunk&lt;br /&gt;
WORD - Pixel height of the frame chunk&lt;br /&gt;
BYTE - Unknown&lt;br /&gt;
BYTE - Unknown&lt;br /&gt;
BYTE - In TS2 movies, chunk type. 02 = B-frame, 00 = P-frame, 01 = I-frame. In SC4 movies, blank&lt;br /&gt;
BYTE - Unknown (0)&lt;br /&gt;
&lt;br /&gt;
--MAD TYPES&lt;br /&gt;
---k = Intra Coded Keyframes (I-Frame) (estimated size, 30 byte block)&lt;br /&gt;
---m = Predictive coded (previous) frames (P-Frame) (estimated 18 byte block)&lt;br /&gt;
---e = Bidirectionally-predictive coded (both previous and following) frames (B-frame) (estimated 18 byte block)&lt;br /&gt;
-----Note: E blocks are only present in TS2 movies and not SC4&lt;br /&gt;
&lt;br /&gt;
SC4 uses a KMMMM KMMMM format with a keyframe every 5 frames&lt;br /&gt;
TS2 uses a KEMEMEMEMEMEME KEMEMEMEMEMEME format with a keyframe every 14 frames&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Video Data - Each video chunk has readable data blocks with a size dependant on its identifier (k,m,e). The codec breakdown is unknown, so we cant view the movies yet&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
========&lt;br /&gt;
1. .ASF/.STR Music Files (MAD Audio Blocks) - Valery V. Anisimovsky&lt;br /&gt;
========&lt;br /&gt;
&lt;br /&gt;
The music in many new Electronic Arts games is in .ASF stand-alone files&lt;br /&gt;
(sometimes ASF files have extension .STR). These files have the block&lt;br /&gt;
structure analoguous to RIFF. Namely, these files are divided into blocks&lt;br /&gt;
(without any global file header like RIFFs have). Each block has the&lt;br /&gt;
following header:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;(C)&lt;br /&gt;
struct ASFBlockHeader&lt;br /&gt;
{&lt;br /&gt;
  char	szBlockID[4];&lt;br /&gt;
  DWORD dwSize;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
szBlockID -- string ID for the block.&lt;br /&gt;
&lt;br /&gt;
dwSize -- size of the block (in bytes) INCLUDING this header.&lt;br /&gt;
&lt;br /&gt;
Further I'll describe the contents of blocks of all block types in .ASF file.&lt;br /&gt;
&lt;br /&gt;
When I say &amp;quot;block begins with...&amp;quot; that means &amp;quot;the contents of that&lt;br /&gt;
block (which begin just after ASFBlockHeader) begin with...&amp;quot;.&lt;br /&gt;
Quoted strings are block IDs.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;SCHl&amp;quot;: header block. This is the first block in ASF.&lt;br /&gt;
In the most of files this block begins with the ID string &amp;quot;PT\0\0&amp;quot; (or number&lt;br /&gt;
0x50540000). Further goes the PT header data which describes audio data in&lt;br /&gt;
the file. This PT header should be parsed rather than just read as a simple&lt;br /&gt;
structure. Here I give the parsing code. These functions use fread() and fseek()&lt;br /&gt;
stdio functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;(C)&lt;br /&gt;
'' first of all, we need a function which reads a small (variable) number&lt;br /&gt;
'' bytes and composes a DWORD of them. Note that such DWORD will be a kind&lt;br /&gt;
'' of big-endian (Motorola) stored, e.g. 3 consecutive bytes 0x12 0x34 0x56&lt;br /&gt;
'' will give a DWORD 0x00123456.&lt;br /&gt;
DWORD ReadBytes(FILE* file, BYTE count)&lt;br /&gt;
{&lt;br /&gt;
  BYTE	i, byte;&lt;br /&gt;
  DWORD result;&lt;br /&gt;
&lt;br /&gt;
  result=0L;&lt;br /&gt;
  for (i=0;i&amp;lt;count; i+ + )&lt;br /&gt;
  {&lt;br /&gt;
	fread(&amp;amp;byte,sizeof(BYTE),1,file);&lt;br /&gt;
	result&amp;lt;&amp;lt;=8;&lt;br /&gt;
	result+=byte;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
'' these will be set by ParsePTHeader&lt;br /&gt;
DWORD dwSampleRate;&lt;br /&gt;
DWORD dwChannels;&lt;br /&gt;
DWORD dwCompression;&lt;br /&gt;
DWORD dwNumSamples;&lt;br /&gt;
DWORD dwDataStart;&lt;br /&gt;
DWORD dwLoopOffset;&lt;br /&gt;
DWORD dwLoopLength;&lt;br /&gt;
DWORD dwBytesPerSample;&lt;br /&gt;
BYTE  bSplit;&lt;br /&gt;
BYTE  bSplitCompression;&lt;br /&gt;
&lt;br /&gt;
'' Here goes the parser itself&lt;br /&gt;
'' This function assumes that the current file pointer is set to the&lt;br /&gt;
'' start of PT header data, that is, just after PT string ID &amp;quot;PT\0\0&amp;quot;&lt;br /&gt;
void ParsePTHeader(FILE* file)&lt;br /&gt;
{&lt;br /&gt;
  BYTE byte;&lt;br /&gt;
  BOOL bInHeader, bInSubHeader;&lt;br /&gt;
&lt;br /&gt;
  bInHeader=TRUE;&lt;br /&gt;
  while (bInHeader)&lt;br /&gt;
  {&lt;br /&gt;
	fread(&amp;amp;byte,sizeof(BYTE),1,file);&lt;br /&gt;
	switch (byte) '' parse header code&lt;br /&gt;
	{&lt;br /&gt;
	  case 0xFF: '' end of header&lt;br /&gt;
	   bInHeader=FALSE;&lt;br /&gt;
	  case 0xFE: '' skip&lt;br /&gt;
	  case 0xFC: '' skip&lt;br /&gt;
	   break;&lt;br /&gt;
	  case 0xFD: '' subheader starts...&lt;br /&gt;
	   bInSubHeader=TRUE;&lt;br /&gt;
	   while (bInSubHeader)&lt;br /&gt;
	   {&lt;br /&gt;
	     fread(&amp;amp;byte,sizeof(BYTE),1,file);&lt;br /&gt;
	     switch (byte) '' parse subheader code&lt;br /&gt;
	     {&lt;br /&gt;
	       case 0x82:&lt;br /&gt;
		    fread(&amp;amp;byte,sizeof(BYTE),1,file);&lt;br /&gt;
		    dwChannels=ReadBytes(file,byte);&lt;br /&gt;
		    break;&lt;br /&gt;
	       case 0x83:&lt;br /&gt;
		    fread(&amp;amp;byte,sizeof(BYTE),1,file);&lt;br /&gt;
		    dwCompression=ReadBytes(file,byte);&lt;br /&gt;
		    break;&lt;br /&gt;
	       case 0x84:&lt;br /&gt;
		    fread(&amp;amp;byte,sizeof(BYTE),1,file);&lt;br /&gt;
		    dwSampleRate=ReadBytes(file,byte);&lt;br /&gt;
		    break;&lt;br /&gt;
	       case 0x85:&lt;br /&gt;
		    fread(&amp;amp;byte,sizeof(BYTE),1,file);&lt;br /&gt;
		    dwNumSamples=ReadBytes(file,byte);&lt;br /&gt;
		    break;&lt;br /&gt;
	       case 0x86:&lt;br /&gt;
		    fread(&amp;amp;byte,sizeof(BYTE),1,file);&lt;br /&gt;
		    dwLoopOffset=ReadBytes(file,byte);&lt;br /&gt;
		    break;&lt;br /&gt;
	       case 0x87:&lt;br /&gt;
		    fread(&amp;amp;byte,sizeof(BYTE),1,file);&lt;br /&gt;
		    dwLoopLength=ReadBytes(file,byte);&lt;br /&gt;
		    break;&lt;br /&gt;
	       case 0x88:&lt;br /&gt;
		    fread(&amp;amp;byte,sizeof(BYTE),1,file);&lt;br /&gt;
		    dwDataStart=ReadBytes(file,byte);&lt;br /&gt;
		    break;&lt;br /&gt;
	       case 0x92:&lt;br /&gt;
		    fread(&amp;amp;byte,sizeof(BYTE),1,file);&lt;br /&gt;
		    dwBytesPerSample=ReadBytes(file,byte);&lt;br /&gt;
		    break;&lt;br /&gt;
	       case 0x80: '' ???&lt;br /&gt;
		    fread(&amp;amp;byte,sizeof(BYTE),1,file);&lt;br /&gt;
		    bSplit=ReadBytes(file,byte);&lt;br /&gt;
		    break;&lt;br /&gt;
	       case 0xA0: '' ???&lt;br /&gt;
		    fread(&amp;amp;byte,sizeof(BYTE),1,file);&lt;br /&gt;
		    bSplitCompression=ReadBytes(file,byte);&lt;br /&gt;
		    break;&lt;br /&gt;
	       case 0xFF:&lt;br /&gt;
		    subflag=FALSE;&lt;br /&gt;
		    flag=FALSE;&lt;br /&gt;
		    break;&lt;br /&gt;
	       case 0x8A: '' end of subheader&lt;br /&gt;
		    bInSubHeader=FALSE;&lt;br /&gt;
	       default: '' ???&lt;br /&gt;
		    fread(&amp;amp;byte,sizeof(BYTE),1,file);&lt;br /&gt;
		    fseek(file,byte,SEEK_CUR);&lt;br /&gt;
	     }&lt;br /&gt;
	   }&lt;br /&gt;
	   break;&lt;br /&gt;
	  default:&lt;br /&gt;
	   fread(&amp;amp;byte,sizeof(BYTE),1,file);&lt;br /&gt;
	   if (byte==0xFF)&lt;br /&gt;
	      fseek(file,4,SEEK_CUR);&lt;br /&gt;
	   fseek(file,byte,SEEK_CUR);&lt;br /&gt;
	}&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
dwSampleRate -- sample rate for the file. Note that headers of most of&lt;br /&gt;
ASFs/MUSes I've seen DO NOT contain sample rate subheader section. Currently&lt;br /&gt;
I just set sample rate for such files to the default: 22050 Hz. It seems to&lt;br /&gt;
work okay.&lt;br /&gt;
&lt;br /&gt;
dwChannels -- number of channels for the file: 1 for mono, 2 for stereo.&lt;br /&gt;
If this is NOT set by ParsePTHeader, then you may use the default: stereo.&lt;br /&gt;
&lt;br /&gt;
dwCompression -- Compression tag. If this is 0x00, then no compression is&lt;br /&gt;
used and audio data is signed 16-bit PCM. If this is 0x07, the audio data is&lt;br /&gt;
compressed with EA ADPCM algorithm. Please read the next section for the&lt;br /&gt;
description of EA ADPCM decompression scheme. In some files this tag is&lt;br /&gt;
omitted -- I use 0x00 (no compression) for them.&lt;br /&gt;
&lt;br /&gt;
dwNumSamples -- number of samples in the file.&lt;br /&gt;
&lt;br /&gt;
dwDataStart -- in ASF files this's not used.&lt;br /&gt;
&lt;br /&gt;
dwLoopOffset -- offset when looping (from start of sound part).&lt;br /&gt;
&lt;br /&gt;
dwLoopLength -- length when looping.&lt;br /&gt;
&lt;br /&gt;
dwBytesPerSample -- bytes per sample (Default is 2). Divide this by&lt;br /&gt;
dwChannels to get resolution of sound data.&lt;br /&gt;
&lt;br /&gt;
bSplit -- this looks like to be 0x01 for files using &amp;quot;split&amp;quot; SCDl blocks&lt;br /&gt;
(see below). If this subheader field is absent, the file uses &amp;quot;normal&amp;quot;&lt;br /&gt;
(interleaved) SCDl blocks.&lt;br /&gt;
&lt;br /&gt;
bSplitCompression -- this looks like to be 0x08 for files using non-compressed&lt;br /&gt;
&amp;quot;split&amp;quot; SCDl blocks. If this subheader field is absent in the file using&lt;br /&gt;
&amp;quot;split&amp;quot; SCDls, the file uses EA ADPCM compression. This subheader field&lt;br /&gt;
should not appear in a file using &amp;quot;normal&amp;quot; (interleaved) SCDls.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;SCCl&amp;quot;: count block. This block goes after &amp;quot;SCHl&amp;quot; and contains one DWORD&lt;br /&gt;
value which is a number of &amp;quot;SCDl&amp;quot; data blocks in ASF file.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;SCDl&amp;quot;: data block. These blocks contain audio data. Depending on the&lt;br /&gt;
parameters set in the header (see above) SCDl block may contain compressed&lt;br /&gt;
(by EA ADPCM or IMA ADPCM) or non-compressed audio data and the data itself&lt;br /&gt;
may be interleaved or split (see below).&lt;br /&gt;
&lt;br /&gt;
If no compression is used and the file does not use &amp;quot;split&amp;quot; SCDl blocks,&lt;br /&gt;
SCDl block begins with a DWORD value which is the number of samples in this&lt;br /&gt;
block and after that comes signed 16-bit PCM data, in the interleaved form:&lt;br /&gt;
LRLR...LR (L and R are 16-bit sample values for left and right channels).&lt;br /&gt;
&lt;br /&gt;
Hereafter by &amp;quot;chunk&amp;quot; I mean the audio data in the &amp;quot;SCDl&amp;quot; data block, that is,&lt;br /&gt;
compressed/non-compressed data which starts after chunk header.&lt;br /&gt;
&lt;br /&gt;
In the newer EA games (NHL'2000/NBA'2000/FIFA'99'2000/NFS5) non-compressed&lt;br /&gt;
&amp;quot;split&amp;quot; SCDl blocks are used. These blocks begin with a chunk header:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;(C)&lt;br /&gt;
struct ASFSplitPCMChunkHeader&lt;br /&gt;
{&lt;br /&gt;
  DWORD dwOutSize;&lt;br /&gt;
  DWORD dwLeftChannelOffset;&lt;br /&gt;
  DWORD dwRightChannelOffset;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
dwOutSize -- size of audio data in this chunk (in samples).&lt;br /&gt;
&lt;br /&gt;
dwLeftChannelOffset, dwRightChannelOffset -- offsets to PCM data for&lt;br /&gt;
left and right channels, relative to the byte which immediately follows&lt;br /&gt;
ASFSplitPCMChunkHeader structure. E.g. for left channel this offset is zero&lt;br /&gt;
-- the data starts immediately after this structure.&lt;br /&gt;
&lt;br /&gt;
After this structure comes PCM data for stereo wavestream and it's not&lt;br /&gt;
interleaved (LRLRLR...), but it's split: first go sample values for left&lt;br /&gt;
channel, then -- for right channel, that is the layout is LL...LRR...R.&lt;br /&gt;
&lt;br /&gt;
If EA ADPCM (or IMA ADPCM) compression is used, but the file does not use&lt;br /&gt;
&amp;quot;split&amp;quot; SCDls, each SCDl block begins with a chunk header:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;(C)&lt;br /&gt;
struct ASFChunkHeader&lt;br /&gt;
{&lt;br /&gt;
  DWORD dwOutSize;&lt;br /&gt;
  SHORT lCurSampleLeft;&lt;br /&gt;
  SHORT lPrevSampleLeft;&lt;br /&gt;
  SHORT lCurSampleRight;&lt;br /&gt;
  SHORT lPrevSampleRight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
dwOutSize -- size of decompressed audio data in this chunk (in samples).&lt;br /&gt;
&lt;br /&gt;
lCurSampleLeft, lCurSampleRight, lPrevSampleLeft, lPrevSampleRight are initial&lt;br /&gt;
values for EA ADPCM decompression routine for this data block (for left and right&lt;br /&gt;
channels respectively). I'll describe the usage of these further when I get to&lt;br /&gt;
EA ADPCM decompression scheme.&lt;br /&gt;
&lt;br /&gt;
Note that the structure above is ONLY for stereo files. For mono there're&lt;br /&gt;
just no lCurSampleRight, lPrevSampleRight fields.&lt;br /&gt;
&lt;br /&gt;
If IMA ADPCM compression is used, the meanings of some chunk header fields&lt;br /&gt;
are different -- see my EA-ASF.TXT specs for details.&lt;br /&gt;
&lt;br /&gt;
After this chunk header the compressed data comes. See the next section for&lt;br /&gt;
EA ADPCM decompression scheme description.&lt;br /&gt;
&lt;br /&gt;
If EA ADPCM (or IMA ADPCM) compression is used and the file uses &amp;quot;split&amp;quot; SCDls,&lt;br /&gt;
each SCDl block begins with a different chunk header:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;(C)&lt;br /&gt;
struct ASFSplitChunkHeader&lt;br /&gt;
{&lt;br /&gt;
  DWORD dwOutSize;&lt;br /&gt;
  DWORD dwLeftChannelOffset;&lt;br /&gt;
  DWORD dwRightChannelOffset;&lt;br /&gt;
};&lt;br /&gt;
SHORT lCurSampleLeft;&lt;br /&gt;
SHORT lPrevSampleLeft;&lt;br /&gt;
BYTE  bLeftChannelData[]; '' compressed data for left channel goes here...&lt;br /&gt;
SHORT lCurSampleRight;&lt;br /&gt;
SHORT lPrevSampleRight;&lt;br /&gt;
BYTE  bRightChannelData[]; '' compressed data for right channel goes here...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
dwOutSize -- size of decompressed audio data in this chunk (in samples).&lt;br /&gt;
&lt;br /&gt;
dwLeftChannelOffset, dwRightChannelOffset -- offsets to compressed data for&lt;br /&gt;
left and right channels, relative to the byte which immediately follows&lt;br /&gt;
ASFSplitChunkHeader structure. E.g. for left channel this offset is zero --&lt;br /&gt;
the data starts immediately after this structure.&lt;br /&gt;
&lt;br /&gt;
lCurSampleLeft, lCurSampleRight, lPrevSampleLeft, lPrevSampleRight have the&lt;br /&gt;
same meaning as above, but note that these values are SHORTs.&lt;br /&gt;
&lt;br /&gt;
So, use mono decoder for each channel data and then create normal LRLR...&lt;br /&gt;
stereo waveform before outputting.&lt;br /&gt;
Such (newer) files may be separated from the others by presence of 0x80 type&lt;br /&gt;
section in PT header (the value stored in the section is 0x01 for such files).&lt;br /&gt;
Some of such files also do not contain compression type (0x83) section in&lt;br /&gt;
their PT header.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;SCLl&amp;quot;: loop block. This block defines looping point for the song. It&lt;br /&gt;
contains only DWORD value, which is the looping jump position (in samples)&lt;br /&gt;
relative to the start of the song. You should make the jump just when you&lt;br /&gt;
encounter this block.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;SCEl&amp;quot;: end block. This block indicates the end of audio stream.&lt;br /&gt;
&lt;br /&gt;
Note that in some games audio files are contained within game resources. As&lt;br /&gt;
a rule, such resources are not compressed/encrypted, so you may just search&lt;br /&gt;
for ASF file signature (e.g. &amp;quot;SCHl&amp;quot;) and this will mark the beginning of audio&lt;br /&gt;
stream, while &amp;quot;SCEl&amp;quot; block marks the end of that stream.&lt;br /&gt;
&lt;br /&gt;
============&lt;br /&gt;
2. EA ADPCM Decompression Algorithm&lt;br /&gt;
============&lt;br /&gt;
&lt;br /&gt;
During the decompression four LONG variables must be maintained for stereo&lt;br /&gt;
stream: lCurSampleLeft, lCurSampleRight, lPrevSampleLeft, lPrevSampleRight&lt;br /&gt;
and two -- for mono stream: lCurSample, lPrevSample. At the beginning of each&lt;br /&gt;
&amp;quot;SCDl&amp;quot; data block you must initialize these variables using the values in&lt;br /&gt;
ASFChunkHeader.&lt;br /&gt;
Note that LONG here is signed.&lt;br /&gt;
&lt;br /&gt;
Here's the code which decompresses one &amp;quot;SCDl&amp;quot; block of EA ADPCM compressed&lt;br /&gt;
stereo stream.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;(C)&lt;br /&gt;
BYTE  InputBuffer[InputBufferSize]; '' buffer containing audio data of &amp;quot;SCDl&amp;quot; block&lt;br /&gt;
BYTE  bInput;&lt;br /&gt;
DWORD dwOutSize; '' outsize value from the ASFChunkHeader&lt;br /&gt;
DWORD i, bCount, sCount;&lt;br /&gt;
LONG  c1left,c2left,c1right,c2right,left,right;&lt;br /&gt;
BYTE  dleft,dright;&lt;br /&gt;
&lt;br /&gt;
DWORD dwSubOutSize=0x1c;&lt;br /&gt;
&lt;br /&gt;
i=0;&lt;br /&gt;
&lt;br /&gt;
'' process integral number of (dwSubOutSize) samples&lt;br /&gt;
for (bCount=0;bCount&amp;lt;(dwOutSize/dwSubOutSize);bCount++)&lt;br /&gt;
{&lt;br /&gt;
  bInput=InputBuffer[i++];&lt;br /&gt;
  c1left=EATable[HINIBBLE(bInput)];   '' predictor coeffs for left channel&lt;br /&gt;
  c2left=EATable[HINIBBLE(bInput)+4];&lt;br /&gt;
  c1right=EATable[LONIBBLE(bInput)];  '' predictor coeffs for right channel&lt;br /&gt;
  c2right=EATable[LONIBBLE(bInput)+4];&lt;br /&gt;
  bInput=InputBuffer[i++];&lt;br /&gt;
  dleft=HINIBBLE(bInput)+8;   '' shift value for left channel&lt;br /&gt;
  dright=LONIBBLE(bInput)+8;  '' shift value for right channel&lt;br /&gt;
  for (sCount=0;sCount&amp;lt;dwSubOutSize;sCount++)&lt;br /&gt;
  {&lt;br /&gt;
	bInput=InputBuffer[i++];&lt;br /&gt;
	left=HINIBBLE(bInput);  '' HIGHER nibble for left channel&lt;br /&gt;
	right=LONIBBLE(bInput); '' LOWER nibble for right channel&lt;br /&gt;
	left=(left&amp;lt;&amp;lt;0x1c)&amp;gt;&amp;gt;dleft;&lt;br /&gt;
	right=(right&amp;lt;&amp;lt;0x1c)&amp;gt;&amp;gt;dright;&lt;br /&gt;
	left=(left+lCurSampleLeft*c1left+lPrevSampleLeft*c2left+0x80)&amp;gt;&amp;gt;8;&lt;br /&gt;
	right=(right+lCurSampleRight*c1right+lPrevSampleRight*c2right+0x80)&amp;gt;&amp;gt;8;&lt;br /&gt;
	left=Clip16BitSample(left);&lt;br /&gt;
	right=Clip16BitSample(right);&lt;br /&gt;
	lPrevSampleLeft=lCurSampleLeft;&lt;br /&gt;
	lCurSampleLeft=left;&lt;br /&gt;
	lPrevSampleRight=lCurSampleRight;&lt;br /&gt;
	lCurSampleRight=right;&lt;br /&gt;
&lt;br /&gt;
	'' Now we've got lCurSampleLeft and lCurSampleRight which form one stereo&lt;br /&gt;
	'' sample and all is set for the next input byte...&lt;br /&gt;
	Output((SHORT)lCurSampleLeft,(SHORT)lCurSampleRight); '' send the sample to output&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
'' process the rest (if any)&lt;br /&gt;
if ((dwOutSize % dwSubOutSize) != 0)&lt;br /&gt;
{&lt;br /&gt;
  bInput=InputBuffer[i++];&lt;br /&gt;
  c1left=EATable[HINIBBLE(bInput)];   '' predictor coeffs for left channel&lt;br /&gt;
  c2left=EATable[HINIBBLE(bInput)+4];&lt;br /&gt;
  c1right=EATable[LONIBBLE(bInput)];  '' predictor coeffs for right channel&lt;br /&gt;
  c2right=EATable[LONIBBLE(bInput)+4];&lt;br /&gt;
  bInput=InputBuffer[i++];&lt;br /&gt;
  dleft=HINIBBLE(bInput)+8;   '' shift value for left channel&lt;br /&gt;
  dright=LONIBBLE(bInput)+8;  '' shift value for right channel&lt;br /&gt;
  for (sCount=0;sCount&amp;lt;(dwOutSize % dwSubOutSize);sCount++)&lt;br /&gt;
  {&lt;br /&gt;
	bInput=InputBuffer[i++];&lt;br /&gt;
	left=HINIBBLE(bInput);  '' HIGHER nibble for left channel&lt;br /&gt;
	right=LONIBBLE(bInput); '' LOWER nibble for right channel&lt;br /&gt;
	left=(left&amp;lt;&amp;lt;0x1c)&amp;gt;&amp;gt;dleft;&lt;br /&gt;
	right=(right&amp;lt;&amp;lt;0x1c)&amp;gt;&amp;gt;dright;&lt;br /&gt;
	left=(left+lCurSampleLeft*c1left+lPrevSampleLeft*c2left+0x80)&amp;gt;&amp;gt;8;&lt;br /&gt;
	right=(right+lCurSampleRight*c1right+lPrevSampleRight*c2right+0x80)&amp;gt;&amp;gt;8;&lt;br /&gt;
	left=Clip16BitSample(left);&lt;br /&gt;
	right=Clip16BitSample(right);&lt;br /&gt;
	lPrevSampleLeft=lCurSampleLeft;&lt;br /&gt;
	lCurSampleLeft=left;&lt;br /&gt;
	lPrevSampleRight=lCurSampleRight;&lt;br /&gt;
	lCurSampleRight=right;&lt;br /&gt;
&lt;br /&gt;
	'' Now we've got lCurSampleLeft and lCurSampleRight which form one stereo&lt;br /&gt;
	'' sample and all is set for the next input byte...&lt;br /&gt;
	Output((SHORT)lCurSampleLeft,(SHORT)lCurSampleRight); '' send the sample to output&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
HINIBBLE and LONIBBLE are higher and lower 4-bit nibbles:&lt;br /&gt;
&amp;quot;&amp;quot;#define HINIBBLE(byte) ((byte) &amp;gt;&amp;gt; 4)&amp;quot;&amp;quot;&lt;br /&gt;
&amp;quot;&amp;quot;#define LONIBBLE(byte) ((byte) &amp;amp; 0x0F)&amp;quot;&amp;quot;&lt;br /&gt;
Note that depending on your compiler you may need to use additional nibble&lt;br /&gt;
separation in these defines, e.g. &amp;quot;&amp;quot;(((byte) &amp;gt;&amp;gt; 4) &amp;amp; 0x0F).&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
EATable is the table given in the next section of this document.&lt;br /&gt;
&lt;br /&gt;
Output() is just a placeholder for any action you would like to perform for&lt;br /&gt;
decompressed sample value.&lt;br /&gt;
&lt;br /&gt;
Clip16BitSample is quite evident:&lt;br /&gt;
&amp;lt;pre&amp;gt;(C)&lt;br /&gt;
LONG Clip16BitSample(LONG sample)&lt;br /&gt;
{&lt;br /&gt;
  if (sample&amp;gt;32767)&lt;br /&gt;
	 return 32767;&lt;br /&gt;
  else if (sample&amp;lt;-32768)&lt;br /&gt;
	 return (-32768);&lt;br /&gt;
  else&lt;br /&gt;
	 return sample;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
As to mono sound, it's just analoguous: dwSubOutSize=0x0E for mono and&lt;br /&gt;
you should get predictor coeffs and shift from one byte:&lt;br /&gt;
&amp;lt;pre&amp;gt;(C)&lt;br /&gt;
bInput=InputBuffer[i++];&lt;br /&gt;
c1=EATable[HINIBBLE(bInput)];	'' predictor coeffs&lt;br /&gt;
c2=EATable[HINIBBLE(bInput)+4];&lt;br /&gt;
d=LONIBBLE(bInput)+8;  '' shift value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And also you should process HIGHER nibble of the input byte first and then&lt;br /&gt;
LOWER nibble for mono sound.&lt;br /&gt;
&lt;br /&gt;
Of course, this decompression routine may be greatly optimized.&lt;br /&gt;
&lt;br /&gt;
======&lt;br /&gt;
3. EA ADPCM Table&lt;br /&gt;
======&lt;br /&gt;
&amp;lt;pre&amp;gt;(C)&lt;br /&gt;
LONG EATable[]=&lt;br /&gt;
{&lt;br /&gt;
  0x00000000,&lt;br /&gt;
  0x000000F0,&lt;br /&gt;
  0x000001CC,&lt;br /&gt;
  0x00000188,&lt;br /&gt;
  0x00000000,&lt;br /&gt;
  0x00000000,&lt;br /&gt;
  0xFFFFFF30,&lt;br /&gt;
  0xFFFFFF24,&lt;br /&gt;
  0x00000000,&lt;br /&gt;
  0x00000001,&lt;br /&gt;
  0x00000003,&lt;br /&gt;
  0x00000004,&lt;br /&gt;
  0x00000007,&lt;br /&gt;
  0x00000008,&lt;br /&gt;
  0x0000000A,&lt;br /&gt;
  0x0000000B,&lt;br /&gt;
  0x00000000,&lt;br /&gt;
  0xFFFFFFFF,&lt;br /&gt;
  0xFFFFFFFD,&lt;br /&gt;
  0xFFFFFFFC&lt;br /&gt;
};&amp;lt;/pre&amp;gt; [[Category:Modding]]&lt;/div&gt;</summary>
		<author><name>Delphy</name></author>	</entry>

	</feed>