How to create destroyable wheels: Difference between revisions
Categories:
mNo edit summary |
No edit summary |
||
| Line 1: | Line 1: | ||
==File Format== | |||
{| border="1" | |||
!Offset | |||
!Datatype | |||
!Content | |||
!Description | |||
|- | |||
|0 | |||
|char[4] | |||
|"WSS0" | |||
|file signature | |||
|- | |||
|4 | |||
|ulong | |||
|<compression> | |||
|if <compression> == 8 the PCM data is compressed, otherwise <compression> == 0 | |||
|- | |||
|8 | |||
|ushort | |||
|<format tag> | |||
|defines in which format the data is saved. Always 0x0001 in WSS files | |||
|- | |||
|10 | |||
|ushort | |||
|<channels> | |||
|number of channels: 1=mono, 2=stereo | |||
|- | |||
|12 | |||
|ulong | |||
|<sample rate> | |||
|sample rate in Hz (e.g. 44100Hz) | |||
|- | |||
|16 | |||
|ulong | |||
|<bytes/second> | |||
|<sample rate> * <block align> | |||
|- | |||
|20 | |||
|ushort | |||
|<block align> | |||
|<channels> * (<bits/sample> / 8) | |||
|- | |||
|22 | |||
|ushort | |||
|<bits/sample> | |||
|usually 0x0010 in WSS files | |||
|- | |||
|24 | |||
|ushort | |||
|<unknown> | |||
|unknown value | |||
|- | |||
|26 | |||
|byte[fileSize-26] | |||
|<soundData> | |||
|here the PCM data of the sound is stored | |||
|- | |||
|} | |||
==Decompression== | |||
If the <soundData> is compressed the following (C#) code can be used for decompression: | |||
PCMData = new Int16[soundData.Length]; | |||
for (int j = 0; j < PCMData.Length; j++) | |||
{ | |||
SByte srcSample = (SByte)soundData[j]; | |||
if (srcSample != 0) | |||
{ | |||
double asFloat = Math.Abs(srcSample) / 28.12574042515172; | |||
asFloat *= 2.3025850929940456840; //ln(10) | |||
asFloat *= 1.4426950408889634070; //log2(e) | |||
double rnd = Math.Round(asFloat); | |||
double mantisse = Math.Pow(2.0, asFloat - rnd); | |||
asFloat = mantisse * Math.Pow(2, rnd); | |||
if (srcSample < 0) asFloat *= -1; | |||
Int32 asInt = (int)Math.Round(asFloat); | |||
asInt = (j == 0) ? asInt : (asInt + PCMData[j - 1]); | |||
if (asInt > short.MaxValue) asInt = short.MaxValue; | |||
if (asInt < short.MinValue) asInt = short.MinValue; | |||
PCMData[j] = (Int16)asInt; | |||
} | |||
else PCMData[j] = (j == 0) ? (Int16)0 : PCMData[j - 1]; | |||
} | |||
Revision as of 23:29, 24 January 2010
File Format
| Offset | Datatype | Content | Description |
|---|---|---|---|
| 0 | char[4] | "WSS0" | file signature |
| 4 | ulong | <compression> | if <compression> == 8 the PCM data is compressed, otherwise <compression> == 0 |
| 8 | ushort | <format tag> | defines in which format the data is saved. Always 0x0001 in WSS files |
| 10 | ushort | <channels> | number of channels: 1=mono, 2=stereo |
| 12 | ulong | <sample rate> | sample rate in Hz (e.g. 44100Hz) |
| 16 | ulong | <bytes/second> | <sample rate> * <block align> |
| 20 | ushort | <block align> | <channels> * (<bits/sample> / 8) |
| 22 | ushort | <bits/sample> | usually 0x0010 in WSS files |
| 24 | ushort | <unknown> | unknown value |
| 26 | byte[fileSize-26] | <soundData> | here the PCM data of the sound is stored |
Decompression
If the <soundData> is compressed the following (C#) code can be used for decompression:
PCMData = new Int16[soundData.Length];
for (int j = 0; j < PCMData.Length; j++)
{
SByte srcSample = (SByte)soundData[j];
if (srcSample != 0)
{
double asFloat = Math.Abs(srcSample) / 28.12574042515172;
asFloat *= 2.3025850929940456840; //ln(10)
asFloat *= 1.4426950408889634070; //log2(e)
double rnd = Math.Round(asFloat);
double mantisse = Math.Pow(2.0, asFloat - rnd);
asFloat = mantisse * Math.Pow(2, rnd);
if (srcSample < 0) asFloat *= -1;
Int32 asInt = (int)Math.Round(asFloat);
asInt = (j == 0) ? asInt : (asInt + PCMData[j - 1]);
if (asInt > short.MaxValue) asInt = short.MaxValue;
if (asInt < short.MinValue) asInt = short.MinValue;
PCMData[j] = (Int16)asInt;
}
else PCMData[j] = (j == 0) ? (Int16)0 : PCMData[j - 1];
}